pax_global_header 0000666 0000000 0000000 00000000064 15160017072 0014511 g ustar 00root root 0000000 0000000 52 comment=cfe6dd5ed7fff8b7c7ad1e90c2a2cad151948620
diff-1.0.1/ 0000775 0000000 0000000 00000000000 15160017072 0012420 5 ustar 00root root 0000000 0000000 diff-1.0.1/.github/ 0000775 0000000 0000000 00000000000 15160017072 0013760 5 ustar 00root root 0000000 0000000 diff-1.0.1/.github/workflows/ 0000775 0000000 0000000 00000000000 15160017072 0016015 5 ustar 00root root 0000000 0000000 diff-1.0.1/.github/workflows/go.yml 0000664 0000000 0000000 00000002207 15160017072 0017146 0 ustar 00root root 0000000 0000000 # This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
name: Go
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
- name: Build
run: go build -v ./...
- name: Test
run: go test -v -vet=off ./...
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
- name: Go Format
run: gofmt -s -w . && git diff --exit-code
- name: Verify dependencies
run: go mod verify
- name: Go Mod Tidy
run: go mod tidy && git diff --exit-code
- name: Go Vet
run: go vet ./...
- name: Go Generate
run: go generate ./... && git diff --exit-code
vulncheck:
runs-on: ubuntu-latest
steps:
- name: Go Vulncheck
uses: golang/govulncheck-action@v1 diff-1.0.1/.github/workflows/latest-deps.yml 0000664 0000000 0000000 00000000672 15160017072 0020772 0 ustar 00root root 0000000 0000000 name: Test Latest Deps
on:
schedule:
- cron: '0 13 * * *' # daily at 1pm UTC
workflow_dispatch:
jobs:
test-latest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Update all dependencies
run: go get -t -u ./...
- name: Tidy
run: go mod tidy
- name: Test
run: go test ./...
diff-1.0.1/.github/workflows/vuln.yml 0000664 0000000 0000000 00000000625 15160017072 0017527 0 ustar 00root root 0000000 0000000 name: Vulncheck
on:
schedule:
- cron: '0 12 * * *' # daily at noon UTC
workflow_dispatch:
jobs:
govulncheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
- name: Run govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest && govulncheck ./...
diff-1.0.1/LICENSE 0000664 0000000 0000000 00000026135 15160017072 0013434 0 ustar 00root root 0000000 0000000 Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
diff-1.0.1/README.md 0000664 0000000 0000000 00000025110 15160017072 0013676 0 ustar 00root root 0000000 0000000 # znkr.io/diff
[](https://pkg.go.dev/znkr.io/diff)
[](https://goreportcard.com/report/znkr.io/diff)
A high-performance difference algorithm module for Go.
Difference algorithms compare two inputs and find the edits that transform one to the other. This is
very useful to understand changes, for example when comparing a test result with the expected result
or to understand which changes have been made to a file.
This module provides diffing for arbitrary Go slices and text.
I wrote a bit about the background and the design decisions that went into this module on
[flo.znkr.io/diff](https://flo.znkr.io/diff).
## Installation
To use this module in your Go project, run:
```bash
go get znkr.io/diff
```
## API Documentation
Full documentation available at [pkg.go.dev/znkr.io/diff](https://pkg.go.dev/znkr.io/diff).
## Examples
### Comparing Slices
Diffing two slices produces either the full list of edits
```go
x := strings.Fields("calm seas reflect the sky")
y := strings.Fields("restless seas reflect the sky defiantly")
edits := diff.Edits(x, y)
for i, edit := range edits {
if i > 0 {
fmt.Print(" ")
}
switch edit.Op {
case diff.Match:
fmt.Printf("%s", edit.X)
case diff.Delete:
fmt.Printf("[-%s-]", edit.X)
case diff.Insert:
fmt.Printf("{+%s+}", edit.Y)
default:
panic("never reached")
}
}
// Output:
// [-calm-] {+restless+} seas reflect the sky {+defiantly+}
```
or a list of hunks representing consecutive edits
```go
x := strings.Fields("calm seas reflect the sky")
y := strings.Fields("restless seas reflect the sky defiantly")
hunks := diff.Hunks(x, y, diff.Context(1))
for i, h := range hunks {
if i > 0 {
fmt.Print(" … ")
}
for i, edit := range h.Edits {
if i > 0 {
fmt.Print(" ")
}
switch edit.Op {
case diff.Match:
fmt.Printf("%s", edit.X)
case diff.Delete:
fmt.Printf("[-%s-]", edit.X)
case diff.Insert:
fmt.Printf("{+%s+}", edit.Y)
default:
panic("never reached")
}
}
}
// Output:
// [-calm-] {+restless+} seas … sky {+defiantly+}
```
For both functions, a `...Func` variant exists that works with arbitrary slices by taking an
equality function.
### Comparing Text
Because of its importance, comparing text line by line has special support and produces output
in the unified diff format:
```go
x := `this paragraph
is not
changed and
barely long
enough to
create a
new hunk
this paragraph
is going to be
removed
`
y := `this is a new paragraph
that is inserted at the top
this paragraph
is not
changed and
barely long
enough to
create a
new hunk
`
fmt.Print(textdiff.Unified(x, y))
// Output:
// @@ -1,3 +1,6 @@
// +this is a new paragraph
// +that is inserted at the top
// +
// this paragraph
// is not
// changed and
// @@ -5,7 +8,3 @@
// enough to
// create a
// new hunk
// -
// -this paragraph
// -is going to be
// -removed
```
## Stability
**API: Stable** - The API is stable and follows the Go module compatibility
[guidelines](https://go.dev/doc/modules/version-policy).
The exact diff output is not guaranteed to be stable: performance and quality improvements will
likely change the output of a diff. Committing to a stable diff result would be too limiting.
## Diff Readability
Diffs produced by this module are intended to be readable by humans.
Readable diffs have been the subject of a lot of discussions and have even resulted in some new
diffing algorithms like the patience or histogram algorithms in git. However, the best work about
diff readability by far is [diff-slider-tools](https://github.com/mhagger/diff-slider-tools) by
[Michael Haggerty](https://github.com/mhagger). He implemented a heuristic that's applied in a
post-processing step to improve the readability. This module implements this heuristic in the
[textdiff](https://pkg.go.dev/znkr.io/diff/textdiff) package.
For example:
```go
x := `// ...
["foo", "bar", "baz"].map do |i|
i.upcase
end
`
y := `// ...
["foo", "bar", "baz"].map do |i|
i
end
["foo", "bar", "baz"].map do |i|
i.upcase
end
`
fmt.Println("With textdiff.IndentHeuristic:")
fmt.Print(textdiff.Unified(x, y, textdiff.IndentHeuristic()))
fmt.Println()
fmt.Println("Without textdiff.IndentHeuristic:")
fmt.Print(textdiff.Unified(x, y))
// Output:
// With textdiff.IndentHeuristic:
// @@ -1,4 +1,8 @@
// // ...
// +["foo", "bar", "baz"].map do |i|
// + i
// +end
// +
// ["foo", "bar", "baz"].map do |i|
// i.upcase
// end
//
// Without textdiff.IndentHeuristic:
// @@ -1,4 +1,8 @@
// // ...
// ["foo", "bar", "baz"].map do |i|
// + i
// +end
// +
// +["foo", "bar", "baz"].map do |i|
// i.upcase
// end
```
## Performance
By default, the underlying diff algorithm used is Myers' algorithm augmented by a number of
heuristics to speed up the algorithm in exchange for non-minimal diffs. The `diff.Minimal` option is
provided to skip these heuristics to get a minimal diff independent of the costs and `diff.Fast` to
use a fast heuristic to get a non-minimal diff as fast as possible.
On an M1 Mac, the default settings almost always result in runtimes < 1 ms, but truly large diffs
(e.g. caused by changing generators for generated files) can result in runtimes of almost 100 ms.
Below is the distribution of runtimes applying `textdiff.Unified` to every commit in the [Go
repository](http://go.googlesource.com/go) (y-axis is in log scale):

### Comparison with other Implementations
Comparing the performance with other Go modules that implement the same features is always
interesting, because it can surface missed optimization opportunities. This is especially
interesting for larger inputs where superlinear growth can become a problem. Below are benchmarks of
`znkr.io/diff` against other popular Go diff modules:
- **znkr**: Default configuration with performance optimizations enabled
- **znkr-minimal**: With `diff.Minimal()` option for minimal diffs
- **znkr-fast**: With `diff.Fast()` option for fastest possible diffing
- **go-internal**: Patience diff algorithm from [`github.com/rogpeppe/go-internal`](https://github.com/rogpeppe/go-internal)
- **diffmatchpatch**: Implementation from [`github.com/sergi/go-diff`](https://github.com/sergi/go-diff)
- **godebug**: Implementation from [`golang.org/x/tools/godebug`](https://pkg.go.dev/golang.org/x/tools/godebug)
- **mb0**: Implementation from [`github.com/mb0/diff`](https://github.com/mb0/diff)
- **udiff**: Implementation from [`github.com/aymanbagabas/go-udiff`](https://github.com/aymanbagabas/go-udiff)
**Note:** It's possible that the benchmark is using `diffmatchpatch` incorrectly, the benchmark
numbers certainly look suspiciously high. However, the way it's used in the benchmark is used in
at least one large open source project.
#### Runtime Performance (seconds per operation)
On the benchmarks used for this comparison znkr.io/diff almost always outperforms the other
implementations. However, there's one case where go-internal is significantly faster, but the
resulting diff is 10% larger (see numbers below).
| Test Case | znkr (baseline) | znkr-minimal | znkr-fast | go-internal | diffmatchpatch | godebug | mb0 | udiff |
|-----------|-----------------|--------------|-----------|-------------|----------------|---------|-----|-------|
| **large_01** | 2.707ms | 10.993ms
(+306.14%) | 2.642ms
(-2.40%) | 4.928ms
(+82.04%) | 43.205ms
(+1496.15%) | 181.374ms
(+6600.66%) | 84.950ms
(+3038.39%) | 7.915ms
(+192.40%) |
| **large_02** | 20.591ms | 49.798ms
(+141.84%) | 1.840ms
(-91.06%) | 4.139ms
(-79.90%) | 623.986ms
(+2930.32%) | 3000.340ms
(+14470.84%) | 1513.701ms
(+7251.13%) | 6.457ms
(-68.64%) |
| **large_03** | 3.210ms | 15.138ms
(+371.61%) | 3.130ms
(-2.49%) | 4.688ms
(+46.04%) | 31.851ms
(+892.26%) | 187.093ms
(+5728.54%) | 105.379ms
(+3182.89%) | 10.057ms
(+213.31%) |
| **large_04** | 7.125ms | 249.229ms
(+3397.94%) | 5.557ms
(-22.01%) | 8.656ms
(+21.49%) | 1012.579ms
(+14111.61%) | 13230.536ms
(+185591.43%) | 2229.906ms
(+31196.87%) | 15.818ms
(+122.01%) |
| **medium** | 26.79µs | 27.38µs
(+2.23%) | 27.54µs
(+2.81%) | 64.70µs
(+141.55%) | 258.27µs
(+864.18%) | 705.62µs
(+2534.24%) | 269.56µs
(+906.34%) | 290.81µs
(+985.66%) |
| **small** | 18.30µs | 18.49µs
(+1.05%) | 18.43µs
(±0%) | 38.06µs
(+107.97%) | 78.23µs
(+327.41%) | 200.04µs
(+992.97%) | 52.86µs
(+188.83%) | 106.99µs
(+484.55%) |
#### Diff Minimality (number of edits produced)
| Test Case | znkr (baseline) | znkr-minimal | znkr-fast | go-internal | diffmatchpatch | godebug | mb0 | udiff |
|-----------|----------------|---------------|-----------|-------------|----------------|---------|-----|-------|
| **large_01** | 5.615k edits | 5.615k edits
(±0%) | 5.615k edits
(±0%) | 5.617k edits
(+0.04%) | 5.615k edits
(±0%) | 5.615k edits
(±0%) | 5.615k edits
(±0%) | 35.805k edits
(+537.67%) |
| **large_02** | 28.87k edits | 28.83k edits
(-0.15%) | 31.80k edits
(+10.15%) | 31.81k edits
(+10.17%) | 28.83k edits
(-0.14%) | 28.83k edits
(-0.15%) | 28.83k edits
(-0.15%) | 31.80k edits
(+10.13%) |
| **large_03** | 5.504k edits | 5.504k edits
(±0%) | 5.504k edits
(±0%) | 5.506k edits
(+0.04%) | 5.504k edits
(±0%) | 5.504k edits
(±0%) | 5.504k edits
(±0%) | 55.738k edits
(+912.68%) |
| **large_04** | 26.99k edits | 26.99k edits
(-0.01%) | 27.80k edits
(+2.99%) | 27.80k edits
(+2.99%) | 60.36k edits
(+123.65%) | 26.99k edits
(-0.01%) | 26.99k edits
(-0.01%) | 103.22k edits
(+282.45%) |
| **medium** | 277 edits | 277 edits
(±0%) | 277 edits
(±0%) | 283 edits
(+2.17%) | 277 edits
(±0%) | 277 edits
(±0%) | 277 edits
(±0%) | 431 edits
(+55.60%) |
| **small** | 108 edits | 108 edits
(±0%) | 114 edits
(+5.56%) | 120 edits
(+11.11%) | 108 edits
(±0%) | 108 edits
(±0%) | 108 edits
(±0%) | 280 edits
(+159.26%) |
## Correctness
I tested this diff implementation against every commit in the [Go
repository](http://go.googlesource.com/go) using the standard unix `patch` tool to ensure that all
diff results are correct.
This test is part of the test suite for this module and can be run with
```
go run ./internal/cmd/eval -repo
```
## License
This module is distributed under the [Apache License, Version
2.0](https://www.apache.org/licenses/LICENSE-2.0), see [LICENSE](LICENSE) for more information.
diff-1.0.1/diff.go 0000664 0000000 0000000 00000016233 15160017072 0013664 0 ustar 00root root 0000000 0000000 // Copyright 2025 Florian Zenker (flo@znkr.io)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package diff
import (
"slices"
"znkr.io/diff/internal/config"
"znkr.io/diff/internal/impl"
"znkr.io/diff/internal/rvecs"
)
// Op describes an edit operation.
//
//go:generate go tool golang.org/x/tools/cmd/stringer -type=Op
type Op int
const (
Match Op = iota // Two slice elements match
Delete // A deletion from an element on the left slice
Insert // An insertion of an element from the right side
)
// Edit describes a single edit of a diff.
//
// - For Match, both X and Y contain the matching element. PosX and PosY contain their respective
// positions in the input.
// - For Delete, X contains the deleted element and Y is unset (zero value). PosX contains its
// position in the input and PosY is -1.
// - For Insert, Y contains the inserted element and X is unset (zero value). PosY contains its
// position in the input and PosX is -1.
type Edit[T any] struct {
Op Op
PosX, PosY int
X, Y T
}
// Hunk describes a sequence of consecutive edits.
type Hunk[T any] struct {
PosX, EndX int // Start and end position in x.
PosY, EndY int // Start and end position in y.
Edits []Edit[T] // Edits to transform x[PosX:EndX] to y[PosY:EndY]
}
// Hunks compares the contents of x and y and returns the changes necessary to convert from one to
// the other.
//
// The output is a sequence of hunks. A hunk represents a contiguous block of changes (insertions
// and deletions) along with some surrounding context. The amount of context can be configured using
// [Context].
//
// If x and y are identical, the output has length zero.
//
// The following options are supported: [Context], [Minimal], [Fast]
//
// Important: The output is not guaranteed to be stable and may change with minor version upgrades.
// DO NOT rely on the output being stable.
func Hunks[T comparable](x, y []T, opts ...Option) []Hunk[T] {
cfg := config.FromOptions(opts, config.Context|config.Minimal|config.Fast)
rx, ry := impl.Diff(x, y, cfg)
return hunks(x, y, rx, ry, cfg)
}
// HunksFunc compares the contents of x and y using the provided equality comparison and returns the
// changes necessary to convert from one to the other.
//
// The output is a sequence of hunks that each describe a number of consecutive edits. Hunks include
// a number of matching elements before and after the last delete or insert operation. The number of
// elements can be configured using [Context].
//
// If x and y are identical, the output has length zero.
//
// The following options are supported: [Context], [Minimal]
//
// Note that this function has generally worse performance than [Hunks] for diffs with many changes.
//
// Important: The output is not guaranteed to be stable and may change with minor version upgrades.
// DO NOT rely on the output being stable.
func HunksFunc[T any](x, y []T, eq func(a, b T) bool, opts ...Option) []Hunk[T] {
cfg := config.FromOptions(opts, config.Context|config.Minimal)
rx, ry := impl.DiffFunc(x, y, eq, cfg)
return hunks(x, y, rx, ry, cfg)
}
func hunks[T any](x, y []T, rx, ry []bool, cfg config.Config) []Hunk[T] {
// Compute the number of hunks and edits, this is relatively cheap and allows us to preallocate
// the return values.
var nhunks, nedits int
for hunk := range rvecs.Hunks(rx, ry, cfg) {
nhunks++
nedits += hunk.Edits
}
if nhunks == 0 {
return nil
}
eout := make([]Edit[T], 0, nedits)
hout := make([]Hunk[T], 0, nhunks)
for hunk := range rvecs.Hunks(rx, ry, cfg) {
for s, t := hunk.S0, hunk.T0; s < hunk.S1 || t < hunk.T1; {
for s < hunk.S1 && rx[s] {
eout = append(eout, Edit[T]{
Op: Delete,
X: x[s],
PosX: s,
PosY: -1,
})
s++
}
for t < hunk.T1 && ry[t] {
eout = append(eout, Edit[T]{
Op: Insert,
Y: y[t],
PosX: -1,
PosY: t,
})
t++
}
for s < hunk.S1 && t < hunk.T1 && !rx[s] && !ry[t] {
eout = append(eout, Edit[T]{
Op: Match,
X: x[s],
Y: y[t],
PosX: s,
PosY: t,
})
s++
t++
}
}
hout = append(hout, Hunk[T]{
PosX: hunk.S0,
EndX: hunk.S1,
PosY: hunk.T0,
EndY: hunk.T1,
Edits: slices.Clip(eout),
})
eout = eout[len(eout):]
}
return hout
}
// Edits compares the contents of x and y and returns the changes necessary to convert from one to
// the other.
//
// Edits returns one edit for every element in the input slices. If x and y are identical, the
// output will consist of a match edit for every input element.
//
// The following option is supported: [Minimal], [Fast]
//
// Important: The output is not guaranteed to be stable and may change with minor version upgrades.
// DO NOT rely on the output being stable.
func Edits[T comparable](x, y []T, opts ...Option) []Edit[T] {
cfg := config.FromOptions(opts, config.Minimal|config.Fast)
rx, ry := impl.Diff(x, y, cfg)
return edits(x, y, rx, ry)
}
// EditsFunc compares the contents of x and y using the provided equality comparison and returns the
// changes necessary to convert from one to the other.
//
// EditsFunc returns edits for every element in the input. If both x and y are identical, the output
// will consist of a match edit for every input element.
//
// The following option is supported: [Minimal]
//
// Note that this function has generally worse performance than [Edits] for diffs with many changes.
//
// Important: The output is not guaranteed to be stable and may change with minor version upgrades.
// DO NOT rely on the output being stable.
func EditsFunc[T any](x, y []T, eq func(a, b T) bool, opts ...Option) []Edit[T] {
cfg := config.FromOptions(opts, config.Minimal)
rx, ry := impl.DiffFunc(x, y, eq, cfg)
return edits(x, y, rx, ry)
}
func edits[T any](x, y []T, rx, ry []bool) []Edit[T] {
// Compute the number of edits, this is relatively cheap and allows us to preallocate the return
// value.
n, m := len(rx)-1, len(ry)-1
var nedits int
for s, t := 0, 0; s < n || t < m; {
for s < n && rx[s] {
nedits++
s++
}
for t < m && ry[t] {
nedits++
t++
}
for s < n && t < m && !rx[s] && !ry[t] {
nedits++
s++
t++
}
}
if nedits == 0 {
return nil
}
eout := make([]Edit[T], 0, nedits)
for s, t := 0, 0; s < n || t < m; {
for s < n && rx[s] {
eout = append(eout, Edit[T]{
Op: Delete,
X: x[s],
PosX: s,
PosY: -1,
})
s++
}
for t < m && ry[t] {
eout = append(eout, Edit[T]{
Op: Insert,
Y: y[t],
PosX: -1,
PosY: t,
})
t++
}
for s < n && t < m && !rx[s] && !ry[t] {
eout = append(eout, Edit[T]{
Op: Match,
X: x[s],
Y: y[t],
PosX: s,
PosY: t,
})
s++
t++
}
}
return eout
}
diff-1.0.1/diff_test.go 0000664 0000000 0000000 00000024732 15160017072 0014726 0 ustar 00root root 0000000 0000000 // Copyright 2025 Florian Zenker (flo@znkr.io)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package diff
import (
"crypto/sha256"
"fmt"
"math/rand/v2"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
)
func TestHunks(t *testing.T) {
tests := []struct {
name string
x, y []string
opts []Option
want []Hunk[string]
}{
{
name: "identical",
x: []string{"foo", "bar", "baz"},
y: []string{"foo", "bar", "baz"},
want: nil,
},
{
name: "empty",
x: nil,
y: nil,
want: nil,
},
{
name: "x-empty",
x: nil,
y: []string{"foo", "bar", "baz"},
want: []Hunk[string]{
{
PosX: 0,
PosY: 0,
EndX: 0,
EndY: 3,
Edits: []Edit[string]{
{Insert, -1, 0, "", "foo"},
{Insert, -1, 1, "", "bar"},
{Insert, -1, 2, "", "baz"},
},
},
},
},
{
name: "y-empty",
x: []string{"foo", "bar", "baz"},
y: nil,
want: []Hunk[string]{
{
PosX: 0,
PosY: 0,
EndX: 3,
EndY: 0,
Edits: []Edit[string]{
{Delete, 0, -1, "foo", ""},
{Delete, 1, -1, "bar", ""},
{Delete, 2, -1, "baz", ""},
},
},
},
},
{
name: "same-prefix",
x: []string{"foo", "bar"},
y: []string{"foo", "baz"},
want: []Hunk[string]{
{
PosX: 0,
EndX: 2,
PosY: 0,
EndY: 2,
Edits: []Edit[string]{
{Match, 0, 0, "foo", "foo"},
{Delete, 1, -1, "bar", ""},
{Insert, -1, 1, "", "baz"},
},
},
},
},
{
name: "same-suffix",
x: []string{"foo", "bar"},
y: []string{"loo", "bar"},
want: []Hunk[string]{
{
PosX: 0,
EndX: 2,
PosY: 0,
EndY: 2,
Edits: []Edit[string]{
{Delete, 0, -1, "foo", ""},
{Insert, -1, 0, "", "loo"},
{Match, 1, 1, "bar", "bar"},
},
},
},
},
{
name: "ABCABBA_to_CBABAC",
x: strings.Split("ABCABBA", ""),
y: strings.Split("CBABAC", ""),
want: []Hunk[string]{
{
PosX: 0,
PosY: 0,
EndX: 7,
EndY: 6,
Edits: []Edit[string]{
{Delete, 0, -1, "A", ""},
{Insert, -1, 0, "", "C"},
{Match, 1, 1, "B", "B"},
{Delete, 2, -1, "C", ""},
{Match, 3, 2, "A", "A"},
{Match, 4, 3, "B", "B"},
{Delete, 5, -1, "B", ""},
{Match, 6, 4, "A", "A"},
{Insert, -1, 5, "", "C"},
},
},
},
},
{
name: "ABCABBA_to_CBABAC_no_context",
x: strings.Split("ABCABBA", ""),
y: strings.Split("CBABAC", ""),
opts: []Option{Context(0)},
want: []Hunk[string]{
{
PosX: 0,
PosY: 0,
EndX: 1,
EndY: 1,
Edits: []Edit[string]{
{Delete, 0, -1, "A", ""},
{Insert, -1, 0, "", "C"},
},
},
{
PosX: 2,
PosY: 2,
EndX: 3,
EndY: 2,
Edits: []Edit[string]{
{Delete, 2, -1, "C", ""},
},
},
{
PosX: 5,
PosY: 4,
EndX: 6,
EndY: 4,
Edits: []Edit[string]{
{Delete, 5, -1, "B", ""},
},
},
{
PosX: 7,
PosY: 5,
EndX: 7,
EndY: 6,
Edits: []Edit[string]{
{Insert, -1, 5, "", "C"},
},
},
},
},
{
name: "two-hunks",
x: []string{
"this paragraph",
"is not",
"changed and",
"barely long",
"enough to",
"create a",
"new hunk",
"",
"this paragraph",
"is going to be",
"removed",
},
y: []string{
"this is a new paragraph",
"that is inserted at the top",
"",
"this paragraph",
"is not",
"changed and",
"barely long",
"enough to",
"create a",
"new hunk",
},
want: []Hunk[string]{
{
PosX: 0,
EndX: 3,
PosY: 0,
EndY: 6,
Edits: []Edit[string]{
{Insert, -1, 0, "", "this is a new paragraph"},
{Insert, -1, 1, "", "that is inserted at the top"},
{Insert, -1, 2, "", ""},
{Match, 0, 3, "this paragraph", "this paragraph"},
{Match, 1, 4, "is not", "is not"},
{Match, 2, 5, "changed and", "changed and"},
},
},
{
PosX: 4,
EndX: 11,
PosY: 7,
EndY: 10,
Edits: []Edit[string]{
{Match, 4, 7, "enough to", "enough to"},
{Match, 5, 8, "create a", "create a"},
{Match, 6, 9, "new hunk", "new hunk"},
{Delete, 7, -1, "", ""},
{Delete, 8, -1, "this paragraph", ""},
{Delete, 9, -1, "is going to be", ""},
{Delete, 10, -1, "removed", ""},
},
},
},
},
{
name: "overlapping-consecutive-hunks-are-merged",
x: []string{
"this paragraph",
"stays but is",
"not long enough",
"to create a",
"new hunk",
"",
"this paragraph",
"is going to be",
"removed",
},
y: []string{
"this is a new paragraph",
"that is inserted at the top",
"",
"this paragraph",
"stays but is",
"not long enough",
"to create a",
"new hunk",
},
want: []Hunk[string]{
{
PosX: 0,
EndX: 9,
PosY: 0,
EndY: 8,
Edits: []Edit[string]{
{Insert, -1, 0, "", "this is a new paragraph"},
{Insert, -1, 1, "", "that is inserted at the top"},
{Insert, -1, 2, "", ""},
{Match, 0, 3, "this paragraph", "this paragraph"},
{Match, 1, 4, "stays but is", "stays but is"},
{Match, 2, 5, "not long enough", "not long enough"},
{Match, 3, 6, "to create a", "to create a"},
{Match, 4, 7, "new hunk", "new hunk"},
{Delete, 5, -1, "", ""},
{Delete, 6, -1, "this paragraph", ""},
{Delete, 7, -1, "is going to be", ""},
{Delete, 8, -1, "removed", ""},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
{
got := Hunks(tt.x, tt.y, tt.opts...)
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("Hunks(...) result is different [-want, +got]:\n%s", diff)
}
}
{
got := HunksFunc(tt.x, tt.y, func(a, b string) bool { return a == b }, tt.opts...)
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("HunksFunc(...) result is different [-want, +got]:\n%s", diff)
}
}
})
}
}
func TestEdits(t *testing.T) {
tests := []struct {
name string
x, y []string
want []Edit[string]
}{
{
name: "identical",
x: []string{"foo", "bar", "baz"},
y: []string{"foo", "bar", "baz"},
want: []Edit[string]{
{Match, 0, 0, "foo", "foo"},
{Match, 1, 1, "bar", "bar"},
{Match, 2, 2, "baz", "baz"},
},
},
{
name: "empty",
},
{
name: "x-empty",
y: []string{"foo", "bar", "baz"},
want: []Edit[string]{
{Insert, -1, 0, "", "foo"},
{Insert, -1, 1, "", "bar"},
{Insert, -1, 2, "", "baz"},
},
},
{
name: "y-empty",
x: []string{"foo", "bar", "baz"},
want: []Edit[string]{
{Delete, 0, -1, "foo", ""},
{Delete, 1, -1, "bar", ""},
{Delete, 2, -1, "baz", ""},
},
},
{
name: "ABCABBA_to_CBABAC",
x: strings.Split("ABCABBA", ""),
y: strings.Split("CBABAC", ""),
want: []Edit[string]{
{Delete, 0, -1, "A", ""},
{Insert, -1, 0, "", "C"},
{Match, 1, 1, "B", "B"},
{Delete, 2, -1, "C", ""},
{Match, 3, 2, "A", "A"},
{Match, 4, 3, "B", "B"},
{Delete, 5, -1, "B", ""},
{Match, 6, 4, "A", "A"},
{Insert, -1, 5, "", "C"},
},
},
{
name: "same-prefix",
x: []string{"foo", "bar"},
y: []string{"foo", "baz"},
want: []Edit[string]{
{Match, 0, 0, "foo", "foo"},
{Delete, 1, -1, "bar", ""},
{Insert, -1, 1, "", "baz"},
},
},
{
name: "same-suffix",
x: []string{"foo", "bar"},
y: []string{"loo", "bar"},
want: []Edit[string]{
{Delete, 0, -1, "foo", ""},
{Insert, -1, 0, "", "loo"},
{Match, 1, 1, "bar", "bar"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
{
got := Edits(tt.x, tt.y)
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("Edits(...) result is different (-want, +got):\n%s", diff)
}
}
{
got := EditsFunc(tt.x, tt.y, func(a, b string) bool { return a == b })
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("EditsFunc(...) result is different (-want, +got):\n%s", diff)
}
}
})
}
}
func BenchmarkHunks(b *testing.B) {
for _, s := range benchmarkSpecs {
b.Run(s.name(), func(b *testing.B) {
b.ReportAllocs()
x, y := s.generate([]byte{})
for b.Loop() {
_ = Hunks(x, y)
}
})
}
}
func BenchmarkHunksFunc(b *testing.B) {
for _, s := range benchmarkSpecs {
b.Run(s.name(), func(b *testing.B) {
b.ReportAllocs()
x, y := s.generate([]byte{})
for b.Loop() {
_ = HunksFunc(x, y, func(a, b int) bool { return a == b })
}
})
}
}
func BenchmarkEdits(b *testing.B) {
for _, s := range benchmarkSpecs {
b.Run(s.name(), func(b *testing.B) {
b.ReportAllocs()
x, y := s.generate([]byte{})
for b.Loop() {
_ = Edits(x, y)
}
})
}
}
func BenchmarkEditsFunc(b *testing.B) {
for _, s := range benchmarkSpecs {
b.Run(s.name(), func(b *testing.B) {
b.ReportAllocs()
x, y := s.generate([]byte{})
for b.Loop() {
_ = EditsFunc(x, y, func(a, b int) bool { return a == b })
}
})
}
}
type spec struct {
N, M int // Length of x and y respectively
D int // Number of edits (besides edits due to size differences)
}
var benchmarkSpecs = []spec{
{50, 50, 10},
{500, 50, 10},
{50, 500, 10},
{500, 500, 10},
{500, 500, 100},
{5000, 5500, 100},
}
func (s spec) name() string {
return fmt.Sprintf("N=%d_M=%d_D=%d", s.N, s.M, s.D)
}
func (s spec) generate(seed []byte) (x, y []int) {
rng := rand.New(rand.NewChaCha8(sha256.Sum256(seed)))
// Construct inputs based on the N, M, D specification.
flipped := false
n, m := s.N, s.M
if n < m {
n, m = m, n
flipped = true
}
x = make([]int, n)
for i := range x {
x[i] = rng.IntN(100)
}
y = make([]int, m)
delta := 0
if n != m {
delta = rng.IntN((n - m) / 2)
}
for i := range y {
y[i] = x[i+delta]
}
// We might already have some changes due to the different sizes for N and M, add D
// additional changes.
for d := s.D; d > 0; {
i := rng.IntN(len(y))
if y[i] >= 0 {
y[i] = -y[i]
d--
}
}
if flipped {
x, y = y, x
}
return
}
diff-1.0.1/doc.go 0000664 0000000 0000000 00000002664 15160017072 0013524 0 ustar 00root root 0000000 0000000 // Copyright 2025 Florian Zenker (flo@znkr.io)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package diff provides functions to efficiently compare two slices similar to the Unix diff
// command line tool to compare files.
//
// The main functions are [Hunks], which groups changes into contextual blocks, and [Edits], which
// returns every individual change. By default, the algorithms are optimized for performance and may
// use heuristics for very large inputs. Use [Minimal] to disable these heuristics when you need the
// shortest possible diff.
//
// Performance: Default complexity is O(N^1.5 log N) time and O(N) space. With [Minimal], time
// complexity is O(ND) where N = len(x) + len(y) and D is the number of edits. With [Fast], time
// complexity is O(N log N).
//
// Note: For a line-by-line diff of text, please see [znkr.io/diff/textdiff].
//
// [znkr.io/diff/textdiff]: https://pkg.go.dev/znkr.io/diff/textdiff
package diff
diff-1.0.1/example_test.go 0000664 0000000 0000000 00000007261 15160017072 0015447 0 ustar 00root root 0000000 0000000 // Copyright 2025 Florian Zenker (flo@znkr.io)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package diff_test
import (
"fmt"
"strings"
"znkr.io/diff"
)
// Compare to strings line by line and output the difference as a pseudo-unified diff output (i.e.
// it's similar to what diff -u would produce). The format is not a correct unified diff though, in
// particular line endings (esp. at the end of the input) are handled differently.
//
// More generally, comparing text line by line is better solved with the textdiff subpackage.
func ExampleHunks_pseudoUnified() {
x := `this paragraph
is not
changed and
barely long
enough to
create a
new hunk
this paragraph
is going to be
removed`
y := `this is a new paragraph
that is inserted at the top
this paragraph
is not
changed and
barely long
enough to
create a
new hunk`
xlines := strings.Split(x, "\n")
ylines := strings.Split(y, "\n")
hunks := diff.Hunks(xlines, ylines)
for _, h := range hunks {
fmt.Printf("@@ -%d,%d +%d,%d @@\n", h.PosX+1, h.EndX-h.PosX, h.PosY+1, h.EndY-h.PosY)
for _, edit := range h.Edits {
switch edit.Op {
case diff.Match:
fmt.Printf(" %s\n", edit.X)
case diff.Delete:
fmt.Printf("-%s\n", edit.X)
case diff.Insert:
fmt.Printf("+%s\n", edit.Y)
default:
panic("never reached")
}
}
}
// Output:
// @@ -1,3 +1,6 @@
// +this is a new paragraph
// +that is inserted at the top
// +
// this paragraph
// is not
// changed and
// @@ -5,7 +8,3 @@
// enough to
// create a
// new hunk
// -
// -this paragraph
// -is going to be
// -removed
}
// Compare two strings rune by rune.
func ExampleEdits_runes() {
x := []rune("Hello, World")
y := []rune("Hello, 世界")
edits := diff.Edits(x, y)
for _, edit := range edits {
switch edit.Op {
case diff.Match:
fmt.Printf("%s", string(edit.X))
case diff.Delete:
fmt.Printf("[-%s-]", string(edit.X))
case diff.Insert:
fmt.Printf("{+%s+}", string(edit.Y))
default:
panic("never reached")
}
}
// Output:
// Hello, [-W-][-o-][-r-][-l-][-d-]{+世+}{+界+}
}
// Compare two strings word by word.
func ExampleEdits_words() {
x := strings.Fields("calm seas reflect the sky")
y := strings.Fields("restless seas reflect the sky defiantly")
edits := diff.Edits(x, y)
for i, edit := range edits {
if i > 0 {
fmt.Print(" ")
}
switch edit.Op {
case diff.Match:
fmt.Printf("%s", edit.X)
case diff.Delete:
fmt.Printf("[-%s-]", edit.X)
case diff.Insert:
fmt.Printf("{+%s+}", edit.Y)
default:
panic("never reached")
}
}
// Output:
// [-calm-] {+restless+} seas reflect the sky {+defiantly+}
}
func ExampleContext() {
x := strings.Fields("calm seas reflect the sky")
y := strings.Fields("restless seas reflect the sky defiantly")
hunks := diff.Hunks(x, y, diff.Context(1))
for i, h := range hunks {
if i > 0 {
fmt.Print(" … ")
}
for i, edit := range h.Edits {
if i > 0 {
fmt.Print(" ")
}
switch edit.Op {
case diff.Match:
fmt.Printf("%s", edit.X)
case diff.Delete:
fmt.Printf("[-%s-]", edit.X)
case diff.Insert:
fmt.Printf("{+%s+}", edit.Y)
default:
panic("never reached")
}
}
}
// Output:
// [-calm-] {+restless+} seas … sky {+defiantly+}
}
diff-1.0.1/go.mod 0000664 0000000 0000000 00000000432 15160017072 0013525 0 ustar 00root root 0000000 0000000 module znkr.io/diff
go 1.24.13
tool (
golang.org/x/tools/cmd/stringer
znkr.io/diff/internal/cmd/specializemyers
)
require (
github.com/google/go-cmp v0.7.0
golang.org/x/tools v0.42.0
)
require (
golang.org/x/mod v0.33.0 // indirect
golang.org/x/sync v0.19.0 // indirect
)
diff-1.0.1/go.sum 0000664 0000000 0000000 00000001170 15160017072 0013552 0 ustar 00root root 0000000 0000000 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
diff-1.0.1/internal/ 0000775 0000000 0000000 00000000000 15160017072 0014234 5 ustar 00root root 0000000 0000000 diff-1.0.1/internal/benchmarks/ 0000775 0000000 0000000 00000000000 15160017072 0016351 5 ustar 00root root 0000000 0000000 diff-1.0.1/internal/benchmarks/README.md 0000664 0000000 0000000 00000000257 15160017072 0017634 0 ustar 00root root 0000000 0000000 # Comparison of znkr.io/diff with other implementations
Run this command to produce the comparison:
```
go test -count 10 -bench=. . | benchstat -col /impl -row /name -
```
diff-1.0.1/internal/benchmarks/benchmark_test.go 0000664 0000000 0000000 00000003217 15160017072 0021674 0 ustar 00root root 0000000 0000000 package benchmarks
import (
"bytes"
"path/filepath"
"strings"
"testing"
"golang.org/x/tools/txtar"
"znkr.io/diff"
"znkr.io/diff/textdiff"
)
type testdata struct {
name string
x, y []byte
}
func loadTestdata(t testing.TB) []testdata {
t.Helper()
testFiles, err := filepath.Glob("testdata/*.test")
if err != nil {
t.Fatalf("Failed to read testdata: %v", err)
}
var tests []testdata
for _, filename := range testFiles {
ar, err := txtar.ParseFile(filename)
if err != nil {
t.Fatalf("failed to parse test case: %v", err)
}
name := strings.TrimPrefix(filename, "testdata/")
test := testdata{
name: name,
}
for _, f := range ar.Files {
switch f.Name {
case "x":
test.x = f.Data
case "y":
test.y = f.Data
default:
t.Fatalf("unknown file in archive: %v", f)
}
}
tests = append(tests, test)
}
return tests
}
func BenchmarkDiffs(b *testing.B) {
optD := make(map[string]int)
for _, td := range loadTestdata(b) {
edits := textdiff.Edits(td.x, td.y, diff.Minimal())
d := 0
for _, edit := range edits {
if edit.Op != diff.Match {
d++
}
}
optD[td.name] = d
}
for _, impl := range Impls {
b.Run("impl="+impl.Name, func(b *testing.B) {
for _, td := range loadTestdata(b) {
b.Run("name="+td.name, func(b *testing.B) {
for b.Loop() {
_ = impl.Diff(td.x, td.y)
}
b.StopTimer()
out := impl.Diff(td.x, td.y)
edits := 0
for _, line := range bytes.Split(out, []byte("\n")) {
if bytes.HasPrefix(line, []byte{'+'}) || bytes.HasPrefix(line, []byte{'-'}) {
edits++
}
}
b.ReportMetric(float64(edits), "edits")
})
}
})
}
}
diff-1.0.1/internal/benchmarks/cmd/ 0000775 0000000 0000000 00000000000 15160017072 0017114 5 ustar 00root root 0000000 0000000 diff-1.0.1/internal/benchmarks/cmd/diff/ 0000775 0000000 0000000 00000000000 15160017072 0020024 5 ustar 00root root 0000000 0000000 diff-1.0.1/internal/benchmarks/cmd/diff/main.go 0000664 0000000 0000000 00000003041 15160017072 0021275 0 ustar 00root root 0000000 0000000 // diff is a small CLI to manually run the diffing implementations used for benchmarking.
package main
import (
"flag"
"fmt"
"os"
"golang.org/x/tools/txtar"
"znkr.io/diff/internal/benchmarks"
)
type config struct {
lib string
x, y string
txtar string
}
func main() {
var cfg config
flag.StringVar(&cfg.lib, "lib", "znkr", "library to use for diffing")
flag.StringVar(&cfg.txtar, "txtar", "", "use testdata txtar file instead of two input files")
flag.Parse()
if cfg.txtar != "" {
if flag.CommandLine.NArg() != 0 {
fmt.Fprintf(os.Stderr, "error: usage: diff -txtar \n")
os.Exit(1)
}
} else {
if flag.CommandLine.NArg() != 2 {
fmt.Fprintf(os.Stderr, "error: usage: diff \n")
os.Exit(1)
}
cfg.x = flag.CommandLine.Arg(0)
cfg.y = flag.CommandLine.Arg(1)
}
if err := run(cfg); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}
func run(cfg config) error {
var lib *benchmarks.Impl
for _, l := range benchmarks.Impls {
if l.Name == cfg.lib {
lib = &l
}
}
if lib == nil {
return fmt.Errorf("lib not found %q", cfg.lib)
}
var x, y []byte
if cfg.txtar != "" {
ar, err := txtar.ParseFile(cfg.txtar)
if err != nil {
return err
}
for _, f := range ar.Files {
switch f.Name {
case "x":
x = f.Data
case "y":
y = f.Data
}
}
} else {
var err error
x, err = os.ReadFile(cfg.x)
if err != nil {
return err
}
y, err = os.ReadFile(cfg.y)
if err != nil {
return err
}
}
out := lib.Diff(x, y)
os.Stdout.Write(out)
return nil
}
diff-1.0.1/internal/benchmarks/go.mod 0000664 0000000 0000000 00000000575 15160017072 0017466 0 ustar 00root root 0000000 0000000 module znkr.io/diff/internal/benchmarks
go 1.24.0
require (
github.com/aymanbagabas/go-udiff v0.3.1
github.com/kylelemons/godebug v1.1.0
github.com/mb0/diff v0.0.0-20131118162322-d8d9a906c24d
github.com/rogpeppe/go-internal v1.14.1
github.com/sergi/go-diff v1.4.0
golang.org/x/tools v0.37.0
znkr.io/diff v0.0.0-20250814195549-58fd23adf4e1
)
replace znkr.io/diff => ../..
diff-1.0.1/internal/benchmarks/go.sum 0000664 0000000 0000000 00000005112 15160017072 0017503 0 ustar 00root root 0000000 0000000 github.com/aymanbagabas/go-udiff v0.3.1 h1:LV+qyBQ2pqe0u42ZsUEtPiCaUoqgA9gYRDs3vj1nolY=
github.com/aymanbagabas/go-udiff v0.3.1/go.mod h1:G0fsKmG+P6ylD0r6N/KgQD/nWzgfnl8ZBcNLgcbrw8E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mb0/diff v0.0.0-20131118162322-d8d9a906c24d h1:eAS2t2Vy+6psf9LZ4T5WXWsbkBt3Tu5PWekJy5AGyEU=
github.com/mb0/diff v0.0.0-20131118162322-d8d9a906c24d/go.mod h1:3YMHqrw2Qu3Liy82v4QdAG17e9k91HZ7w3hqlpWqhDo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
diff-1.0.1/internal/benchmarks/libraries.go 0000664 0000000 0000000 00000006430 15160017072 0020657 0 ustar 00root root 0000000 0000000 package benchmarks
import (
"bytes"
"strings"
"github.com/aymanbagabas/go-udiff"
godebug "github.com/kylelemons/godebug/diff"
mb0 "github.com/mb0/diff"
gointernal "github.com/rogpeppe/go-internal/diff"
"github.com/sergi/go-diff/diffmatchpatch"
"znkr.io/diff"
"znkr.io/diff/textdiff"
)
type Impl struct {
Name string
Diff func(x, y []byte) []byte
}
var Impls = []Impl{
{
Name: "znkr",
Diff: func(x, y []byte) []byte {
return textdiff.Unified(x, y, textdiff.IndentHeuristic())
},
},
{
Name: "znkr-minimal",
Diff: func(x, y []byte) []byte {
return textdiff.Unified(x, y, diff.Minimal(), textdiff.IndentHeuristic())
},
},
{
Name: "znkr-fast",
Diff: func(x, y []byte) []byte {
return textdiff.Unified(x, y, diff.Fast(), textdiff.IndentHeuristic())
},
},
{
Name: "go-internal",
Diff: func(x, y []byte) []byte {
return gointernal.Diff("x", x, "y", y)
},
},
{
Name: "diffmatchpatch",
Diff: func(x, y []byte) []byte {
// This function is not exactly creating a unified diff, but it's close enough to be
// comparable.
dmp := diffmatchpatch.New()
rx, ry, lines := dmp.DiffLinesToRunes(string(x), string(y))
diffs := dmp.DiffMainRunes(rx, ry, false)
diffs = dmp.DiffCharsToLines(diffs, lines)
var buf bytes.Buffer
for _, diff := range diffs {
text := diff.Text
switch diff.Type {
case diffmatchpatch.DiffInsert:
lines := strings.SplitAfter(text, "\n")
for _, line := range lines {
if line == "" {
continue
}
buf.WriteString("+")
buf.WriteString(line)
}
case diffmatchpatch.DiffDelete:
lines := strings.SplitAfter(text, "\n")
for _, line := range lines {
if line == "" {
continue
}
buf.WriteString("-")
buf.WriteString(line)
}
case diffmatchpatch.DiffEqual:
lines := strings.SplitAfter(text, "\n")
for _, line := range lines {
if line == "" {
continue
}
buf.WriteString(" ")
buf.WriteString(line)
}
}
}
return buf.Bytes()
},
},
{
Name: "godebug",
Diff: func(x, y []byte) []byte {
// This function is not exactly creating a unified diff, but it's close enough to be
// comparable.
return []byte(godebug.Diff(string(x), string(y)))
},
},
{
Name: "mb0",
Diff: func(x, y []byte) []byte {
// This function is not exactly creating a unified diff, but it's close enough to be
// comparable.
d := mb0lines{
x: bytes.SplitAfter(x, []byte("\n")),
y: bytes.SplitAfter(y, []byte("\n")),
}
changes := mb0.Diff(len(d.x), len(d.y), d)
var buf bytes.Buffer
a, b := 0, 0
for _, ch := range changes {
for a < ch.A {
buf.WriteString(" ")
buf.Write(d.x[a])
a++
b++
}
for i := range ch.Del {
buf.WriteString("-")
buf.Write(d.x[ch.A+i])
a++
}
for i := range ch.Ins {
buf.WriteString("+")
buf.Write(d.y[ch.B+i])
b++
}
}
for a < len(d.x) {
buf.WriteString(" ")
buf.Write(d.x[a])
a++
}
return buf.Bytes()
},
},
{
Name: "udiff",
Diff: func(x, y []byte) []byte {
return []byte(udiff.Unified("x", "y", string(x), string(y)))
},
},
}
type mb0lines struct {
x [][]byte
y [][]byte
}
func (d mb0lines) Equal(i, j int) bool { return bytes.Equal(d.x[i], d.y[j]) }
diff-1.0.1/internal/benchmarks/testdata/ 0000775 0000000 0000000 00000000000 15160017072 0020162 5 ustar 00root root 0000000 0000000 diff-1.0.1/internal/benchmarks/testdata/large_01.test 0000664 0000000 0000000 00005360127 15160017072 0022473 0 ustar 00root root 0000000 0000000 From https://go.googlesource.com/go
commit cedf5008a84d3726f98fac551a4016bf0a91157f
file src/cmd/compile/internal/ssa/rewriteARM64.go
-- x --
// Code generated from _gen/ARM64.rules using 'go generate'; DO NOT EDIT.
package ssa
import "cmd/compile/internal/types"
func rewriteValueARM64(v *Value) bool {
switch v.Op {
case OpARM64ADCSflags:
return rewriteValueARM64_OpARM64ADCSflags(v)
case OpARM64ADD:
return rewriteValueARM64_OpARM64ADD(v)
case OpARM64ADDSflags:
return rewriteValueARM64_OpARM64ADDSflags(v)
case OpARM64ADDconst:
return rewriteValueARM64_OpARM64ADDconst(v)
case OpARM64ADDshiftLL:
return rewriteValueARM64_OpARM64ADDshiftLL(v)
case OpARM64ADDshiftRA:
return rewriteValueARM64_OpARM64ADDshiftRA(v)
case OpARM64ADDshiftRL:
return rewriteValueARM64_OpARM64ADDshiftRL(v)
case OpARM64AND:
return rewriteValueARM64_OpARM64AND(v)
case OpARM64ANDconst:
return rewriteValueARM64_OpARM64ANDconst(v)
case OpARM64ANDshiftLL:
return rewriteValueARM64_OpARM64ANDshiftLL(v)
case OpARM64ANDshiftRA:
return rewriteValueARM64_OpARM64ANDshiftRA(v)
case OpARM64ANDshiftRL:
return rewriteValueARM64_OpARM64ANDshiftRL(v)
case OpARM64ANDshiftRO:
return rewriteValueARM64_OpARM64ANDshiftRO(v)
case OpARM64BIC:
return rewriteValueARM64_OpARM64BIC(v)
case OpARM64BICshiftLL:
return rewriteValueARM64_OpARM64BICshiftLL(v)
case OpARM64BICshiftRA:
return rewriteValueARM64_OpARM64BICshiftRA(v)
case OpARM64BICshiftRL:
return rewriteValueARM64_OpARM64BICshiftRL(v)
case OpARM64BICshiftRO:
return rewriteValueARM64_OpARM64BICshiftRO(v)
case OpARM64CMN:
return rewriteValueARM64_OpARM64CMN(v)
case OpARM64CMNW:
return rewriteValueARM64_OpARM64CMNW(v)
case OpARM64CMNWconst:
return rewriteValueARM64_OpARM64CMNWconst(v)
case OpARM64CMNconst:
return rewriteValueARM64_OpARM64CMNconst(v)
case OpARM64CMNshiftLL:
return rewriteValueARM64_OpARM64CMNshiftLL(v)
case OpARM64CMNshiftRA:
return rewriteValueARM64_OpARM64CMNshiftRA(v)
case OpARM64CMNshiftRL:
return rewriteValueARM64_OpARM64CMNshiftRL(v)
case OpARM64CMP:
return rewriteValueARM64_OpARM64CMP(v)
case OpARM64CMPW:
return rewriteValueARM64_OpARM64CMPW(v)
case OpARM64CMPWconst:
return rewriteValueARM64_OpARM64CMPWconst(v)
case OpARM64CMPconst:
return rewriteValueARM64_OpARM64CMPconst(v)
case OpARM64CMPshiftLL:
return rewriteValueARM64_OpARM64CMPshiftLL(v)
case OpARM64CMPshiftRA:
return rewriteValueARM64_OpARM64CMPshiftRA(v)
case OpARM64CMPshiftRL:
return rewriteValueARM64_OpARM64CMPshiftRL(v)
case OpARM64CSEL:
return rewriteValueARM64_OpARM64CSEL(v)
case OpARM64CSEL0:
return rewriteValueARM64_OpARM64CSEL0(v)
case OpARM64CSETM:
return rewriteValueARM64_OpARM64CSETM(v)
case OpARM64CSINC:
return rewriteValueARM64_OpARM64CSINC(v)
case OpARM64CSINV:
return rewriteValueARM64_OpARM64CSINV(v)
case OpARM64CSNEG:
return rewriteValueARM64_OpARM64CSNEG(v)
case OpARM64DIV:
return rewriteValueARM64_OpARM64DIV(v)
case OpARM64DIVW:
return rewriteValueARM64_OpARM64DIVW(v)
case OpARM64EON:
return rewriteValueARM64_OpARM64EON(v)
case OpARM64EONshiftLL:
return rewriteValueARM64_OpARM64EONshiftLL(v)
case OpARM64EONshiftRA:
return rewriteValueARM64_OpARM64EONshiftRA(v)
case OpARM64EONshiftRL:
return rewriteValueARM64_OpARM64EONshiftRL(v)
case OpARM64EONshiftRO:
return rewriteValueARM64_OpARM64EONshiftRO(v)
case OpARM64Equal:
return rewriteValueARM64_OpARM64Equal(v)
case OpARM64FADDD:
return rewriteValueARM64_OpARM64FADDD(v)
case OpARM64FADDS:
return rewriteValueARM64_OpARM64FADDS(v)
case OpARM64FCMPD:
return rewriteValueARM64_OpARM64FCMPD(v)
case OpARM64FCMPS:
return rewriteValueARM64_OpARM64FCMPS(v)
case OpARM64FMOVDfpgp:
return rewriteValueARM64_OpARM64FMOVDfpgp(v)
case OpARM64FMOVDgpfp:
return rewriteValueARM64_OpARM64FMOVDgpfp(v)
case OpARM64FMOVDload:
return rewriteValueARM64_OpARM64FMOVDload(v)
case OpARM64FMOVDloadidx:
return rewriteValueARM64_OpARM64FMOVDloadidx(v)
case OpARM64FMOVDloadidx8:
return rewriteValueARM64_OpARM64FMOVDloadidx8(v)
case OpARM64FMOVDstore:
return rewriteValueARM64_OpARM64FMOVDstore(v)
case OpARM64FMOVDstoreidx:
return rewriteValueARM64_OpARM64FMOVDstoreidx(v)
case OpARM64FMOVDstoreidx8:
return rewriteValueARM64_OpARM64FMOVDstoreidx8(v)
case OpARM64FMOVSload:
return rewriteValueARM64_OpARM64FMOVSload(v)
case OpARM64FMOVSloadidx:
return rewriteValueARM64_OpARM64FMOVSloadidx(v)
case OpARM64FMOVSloadidx4:
return rewriteValueARM64_OpARM64FMOVSloadidx4(v)
case OpARM64FMOVSstore:
return rewriteValueARM64_OpARM64FMOVSstore(v)
case OpARM64FMOVSstoreidx:
return rewriteValueARM64_OpARM64FMOVSstoreidx(v)
case OpARM64FMOVSstoreidx4:
return rewriteValueARM64_OpARM64FMOVSstoreidx4(v)
case OpARM64FMULD:
return rewriteValueARM64_OpARM64FMULD(v)
case OpARM64FMULS:
return rewriteValueARM64_OpARM64FMULS(v)
case OpARM64FNEGD:
return rewriteValueARM64_OpARM64FNEGD(v)
case OpARM64FNEGS:
return rewriteValueARM64_OpARM64FNEGS(v)
case OpARM64FNMULD:
return rewriteValueARM64_OpARM64FNMULD(v)
case OpARM64FNMULS:
return rewriteValueARM64_OpARM64FNMULS(v)
case OpARM64FSUBD:
return rewriteValueARM64_OpARM64FSUBD(v)
case OpARM64FSUBS:
return rewriteValueARM64_OpARM64FSUBS(v)
case OpARM64GreaterEqual:
return rewriteValueARM64_OpARM64GreaterEqual(v)
case OpARM64GreaterEqualF:
return rewriteValueARM64_OpARM64GreaterEqualF(v)
case OpARM64GreaterEqualU:
return rewriteValueARM64_OpARM64GreaterEqualU(v)
case OpARM64GreaterThan:
return rewriteValueARM64_OpARM64GreaterThan(v)
case OpARM64GreaterThanF:
return rewriteValueARM64_OpARM64GreaterThanF(v)
case OpARM64GreaterThanU:
return rewriteValueARM64_OpARM64GreaterThanU(v)
case OpARM64LDP:
return rewriteValueARM64_OpARM64LDP(v)
case OpARM64LessEqual:
return rewriteValueARM64_OpARM64LessEqual(v)
case OpARM64LessEqualF:
return rewriteValueARM64_OpARM64LessEqualF(v)
case OpARM64LessEqualU:
return rewriteValueARM64_OpARM64LessEqualU(v)
case OpARM64LessThan:
return rewriteValueARM64_OpARM64LessThan(v)
case OpARM64LessThanF:
return rewriteValueARM64_OpARM64LessThanF(v)
case OpARM64LessThanU:
return rewriteValueARM64_OpARM64LessThanU(v)
case OpARM64MADD:
return rewriteValueARM64_OpARM64MADD(v)
case OpARM64MADDW:
return rewriteValueARM64_OpARM64MADDW(v)
case OpARM64MNEG:
return rewriteValueARM64_OpARM64MNEG(v)
case OpARM64MNEGW:
return rewriteValueARM64_OpARM64MNEGW(v)
case OpARM64MOD:
return rewriteValueARM64_OpARM64MOD(v)
case OpARM64MODW:
return rewriteValueARM64_OpARM64MODW(v)
case OpARM64MOVBUload:
return rewriteValueARM64_OpARM64MOVBUload(v)
case OpARM64MOVBUloadidx:
return rewriteValueARM64_OpARM64MOVBUloadidx(v)
case OpARM64MOVBUreg:
return rewriteValueARM64_OpARM64MOVBUreg(v)
case OpARM64MOVBload:
return rewriteValueARM64_OpARM64MOVBload(v)
case OpARM64MOVBloadidx:
return rewriteValueARM64_OpARM64MOVBloadidx(v)
case OpARM64MOVBreg:
return rewriteValueARM64_OpARM64MOVBreg(v)
case OpARM64MOVBstore:
return rewriteValueARM64_OpARM64MOVBstore(v)
case OpARM64MOVBstoreidx:
return rewriteValueARM64_OpARM64MOVBstoreidx(v)
case OpARM64MOVBstorezero:
return rewriteValueARM64_OpARM64MOVBstorezero(v)
case OpARM64MOVBstorezeroidx:
return rewriteValueARM64_OpARM64MOVBstorezeroidx(v)
case OpARM64MOVDload:
return rewriteValueARM64_OpARM64MOVDload(v)
case OpARM64MOVDloadidx:
return rewriteValueARM64_OpARM64MOVDloadidx(v)
case OpARM64MOVDloadidx8:
return rewriteValueARM64_OpARM64MOVDloadidx8(v)
case OpARM64MOVDnop:
return rewriteValueARM64_OpARM64MOVDnop(v)
case OpARM64MOVDreg:
return rewriteValueARM64_OpARM64MOVDreg(v)
case OpARM64MOVDstore:
return rewriteValueARM64_OpARM64MOVDstore(v)
case OpARM64MOVDstoreidx:
return rewriteValueARM64_OpARM64MOVDstoreidx(v)
case OpARM64MOVDstoreidx8:
return rewriteValueARM64_OpARM64MOVDstoreidx8(v)
case OpARM64MOVDstorezero:
return rewriteValueARM64_OpARM64MOVDstorezero(v)
case OpARM64MOVDstorezeroidx:
return rewriteValueARM64_OpARM64MOVDstorezeroidx(v)
case OpARM64MOVDstorezeroidx8:
return rewriteValueARM64_OpARM64MOVDstorezeroidx8(v)
case OpARM64MOVHUload:
return rewriteValueARM64_OpARM64MOVHUload(v)
case OpARM64MOVHUloadidx:
return rewriteValueARM64_OpARM64MOVHUloadidx(v)
case OpARM64MOVHUloadidx2:
return rewriteValueARM64_OpARM64MOVHUloadidx2(v)
case OpARM64MOVHUreg:
return rewriteValueARM64_OpARM64MOVHUreg(v)
case OpARM64MOVHload:
return rewriteValueARM64_OpARM64MOVHload(v)
case OpARM64MOVHloadidx:
return rewriteValueARM64_OpARM64MOVHloadidx(v)
case OpARM64MOVHloadidx2:
return rewriteValueARM64_OpARM64MOVHloadidx2(v)
case OpARM64MOVHreg:
return rewriteValueARM64_OpARM64MOVHreg(v)
case OpARM64MOVHstore:
return rewriteValueARM64_OpARM64MOVHstore(v)
case OpARM64MOVHstoreidx:
return rewriteValueARM64_OpARM64MOVHstoreidx(v)
case OpARM64MOVHstoreidx2:
return rewriteValueARM64_OpARM64MOVHstoreidx2(v)
case OpARM64MOVHstorezero:
return rewriteValueARM64_OpARM64MOVHstorezero(v)
case OpARM64MOVHstorezeroidx:
return rewriteValueARM64_OpARM64MOVHstorezeroidx(v)
case OpARM64MOVHstorezeroidx2:
return rewriteValueARM64_OpARM64MOVHstorezeroidx2(v)
case OpARM64MOVQstorezero:
return rewriteValueARM64_OpARM64MOVQstorezero(v)
case OpARM64MOVWUload:
return rewriteValueARM64_OpARM64MOVWUload(v)
case OpARM64MOVWUloadidx:
return rewriteValueARM64_OpARM64MOVWUloadidx(v)
case OpARM64MOVWUloadidx4:
return rewriteValueARM64_OpARM64MOVWUloadidx4(v)
case OpARM64MOVWUreg:
return rewriteValueARM64_OpARM64MOVWUreg(v)
case OpARM64MOVWload:
return rewriteValueARM64_OpARM64MOVWload(v)
case OpARM64MOVWloadidx:
return rewriteValueARM64_OpARM64MOVWloadidx(v)
case OpARM64MOVWloadidx4:
return rewriteValueARM64_OpARM64MOVWloadidx4(v)
case OpARM64MOVWreg:
return rewriteValueARM64_OpARM64MOVWreg(v)
case OpARM64MOVWstore:
return rewriteValueARM64_OpARM64MOVWstore(v)
case OpARM64MOVWstoreidx:
return rewriteValueARM64_OpARM64MOVWstoreidx(v)
case OpARM64MOVWstoreidx4:
return rewriteValueARM64_OpARM64MOVWstoreidx4(v)
case OpARM64MOVWstorezero:
return rewriteValueARM64_OpARM64MOVWstorezero(v)
case OpARM64MOVWstorezeroidx:
return rewriteValueARM64_OpARM64MOVWstorezeroidx(v)
case OpARM64MOVWstorezeroidx4:
return rewriteValueARM64_OpARM64MOVWstorezeroidx4(v)
case OpARM64MSUB:
return rewriteValueARM64_OpARM64MSUB(v)
case OpARM64MSUBW:
return rewriteValueARM64_OpARM64MSUBW(v)
case OpARM64MUL:
return rewriteValueARM64_OpARM64MUL(v)
case OpARM64MULW:
return rewriteValueARM64_OpARM64MULW(v)
case OpARM64MVN:
return rewriteValueARM64_OpARM64MVN(v)
case OpARM64MVNshiftLL:
return rewriteValueARM64_OpARM64MVNshiftLL(v)
case OpARM64MVNshiftRA:
return rewriteValueARM64_OpARM64MVNshiftRA(v)
case OpARM64MVNshiftRL:
return rewriteValueARM64_OpARM64MVNshiftRL(v)
case OpARM64MVNshiftRO:
return rewriteValueARM64_OpARM64MVNshiftRO(v)
case OpARM64NEG:
return rewriteValueARM64_OpARM64NEG(v)
case OpARM64NEGshiftLL:
return rewriteValueARM64_OpARM64NEGshiftLL(v)
case OpARM64NEGshiftRA:
return rewriteValueARM64_OpARM64NEGshiftRA(v)
case OpARM64NEGshiftRL:
return rewriteValueARM64_OpARM64NEGshiftRL(v)
case OpARM64NotEqual:
return rewriteValueARM64_OpARM64NotEqual(v)
case OpARM64OR:
return rewriteValueARM64_OpARM64OR(v)
case OpARM64ORN:
return rewriteValueARM64_OpARM64ORN(v)
case OpARM64ORNshiftLL:
return rewriteValueARM64_OpARM64ORNshiftLL(v)
case OpARM64ORNshiftRA:
return rewriteValueARM64_OpARM64ORNshiftRA(v)
case OpARM64ORNshiftRL:
return rewriteValueARM64_OpARM64ORNshiftRL(v)
case OpARM64ORNshiftRO:
return rewriteValueARM64_OpARM64ORNshiftRO(v)
case OpARM64ORconst:
return rewriteValueARM64_OpARM64ORconst(v)
case OpARM64ORshiftLL:
return rewriteValueARM64_OpARM64ORshiftLL(v)
case OpARM64ORshiftRA:
return rewriteValueARM64_OpARM64ORshiftRA(v)
case OpARM64ORshiftRL:
return rewriteValueARM64_OpARM64ORshiftRL(v)
case OpARM64ORshiftRO:
return rewriteValueARM64_OpARM64ORshiftRO(v)
case OpARM64REV:
return rewriteValueARM64_OpARM64REV(v)
case OpARM64REVW:
return rewriteValueARM64_OpARM64REVW(v)
case OpARM64ROR:
return rewriteValueARM64_OpARM64ROR(v)
case OpARM64RORW:
return rewriteValueARM64_OpARM64RORW(v)
case OpARM64SBCSflags:
return rewriteValueARM64_OpARM64SBCSflags(v)
case OpARM64SLL:
return rewriteValueARM64_OpARM64SLL(v)
case OpARM64SLLconst:
return rewriteValueARM64_OpARM64SLLconst(v)
case OpARM64SRA:
return rewriteValueARM64_OpARM64SRA(v)
case OpARM64SRAconst:
return rewriteValueARM64_OpARM64SRAconst(v)
case OpARM64SRL:
return rewriteValueARM64_OpARM64SRL(v)
case OpARM64SRLconst:
return rewriteValueARM64_OpARM64SRLconst(v)
case OpARM64STP:
return rewriteValueARM64_OpARM64STP(v)
case OpARM64SUB:
return rewriteValueARM64_OpARM64SUB(v)
case OpARM64SUBconst:
return rewriteValueARM64_OpARM64SUBconst(v)
case OpARM64SUBshiftLL:
return rewriteValueARM64_OpARM64SUBshiftLL(v)
case OpARM64SUBshiftRA:
return rewriteValueARM64_OpARM64SUBshiftRA(v)
case OpARM64SUBshiftRL:
return rewriteValueARM64_OpARM64SUBshiftRL(v)
case OpARM64TST:
return rewriteValueARM64_OpARM64TST(v)
case OpARM64TSTW:
return rewriteValueARM64_OpARM64TSTW(v)
case OpARM64TSTWconst:
return rewriteValueARM64_OpARM64TSTWconst(v)
case OpARM64TSTconst:
return rewriteValueARM64_OpARM64TSTconst(v)
case OpARM64TSTshiftLL:
return rewriteValueARM64_OpARM64TSTshiftLL(v)
case OpARM64TSTshiftRA:
return rewriteValueARM64_OpARM64TSTshiftRA(v)
case OpARM64TSTshiftRL:
return rewriteValueARM64_OpARM64TSTshiftRL(v)
case OpARM64TSTshiftRO:
return rewriteValueARM64_OpARM64TSTshiftRO(v)
case OpARM64UBFIZ:
return rewriteValueARM64_OpARM64UBFIZ(v)
case OpARM64UBFX:
return rewriteValueARM64_OpARM64UBFX(v)
case OpARM64UDIV:
return rewriteValueARM64_OpARM64UDIV(v)
case OpARM64UDIVW:
return rewriteValueARM64_OpARM64UDIVW(v)
case OpARM64UMOD:
return rewriteValueARM64_OpARM64UMOD(v)
case OpARM64UMODW:
return rewriteValueARM64_OpARM64UMODW(v)
case OpARM64XOR:
return rewriteValueARM64_OpARM64XOR(v)
case OpARM64XORconst:
return rewriteValueARM64_OpARM64XORconst(v)
case OpARM64XORshiftLL:
return rewriteValueARM64_OpARM64XORshiftLL(v)
case OpARM64XORshiftRA:
return rewriteValueARM64_OpARM64XORshiftRA(v)
case OpARM64XORshiftRL:
return rewriteValueARM64_OpARM64XORshiftRL(v)
case OpARM64XORshiftRO:
return rewriteValueARM64_OpARM64XORshiftRO(v)
case OpAbs:
v.Op = OpARM64FABSD
return true
case OpAdd16:
v.Op = OpARM64ADD
return true
case OpAdd32:
v.Op = OpARM64ADD
return true
case OpAdd32F:
v.Op = OpARM64FADDS
return true
case OpAdd64:
v.Op = OpARM64ADD
return true
case OpAdd64F:
v.Op = OpARM64FADDD
return true
case OpAdd8:
v.Op = OpARM64ADD
return true
case OpAddPtr:
v.Op = OpARM64ADD
return true
case OpAddr:
return rewriteValueARM64_OpAddr(v)
case OpAnd16:
v.Op = OpARM64AND
return true
case OpAnd32:
v.Op = OpARM64AND
return true
case OpAnd64:
v.Op = OpARM64AND
return true
case OpAnd8:
v.Op = OpARM64AND
return true
case OpAndB:
v.Op = OpARM64AND
return true
case OpAtomicAdd32:
v.Op = OpARM64LoweredAtomicAdd32
return true
case OpAtomicAdd32Variant:
v.Op = OpARM64LoweredAtomicAdd32Variant
return true
case OpAtomicAdd64:
v.Op = OpARM64LoweredAtomicAdd64
return true
case OpAtomicAdd64Variant:
v.Op = OpARM64LoweredAtomicAdd64Variant
return true
case OpAtomicAnd32:
return rewriteValueARM64_OpAtomicAnd32(v)
case OpAtomicAnd32Variant:
return rewriteValueARM64_OpAtomicAnd32Variant(v)
case OpAtomicAnd8:
return rewriteValueARM64_OpAtomicAnd8(v)
case OpAtomicAnd8Variant:
return rewriteValueARM64_OpAtomicAnd8Variant(v)
case OpAtomicCompareAndSwap32:
v.Op = OpARM64LoweredAtomicCas32
return true
case OpAtomicCompareAndSwap32Variant:
v.Op = OpARM64LoweredAtomicCas32Variant
return true
case OpAtomicCompareAndSwap64:
v.Op = OpARM64LoweredAtomicCas64
return true
case OpAtomicCompareAndSwap64Variant:
v.Op = OpARM64LoweredAtomicCas64Variant
return true
case OpAtomicExchange32:
v.Op = OpARM64LoweredAtomicExchange32
return true
case OpAtomicExchange32Variant:
v.Op = OpARM64LoweredAtomicExchange32Variant
return true
case OpAtomicExchange64:
v.Op = OpARM64LoweredAtomicExchange64
return true
case OpAtomicExchange64Variant:
v.Op = OpARM64LoweredAtomicExchange64Variant
return true
case OpAtomicLoad32:
v.Op = OpARM64LDARW
return true
case OpAtomicLoad64:
v.Op = OpARM64LDAR
return true
case OpAtomicLoad8:
v.Op = OpARM64LDARB
return true
case OpAtomicLoadPtr:
v.Op = OpARM64LDAR
return true
case OpAtomicOr32:
return rewriteValueARM64_OpAtomicOr32(v)
case OpAtomicOr32Variant:
return rewriteValueARM64_OpAtomicOr32Variant(v)
case OpAtomicOr8:
return rewriteValueARM64_OpAtomicOr8(v)
case OpAtomicOr8Variant:
return rewriteValueARM64_OpAtomicOr8Variant(v)
case OpAtomicStore32:
v.Op = OpARM64STLRW
return true
case OpAtomicStore64:
v.Op = OpARM64STLR
return true
case OpAtomicStore8:
v.Op = OpARM64STLRB
return true
case OpAtomicStorePtrNoWB:
v.Op = OpARM64STLR
return true
case OpAvg64u:
return rewriteValueARM64_OpAvg64u(v)
case OpBitLen32:
return rewriteValueARM64_OpBitLen32(v)
case OpBitLen64:
return rewriteValueARM64_OpBitLen64(v)
case OpBitRev16:
return rewriteValueARM64_OpBitRev16(v)
case OpBitRev32:
v.Op = OpARM64RBITW
return true
case OpBitRev64:
v.Op = OpARM64RBIT
return true
case OpBitRev8:
return rewriteValueARM64_OpBitRev8(v)
case OpBswap32:
v.Op = OpARM64REVW
return true
case OpBswap64:
v.Op = OpARM64REV
return true
case OpCeil:
v.Op = OpARM64FRINTPD
return true
case OpClosureCall:
v.Op = OpARM64CALLclosure
return true
case OpCom16:
v.Op = OpARM64MVN
return true
case OpCom32:
v.Op = OpARM64MVN
return true
case OpCom64:
v.Op = OpARM64MVN
return true
case OpCom8:
v.Op = OpARM64MVN
return true
case OpCondSelect:
return rewriteValueARM64_OpCondSelect(v)
case OpConst16:
return rewriteValueARM64_OpConst16(v)
case OpConst32:
return rewriteValueARM64_OpConst32(v)
case OpConst32F:
return rewriteValueARM64_OpConst32F(v)
case OpConst64:
return rewriteValueARM64_OpConst64(v)
case OpConst64F:
return rewriteValueARM64_OpConst64F(v)
case OpConst8:
return rewriteValueARM64_OpConst8(v)
case OpConstBool:
return rewriteValueARM64_OpConstBool(v)
case OpConstNil:
return rewriteValueARM64_OpConstNil(v)
case OpCtz16:
return rewriteValueARM64_OpCtz16(v)
case OpCtz16NonZero:
v.Op = OpCtz32
return true
case OpCtz32:
return rewriteValueARM64_OpCtz32(v)
case OpCtz32NonZero:
v.Op = OpCtz32
return true
case OpCtz64:
return rewriteValueARM64_OpCtz64(v)
case OpCtz64NonZero:
v.Op = OpCtz64
return true
case OpCtz8:
return rewriteValueARM64_OpCtz8(v)
case OpCtz8NonZero:
v.Op = OpCtz32
return true
case OpCvt32Fto32:
v.Op = OpARM64FCVTZSSW
return true
case OpCvt32Fto32U:
v.Op = OpARM64FCVTZUSW
return true
case OpCvt32Fto64:
v.Op = OpARM64FCVTZSS
return true
case OpCvt32Fto64F:
v.Op = OpARM64FCVTSD
return true
case OpCvt32Fto64U:
v.Op = OpARM64FCVTZUS
return true
case OpCvt32Uto32F:
v.Op = OpARM64UCVTFWS
return true
case OpCvt32Uto64F:
v.Op = OpARM64UCVTFWD
return true
case OpCvt32to32F:
v.Op = OpARM64SCVTFWS
return true
case OpCvt32to64F:
v.Op = OpARM64SCVTFWD
return true
case OpCvt64Fto32:
v.Op = OpARM64FCVTZSDW
return true
case OpCvt64Fto32F:
v.Op = OpARM64FCVTDS
return true
case OpCvt64Fto32U:
v.Op = OpARM64FCVTZUDW
return true
case OpCvt64Fto64:
v.Op = OpARM64FCVTZSD
return true
case OpCvt64Fto64U:
v.Op = OpARM64FCVTZUD
return true
case OpCvt64Uto32F:
v.Op = OpARM64UCVTFS
return true
case OpCvt64Uto64F:
v.Op = OpARM64UCVTFD
return true
case OpCvt64to32F:
v.Op = OpARM64SCVTFS
return true
case OpCvt64to64F:
v.Op = OpARM64SCVTFD
return true
case OpCvtBoolToUint8:
v.Op = OpCopy
return true
case OpDiv16:
return rewriteValueARM64_OpDiv16(v)
case OpDiv16u:
return rewriteValueARM64_OpDiv16u(v)
case OpDiv32:
return rewriteValueARM64_OpDiv32(v)
case OpDiv32F:
v.Op = OpARM64FDIVS
return true
case OpDiv32u:
v.Op = OpARM64UDIVW
return true
case OpDiv64:
return rewriteValueARM64_OpDiv64(v)
case OpDiv64F:
v.Op = OpARM64FDIVD
return true
case OpDiv64u:
v.Op = OpARM64UDIV
return true
case OpDiv8:
return rewriteValueARM64_OpDiv8(v)
case OpDiv8u:
return rewriteValueARM64_OpDiv8u(v)
case OpEq16:
return rewriteValueARM64_OpEq16(v)
case OpEq32:
return rewriteValueARM64_OpEq32(v)
case OpEq32F:
return rewriteValueARM64_OpEq32F(v)
case OpEq64:
return rewriteValueARM64_OpEq64(v)
case OpEq64F:
return rewriteValueARM64_OpEq64F(v)
case OpEq8:
return rewriteValueARM64_OpEq8(v)
case OpEqB:
return rewriteValueARM64_OpEqB(v)
case OpEqPtr:
return rewriteValueARM64_OpEqPtr(v)
case OpFMA:
return rewriteValueARM64_OpFMA(v)
case OpFloor:
v.Op = OpARM64FRINTMD
return true
case OpGetCallerPC:
v.Op = OpARM64LoweredGetCallerPC
return true
case OpGetCallerSP:
v.Op = OpARM64LoweredGetCallerSP
return true
case OpGetClosurePtr:
v.Op = OpARM64LoweredGetClosurePtr
return true
case OpHmul32:
return rewriteValueARM64_OpHmul32(v)
case OpHmul32u:
return rewriteValueARM64_OpHmul32u(v)
case OpHmul64:
v.Op = OpARM64MULH
return true
case OpHmul64u:
v.Op = OpARM64UMULH
return true
case OpInterCall:
v.Op = OpARM64CALLinter
return true
case OpIsInBounds:
return rewriteValueARM64_OpIsInBounds(v)
case OpIsNonNil:
return rewriteValueARM64_OpIsNonNil(v)
case OpIsSliceInBounds:
return rewriteValueARM64_OpIsSliceInBounds(v)
case OpLeq16:
return rewriteValueARM64_OpLeq16(v)
case OpLeq16U:
return rewriteValueARM64_OpLeq16U(v)
case OpLeq32:
return rewriteValueARM64_OpLeq32(v)
case OpLeq32F:
return rewriteValueARM64_OpLeq32F(v)
case OpLeq32U:
return rewriteValueARM64_OpLeq32U(v)
case OpLeq64:
return rewriteValueARM64_OpLeq64(v)
case OpLeq64F:
return rewriteValueARM64_OpLeq64F(v)
case OpLeq64U:
return rewriteValueARM64_OpLeq64U(v)
case OpLeq8:
return rewriteValueARM64_OpLeq8(v)
case OpLeq8U:
return rewriteValueARM64_OpLeq8U(v)
case OpLess16:
return rewriteValueARM64_OpLess16(v)
case OpLess16U:
return rewriteValueARM64_OpLess16U(v)
case OpLess32:
return rewriteValueARM64_OpLess32(v)
case OpLess32F:
return rewriteValueARM64_OpLess32F(v)
case OpLess32U:
return rewriteValueARM64_OpLess32U(v)
case OpLess64:
return rewriteValueARM64_OpLess64(v)
case OpLess64F:
return rewriteValueARM64_OpLess64F(v)
case OpLess64U:
return rewriteValueARM64_OpLess64U(v)
case OpLess8:
return rewriteValueARM64_OpLess8(v)
case OpLess8U:
return rewriteValueARM64_OpLess8U(v)
case OpLoad:
return rewriteValueARM64_OpLoad(v)
case OpLocalAddr:
return rewriteValueARM64_OpLocalAddr(v)
case OpLsh16x16:
return rewriteValueARM64_OpLsh16x16(v)
case OpLsh16x32:
return rewriteValueARM64_OpLsh16x32(v)
case OpLsh16x64:
return rewriteValueARM64_OpLsh16x64(v)
case OpLsh16x8:
return rewriteValueARM64_OpLsh16x8(v)
case OpLsh32x16:
return rewriteValueARM64_OpLsh32x16(v)
case OpLsh32x32:
return rewriteValueARM64_OpLsh32x32(v)
case OpLsh32x64:
return rewriteValueARM64_OpLsh32x64(v)
case OpLsh32x8:
return rewriteValueARM64_OpLsh32x8(v)
case OpLsh64x16:
return rewriteValueARM64_OpLsh64x16(v)
case OpLsh64x32:
return rewriteValueARM64_OpLsh64x32(v)
case OpLsh64x64:
return rewriteValueARM64_OpLsh64x64(v)
case OpLsh64x8:
return rewriteValueARM64_OpLsh64x8(v)
case OpLsh8x16:
return rewriteValueARM64_OpLsh8x16(v)
case OpLsh8x32:
return rewriteValueARM64_OpLsh8x32(v)
case OpLsh8x64:
return rewriteValueARM64_OpLsh8x64(v)
case OpLsh8x8:
return rewriteValueARM64_OpLsh8x8(v)
case OpMod16:
return rewriteValueARM64_OpMod16(v)
case OpMod16u:
return rewriteValueARM64_OpMod16u(v)
case OpMod32:
return rewriteValueARM64_OpMod32(v)
case OpMod32u:
v.Op = OpARM64UMODW
return true
case OpMod64:
return rewriteValueARM64_OpMod64(v)
case OpMod64u:
v.Op = OpARM64UMOD
return true
case OpMod8:
return rewriteValueARM64_OpMod8(v)
case OpMod8u:
return rewriteValueARM64_OpMod8u(v)
case OpMove:
return rewriteValueARM64_OpMove(v)
case OpMul16:
v.Op = OpARM64MULW
return true
case OpMul32:
v.Op = OpARM64MULW
return true
case OpMul32F:
v.Op = OpARM64FMULS
return true
case OpMul64:
v.Op = OpARM64MUL
return true
case OpMul64F:
v.Op = OpARM64FMULD
return true
case OpMul8:
v.Op = OpARM64MULW
return true
case OpNeg16:
v.Op = OpARM64NEG
return true
case OpNeg32:
v.Op = OpARM64NEG
return true
case OpNeg32F:
v.Op = OpARM64FNEGS
return true
case OpNeg64:
v.Op = OpARM64NEG
return true
case OpNeg64F:
v.Op = OpARM64FNEGD
return true
case OpNeg8:
v.Op = OpARM64NEG
return true
case OpNeq16:
return rewriteValueARM64_OpNeq16(v)
case OpNeq32:
return rewriteValueARM64_OpNeq32(v)
case OpNeq32F:
return rewriteValueARM64_OpNeq32F(v)
case OpNeq64:
return rewriteValueARM64_OpNeq64(v)
case OpNeq64F:
return rewriteValueARM64_OpNeq64F(v)
case OpNeq8:
return rewriteValueARM64_OpNeq8(v)
case OpNeqB:
v.Op = OpARM64XOR
return true
case OpNeqPtr:
return rewriteValueARM64_OpNeqPtr(v)
case OpNilCheck:
v.Op = OpARM64LoweredNilCheck
return true
case OpNot:
return rewriteValueARM64_OpNot(v)
case OpOffPtr:
return rewriteValueARM64_OpOffPtr(v)
case OpOr16:
v.Op = OpARM64OR
return true
case OpOr32:
v.Op = OpARM64OR
return true
case OpOr64:
v.Op = OpARM64OR
return true
case OpOr8:
v.Op = OpARM64OR
return true
case OpOrB:
v.Op = OpARM64OR
return true
case OpPanicBounds:
return rewriteValueARM64_OpPanicBounds(v)
case OpPopCount16:
return rewriteValueARM64_OpPopCount16(v)
case OpPopCount32:
return rewriteValueARM64_OpPopCount32(v)
case OpPopCount64:
return rewriteValueARM64_OpPopCount64(v)
case OpPrefetchCache:
return rewriteValueARM64_OpPrefetchCache(v)
case OpPrefetchCacheStreamed:
return rewriteValueARM64_OpPrefetchCacheStreamed(v)
case OpPubBarrier:
return rewriteValueARM64_OpPubBarrier(v)
case OpRotateLeft16:
return rewriteValueARM64_OpRotateLeft16(v)
case OpRotateLeft32:
return rewriteValueARM64_OpRotateLeft32(v)
case OpRotateLeft64:
return rewriteValueARM64_OpRotateLeft64(v)
case OpRotateLeft8:
return rewriteValueARM64_OpRotateLeft8(v)
case OpRound:
v.Op = OpARM64FRINTAD
return true
case OpRound32F:
v.Op = OpARM64LoweredRound32F
return true
case OpRound64F:
v.Op = OpARM64LoweredRound64F
return true
case OpRoundToEven:
v.Op = OpARM64FRINTND
return true
case OpRsh16Ux16:
return rewriteValueARM64_OpRsh16Ux16(v)
case OpRsh16Ux32:
return rewriteValueARM64_OpRsh16Ux32(v)
case OpRsh16Ux64:
return rewriteValueARM64_OpRsh16Ux64(v)
case OpRsh16Ux8:
return rewriteValueARM64_OpRsh16Ux8(v)
case OpRsh16x16:
return rewriteValueARM64_OpRsh16x16(v)
case OpRsh16x32:
return rewriteValueARM64_OpRsh16x32(v)
case OpRsh16x64:
return rewriteValueARM64_OpRsh16x64(v)
case OpRsh16x8:
return rewriteValueARM64_OpRsh16x8(v)
case OpRsh32Ux16:
return rewriteValueARM64_OpRsh32Ux16(v)
case OpRsh32Ux32:
return rewriteValueARM64_OpRsh32Ux32(v)
case OpRsh32Ux64:
return rewriteValueARM64_OpRsh32Ux64(v)
case OpRsh32Ux8:
return rewriteValueARM64_OpRsh32Ux8(v)
case OpRsh32x16:
return rewriteValueARM64_OpRsh32x16(v)
case OpRsh32x32:
return rewriteValueARM64_OpRsh32x32(v)
case OpRsh32x64:
return rewriteValueARM64_OpRsh32x64(v)
case OpRsh32x8:
return rewriteValueARM64_OpRsh32x8(v)
case OpRsh64Ux16:
return rewriteValueARM64_OpRsh64Ux16(v)
case OpRsh64Ux32:
return rewriteValueARM64_OpRsh64Ux32(v)
case OpRsh64Ux64:
return rewriteValueARM64_OpRsh64Ux64(v)
case OpRsh64Ux8:
return rewriteValueARM64_OpRsh64Ux8(v)
case OpRsh64x16:
return rewriteValueARM64_OpRsh64x16(v)
case OpRsh64x32:
return rewriteValueARM64_OpRsh64x32(v)
case OpRsh64x64:
return rewriteValueARM64_OpRsh64x64(v)
case OpRsh64x8:
return rewriteValueARM64_OpRsh64x8(v)
case OpRsh8Ux16:
return rewriteValueARM64_OpRsh8Ux16(v)
case OpRsh8Ux32:
return rewriteValueARM64_OpRsh8Ux32(v)
case OpRsh8Ux64:
return rewriteValueARM64_OpRsh8Ux64(v)
case OpRsh8Ux8:
return rewriteValueARM64_OpRsh8Ux8(v)
case OpRsh8x16:
return rewriteValueARM64_OpRsh8x16(v)
case OpRsh8x32:
return rewriteValueARM64_OpRsh8x32(v)
case OpRsh8x64:
return rewriteValueARM64_OpRsh8x64(v)
case OpRsh8x8:
return rewriteValueARM64_OpRsh8x8(v)
case OpSelect0:
return rewriteValueARM64_OpSelect0(v)
case OpSelect1:
return rewriteValueARM64_OpSelect1(v)
case OpSelectN:
return rewriteValueARM64_OpSelectN(v)
case OpSignExt16to32:
v.Op = OpARM64MOVHreg
return true
case OpSignExt16to64:
v.Op = OpARM64MOVHreg
return true
case OpSignExt32to64:
v.Op = OpARM64MOVWreg
return true
case OpSignExt8to16:
v.Op = OpARM64MOVBreg
return true
case OpSignExt8to32:
v.Op = OpARM64MOVBreg
return true
case OpSignExt8to64:
v.Op = OpARM64MOVBreg
return true
case OpSlicemask:
return rewriteValueARM64_OpSlicemask(v)
case OpSqrt:
v.Op = OpARM64FSQRTD
return true
case OpSqrt32:
v.Op = OpARM64FSQRTS
return true
case OpStaticCall:
v.Op = OpARM64CALLstatic
return true
case OpStore:
return rewriteValueARM64_OpStore(v)
case OpSub16:
v.Op = OpARM64SUB
return true
case OpSub32:
v.Op = OpARM64SUB
return true
case OpSub32F:
v.Op = OpARM64FSUBS
return true
case OpSub64:
v.Op = OpARM64SUB
return true
case OpSub64F:
v.Op = OpARM64FSUBD
return true
case OpSub8:
v.Op = OpARM64SUB
return true
case OpSubPtr:
v.Op = OpARM64SUB
return true
case OpTailCall:
v.Op = OpARM64CALLtail
return true
case OpTrunc:
v.Op = OpARM64FRINTZD
return true
case OpTrunc16to8:
v.Op = OpCopy
return true
case OpTrunc32to16:
v.Op = OpCopy
return true
case OpTrunc32to8:
v.Op = OpCopy
return true
case OpTrunc64to16:
v.Op = OpCopy
return true
case OpTrunc64to32:
v.Op = OpCopy
return true
case OpTrunc64to8:
v.Op = OpCopy
return true
case OpWB:
v.Op = OpARM64LoweredWB
return true
case OpXor16:
v.Op = OpARM64XOR
return true
case OpXor32:
v.Op = OpARM64XOR
return true
case OpXor64:
v.Op = OpARM64XOR
return true
case OpXor8:
v.Op = OpARM64XOR
return true
case OpZero:
return rewriteValueARM64_OpZero(v)
case OpZeroExt16to32:
v.Op = OpARM64MOVHUreg
return true
case OpZeroExt16to64:
v.Op = OpARM64MOVHUreg
return true
case OpZeroExt32to64:
v.Op = OpARM64MOVWUreg
return true
case OpZeroExt8to16:
v.Op = OpARM64MOVBUreg
return true
case OpZeroExt8to32:
v.Op = OpARM64MOVBUreg
return true
case OpZeroExt8to64:
v.Op = OpARM64MOVBUreg
return true
}
return false
}
func rewriteValueARM64_OpARM64ADCSflags(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (ADCSflags x y (Select1 (ADDSconstflags [-1] (ADCzerocarry c))))
// result: (ADCSflags x y c)
for {
x := v_0
y := v_1
if v_2.Op != OpSelect1 || v_2.Type != types.TypeFlags {
break
}
v_2_0 := v_2.Args[0]
if v_2_0.Op != OpARM64ADDSconstflags || auxIntToInt64(v_2_0.AuxInt) != -1 {
break
}
v_2_0_0 := v_2_0.Args[0]
if v_2_0_0.Op != OpARM64ADCzerocarry || v_2_0_0.Type != typ.UInt64 {
break
}
c := v_2_0_0.Args[0]
v.reset(OpARM64ADCSflags)
v.AddArg3(x, y, c)
return true
}
// match: (ADCSflags x y (Select1 (ADDSconstflags [-1] (MOVDconst [0]))))
// result: (ADDSflags x y)
for {
x := v_0
y := v_1
if v_2.Op != OpSelect1 || v_2.Type != types.TypeFlags {
break
}
v_2_0 := v_2.Args[0]
if v_2_0.Op != OpARM64ADDSconstflags || auxIntToInt64(v_2_0.AuxInt) != -1 {
break
}
v_2_0_0 := v_2_0.Args[0]
if v_2_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_2_0_0.AuxInt) != 0 {
break
}
v.reset(OpARM64ADDSflags)
v.AddArg2(x, y)
return true
}
return false
}
func rewriteValueARM64_OpARM64ADD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADD x (MOVDconst [c]))
// cond: !t.IsPtr()
// result: (ADDconst [c] x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
t := v_1.Type
c := auxIntToInt64(v_1.AuxInt)
if !(!t.IsPtr()) {
continue
}
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(x)
return true
}
break
}
// match: (ADD a l:(MUL x y))
// cond: l.Uses==1 && clobber(l)
// result: (MADD a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
l := v_1
if l.Op != OpARM64MUL {
continue
}
y := l.Args[1]
x := l.Args[0]
if !(l.Uses == 1 && clobber(l)) {
continue
}
v.reset(OpARM64MADD)
v.AddArg3(a, x, y)
return true
}
break
}
// match: (ADD a l:(MNEG x y))
// cond: l.Uses==1 && clobber(l)
// result: (MSUB a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
l := v_1
if l.Op != OpARM64MNEG {
continue
}
y := l.Args[1]
x := l.Args[0]
if !(l.Uses == 1 && clobber(l)) {
continue
}
v.reset(OpARM64MSUB)
v.AddArg3(a, x, y)
return true
}
break
}
// match: (ADD a l:(MULW x y))
// cond: a.Type.Size() != 8 && l.Uses==1 && clobber(l)
// result: (MADDW a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
l := v_1
if l.Op != OpARM64MULW {
continue
}
y := l.Args[1]
x := l.Args[0]
if !(a.Type.Size() != 8 && l.Uses == 1 && clobber(l)) {
continue
}
v.reset(OpARM64MADDW)
v.AddArg3(a, x, y)
return true
}
break
}
// match: (ADD a l:(MNEGW x y))
// cond: a.Type.Size() != 8 && l.Uses==1 && clobber(l)
// result: (MSUBW a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
l := v_1
if l.Op != OpARM64MNEGW {
continue
}
y := l.Args[1]
x := l.Args[0]
if !(a.Type.Size() != 8 && l.Uses == 1 && clobber(l)) {
continue
}
v.reset(OpARM64MSUBW)
v.AddArg3(a, x, y)
return true
}
break
}
// match: (ADD x (NEG y))
// result: (SUB x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64NEG {
continue
}
y := v_1.Args[0]
v.reset(OpARM64SUB)
v.AddArg2(x, y)
return true
}
break
}
// match: (ADD x0 x1:(SLLconst [c] y))
// cond: clobberIfDead(x1)
// result: (ADDshiftLL x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SLLconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (ADD x0 x1:(SRLconst [c] y))
// cond: clobberIfDead(x1)
// result: (ADDshiftRL x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRLconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ADDshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (ADD x0 x1:(SRAconst [c] y))
// cond: clobberIfDead(x1)
// result: (ADDshiftRA x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRAconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ADDshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64ADDSflags(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADDSflags x (MOVDconst [c]))
// result: (ADDSconstflags [c] x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ADDSconstflags)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(x)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64ADDconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ADDconst [off1] (MOVDaddr [off2] {sym} ptr))
// cond: is32Bit(off1+int64(off2))
// result: (MOVDaddr [int32(off1)+off2] {sym} ptr)
for {
off1 := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
if !(is32Bit(off1 + int64(off2))) {
break
}
v.reset(OpARM64MOVDaddr)
v.AuxInt = int32ToAuxInt(int32(off1) + off2)
v.Aux = symToAux(sym)
v.AddArg(ptr)
return true
}
// match: (ADDconst [c] y)
// cond: c < 0
// result: (SUBconst [-c] y)
for {
c := auxIntToInt64(v.AuxInt)
y := v_0
if !(c < 0) {
break
}
v.reset(OpARM64SUBconst)
v.AuxInt = int64ToAuxInt(-c)
v.AddArg(y)
return true
}
// match: (ADDconst [0] x)
// result: x
for {
if auxIntToInt64(v.AuxInt) != 0 {
break
}
x := v_0
v.copyOf(x)
return true
}
// match: (ADDconst [c] (MOVDconst [d]))
// result: (MOVDconst [c+d])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c + d)
return true
}
// match: (ADDconst [c] (ADDconst [d] x))
// result: (ADDconst [c+d] x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64ADDconst {
break
}
d := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c + d)
v.AddArg(x)
return true
}
// match: (ADDconst [c] (SUBconst [d] x))
// result: (ADDconst [c-d] x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SUBconst {
break
}
d := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c - d)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64ADDshiftLL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (ADDshiftLL (MOVDconst [c]) x [d])
// result: (ADDconst [c] (SLLconst x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (ADDshiftLL x (MOVDconst [c]) [d])
// result: (ADDconst x [int64(uint64(c)< [8] (UBFX [armBFAuxInt(8, 8)] x) x)
// result: (REV16W x)
for {
if v.Type != typ.UInt16 || auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || v_0.Type != typ.UInt16 || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 8) {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64REV16W)
v.AddArg(x)
return true
}
// match: (ADDshiftLL [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
// cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
// result: (REV16W x)
for {
if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 24) {
break
}
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpARM64ANDconst {
break
}
c1 := auxIntToInt64(v_0_0.AuxInt)
x := v_0_0.Args[0]
if v_1.Op != OpARM64ANDconst {
break
}
c2 := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
break
}
v.reset(OpARM64REV16W)
v.AddArg(x)
return true
}
// match: (ADDshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
// cond: (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
// result: (REV16 x)
for {
if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
break
}
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpARM64ANDconst {
break
}
c1 := auxIntToInt64(v_0_0.AuxInt)
x := v_0_0.Args[0]
if v_1.Op != OpARM64ANDconst {
break
}
c2 := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
break
}
v.reset(OpARM64REV16)
v.AddArg(x)
return true
}
// match: (ADDshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
// cond: (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
// result: (REV16 (ANDconst [0xffffffff] x))
for {
if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
break
}
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpARM64ANDconst {
break
}
c1 := auxIntToInt64(v_0_0.AuxInt)
x := v_0_0.Args[0]
if v_1.Op != OpARM64ANDconst {
break
}
c2 := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
break
}
v.reset(OpARM64REV16)
v0 := b.NewValue0(v.Pos, OpARM64ANDconst, x.Type)
v0.AuxInt = int64ToAuxInt(0xffffffff)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (ADDshiftLL [c] (SRLconst x [64-c]) x2)
// result: (EXTRconst [64-c] x2 x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
break
}
x := v_0.Args[0]
x2 := v_1
v.reset(OpARM64EXTRconst)
v.AuxInt = int64ToAuxInt(64 - c)
v.AddArg2(x2, x)
return true
}
// match: (ADDshiftLL [c] (UBFX [bfc] x) x2)
// cond: c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
// result: (EXTRWconst [32-c] x2 x)
for {
t := v.Type
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64UBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
x2 := v_1
if !(c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)) {
break
}
v.reset(OpARM64EXTRWconst)
v.AuxInt = int64ToAuxInt(32 - c)
v.AddArg2(x2, x)
return true
}
return false
}
func rewriteValueARM64_OpARM64ADDshiftRA(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (ADDshiftRA (MOVDconst [c]) x [d])
// result: (ADDconst [c] (SRAconst x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (ADDshiftRA x (MOVDconst [c]) [d])
// result: (ADDconst x [c>>uint64(d)])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c >> uint64(d))
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64ADDshiftRL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (ADDshiftRL (MOVDconst [c]) x [d])
// result: (ADDconst [c] (SRLconst x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (ADDshiftRL x (MOVDconst [c]) [d])
// result: (ADDconst x [int64(uint64(c)>>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64AND(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (AND x (MOVDconst [c]))
// result: (ANDconst [c] x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(x)
return true
}
break
}
// match: (AND x x)
// result: x
for {
x := v_0
if x != v_1 {
break
}
v.copyOf(x)
return true
}
// match: (AND x (MVN y))
// result: (BIC x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MVN {
continue
}
y := v_1.Args[0]
v.reset(OpARM64BIC)
v.AddArg2(x, y)
return true
}
break
}
// match: (AND x0 x1:(SLLconst [c] y))
// cond: clobberIfDead(x1)
// result: (ANDshiftLL x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SLLconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ANDshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (AND x0 x1:(SRLconst [c] y))
// cond: clobberIfDead(x1)
// result: (ANDshiftRL x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRLconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ANDshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (AND x0 x1:(SRAconst [c] y))
// cond: clobberIfDead(x1)
// result: (ANDshiftRA x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRAconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ANDshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (AND x0 x1:(RORconst [c] y))
// cond: clobberIfDead(x1)
// result: (ANDshiftRO x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64RORconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ANDshiftRO)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64ANDconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ANDconst [0] _)
// result: (MOVDconst [0])
for {
if auxIntToInt64(v.AuxInt) != 0 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (ANDconst [-1] x)
// result: x
for {
if auxIntToInt64(v.AuxInt) != -1 {
break
}
x := v_0
v.copyOf(x)
return true
}
// match: (ANDconst [c] (MOVDconst [d]))
// result: (MOVDconst [c&d])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c & d)
return true
}
// match: (ANDconst [c] (ANDconst [d] x))
// result: (ANDconst [c&d] x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64ANDconst {
break
}
d := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c & d)
v.AddArg(x)
return true
}
// match: (ANDconst [c] (MOVWUreg x))
// result: (ANDconst [c&(1<<32-1)] x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVWUreg {
break
}
x := v_0.Args[0]
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c & (1<<32 - 1))
v.AddArg(x)
return true
}
// match: (ANDconst [c] (MOVHUreg x))
// result: (ANDconst [c&(1<<16-1)] x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVHUreg {
break
}
x := v_0.Args[0]
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c & (1<<16 - 1))
v.AddArg(x)
return true
}
// match: (ANDconst [c] (MOVBUreg x))
// result: (ANDconst [c&(1<<8-1)] x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVBUreg {
break
}
x := v_0.Args[0]
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c & (1<<8 - 1))
v.AddArg(x)
return true
}
// match: (ANDconst [ac] (SLLconst [sc] x))
// cond: isARM64BFMask(sc, ac, sc)
// result: (UBFIZ [armBFAuxInt(sc, arm64BFWidth(ac, sc))] x)
for {
ac := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst {
break
}
sc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(isARM64BFMask(sc, ac, sc)) {
break
}
v.reset(OpARM64UBFIZ)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(sc, arm64BFWidth(ac, sc)))
v.AddArg(x)
return true
}
// match: (ANDconst [ac] (SRLconst [sc] x))
// cond: isARM64BFMask(sc, ac, 0)
// result: (UBFX [armBFAuxInt(sc, arm64BFWidth(ac, 0))] x)
for {
ac := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst {
break
}
sc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(isARM64BFMask(sc, ac, 0)) {
break
}
v.reset(OpARM64UBFX)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(sc, arm64BFWidth(ac, 0)))
v.AddArg(x)
return true
}
// match: (ANDconst [c] (UBFX [bfc] x))
// cond: isARM64BFMask(0, c, 0)
// result: (UBFX [armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0)))] x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64UBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
if !(isARM64BFMask(0, c, 0)) {
break
}
v.reset(OpARM64UBFX)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0))))
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64ANDshiftLL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (ANDshiftLL (MOVDconst [c]) x [d])
// result: (ANDconst [c] (SLLconst x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (ANDshiftLL x (MOVDconst [c]) [d])
// result: (ANDconst x [int64(uint64(c)< x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (ANDshiftRA x (MOVDconst [c]) [d])
// result: (ANDconst x [c>>uint64(d)])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c >> uint64(d))
v.AddArg(x)
return true
}
// match: (ANDshiftRA y:(SRAconst x [c]) x [c])
// result: y
for {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRAconst || auxIntToInt64(y.AuxInt) != c {
break
}
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
return true
}
return false
}
func rewriteValueARM64_OpARM64ANDshiftRL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (ANDshiftRL (MOVDconst [c]) x [d])
// result: (ANDconst [c] (SRLconst x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (ANDshiftRL x (MOVDconst [c]) [d])
// result: (ANDconst x [int64(uint64(c)>>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
v.AddArg(x)
return true
}
// match: (ANDshiftRL y:(SRLconst x [c]) x [c])
// result: y
for {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRLconst || auxIntToInt64(y.AuxInt) != c {
break
}
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
return true
}
return false
}
func rewriteValueARM64_OpARM64ANDshiftRO(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (ANDshiftRO (MOVDconst [c]) x [d])
// result: (ANDconst [c] (RORconst x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64RORconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (ANDshiftRO x (MOVDconst [c]) [d])
// result: (ANDconst x [rotateRight64(c, d)])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(rotateRight64(c, d))
v.AddArg(x)
return true
}
// match: (ANDshiftRO y:(RORconst x [c]) x [c])
// result: y
for {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64RORconst || auxIntToInt64(y.AuxInt) != c {
break
}
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
return true
}
return false
}
func rewriteValueARM64_OpARM64BIC(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BIC x (MOVDconst [c]))
// result: (ANDconst [^c] x)
for {
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(^c)
v.AddArg(x)
return true
}
// match: (BIC x x)
// result: (MOVDconst [0])
for {
x := v_0
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (BIC x0 x1:(SLLconst [c] y))
// cond: clobberIfDead(x1)
// result: (BICshiftLL x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SLLconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64BICshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (BIC x0 x1:(SRLconst [c] y))
// cond: clobberIfDead(x1)
// result: (BICshiftRL x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRLconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64BICshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (BIC x0 x1:(SRAconst [c] y))
// cond: clobberIfDead(x1)
// result: (BICshiftRA x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRAconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64BICshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (BIC x0 x1:(RORconst [c] y))
// cond: clobberIfDead(x1)
// result: (BICshiftRO x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64RORconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64BICshiftRO)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
return false
}
func rewriteValueARM64_OpARM64BICshiftLL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BICshiftLL x (MOVDconst [c]) [d])
// result: (ANDconst x [^int64(uint64(c)<>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(^(c >> uint64(d)))
v.AddArg(x)
return true
}
// match: (BICshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [0])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64BICshiftRL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BICshiftRL x (MOVDconst [c]) [d])
// result: (ANDconst x [^int64(uint64(c)>>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(^int64(uint64(c) >> uint64(d)))
v.AddArg(x)
return true
}
// match: (BICshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64BICshiftRO(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (BICshiftRO x (MOVDconst [c]) [d])
// result: (ANDconst x [^rotateRight64(c, d)])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
v.AddArg(x)
return true
}
// match: (BICshiftRO (RORconst x [c]) x [c])
// result: (MOVDconst [0])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64RORconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64CMN(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMN x (MOVDconst [c]))
// result: (CMNconst [c] x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64CMNconst)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(x)
return true
}
break
}
// match: (CMN x0 x1:(SLLconst [c] y))
// cond: clobberIfDead(x1)
// result: (CMNshiftLL x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SLLconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64CMNshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (CMN x0 x1:(SRLconst [c] y))
// cond: clobberIfDead(x1)
// result: (CMNshiftRL x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRLconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64CMNshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (CMN x0 x1:(SRAconst [c] y))
// cond: clobberIfDead(x1)
// result: (CMNshiftRA x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRAconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64CMNshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64CMNW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CMNW x (MOVDconst [c]))
// result: (CMNWconst [int32(c)] x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64CMNWconst)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64CMNWconst(v *Value) bool {
v_0 := v.Args[0]
// match: (CMNWconst [c] y)
// cond: c < 0 && c != -1<<31
// result: (CMPWconst [-c] y)
for {
c := auxIntToInt32(v.AuxInt)
y := v_0
if !(c < 0 && c != -1<<31) {
break
}
v.reset(OpARM64CMPWconst)
v.AuxInt = int32ToAuxInt(-c)
v.AddArg(y)
return true
}
// match: (CMNWconst (MOVDconst [x]) [y])
// result: (FlagConstant [addFlags32(int32(x),y)])
for {
y := auxIntToInt32(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
x := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(addFlags32(int32(x), y))
return true
}
return false
}
func rewriteValueARM64_OpARM64CMNconst(v *Value) bool {
v_0 := v.Args[0]
// match: (CMNconst [c] y)
// cond: c < 0 && c != -1<<63
// result: (CMPconst [-c] y)
for {
c := auxIntToInt64(v.AuxInt)
y := v_0
if !(c < 0 && c != -1<<63) {
break
}
v.reset(OpARM64CMPconst)
v.AuxInt = int64ToAuxInt(-c)
v.AddArg(y)
return true
}
// match: (CMNconst (MOVDconst [x]) [y])
// result: (FlagConstant [addFlags64(x,y)])
for {
y := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
x := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(addFlags64(x, y))
return true
}
return false
}
func rewriteValueARM64_OpARM64CMNshiftLL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (CMNshiftLL (MOVDconst [c]) x [d])
// result: (CMNconst [c] (SLLconst x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64CMNconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (CMNshiftLL x (MOVDconst [c]) [d])
// result: (CMNconst x [int64(uint64(c)< x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64CMNconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (CMNshiftRA x (MOVDconst [c]) [d])
// result: (CMNconst x [c>>uint64(d)])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64CMNconst)
v.AuxInt = int64ToAuxInt(c >> uint64(d))
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64CMNshiftRL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (CMNshiftRL (MOVDconst [c]) x [d])
// result: (CMNconst [c] (SRLconst x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64CMNconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (CMNshiftRL x (MOVDconst [c]) [d])
// result: (CMNconst x [int64(uint64(c)>>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64CMNconst)
v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64CMP(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (CMP x (MOVDconst [c]))
// result: (CMPconst [c] x)
for {
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64CMPconst)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(x)
return true
}
// match: (CMP (MOVDconst [c]) x)
// result: (InvertFlags (CMPconst [c] x))
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (CMP x y)
// cond: canonLessThan(x,y)
// result: (InvertFlags (CMP y x))
for {
x := v_0
y := v_1
if !(canonLessThan(x, y)) {
break
}
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
v0.AddArg2(y, x)
v.AddArg(v0)
return true
}
// match: (CMP x0 x1:(SLLconst [c] y))
// cond: clobberIfDead(x1)
// result: (CMPshiftLL x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SLLconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64CMPshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (CMP x0:(SLLconst [c] y) x1)
// cond: clobberIfDead(x0)
// result: (InvertFlags (CMPshiftLL x1 y [c]))
for {
x0 := v_0
if x0.Op != OpARM64SLLconst {
break
}
c := auxIntToInt64(x0.AuxInt)
y := x0.Args[0]
x1 := v_1
if !(clobberIfDead(x0)) {
break
}
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMPshiftLL, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg2(x1, y)
v.AddArg(v0)
return true
}
// match: (CMP x0 x1:(SRLconst [c] y))
// cond: clobberIfDead(x1)
// result: (CMPshiftRL x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRLconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64CMPshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (CMP x0:(SRLconst [c] y) x1)
// cond: clobberIfDead(x0)
// result: (InvertFlags (CMPshiftRL x1 y [c]))
for {
x0 := v_0
if x0.Op != OpARM64SRLconst {
break
}
c := auxIntToInt64(x0.AuxInt)
y := x0.Args[0]
x1 := v_1
if !(clobberIfDead(x0)) {
break
}
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMPshiftRL, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg2(x1, y)
v.AddArg(v0)
return true
}
// match: (CMP x0 x1:(SRAconst [c] y))
// cond: clobberIfDead(x1)
// result: (CMPshiftRA x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRAconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64CMPshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (CMP x0:(SRAconst [c] y) x1)
// cond: clobberIfDead(x0)
// result: (InvertFlags (CMPshiftRA x1 y [c]))
for {
x0 := v_0
if x0.Op != OpARM64SRAconst {
break
}
c := auxIntToInt64(x0.AuxInt)
y := x0.Args[0]
x1 := v_1
if !(clobberIfDead(x0)) {
break
}
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMPshiftRA, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg2(x1, y)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueARM64_OpARM64CMPW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (CMPW x (MOVDconst [c]))
// result: (CMPWconst [int32(c)] x)
for {
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64CMPWconst)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg(x)
return true
}
// match: (CMPW (MOVDconst [c]) x)
// result: (InvertFlags (CMPWconst [int32(c)] x))
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (CMPW x y)
// cond: canonLessThan(x,y)
// result: (InvertFlags (CMPW y x))
for {
x := v_0
y := v_1
if !(canonLessThan(x, y)) {
break
}
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
v0.AddArg2(y, x)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueARM64_OpARM64CMPWconst(v *Value) bool {
v_0 := v.Args[0]
// match: (CMPWconst [c] y)
// cond: c < 0 && c != -1<<31
// result: (CMNWconst [-c] y)
for {
c := auxIntToInt32(v.AuxInt)
y := v_0
if !(c < 0 && c != -1<<31) {
break
}
v.reset(OpARM64CMNWconst)
v.AuxInt = int32ToAuxInt(-c)
v.AddArg(y)
return true
}
// match: (CMPWconst (MOVDconst [x]) [y])
// result: (FlagConstant [subFlags32(int32(x),y)])
for {
y := auxIntToInt32(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
x := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(subFlags32(int32(x), y))
return true
}
// match: (CMPWconst (MOVBUreg _) [c])
// cond: 0xff < c
// result: (FlagConstant [subFlags64(0,1)])
for {
c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpARM64MOVBUreg || !(0xff < c) {
break
}
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
return true
}
// match: (CMPWconst (MOVHUreg _) [c])
// cond: 0xffff < c
// result: (FlagConstant [subFlags64(0,1)])
for {
c := auxIntToInt32(v.AuxInt)
if v_0.Op != OpARM64MOVHUreg || !(0xffff < c) {
break
}
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
return true
}
return false
}
func rewriteValueARM64_OpARM64CMPconst(v *Value) bool {
v_0 := v.Args[0]
// match: (CMPconst [c] y)
// cond: c < 0 && c != -1<<63
// result: (CMNconst [-c] y)
for {
c := auxIntToInt64(v.AuxInt)
y := v_0
if !(c < 0 && c != -1<<63) {
break
}
v.reset(OpARM64CMNconst)
v.AuxInt = int64ToAuxInt(-c)
v.AddArg(y)
return true
}
// match: (CMPconst (MOVDconst [x]) [y])
// result: (FlagConstant [subFlags64(x,y)])
for {
y := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
x := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(subFlags64(x, y))
return true
}
// match: (CMPconst (MOVBUreg _) [c])
// cond: 0xff < c
// result: (FlagConstant [subFlags64(0,1)])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVBUreg || !(0xff < c) {
break
}
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
return true
}
// match: (CMPconst (MOVHUreg _) [c])
// cond: 0xffff < c
// result: (FlagConstant [subFlags64(0,1)])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVHUreg || !(0xffff < c) {
break
}
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
return true
}
// match: (CMPconst (MOVWUreg _) [c])
// cond: 0xffffffff < c
// result: (FlagConstant [subFlags64(0,1)])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVWUreg || !(0xffffffff < c) {
break
}
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
return true
}
// match: (CMPconst (ANDconst _ [m]) [n])
// cond: 0 <= m && m < n
// result: (FlagConstant [subFlags64(0,1)])
for {
n := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64ANDconst {
break
}
m := auxIntToInt64(v_0.AuxInt)
if !(0 <= m && m < n) {
break
}
v.reset(OpARM64FlagConstant)
v.AuxInt = flagConstantToAuxInt(subFlags64(0, 1))
return true
}
// match: (CMPconst (SRLconst _ [c]) [n])
// cond: 0 <= n && 0 < c && c <= 63 && (1< x [d])))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v1 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v1.AuxInt = int64ToAuxInt(d)
v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0)
return true
}
// match: (CMPshiftLL x (MOVDconst [c]) [d])
// result: (CMPconst x [int64(uint64(c)< x [d])))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v1 := b.NewValue0(v.Pos, OpARM64SRAconst, x.Type)
v1.AuxInt = int64ToAuxInt(d)
v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0)
return true
}
// match: (CMPshiftRA x (MOVDconst [c]) [d])
// result: (CMPconst x [c>>uint64(d)])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64CMPconst)
v.AuxInt = int64ToAuxInt(c >> uint64(d))
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64CMPshiftRL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (CMPshiftRL (MOVDconst [c]) x [d])
// result: (InvertFlags (CMPconst [c] (SRLconst x [d])))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v1 := b.NewValue0(v.Pos, OpARM64SRLconst, x.Type)
v1.AuxInt = int64ToAuxInt(d)
v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0)
return true
}
// match: (CMPshiftRL x (MOVDconst [c]) [d])
// result: (CMPconst x [int64(uint64(c)>>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64CMPconst)
v.AuxInt = int64ToAuxInt(int64(uint64(c) >> uint64(d)))
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64CSEL(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CSEL [cc] (MOVDconst [-1]) (MOVDconst [0]) flag)
// result: (CSETM [cc] flag)
for {
cc := auxIntToOp(v.AuxInt)
if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != -1 || v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
flag := v_2
v.reset(OpARM64CSETM)
v.AuxInt = opToAuxInt(cc)
v.AddArg(flag)
return true
}
// match: (CSEL [cc] (MOVDconst [0]) (MOVDconst [-1]) flag)
// result: (CSETM [arm64Negate(cc)] flag)
for {
cc := auxIntToOp(v.AuxInt)
if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 0 || v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
break
}
flag := v_2
v.reset(OpARM64CSETM)
v.AuxInt = opToAuxInt(arm64Negate(cc))
v.AddArg(flag)
return true
}
// match: (CSEL [cc] x (MOVDconst [0]) flag)
// result: (CSEL0 [cc] x flag)
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
flag := v_2
v.reset(OpARM64CSEL0)
v.AuxInt = opToAuxInt(cc)
v.AddArg2(x, flag)
return true
}
// match: (CSEL [cc] (MOVDconst [0]) y flag)
// result: (CSEL0 [arm64Negate(cc)] y flag)
for {
cc := auxIntToOp(v.AuxInt)
if v_0.Op != OpARM64MOVDconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
y := v_1
flag := v_2
v.reset(OpARM64CSEL0)
v.AuxInt = opToAuxInt(arm64Negate(cc))
v.AddArg2(y, flag)
return true
}
// match: (CSEL [cc] x (ADDconst [1] a) flag)
// result: (CSINC [cc] x a flag)
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
a := v_1.Args[0]
flag := v_2
v.reset(OpARM64CSINC)
v.AuxInt = opToAuxInt(cc)
v.AddArg3(x, a, flag)
return true
}
// match: (CSEL [cc] (ADDconst [1] a) x flag)
// result: (CSINC [arm64Negate(cc)] x a flag)
for {
cc := auxIntToOp(v.AuxInt)
if v_0.Op != OpARM64ADDconst || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
a := v_0.Args[0]
x := v_1
flag := v_2
v.reset(OpARM64CSINC)
v.AuxInt = opToAuxInt(arm64Negate(cc))
v.AddArg3(x, a, flag)
return true
}
// match: (CSEL [cc] x (MVN a) flag)
// result: (CSINV [cc] x a flag)
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MVN {
break
}
a := v_1.Args[0]
flag := v_2
v.reset(OpARM64CSINV)
v.AuxInt = opToAuxInt(cc)
v.AddArg3(x, a, flag)
return true
}
// match: (CSEL [cc] (MVN a) x flag)
// result: (CSINV [arm64Negate(cc)] x a flag)
for {
cc := auxIntToOp(v.AuxInt)
if v_0.Op != OpARM64MVN {
break
}
a := v_0.Args[0]
x := v_1
flag := v_2
v.reset(OpARM64CSINV)
v.AuxInt = opToAuxInt(arm64Negate(cc))
v.AddArg3(x, a, flag)
return true
}
// match: (CSEL [cc] x (NEG a) flag)
// result: (CSNEG [cc] x a flag)
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64NEG {
break
}
a := v_1.Args[0]
flag := v_2
v.reset(OpARM64CSNEG)
v.AuxInt = opToAuxInt(cc)
v.AddArg3(x, a, flag)
return true
}
// match: (CSEL [cc] (NEG a) x flag)
// result: (CSNEG [arm64Negate(cc)] x a flag)
for {
cc := auxIntToOp(v.AuxInt)
if v_0.Op != OpARM64NEG {
break
}
a := v_0.Args[0]
x := v_1
flag := v_2
v.reset(OpARM64CSNEG)
v.AuxInt = opToAuxInt(arm64Negate(cc))
v.AddArg3(x, a, flag)
return true
}
// match: (CSEL [cc] x y (InvertFlags cmp))
// result: (CSEL [arm64Invert(cc)] x y cmp)
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
y := v_1
if v_2.Op != OpARM64InvertFlags {
break
}
cmp := v_2.Args[0]
v.reset(OpARM64CSEL)
v.AuxInt = opToAuxInt(arm64Invert(cc))
v.AddArg3(x, y, cmp)
return true
}
// match: (CSEL [cc] x _ flag)
// cond: ccARM64Eval(cc, flag) > 0
// result: x
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
flag := v_2
if !(ccARM64Eval(cc, flag) > 0) {
break
}
v.copyOf(x)
return true
}
// match: (CSEL [cc] _ y flag)
// cond: ccARM64Eval(cc, flag) < 0
// result: y
for {
cc := auxIntToOp(v.AuxInt)
y := v_1
flag := v_2
if !(ccARM64Eval(cc, flag) < 0) {
break
}
v.copyOf(y)
return true
}
// match: (CSEL [cc] x y (CMPWconst [0] boolval))
// cond: cc == OpARM64NotEqual && flagArg(boolval) != nil
// result: (CSEL [boolval.Op] x y flagArg(boolval))
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
y := v_1
if v_2.Op != OpARM64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
break
}
boolval := v_2.Args[0]
if !(cc == OpARM64NotEqual && flagArg(boolval) != nil) {
break
}
v.reset(OpARM64CSEL)
v.AuxInt = opToAuxInt(boolval.Op)
v.AddArg3(x, y, flagArg(boolval))
return true
}
// match: (CSEL [cc] x y (CMPWconst [0] boolval))
// cond: cc == OpARM64Equal && flagArg(boolval) != nil
// result: (CSEL [arm64Negate(boolval.Op)] x y flagArg(boolval))
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
y := v_1
if v_2.Op != OpARM64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
break
}
boolval := v_2.Args[0]
if !(cc == OpARM64Equal && flagArg(boolval) != nil) {
break
}
v.reset(OpARM64CSEL)
v.AuxInt = opToAuxInt(arm64Negate(boolval.Op))
v.AddArg3(x, y, flagArg(boolval))
return true
}
return false
}
func rewriteValueARM64_OpARM64CSEL0(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CSEL0 [cc] x (InvertFlags cmp))
// result: (CSEL0 [arm64Invert(cc)] x cmp)
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64InvertFlags {
break
}
cmp := v_1.Args[0]
v.reset(OpARM64CSEL0)
v.AuxInt = opToAuxInt(arm64Invert(cc))
v.AddArg2(x, cmp)
return true
}
// match: (CSEL0 [cc] x flag)
// cond: ccARM64Eval(cc, flag) > 0
// result: x
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
flag := v_1
if !(ccARM64Eval(cc, flag) > 0) {
break
}
v.copyOf(x)
return true
}
// match: (CSEL0 [cc] _ flag)
// cond: ccARM64Eval(cc, flag) < 0
// result: (MOVDconst [0])
for {
cc := auxIntToOp(v.AuxInt)
flag := v_1
if !(ccARM64Eval(cc, flag) < 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (CSEL0 [cc] x (CMPWconst [0] boolval))
// cond: cc == OpARM64NotEqual && flagArg(boolval) != nil
// result: (CSEL0 [boolval.Op] x flagArg(boolval))
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
break
}
boolval := v_1.Args[0]
if !(cc == OpARM64NotEqual && flagArg(boolval) != nil) {
break
}
v.reset(OpARM64CSEL0)
v.AuxInt = opToAuxInt(boolval.Op)
v.AddArg2(x, flagArg(boolval))
return true
}
// match: (CSEL0 [cc] x (CMPWconst [0] boolval))
// cond: cc == OpARM64Equal && flagArg(boolval) != nil
// result: (CSEL0 [arm64Negate(boolval.Op)] x flagArg(boolval))
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
if v_1.Op != OpARM64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
break
}
boolval := v_1.Args[0]
if !(cc == OpARM64Equal && flagArg(boolval) != nil) {
break
}
v.reset(OpARM64CSEL0)
v.AuxInt = opToAuxInt(arm64Negate(boolval.Op))
v.AddArg2(x, flagArg(boolval))
return true
}
return false
}
func rewriteValueARM64_OpARM64CSETM(v *Value) bool {
v_0 := v.Args[0]
// match: (CSETM [cc] (InvertFlags cmp))
// result: (CSETM [arm64Invert(cc)] cmp)
for {
cc := auxIntToOp(v.AuxInt)
if v_0.Op != OpARM64InvertFlags {
break
}
cmp := v_0.Args[0]
v.reset(OpARM64CSETM)
v.AuxInt = opToAuxInt(arm64Invert(cc))
v.AddArg(cmp)
return true
}
// match: (CSETM [cc] flag)
// cond: ccARM64Eval(cc, flag) > 0
// result: (MOVDconst [-1])
for {
cc := auxIntToOp(v.AuxInt)
flag := v_0
if !(ccARM64Eval(cc, flag) > 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
// match: (CSETM [cc] flag)
// cond: ccARM64Eval(cc, flag) < 0
// result: (MOVDconst [0])
for {
cc := auxIntToOp(v.AuxInt)
flag := v_0
if !(ccARM64Eval(cc, flag) < 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64CSINC(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CSINC [cc] x y (InvertFlags cmp))
// result: (CSINC [arm64Invert(cc)] x y cmp)
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
y := v_1
if v_2.Op != OpARM64InvertFlags {
break
}
cmp := v_2.Args[0]
v.reset(OpARM64CSINC)
v.AuxInt = opToAuxInt(arm64Invert(cc))
v.AddArg3(x, y, cmp)
return true
}
// match: (CSINC [cc] x _ flag)
// cond: ccARM64Eval(cc, flag) > 0
// result: x
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
flag := v_2
if !(ccARM64Eval(cc, flag) > 0) {
break
}
v.copyOf(x)
return true
}
// match: (CSINC [cc] _ y flag)
// cond: ccARM64Eval(cc, flag) < 0
// result: (ADDconst [1] y)
for {
cc := auxIntToOp(v.AuxInt)
y := v_1
flag := v_2
if !(ccARM64Eval(cc, flag) < 0) {
break
}
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(1)
v.AddArg(y)
return true
}
return false
}
func rewriteValueARM64_OpARM64CSINV(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CSINV [cc] x y (InvertFlags cmp))
// result: (CSINV [arm64Invert(cc)] x y cmp)
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
y := v_1
if v_2.Op != OpARM64InvertFlags {
break
}
cmp := v_2.Args[0]
v.reset(OpARM64CSINV)
v.AuxInt = opToAuxInt(arm64Invert(cc))
v.AddArg3(x, y, cmp)
return true
}
// match: (CSINV [cc] x _ flag)
// cond: ccARM64Eval(cc, flag) > 0
// result: x
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
flag := v_2
if !(ccARM64Eval(cc, flag) > 0) {
break
}
v.copyOf(x)
return true
}
// match: (CSINV [cc] _ y flag)
// cond: ccARM64Eval(cc, flag) < 0
// result: (Not y)
for {
cc := auxIntToOp(v.AuxInt)
y := v_1
flag := v_2
if !(ccARM64Eval(cc, flag) < 0) {
break
}
v.reset(OpNot)
v.AddArg(y)
return true
}
return false
}
func rewriteValueARM64_OpARM64CSNEG(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (CSNEG [cc] x y (InvertFlags cmp))
// result: (CSNEG [arm64Invert(cc)] x y cmp)
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
y := v_1
if v_2.Op != OpARM64InvertFlags {
break
}
cmp := v_2.Args[0]
v.reset(OpARM64CSNEG)
v.AuxInt = opToAuxInt(arm64Invert(cc))
v.AddArg3(x, y, cmp)
return true
}
// match: (CSNEG [cc] x _ flag)
// cond: ccARM64Eval(cc, flag) > 0
// result: x
for {
cc := auxIntToOp(v.AuxInt)
x := v_0
flag := v_2
if !(ccARM64Eval(cc, flag) > 0) {
break
}
v.copyOf(x)
return true
}
// match: (CSNEG [cc] _ y flag)
// cond: ccARM64Eval(cc, flag) < 0
// result: (NEG y)
for {
cc := auxIntToOp(v.AuxInt)
y := v_1
flag := v_2
if !(ccARM64Eval(cc, flag) < 0) {
break
}
v.reset(OpARM64NEG)
v.AddArg(y)
return true
}
return false
}
func rewriteValueARM64_OpARM64DIV(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (DIV (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [c/d])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
if v_1.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c / d)
return true
}
return false
}
func rewriteValueARM64_OpARM64DIVW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (DIVW (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [int64(int32(c)/int32(d))])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
if v_1.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(int32(c) / int32(d)))
return true
}
return false
}
func rewriteValueARM64_OpARM64EON(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (EON x (MOVDconst [c]))
// result: (XORconst [^c] x)
for {
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64XORconst)
v.AuxInt = int64ToAuxInt(^c)
v.AddArg(x)
return true
}
// match: (EON x x)
// result: (MOVDconst [-1])
for {
x := v_0
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
// match: (EON x0 x1:(SLLconst [c] y))
// cond: clobberIfDead(x1)
// result: (EONshiftLL x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SLLconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64EONshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (EON x0 x1:(SRLconst [c] y))
// cond: clobberIfDead(x1)
// result: (EONshiftRL x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRLconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64EONshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (EON x0 x1:(SRAconst [c] y))
// cond: clobberIfDead(x1)
// result: (EONshiftRA x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRAconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64EONshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (EON x0 x1:(RORconst [c] y))
// cond: clobberIfDead(x1)
// result: (EONshiftRO x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64RORconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64EONshiftRO)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
return false
}
func rewriteValueARM64_OpARM64EONshiftLL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (EONshiftLL x (MOVDconst [c]) [d])
// result: (XORconst x [^int64(uint64(c)<>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64XORconst)
v.AuxInt = int64ToAuxInt(^(c >> uint64(d)))
v.AddArg(x)
return true
}
// match: (EONshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
return false
}
func rewriteValueARM64_OpARM64EONshiftRL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (EONshiftRL x (MOVDconst [c]) [d])
// result: (XORconst x [^int64(uint64(c)>>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64XORconst)
v.AuxInt = int64ToAuxInt(^int64(uint64(c) >> uint64(d)))
v.AddArg(x)
return true
}
// match: (EONshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
return false
}
func rewriteValueARM64_OpARM64EONshiftRO(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (EONshiftRO x (MOVDconst [c]) [d])
// result: (XORconst x [^rotateRight64(c, d)])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64XORconst)
v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
v.AddArg(x)
return true
}
// match: (EONshiftRO (RORconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64RORconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
return false
}
func rewriteValueARM64_OpARM64Equal(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (Equal (CMPconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (Equal (TST x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (Equal (CMPWconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (Equal (TSTWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (Equal (CMPWconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (Equal (TSTW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (Equal (CMPconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (Equal (TSTconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (Equal (CMP x z:(NEG y)))
// cond: z.Uses == 1
// result: (Equal (CMN x y))
for {
if v_0.Op != OpARM64CMP {
break
}
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (Equal (CMPW x z:(NEG y)))
// cond: z.Uses == 1
// result: (Equal (CMNW x y))
for {
if v_0.Op != OpARM64CMPW {
break
}
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (Equal (CMPconst [0] x:(ADDconst [c] y)))
// cond: x.Uses == 1
// result: (Equal (CMNconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ADDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (Equal (CMPWconst [0] x:(ADDconst [c] y)))
// cond: x.Uses == 1
// result: (Equal (CMNWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ADDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (Equal (CMPconst [0] z:(ADD x y)))
// cond: z.Uses == 1
// result: (Equal (CMN x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64ADD {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (Equal (CMPWconst [0] z:(ADD x y)))
// cond: z.Uses == 1
// result: (Equal (CMNW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64ADD {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (Equal (CMPconst [0] z:(MADD a x y)))
// cond: z.Uses == 1
// result: (Equal (CMN a (MUL x y)))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MADD {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (Equal (CMPconst [0] z:(MSUB a x y)))
// cond: z.Uses == 1
// result: (Equal (CMP a (MUL x y)))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MSUB {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (Equal (CMPWconst [0] z:(MADDW a x y)))
// cond: z.Uses == 1
// result: (Equal (CMNW a (MULW x y)))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MADDW {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (Equal (CMPWconst [0] z:(MSUBW a x y)))
// cond: z.Uses == 1
// result: (Equal (CMPW a (MULW x y)))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MSUBW {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64Equal)
v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (Equal (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.eq())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.eq()))
return true
}
// match: (Equal (InvertFlags x))
// result: (Equal x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64Equal)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64FADDD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FADDD a (FMULD x y))
// cond: a.Block.Func.useFMA(v)
// result: (FMADDD a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
if v_1.Op != OpARM64FMULD {
continue
}
y := v_1.Args[1]
x := v_1.Args[0]
if !(a.Block.Func.useFMA(v)) {
continue
}
v.reset(OpARM64FMADDD)
v.AddArg3(a, x, y)
return true
}
break
}
// match: (FADDD a (FNMULD x y))
// cond: a.Block.Func.useFMA(v)
// result: (FMSUBD a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
if v_1.Op != OpARM64FNMULD {
continue
}
y := v_1.Args[1]
x := v_1.Args[0]
if !(a.Block.Func.useFMA(v)) {
continue
}
v.reset(OpARM64FMSUBD)
v.AddArg3(a, x, y)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64FADDS(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FADDS a (FMULS x y))
// cond: a.Block.Func.useFMA(v)
// result: (FMADDS a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
if v_1.Op != OpARM64FMULS {
continue
}
y := v_1.Args[1]
x := v_1.Args[0]
if !(a.Block.Func.useFMA(v)) {
continue
}
v.reset(OpARM64FMADDS)
v.AddArg3(a, x, y)
return true
}
break
}
// match: (FADDS a (FNMULS x y))
// cond: a.Block.Func.useFMA(v)
// result: (FMSUBS a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
if v_1.Op != OpARM64FNMULS {
continue
}
y := v_1.Args[1]
x := v_1.Args[0]
if !(a.Block.Func.useFMA(v)) {
continue
}
v.reset(OpARM64FMSUBS)
v.AddArg3(a, x, y)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64FCMPD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (FCMPD x (FMOVDconst [0]))
// result: (FCMPD0 x)
for {
x := v_0
if v_1.Op != OpARM64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != 0 {
break
}
v.reset(OpARM64FCMPD0)
v.AddArg(x)
return true
}
// match: (FCMPD (FMOVDconst [0]) x)
// result: (InvertFlags (FCMPD0 x))
for {
if v_0.Op != OpARM64FMOVDconst || auxIntToFloat64(v_0.AuxInt) != 0 {
break
}
x := v_1
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64FCMPD0, types.TypeFlags)
v0.AddArg(x)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueARM64_OpARM64FCMPS(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (FCMPS x (FMOVSconst [0]))
// result: (FCMPS0 x)
for {
x := v_0
if v_1.Op != OpARM64FMOVSconst || auxIntToFloat64(v_1.AuxInt) != 0 {
break
}
v.reset(OpARM64FCMPS0)
v.AddArg(x)
return true
}
// match: (FCMPS (FMOVSconst [0]) x)
// result: (InvertFlags (FCMPS0 x))
for {
if v_0.Op != OpARM64FMOVSconst || auxIntToFloat64(v_0.AuxInt) != 0 {
break
}
x := v_1
v.reset(OpARM64InvertFlags)
v0 := b.NewValue0(v.Pos, OpARM64FCMPS0, types.TypeFlags)
v0.AddArg(x)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVDfpgp(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (FMOVDfpgp (Arg [off] {sym}))
// result: @b.Func.Entry (Arg [off] {sym})
for {
t := v.Type
if v_0.Op != OpArg {
break
}
off := auxIntToInt32(v_0.AuxInt)
sym := auxToSym(v_0.Aux)
b = b.Func.Entry
v0 := b.NewValue0(v.Pos, OpArg, t)
v.copyOf(v0)
v0.AuxInt = int32ToAuxInt(off)
v0.Aux = symToAux(sym)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVDgpfp(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (FMOVDgpfp (Arg [off] {sym}))
// result: @b.Func.Entry (Arg [off] {sym})
for {
t := v.Type
if v_0.Op != OpArg {
break
}
off := auxIntToInt32(v_0.AuxInt)
sym := auxToSym(v_0.Aux)
b = b.Func.Entry
v0 := b.NewValue0(v.Pos, OpArg, t)
v.copyOf(v0)
v0.AuxInt = int32ToAuxInt(off)
v0.Aux = symToAux(sym)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVDload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr val _))
// result: (FMOVDgpfp val)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVDstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
break
}
val := v_1.Args[1]
if ptr != v_1.Args[0] {
break
}
v.reset(OpARM64FMOVDgpfp)
v.AddArg(val)
return true
}
// match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (FMOVDload [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64FMOVDload)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (FMOVDload [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (FMOVDloadidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64FMOVDloadidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (FMOVDload [off] {sym} (ADDshiftLL [3] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (FMOVDloadidx8 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64FMOVDloadidx8)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64FMOVDload)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVDloadidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVDloadidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (FMOVDload [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64FMOVDload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (FMOVDloadidx (MOVDconst [c]) ptr mem)
// cond: is32Bit(c)
// result: (FMOVDload [int32(c)] ptr mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
ptr := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64FMOVDload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (FMOVDloadidx ptr (SLLconst [3] idx) mem)
// result: (FMOVDloadidx8 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64FMOVDloadidx8)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (FMOVDloadidx (SLLconst [3] idx) ptr mem)
// result: (FMOVDloadidx8 ptr idx mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[0]
ptr := v_1
mem := v_2
v.reset(OpARM64FMOVDloadidx8)
v.AddArg3(ptr, idx, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVDloadidx8(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVDloadidx8 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<3)
// result: (FMOVDload ptr [int32(c)<<3] mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 3)) {
break
}
v.reset(OpARM64FMOVDload)
v.AuxInt = int32ToAuxInt(int32(c) << 3)
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVDstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (FMOVDstore [off] {sym} ptr (FMOVDgpfp val) mem)
// result: (MOVDstore [off] {sym} ptr val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64FMOVDgpfp {
break
}
val := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVDstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (FMOVDstore [off1+int32(off2)] {sym} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64FMOVDstore)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (FMOVDstore [off] {sym} (ADD ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (FMOVDstoreidx ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64FMOVDstoreidx)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (FMOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (FMOVDstoreidx8 ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64FMOVDstoreidx8)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64FMOVDstore)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg3(ptr, val, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVDstoreidx(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVDstoreidx ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c)
// result: (FMOVDstore [int32(c)] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64FMOVDstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(ptr, val, mem)
return true
}
// match: (FMOVDstoreidx (MOVDconst [c]) idx val mem)
// cond: is32Bit(c)
// result: (FMOVDstore [int32(c)] idx val mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64FMOVDstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(idx, val, mem)
return true
}
// match: (FMOVDstoreidx ptr (SLLconst [3] idx) val mem)
// result: (FMOVDstoreidx8 ptr idx val mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
break
}
idx := v_1.Args[0]
val := v_2
mem := v_3
v.reset(OpARM64FMOVDstoreidx8)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (FMOVDstoreidx (SLLconst [3] idx) ptr val mem)
// result: (FMOVDstoreidx8 ptr idx val mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[0]
ptr := v_1
val := v_2
mem := v_3
v.reset(OpARM64FMOVDstoreidx8)
v.AddArg4(ptr, idx, val, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVDstoreidx8(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVDstoreidx8 ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c<<3)
// result: (FMOVDstore [int32(c)<<3] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c << 3)) {
break
}
v.reset(OpARM64FMOVDstore)
v.AuxInt = int32ToAuxInt(int32(c) << 3)
v.AddArg3(ptr, val, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (FMOVSload [off] {sym} ptr (MOVWstore [off] {sym} ptr val _))
// result: (FMOVSgpfp val)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVWstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
break
}
val := v_1.Args[1]
if ptr != v_1.Args[0] {
break
}
v.reset(OpARM64FMOVSgpfp)
v.AddArg(val)
return true
}
// match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (FMOVSload [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64FMOVSload)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (FMOVSload [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (FMOVSloadidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64FMOVSloadidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (FMOVSload [off] {sym} (ADDshiftLL [2] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (FMOVSloadidx4 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64FMOVSloadidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64FMOVSload)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVSloadidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVSloadidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (FMOVSload [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64FMOVSload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (FMOVSloadidx (MOVDconst [c]) ptr mem)
// cond: is32Bit(c)
// result: (FMOVSload [int32(c)] ptr mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
ptr := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64FMOVSload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (FMOVSloadidx ptr (SLLconst [2] idx) mem)
// result: (FMOVSloadidx4 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64FMOVSloadidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (FMOVSloadidx (SLLconst [2] idx) ptr mem)
// result: (FMOVSloadidx4 ptr idx mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[0]
ptr := v_1
mem := v_2
v.reset(OpARM64FMOVSloadidx4)
v.AddArg3(ptr, idx, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVSloadidx4(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVSloadidx4 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<2)
// result: (FMOVSload ptr [int32(c)<<2] mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 2)) {
break
}
v.reset(OpARM64FMOVSload)
v.AuxInt = int32ToAuxInt(int32(c) << 2)
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVSstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (FMOVSstore [off] {sym} ptr (FMOVSgpfp val) mem)
// result: (MOVWstore [off] {sym} ptr val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64FMOVSgpfp {
break
}
val := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (FMOVSstore [off1+int32(off2)] {sym} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64FMOVSstore)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (FMOVSstore [off] {sym} (ADD ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (FMOVSstoreidx ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64FMOVSstoreidx)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (FMOVSstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (FMOVSstoreidx4 ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64FMOVSstoreidx4)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64FMOVSstore)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg3(ptr, val, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVSstoreidx(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVSstoreidx ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c)
// result: (FMOVSstore [int32(c)] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64FMOVSstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(ptr, val, mem)
return true
}
// match: (FMOVSstoreidx (MOVDconst [c]) idx val mem)
// cond: is32Bit(c)
// result: (FMOVSstore [int32(c)] idx val mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64FMOVSstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(idx, val, mem)
return true
}
// match: (FMOVSstoreidx ptr (SLLconst [2] idx) val mem)
// result: (FMOVSstoreidx4 ptr idx val mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
break
}
idx := v_1.Args[0]
val := v_2
mem := v_3
v.reset(OpARM64FMOVSstoreidx4)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (FMOVSstoreidx (SLLconst [2] idx) ptr val mem)
// result: (FMOVSstoreidx4 ptr idx val mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[0]
ptr := v_1
val := v_2
mem := v_3
v.reset(OpARM64FMOVSstoreidx4)
v.AddArg4(ptr, idx, val, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMOVSstoreidx4(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMOVSstoreidx4 ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c<<2)
// result: (FMOVSstore [int32(c)<<2] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c << 2)) {
break
}
v.reset(OpARM64FMOVSstore)
v.AuxInt = int32ToAuxInt(int32(c) << 2)
v.AddArg3(ptr, val, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64FMULD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMULD (FNEGD x) y)
// result: (FNMULD x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64FNEGD {
continue
}
x := v_0.Args[0]
y := v_1
v.reset(OpARM64FNMULD)
v.AddArg2(x, y)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64FMULS(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FMULS (FNEGS x) y)
// result: (FNMULS x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64FNEGS {
continue
}
x := v_0.Args[0]
y := v_1
v.reset(OpARM64FNMULS)
v.AddArg2(x, y)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64FNEGD(v *Value) bool {
v_0 := v.Args[0]
// match: (FNEGD (FMULD x y))
// result: (FNMULD x y)
for {
if v_0.Op != OpARM64FMULD {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
v.reset(OpARM64FNMULD)
v.AddArg2(x, y)
return true
}
// match: (FNEGD (FNMULD x y))
// result: (FMULD x y)
for {
if v_0.Op != OpARM64FNMULD {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
v.reset(OpARM64FMULD)
v.AddArg2(x, y)
return true
}
return false
}
func rewriteValueARM64_OpARM64FNEGS(v *Value) bool {
v_0 := v.Args[0]
// match: (FNEGS (FMULS x y))
// result: (FNMULS x y)
for {
if v_0.Op != OpARM64FMULS {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
v.reset(OpARM64FNMULS)
v.AddArg2(x, y)
return true
}
// match: (FNEGS (FNMULS x y))
// result: (FMULS x y)
for {
if v_0.Op != OpARM64FNMULS {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
v.reset(OpARM64FMULS)
v.AddArg2(x, y)
return true
}
return false
}
func rewriteValueARM64_OpARM64FNMULD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FNMULD (FNEGD x) y)
// result: (FMULD x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64FNEGD {
continue
}
x := v_0.Args[0]
y := v_1
v.reset(OpARM64FMULD)
v.AddArg2(x, y)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64FNMULS(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FNMULS (FNEGS x) y)
// result: (FMULS x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64FNEGS {
continue
}
x := v_0.Args[0]
y := v_1
v.reset(OpARM64FMULS)
v.AddArg2(x, y)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64FSUBD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FSUBD a (FMULD x y))
// cond: a.Block.Func.useFMA(v)
// result: (FMSUBD a x y)
for {
a := v_0
if v_1.Op != OpARM64FMULD {
break
}
y := v_1.Args[1]
x := v_1.Args[0]
if !(a.Block.Func.useFMA(v)) {
break
}
v.reset(OpARM64FMSUBD)
v.AddArg3(a, x, y)
return true
}
// match: (FSUBD (FMULD x y) a)
// cond: a.Block.Func.useFMA(v)
// result: (FNMSUBD a x y)
for {
if v_0.Op != OpARM64FMULD {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
a := v_1
if !(a.Block.Func.useFMA(v)) {
break
}
v.reset(OpARM64FNMSUBD)
v.AddArg3(a, x, y)
return true
}
// match: (FSUBD a (FNMULD x y))
// cond: a.Block.Func.useFMA(v)
// result: (FMADDD a x y)
for {
a := v_0
if v_1.Op != OpARM64FNMULD {
break
}
y := v_1.Args[1]
x := v_1.Args[0]
if !(a.Block.Func.useFMA(v)) {
break
}
v.reset(OpARM64FMADDD)
v.AddArg3(a, x, y)
return true
}
// match: (FSUBD (FNMULD x y) a)
// cond: a.Block.Func.useFMA(v)
// result: (FNMADDD a x y)
for {
if v_0.Op != OpARM64FNMULD {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
a := v_1
if !(a.Block.Func.useFMA(v)) {
break
}
v.reset(OpARM64FNMADDD)
v.AddArg3(a, x, y)
return true
}
return false
}
func rewriteValueARM64_OpARM64FSUBS(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (FSUBS a (FMULS x y))
// cond: a.Block.Func.useFMA(v)
// result: (FMSUBS a x y)
for {
a := v_0
if v_1.Op != OpARM64FMULS {
break
}
y := v_1.Args[1]
x := v_1.Args[0]
if !(a.Block.Func.useFMA(v)) {
break
}
v.reset(OpARM64FMSUBS)
v.AddArg3(a, x, y)
return true
}
// match: (FSUBS (FMULS x y) a)
// cond: a.Block.Func.useFMA(v)
// result: (FNMSUBS a x y)
for {
if v_0.Op != OpARM64FMULS {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
a := v_1
if !(a.Block.Func.useFMA(v)) {
break
}
v.reset(OpARM64FNMSUBS)
v.AddArg3(a, x, y)
return true
}
// match: (FSUBS a (FNMULS x y))
// cond: a.Block.Func.useFMA(v)
// result: (FMADDS a x y)
for {
a := v_0
if v_1.Op != OpARM64FNMULS {
break
}
y := v_1.Args[1]
x := v_1.Args[0]
if !(a.Block.Func.useFMA(v)) {
break
}
v.reset(OpARM64FMADDS)
v.AddArg3(a, x, y)
return true
}
// match: (FSUBS (FNMULS x y) a)
// cond: a.Block.Func.useFMA(v)
// result: (FNMADDS a x y)
for {
if v_0.Op != OpARM64FNMULS {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
a := v_1
if !(a.Block.Func.useFMA(v)) {
break
}
v.reset(OpARM64FNMADDS)
v.AddArg3(a, x, y)
return true
}
return false
}
func rewriteValueARM64_OpARM64GreaterEqual(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (GreaterEqual (CMPconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (GreaterEqual (TST x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqual)
v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPWconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (GreaterEqual (TSTWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqual)
v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPWconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (GreaterEqual (TSTW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqual)
v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (GreaterEqual (TSTconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqual)
v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPconst [0] x:(ADDconst [c] y)))
// cond: x.Uses == 1
// result: (GreaterEqualNoov (CMNconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ADDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqualNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPWconst [0] x:(ADDconst [c] y)))
// cond: x.Uses == 1
// result: (GreaterEqualNoov (CMNWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ADDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqualNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPconst [0] z:(ADD x y)))
// cond: z.Uses == 1
// result: (GreaterEqualNoov (CMN x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64ADD {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqualNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPWconst [0] z:(ADD x y)))
// cond: z.Uses == 1
// result: (GreaterEqualNoov (CMNW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64ADD {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqualNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPconst [0] z:(MADD a x y)))
// cond: z.Uses == 1
// result: (GreaterEqualNoov (CMN a (MUL x y)))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MADD {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqualNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPconst [0] z:(MSUB a x y)))
// cond: z.Uses == 1
// result: (GreaterEqualNoov (CMP a (MUL x y)))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MSUB {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqualNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPWconst [0] z:(MADDW a x y)))
// cond: z.Uses == 1
// result: (GreaterEqualNoov (CMNW a (MULW x y)))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MADDW {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqualNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (CMPWconst [0] z:(MSUBW a x y)))
// cond: z.Uses == 1
// result: (GreaterEqualNoov (CMPW a (MULW x y)))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MSUBW {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterEqualNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (GreaterEqual (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.ge())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.ge()))
return true
}
// match: (GreaterEqual (InvertFlags x))
// result: (LessEqual x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64LessEqual)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64GreaterEqualF(v *Value) bool {
v_0 := v.Args[0]
// match: (GreaterEqualF (InvertFlags x))
// result: (LessEqualF x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64LessEqualF)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64GreaterEqualU(v *Value) bool {
v_0 := v.Args[0]
// match: (GreaterEqualU (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.uge())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.uge()))
return true
}
// match: (GreaterEqualU (InvertFlags x))
// result: (LessEqualU x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64LessEqualU)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64GreaterThan(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (GreaterThan (CMPconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (GreaterThan (TST x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterThan)
v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (GreaterThan (CMPWconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (GreaterThan (TSTWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64GreaterThan)
v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (GreaterThan (CMPWconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (GreaterThan (TSTW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64GreaterThan)
v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (GreaterThan (CMPconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (GreaterThan (TSTconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64GreaterThan)
v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (GreaterThan (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.gt())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.gt()))
return true
}
// match: (GreaterThan (InvertFlags x))
// result: (LessThan x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64LessThan)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64GreaterThanF(v *Value) bool {
v_0 := v.Args[0]
// match: (GreaterThanF (InvertFlags x))
// result: (LessThanF x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64LessThanF)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64GreaterThanU(v *Value) bool {
v_0 := v.Args[0]
// match: (GreaterThanU (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.ugt())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.ugt()))
return true
}
// match: (GreaterThanU (InvertFlags x))
// result: (LessThanU x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64LessThanU)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64LDP(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (LDP [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (LDP [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64LDP)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (LDP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (LDP [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64LDP)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64LessEqual(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (LessEqual (CMPconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (LessEqual (TST x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessEqual)
v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (LessEqual (CMPWconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (LessEqual (TSTWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64LessEqual)
v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (LessEqual (CMPWconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (LessEqual (TSTW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessEqual)
v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (LessEqual (CMPconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (LessEqual (TSTconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64LessEqual)
v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (LessEqual (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.le())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.le()))
return true
}
// match: (LessEqual (InvertFlags x))
// result: (GreaterEqual x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64GreaterEqual)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64LessEqualF(v *Value) bool {
v_0 := v.Args[0]
// match: (LessEqualF (InvertFlags x))
// result: (GreaterEqualF x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64GreaterEqualF)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64LessEqualU(v *Value) bool {
v_0 := v.Args[0]
// match: (LessEqualU (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.ule())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.ule()))
return true
}
// match: (LessEqualU (InvertFlags x))
// result: (GreaterEqualU x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64GreaterEqualU)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64LessThan(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (LessThan (CMPconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (LessThan (TST x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessThan)
v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPWconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (LessThan (TSTWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64LessThan)
v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPWconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (LessThan (TSTW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessThan)
v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (LessThan (TSTconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64LessThan)
v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPconst [0] x:(ADDconst [c] y)))
// cond: x.Uses == 1
// result: (LessThanNoov (CMNconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ADDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64LessThanNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPWconst [0] x:(ADDconst [c] y)))
// cond: x.Uses == 1
// result: (LessThanNoov (CMNWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ADDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64LessThanNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPconst [0] z:(ADD x y)))
// cond: z.Uses == 1
// result: (LessThanNoov (CMN x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64ADD {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessThanNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPWconst [0] z:(ADD x y)))
// cond: z.Uses == 1
// result: (LessThanNoov (CMNW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64ADD {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessThanNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPconst [0] z:(MADD a x y)))
// cond: z.Uses == 1
// result: (LessThanNoov (CMN a (MUL x y)))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MADD {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessThanNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPconst [0] z:(MSUB a x y)))
// cond: z.Uses == 1
// result: (LessThanNoov (CMP a (MUL x y)))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MSUB {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessThanNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPWconst [0] z:(MADDW a x y)))
// cond: z.Uses == 1
// result: (LessThanNoov (CMNW a (MULW x y)))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MADDW {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessThanNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (LessThan (CMPWconst [0] z:(MSUBW a x y)))
// cond: z.Uses == 1
// result: (LessThanNoov (CMPW a (MULW x y)))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MSUBW {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64LessThanNoov)
v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (LessThan (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.lt())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.lt()))
return true
}
// match: (LessThan (InvertFlags x))
// result: (GreaterThan x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64GreaterThan)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64LessThanF(v *Value) bool {
v_0 := v.Args[0]
// match: (LessThanF (InvertFlags x))
// result: (GreaterThanF x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64GreaterThanF)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64LessThanU(v *Value) bool {
v_0 := v.Args[0]
// match: (LessThanU (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.ult())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.ult()))
return true
}
// match: (LessThanU (InvertFlags x))
// result: (GreaterThanU x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64GreaterThanU)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64MADD(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (MADD a x (MOVDconst [-1]))
// result: (SUB a x)
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != -1 {
break
}
v.reset(OpARM64SUB)
v.AddArg2(a, x)
return true
}
// match: (MADD a _ (MOVDconst [0]))
// result: a
for {
a := v_0
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
break
}
v.copyOf(a)
return true
}
// match: (MADD a x (MOVDconst [1]))
// result: (ADD a x)
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 1 {
break
}
v.reset(OpARM64ADD)
v.AddArg2(a, x)
return true
}
// match: (MADD a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c)
// result: (ADDshiftLL a x [log64(c)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg2(a, x)
return true
}
// match: (MADD a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c-1) && c>=3
// result: (ADD a (ADDshiftLL x x [log64(c-1)]))
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c-1) && c >= 3) {
break
}
v.reset(OpARM64ADD)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c+1) && c>=7
// result: (SUB a (SUBshiftLL x x [log64(c+1)]))
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c+1) && c >= 7) {
break
}
v.reset(OpARM64SUB)
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo64(c/3)
// result: (SUBshiftLL a (SUBshiftLL x x [2]) [log64(c/3)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a x (MOVDconst [c]))
// cond: c%5 == 0 && isPowerOfTwo64(c/5)
// result: (ADDshiftLL a (ADDshiftLL x x [2]) [log64(c/5)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo64(c/7)
// result: (SUBshiftLL a (SUBshiftLL x x [3]) [log64(c/7)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a x (MOVDconst [c]))
// cond: c%9 == 0 && isPowerOfTwo64(c/9)
// result: (ADDshiftLL a (ADDshiftLL x x [3]) [log64(c/9)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a (MOVDconst [-1]) x)
// result: (SUB a x)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
break
}
x := v_2
v.reset(OpARM64SUB)
v.AddArg2(a, x)
return true
}
// match: (MADD a (MOVDconst [0]) _)
// result: a
for {
a := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
v.copyOf(a)
return true
}
// match: (MADD a (MOVDconst [1]) x)
// result: (ADD a x)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
x := v_2
v.reset(OpARM64ADD)
v.AddArg2(a, x)
return true
}
// match: (MADD a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c)
// result: (ADDshiftLL a x [log64(c)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg2(a, x)
return true
}
// match: (MADD a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c-1) && c>=3
// result: (ADD a (ADDshiftLL x x [log64(c-1)]))
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c-1) && c >= 3) {
break
}
v.reset(OpARM64ADD)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c+1) && c>=7
// result: (SUB a (SUBshiftLL x x [log64(c+1)]))
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c+1) && c >= 7) {
break
}
v.reset(OpARM64SUB)
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a (MOVDconst [c]) x)
// cond: c%3 == 0 && isPowerOfTwo64(c/3)
// result: (SUBshiftLL a (SUBshiftLL x x [2]) [log64(c/3)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a (MOVDconst [c]) x)
// cond: c%5 == 0 && isPowerOfTwo64(c/5)
// result: (ADDshiftLL a (ADDshiftLL x x [2]) [log64(c/5)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a (MOVDconst [c]) x)
// cond: c%7 == 0 && isPowerOfTwo64(c/7)
// result: (SUBshiftLL a (SUBshiftLL x x [3]) [log64(c/7)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD a (MOVDconst [c]) x)
// cond: c%9 == 0 && isPowerOfTwo64(c/9)
// result: (ADDshiftLL a (ADDshiftLL x x [3]) [log64(c/9)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADD (MOVDconst [c]) x y)
// result: (ADDconst [c] (MUL x y))
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
y := v_2
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (MADD a (MOVDconst [c]) (MOVDconst [d]))
// result: (ADDconst [c*d] a)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
if v_2.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_2.AuxInt)
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c * d)
v.AddArg(a)
return true
}
return false
}
func rewriteValueARM64_OpARM64MADDW(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (MADDW a x (MOVDconst [c]))
// cond: int32(c)==-1
// result: (SUB a x)
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(int32(c) == -1) {
break
}
v.reset(OpARM64SUB)
v.AddArg2(a, x)
return true
}
// match: (MADDW a _ (MOVDconst [c]))
// cond: int32(c)==0
// result: a
for {
a := v_0
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(int32(c) == 0) {
break
}
v.copyOf(a)
return true
}
// match: (MADDW a x (MOVDconst [c]))
// cond: int32(c)==1
// result: (ADD a x)
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(int32(c) == 1) {
break
}
v.reset(OpARM64ADD)
v.AddArg2(a, x)
return true
}
// match: (MADDW a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c)
// result: (ADDshiftLL a x [log64(c)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg2(a, x)
return true
}
// match: (MADDW a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c-1) && int32(c)>=3
// result: (ADD a (ADDshiftLL x x [log64(c-1)]))
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
break
}
v.reset(OpARM64ADD)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c+1) && int32(c)>=7
// result: (SUB a (SUBshiftLL x x [log64(c+1)]))
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
break
}
v.reset(OpARM64SUB)
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
// result: (SUBshiftLL a (SUBshiftLL x x [2]) [log64(c/3)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a x (MOVDconst [c]))
// cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
// result: (ADDshiftLL a (ADDshiftLL x x [2]) [log64(c/5)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
// result: (SUBshiftLL a (SUBshiftLL x x [3]) [log64(c/7)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a x (MOVDconst [c]))
// cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
// result: (ADDshiftLL a (ADDshiftLL x x [3]) [log64(c/9)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a (MOVDconst [c]) x)
// cond: int32(c)==-1
// result: (SUB a x)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(int32(c) == -1) {
break
}
v.reset(OpARM64SUB)
v.AddArg2(a, x)
return true
}
// match: (MADDW a (MOVDconst [c]) _)
// cond: int32(c)==0
// result: a
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
if !(int32(c) == 0) {
break
}
v.copyOf(a)
return true
}
// match: (MADDW a (MOVDconst [c]) x)
// cond: int32(c)==1
// result: (ADD a x)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(int32(c) == 1) {
break
}
v.reset(OpARM64ADD)
v.AddArg2(a, x)
return true
}
// match: (MADDW a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c)
// result: (ADDshiftLL a x [log64(c)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg2(a, x)
return true
}
// match: (MADDW a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c-1) && int32(c)>=3
// result: (ADD a (ADDshiftLL x x [log64(c-1)]))
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
break
}
v.reset(OpARM64ADD)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c+1) && int32(c)>=7
// result: (SUB a (SUBshiftLL x x [log64(c+1)]))
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
break
}
v.reset(OpARM64SUB)
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a (MOVDconst [c]) x)
// cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
// result: (SUBshiftLL a (SUBshiftLL x x [2]) [log64(c/3)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a (MOVDconst [c]) x)
// cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
// result: (ADDshiftLL a (ADDshiftLL x x [2]) [log64(c/5)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a (MOVDconst [c]) x)
// cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
// result: (SUBshiftLL a (SUBshiftLL x x [3]) [log64(c/7)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW a (MOVDconst [c]) x)
// cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
// result: (ADDshiftLL a (ADDshiftLL x x [3]) [log64(c/9)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MADDW (MOVDconst [c]) x y)
// result: (ADDconst [c] (MULW x y))
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
y := v_2
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (MADDW a (MOVDconst [c]) (MOVDconst [d]))
// result: (ADDconst [int64(int32(c)*int32(d))] a)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
if v_2.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_2.AuxInt)
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(int64(int32(c) * int32(d)))
v.AddArg(a)
return true
}
return false
}
func rewriteValueARM64_OpARM64MNEG(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (MNEG x (MOVDconst [-1]))
// result: x
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
continue
}
v.copyOf(x)
return true
}
break
}
// match: (MNEG _ (MOVDconst [0]))
// result: (MOVDconst [0])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
continue
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
break
}
// match: (MNEG x (MOVDconst [1]))
// result: (NEG x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
continue
}
v.reset(OpARM64NEG)
v.AddArg(x)
return true
}
break
}
// match: (MNEG x (MOVDconst [c]))
// cond: isPowerOfTwo64(c)
// result: (NEG (SLLconst [log64(c)] x))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c)) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c))
v0.AddArg(x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEG x (MOVDconst [c]))
// cond: isPowerOfTwo64(c-1) && c >= 3
// result: (NEG (ADDshiftLL x x [log64(c-1)]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c-1) && c >= 3) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEG x (MOVDconst [c]))
// cond: isPowerOfTwo64(c+1) && c >= 7
// result: (NEG (ADDshiftLL (NEG x) x [log64(c+1)]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c+1) && c >= 7) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
v1.AddArg(x)
v0.AddArg2(v1, x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEG x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo64(c/3)
// result: (SLLconst [log64(c/3)] (SUBshiftLL x x [2]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
continue
}
v.reset(OpARM64SLLconst)
v.Type = x.Type
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEG x (MOVDconst [c]))
// cond: c%5 == 0 && isPowerOfTwo64(c/5)
// result: (NEG (SLLconst [log64(c/5)] (ADDshiftLL x x [2])))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c / 5))
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v1.AuxInt = int64ToAuxInt(2)
v1.AddArg2(x, x)
v0.AddArg(v1)
v.AddArg(v0)
return true
}
break
}
// match: (MNEG x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo64(c/7)
// result: (SLLconst [log64(c/7)] (SUBshiftLL x x [3]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
continue
}
v.reset(OpARM64SLLconst)
v.Type = x.Type
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEG x (MOVDconst [c]))
// cond: c%9 == 0 && isPowerOfTwo64(c/9)
// result: (NEG (SLLconst [log64(c/9)] (ADDshiftLL x x [3])))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c / 9))
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v1.AuxInt = int64ToAuxInt(3)
v1.AddArg2(x, x)
v0.AddArg(v1)
v.AddArg(v0)
return true
}
break
}
// match: (MNEG (MOVDconst [c]) (MOVDconst [d]))
// result: (MOVDconst [-c*d])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_0.AuxInt)
if v_1.Op != OpARM64MOVDconst {
continue
}
d := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-c * d)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64MNEGW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (MNEGW x (MOVDconst [c]))
// cond: int32(c)==-1
// result: x
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(int32(c) == -1) {
continue
}
v.copyOf(x)
return true
}
break
}
// match: (MNEGW _ (MOVDconst [c]))
// cond: int32(c)==0
// result: (MOVDconst [0])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(int32(c) == 0) {
continue
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
break
}
// match: (MNEGW x (MOVDconst [c]))
// cond: int32(c)==1
// result: (NEG x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(int32(c) == 1) {
continue
}
v.reset(OpARM64NEG)
v.AddArg(x)
return true
}
break
}
// match: (MNEGW x (MOVDconst [c]))
// cond: isPowerOfTwo64(c)
// result: (NEG (SLLconst [log64(c)] x))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c)) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c))
v0.AddArg(x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEGW x (MOVDconst [c]))
// cond: isPowerOfTwo64(c-1) && int32(c) >= 3
// result: (NEG (ADDshiftLL x x [log64(c-1)]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEGW x (MOVDconst [c]))
// cond: isPowerOfTwo64(c+1) && int32(c) >= 7
// result: (NEG (ADDshiftLL (NEG x) x [log64(c+1)]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
v1.AddArg(x)
v0.AddArg2(v1, x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEGW x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
// result: (SLLconst [log64(c/3)] (SUBshiftLL x x [2]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
continue
}
v.reset(OpARM64SLLconst)
v.Type = x.Type
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEGW x (MOVDconst [c]))
// cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
// result: (NEG (SLLconst [log64(c/5)] (ADDshiftLL x x [2])))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c / 5))
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v1.AuxInt = int64ToAuxInt(2)
v1.AddArg2(x, x)
v0.AddArg(v1)
v.AddArg(v0)
return true
}
break
}
// match: (MNEGW x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
// result: (SLLconst [log64(c/7)] (SUBshiftLL x x [3]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
continue
}
v.reset(OpARM64SLLconst)
v.Type = x.Type
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MNEGW x (MOVDconst [c]))
// cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
// result: (NEG (SLLconst [log64(c/9)] (ADDshiftLL x x [3])))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
continue
}
v.reset(OpARM64NEG)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c / 9))
v1 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v1.AuxInt = int64ToAuxInt(3)
v1.AddArg2(x, x)
v0.AddArg(v1)
v.AddArg(v0)
return true
}
break
}
// match: (MNEGW (MOVDconst [c]) (MOVDconst [d]))
// result: (MOVDconst [-int64(int32(c)*int32(d))])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_0.AuxInt)
if v_1.Op != OpARM64MOVDconst {
continue
}
d := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-int64(int32(c) * int32(d)))
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64MOD(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOD (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [c%d])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
if v_1.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c % d)
return true
}
return false
}
func rewriteValueARM64_OpARM64MODW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MODW (MOVDconst [c]) (MOVDconst [d]))
// cond: d != 0
// result: (MOVDconst [int64(int32(c)%int32(d))])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
if v_1.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_1.AuxInt)
if !(d != 0) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(int32(c) % int32(d)))
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVBUload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVBUload [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVBUload)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBUload [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVBUloadidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVBUloadidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVBUload)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBUload [off] {sym} ptr (MOVBstorezero [off2] {sym2} ptr2 _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVDconst [0])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVBstorezero {
break
}
off2 := auxIntToInt32(v_1.AuxInt)
sym2 := auxToSym(v_1.Aux)
ptr2 := v_1.Args[0]
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (MOVBUload [off] {sym} (SB) _)
// cond: symIsRO(sym)
// result: (MOVDconst [int64(read8(sym, int64(off)))])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpSB || !(symIsRO(sym)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(read8(sym, int64(off))))
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVBUloadidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVBUloadidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVBUload [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVBUload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBUloadidx (MOVDconst [c]) ptr mem)
// cond: is32Bit(c)
// result: (MOVBUload [int32(c)] ptr mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
ptr := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVBUload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBUloadidx ptr idx (MOVBstorezeroidx ptr2 idx2 _))
// cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVBstorezeroidx {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVBUreg(v *Value) bool {
v_0 := v.Args[0]
// match: (MOVBUreg x:(MOVBUload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(MOVBUloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(MOVBUreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg (ANDconst [c] x))
// result: (ANDconst [c&(1<<8-1)] x)
for {
if v_0.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c & (1<<8 - 1))
v.AddArg(x)
return true
}
// match: (MOVBUreg (MOVDconst [c]))
// result: (MOVDconst [int64(uint8(c))])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(uint8(c)))
return true
}
// match: (MOVBUreg x:(Equal _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64Equal {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(NotEqual _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64NotEqual {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(LessThan _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64LessThan {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(LessThanU _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64LessThanU {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(LessThanF _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64LessThanF {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(LessEqual _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64LessEqual {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(LessEqualU _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64LessEqualU {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(LessEqualF _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64LessEqualF {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(GreaterThan _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64GreaterThan {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(GreaterThanU _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64GreaterThanU {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(GreaterThanF _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64GreaterThanF {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(GreaterEqual _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64GreaterEqual {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(GreaterEqualU _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64GreaterEqualU {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg x:(GreaterEqualF _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64GreaterEqualF {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBUreg (SLLconst [lc] x))
// cond: lc >= 8
// result: (MOVDconst [0])
for {
if v_0.Op != OpARM64SLLconst {
break
}
lc := auxIntToInt64(v_0.AuxInt)
if !(lc >= 8) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (MOVBUreg (SLLconst [lc] x))
// cond: lc < 8
// result: (UBFIZ [armBFAuxInt(lc, 8-lc)] x)
for {
if v_0.Op != OpARM64SLLconst {
break
}
lc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(lc < 8) {
break
}
v.reset(OpARM64UBFIZ)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 8-lc))
v.AddArg(x)
return true
}
// match: (MOVBUreg (SRLconst [rc] x))
// cond: rc < 8
// result: (UBFX [armBFAuxInt(rc, 8)] x)
for {
if v_0.Op != OpARM64SRLconst {
break
}
rc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(rc < 8) {
break
}
v.reset(OpARM64UBFX)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 8))
v.AddArg(x)
return true
}
// match: (MOVBUreg (UBFX [bfc] x))
// cond: bfc.getARM64BFwidth() <= 8
// result: (UBFX [bfc] x)
for {
if v_0.Op != OpARM64UBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
if !(bfc.getARM64BFwidth() <= 8) {
break
}
v.reset(OpARM64UBFX)
v.AuxInt = arm64BitFieldToAuxInt(bfc)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVBload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVBload [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVBload)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBload [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVBloadidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVBloadidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVBload)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBload [off] {sym} ptr (MOVBstorezero [off2] {sym2} ptr2 _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVDconst [0])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVBstorezero {
break
}
off2 := auxIntToInt32(v_1.AuxInt)
sym2 := auxToSym(v_1.Aux)
ptr2 := v_1.Args[0]
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVBloadidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVBloadidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVBload [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVBload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBloadidx (MOVDconst [c]) ptr mem)
// cond: is32Bit(c)
// result: (MOVBload [int32(c)] ptr mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
ptr := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVBload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBloadidx ptr idx (MOVBstorezeroidx ptr2 idx2 _))
// cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVBstorezeroidx {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVBreg(v *Value) bool {
v_0 := v.Args[0]
// match: (MOVBreg x:(MOVBload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBreg x:(MOVBloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBreg x:(MOVBreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBreg (MOVDconst [c]))
// result: (MOVDconst [int64(int8(c))])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(int8(c)))
return true
}
// match: (MOVBreg (ANDconst x [c]))
// cond: uint64(c) & uint64(0xffffffffffffff80) == 0
// result: (ANDconst x [c])
for {
t := v.Type
if v_0.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(uint64(c)&uint64(0xffffffffffffff80) == 0) {
break
}
v.reset(OpARM64ANDconst)
v.Type = t
v.AuxInt = int64ToAuxInt(c)
v.AddArg(x)
return true
}
// match: (MOVBreg (SLLconst [lc] x))
// cond: lc < 8
// result: (SBFIZ [armBFAuxInt(lc, 8-lc)] x)
for {
if v_0.Op != OpARM64SLLconst {
break
}
lc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(lc < 8) {
break
}
v.reset(OpARM64SBFIZ)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 8-lc))
v.AddArg(x)
return true
}
// match: (MOVBreg (SBFX [bfc] x))
// cond: bfc.getARM64BFwidth() <= 8
// result: (SBFX [bfc] x)
for {
if v_0.Op != OpARM64SBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
if !(bfc.getARM64BFwidth() <= 8) {
break
}
v.reset(OpARM64SBFX)
v.AuxInt = arm64BitFieldToAuxInt(bfc)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
typ := &b.Func.Config.Types
// match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVBstore [off] {sym} (ADD ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (MOVBstoreidx ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVBstoreidx)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVBstore [off] {sym} ptr (MOVDconst [0]) mem)
// result: (MOVBstorezero [off] {sym} ptr mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
mem := v_2
v.reset(OpARM64MOVBstorezero)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBstore [off] {sym} ptr (MOVBreg x) mem)
// result: (MOVBstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVBreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVBstore [off] {sym} ptr (MOVBUreg x) mem)
// result: (MOVBstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVBUreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVBstore [off] {sym} ptr (MOVHreg x) mem)
// result: (MOVBstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVHreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVBstore [off] {sym} ptr (MOVHUreg x) mem)
// result: (MOVBstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVHUreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVBstore [off] {sym} ptr (MOVWreg x) mem)
// result: (MOVBstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVWreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVBstore [off] {sym} ptr (MOVWUreg x) mem)
// result: (MOVBstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVWUreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVBstore [i] {s} ptr0 (SRLconst [8] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVHstore [i-1] {s} ptr0 w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 8 {
break
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] w) x:(MOVBstoreidx ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr1 idx1 w mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 8 {
continue
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr1, idx1, w, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVHstore [i-1] {s} ptr0 w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(8, 8) {
break
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr1 idx1 w mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(8, 8) {
continue
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr1, idx1, w, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVHstore [i-1] {s} ptr0 w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(8, 24) {
break
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr1 idx1 w mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(8, 24) {
continue
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr1, idx1, w, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr0 (SRLconst [8] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVHstore [i-1] {s} ptr0 w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 8 {
break
}
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64MOVDreg {
break
}
w := v_1_0.Args[0]
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr1 idx1 w mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 8 {
continue
}
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64MOVDreg {
continue
}
w := v_1_0.Args[0]
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr1, idx1, w, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] w) mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVHstore [i-1] {s} ptr0 w0 mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64SRLconst {
break
}
j := auxIntToInt64(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
w0 := x.Args[1]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w0, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] w) mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr1 idx1 w0 mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64SRLconst {
continue
}
j := auxIntToInt64(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
w0 := x.Args[2]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-8 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr1, idx1, w0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr0 (UBFX [bfc] w) x:(MOVBstore [i-1] {s} ptr1 w0:(UBFX [bfc2] w) mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb() && bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb() && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8 && clobber(x)
// result: (MOVHstore [i-1] {s} ptr0 w0 mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64UBFX {
break
}
bfc := auxIntToArm64BitField(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
w0 := x.Args[1]
if w0.Op != OpARM64UBFX {
break
}
bfc2 := auxIntToArm64BitField(w0.AuxInt)
if w != w0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && bfc.getARM64BFwidth() == 32-bfc.getARM64BFlsb() && bfc2.getARM64BFwidth() == 32-bfc2.getARM64BFlsb() && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb()-8 && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w0, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [bfc] w) x:(MOVBstoreidx ptr1 idx1 w0:(UBFX [bfc2] w) mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb() && bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb() && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8 && clobber(x)
// result: (MOVHstoreidx ptr1 idx1 w0 mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64UBFX {
continue
}
bfc := auxIntToArm64BitField(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
w0 := x.Args[2]
if w0.Op != OpARM64UBFX {
continue
}
bfc2 := auxIntToArm64BitField(w0.AuxInt)
if w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && bfc.getARM64BFwidth() == 32-bfc.getARM64BFlsb() && bfc2.getARM64BFwidth() == 32-bfc2.getARM64BFlsb() && bfc2.getARM64BFlsb() == bfc.getARM64BFlsb()-8 && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr1, idx1, w0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr0 (SRLconst [j] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVHstore [i-1] {s} ptr0 w0 mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64SRLconst {
break
}
j := auxIntToInt64(v_1.AuxInt)
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64MOVDreg {
break
}
w := v_1_0.Args[0]
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
w0 := x.Args[1]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-8 {
break
}
w0_0 := w0.Args[0]
if w0_0.Op != OpARM64MOVDreg || w != w0_0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w0, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr1 idx1 w0 mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64SRLconst {
continue
}
j := auxIntToInt64(v_1.AuxInt)
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64MOVDreg {
continue
}
w := v_1_0.Args[0]
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
w0 := x.Args[2]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-8 {
continue
}
w0_0 := w0.Args[0]
if w0_0.Op != OpARM64MOVDreg || w != w0_0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr1, idx1, w0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w) x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w) x3:(MOVBstore [i-4] {s} ptr (SRLconst [32] w) x4:(MOVBstore [i-5] {s} ptr (SRLconst [40] w) x5:(MOVBstore [i-6] {s} ptr (SRLconst [48] w) x6:(MOVBstore [i-7] {s} ptr (SRLconst [56] w) mem))))))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6)
// result: (MOVDstore [i-7] {s} ptr (REV w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr := v_0
w := v_1
x0 := v_2
if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s {
break
}
_ = x0.Args[2]
if ptr != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
break
}
x1 := x0.Args[2]
if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
break
}
x2 := x1.Args[2]
if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != i-3 || auxToSym(x2.Aux) != s {
break
}
_ = x2.Args[2]
if ptr != x2.Args[0] {
break
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64SRLconst || auxIntToInt64(x2_1.AuxInt) != 24 || w != x2_1.Args[0] {
break
}
x3 := x2.Args[2]
if x3.Op != OpARM64MOVBstore || auxIntToInt32(x3.AuxInt) != i-4 || auxToSym(x3.Aux) != s {
break
}
_ = x3.Args[2]
if ptr != x3.Args[0] {
break
}
x3_1 := x3.Args[1]
if x3_1.Op != OpARM64SRLconst || auxIntToInt64(x3_1.AuxInt) != 32 || w != x3_1.Args[0] {
break
}
x4 := x3.Args[2]
if x4.Op != OpARM64MOVBstore || auxIntToInt32(x4.AuxInt) != i-5 || auxToSym(x4.Aux) != s {
break
}
_ = x4.Args[2]
if ptr != x4.Args[0] {
break
}
x4_1 := x4.Args[1]
if x4_1.Op != OpARM64SRLconst || auxIntToInt64(x4_1.AuxInt) != 40 || w != x4_1.Args[0] {
break
}
x5 := x4.Args[2]
if x5.Op != OpARM64MOVBstore || auxIntToInt32(x5.AuxInt) != i-6 || auxToSym(x5.Aux) != s {
break
}
_ = x5.Args[2]
if ptr != x5.Args[0] {
break
}
x5_1 := x5.Args[1]
if x5_1.Op != OpARM64SRLconst || auxIntToInt64(x5_1.AuxInt) != 48 || w != x5_1.Args[0] {
break
}
x6 := x5.Args[2]
if x6.Op != OpARM64MOVBstore || auxIntToInt32(x6.AuxInt) != i-7 || auxToSym(x6.Aux) != s {
break
}
mem := x6.Args[2]
if ptr != x6.Args[0] {
break
}
x6_1 := x6.Args[1]
if x6_1.Op != OpARM64SRLconst || auxIntToInt64(x6_1.AuxInt) != 56 || w != x6_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0, x1, x2, x3, x4, x5, x6)) {
break
}
v.reset(OpARM64MOVDstore)
v.AuxInt = int32ToAuxInt(i - 7)
v.Aux = symToAux(s)
v0 := b.NewValue0(x6.Pos, OpARM64REV, typ.UInt64)
v0.AddArg(w)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (MOVBstore [7] {s} p w x0:(MOVBstore [6] {s} p (SRLconst [8] w) x1:(MOVBstore [5] {s} p (SRLconst [16] w) x2:(MOVBstore [4] {s} p (SRLconst [24] w) x3:(MOVBstore [3] {s} p (SRLconst [32] w) x4:(MOVBstore [2] {s} p (SRLconst [40] w) x5:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [48] w) x6:(MOVBstoreidx ptr0 idx0 (SRLconst [56] w) mem))))))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6)
// result: (MOVDstoreidx ptr0 idx0 (REV w) mem)
for {
if auxIntToInt32(v.AuxInt) != 7 {
break
}
s := auxToSym(v.Aux)
p := v_0
w := v_1
x0 := v_2
if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != 6 || auxToSym(x0.Aux) != s {
break
}
_ = x0.Args[2]
if p != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
break
}
x1 := x0.Args[2]
if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != 5 || auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[2]
if p != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
break
}
x2 := x1.Args[2]
if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != 4 || auxToSym(x2.Aux) != s {
break
}
_ = x2.Args[2]
if p != x2.Args[0] {
break
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64SRLconst || auxIntToInt64(x2_1.AuxInt) != 24 || w != x2_1.Args[0] {
break
}
x3 := x2.Args[2]
if x3.Op != OpARM64MOVBstore || auxIntToInt32(x3.AuxInt) != 3 || auxToSym(x3.Aux) != s {
break
}
_ = x3.Args[2]
if p != x3.Args[0] {
break
}
x3_1 := x3.Args[1]
if x3_1.Op != OpARM64SRLconst || auxIntToInt64(x3_1.AuxInt) != 32 || w != x3_1.Args[0] {
break
}
x4 := x3.Args[2]
if x4.Op != OpARM64MOVBstore || auxIntToInt32(x4.AuxInt) != 2 || auxToSym(x4.Aux) != s {
break
}
_ = x4.Args[2]
if p != x4.Args[0] {
break
}
x4_1 := x4.Args[1]
if x4_1.Op != OpARM64SRLconst || auxIntToInt64(x4_1.AuxInt) != 40 || w != x4_1.Args[0] {
break
}
x5 := x4.Args[2]
if x5.Op != OpARM64MOVBstore || auxIntToInt32(x5.AuxInt) != 1 || auxToSym(x5.Aux) != s {
break
}
_ = x5.Args[2]
p1 := x5.Args[0]
if p1.Op != OpARM64ADD {
break
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
x5_1 := x5.Args[1]
if x5_1.Op != OpARM64SRLconst || auxIntToInt64(x5_1.AuxInt) != 48 || w != x5_1.Args[0] {
continue
}
x6 := x5.Args[2]
if x6.Op != OpARM64MOVBstoreidx {
continue
}
mem := x6.Args[3]
ptr0 := x6.Args[0]
idx0 := x6.Args[1]
x6_2 := x6.Args[2]
if x6_2.Op != OpARM64SRLconst || auxIntToInt64(x6_2.AuxInt) != 56 || w != x6_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6)) {
continue
}
v.reset(OpARM64MOVDstoreidx)
v0 := b.NewValue0(x5.Pos, OpARM64REV, typ.UInt64)
v0.AddArg(w)
v.AddArg4(ptr0, idx0, v0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstore [i-2] {s} ptr (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstore [i-3] {s} ptr (UBFX [armBFAuxInt(24, 8)] w) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
// result: (MOVWstore [i-3] {s} ptr (REVW w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr := v_0
w := v_1
x0 := v_2
if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s {
break
}
_ = x0.Args[2]
if ptr != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64UBFX || auxIntToArm64BitField(x0_1.AuxInt) != armBFAuxInt(8, 24) || w != x0_1.Args[0] {
break
}
x1 := x0.Args[2]
if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64UBFX || auxIntToArm64BitField(x1_1.AuxInt) != armBFAuxInt(16, 16) || w != x1_1.Args[0] {
break
}
x2 := x1.Args[2]
if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != i-3 || auxToSym(x2.Aux) != s {
break
}
mem := x2.Args[2]
if ptr != x2.Args[0] {
break
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64UBFX || auxIntToArm64BitField(x2_1.AuxInt) != armBFAuxInt(24, 8) || w != x2_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(i - 3)
v.Aux = symToAux(s)
v0 := b.NewValue0(x2.Pos, OpARM64REVW, typ.UInt32)
v0.AddArg(w)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (MOVBstore [3] {s} p w x0:(MOVBstore [2] {s} p (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(24, 8)] w) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)
// result: (MOVWstoreidx ptr0 idx0 (REVW w) mem)
for {
if auxIntToInt32(v.AuxInt) != 3 {
break
}
s := auxToSym(v.Aux)
p := v_0
w := v_1
x0 := v_2
if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != 2 || auxToSym(x0.Aux) != s {
break
}
_ = x0.Args[2]
if p != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64UBFX || auxIntToArm64BitField(x0_1.AuxInt) != armBFAuxInt(8, 24) || w != x0_1.Args[0] {
break
}
x1 := x0.Args[2]
if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != 1 || auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[2]
p1 := x1.Args[0]
if p1.Op != OpARM64ADD {
break
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64UBFX || auxIntToArm64BitField(x1_1.AuxInt) != armBFAuxInt(16, 16) || w != x1_1.Args[0] {
continue
}
x2 := x1.Args[2]
if x2.Op != OpARM64MOVBstoreidx {
continue
}
mem := x2.Args[3]
ptr0 := x2.Args[0]
idx0 := x2.Args[1]
x2_2 := x2.Args[2]
if x2_2.Op != OpARM64UBFX || auxIntToArm64BitField(x2_2.AuxInt) != armBFAuxInt(24, 8) || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)) {
continue
}
v.reset(OpARM64MOVWstoreidx)
v0 := b.NewValue0(x1.Pos, OpARM64REVW, typ.UInt32)
v0.AddArg(w)
v.AddArg4(ptr0, idx0, v0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] (MOVDreg w)) x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] (MOVDreg w)) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
// result: (MOVWstore [i-3] {s} ptr (REVW w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr := v_0
w := v_1
x0 := v_2
if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s {
break
}
_ = x0.Args[2]
if ptr != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 {
break
}
x0_1_0 := x0_1.Args[0]
if x0_1_0.Op != OpARM64MOVDreg || w != x0_1_0.Args[0] {
break
}
x1 := x0.Args[2]
if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 {
break
}
x1_1_0 := x1_1.Args[0]
if x1_1_0.Op != OpARM64MOVDreg || w != x1_1_0.Args[0] {
break
}
x2 := x1.Args[2]
if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != i-3 || auxToSym(x2.Aux) != s {
break
}
mem := x2.Args[2]
if ptr != x2.Args[0] {
break
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64SRLconst || auxIntToInt64(x2_1.AuxInt) != 24 {
break
}
x2_1_0 := x2_1.Args[0]
if x2_1_0.Op != OpARM64MOVDreg || w != x2_1_0.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(i - 3)
v.Aux = symToAux(s)
v0 := b.NewValue0(x2.Pos, OpARM64REVW, typ.UInt32)
v0.AddArg(w)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (MOVBstore [3] {s} p w x0:(MOVBstore [2] {s} p (SRLconst [8] (MOVDreg w)) x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] (MOVDreg w)) x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] (MOVDreg w)) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)
// result: (MOVWstoreidx ptr0 idx0 (REVW w) mem)
for {
if auxIntToInt32(v.AuxInt) != 3 {
break
}
s := auxToSym(v.Aux)
p := v_0
w := v_1
x0 := v_2
if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != 2 || auxToSym(x0.Aux) != s {
break
}
_ = x0.Args[2]
if p != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 {
break
}
x0_1_0 := x0_1.Args[0]
if x0_1_0.Op != OpARM64MOVDreg || w != x0_1_0.Args[0] {
break
}
x1 := x0.Args[2]
if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != 1 || auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[2]
p1 := x1.Args[0]
if p1.Op != OpARM64ADD {
break
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 {
continue
}
x1_1_0 := x1_1.Args[0]
if x1_1_0.Op != OpARM64MOVDreg || w != x1_1_0.Args[0] {
continue
}
x2 := x1.Args[2]
if x2.Op != OpARM64MOVBstoreidx {
continue
}
mem := x2.Args[3]
ptr0 := x2.Args[0]
idx0 := x2.Args[1]
x2_2 := x2.Args[2]
if x2_2.Op != OpARM64SRLconst || auxIntToInt64(x2_2.AuxInt) != 24 {
continue
}
x2_2_0 := x2_2.Args[0]
if x2_2_0.Op != OpARM64MOVDreg || w != x2_2_0.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)) {
continue
}
v.reset(OpARM64MOVWstoreidx)
v0 := b.NewValue0(x1.Pos, OpARM64REVW, typ.UInt32)
v0.AddArg(w)
v.AddArg4(ptr0, idx0, v0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w) x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
// result: (MOVWstore [i-3] {s} ptr (REVW w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr := v_0
w := v_1
x0 := v_2
if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != i-1 || auxToSym(x0.Aux) != s {
break
}
_ = x0.Args[2]
if ptr != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
break
}
x1 := x0.Args[2]
if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != i-2 || auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
break
}
x2 := x1.Args[2]
if x2.Op != OpARM64MOVBstore || auxIntToInt32(x2.AuxInt) != i-3 || auxToSym(x2.Aux) != s {
break
}
mem := x2.Args[2]
if ptr != x2.Args[0] {
break
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64SRLconst || auxIntToInt64(x2_1.AuxInt) != 24 || w != x2_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(i - 3)
v.Aux = symToAux(s)
v0 := b.NewValue0(x2.Pos, OpARM64REVW, typ.UInt32)
v0.AddArg(w)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (MOVBstore [3] {s} p w x0:(MOVBstore [2] {s} p (SRLconst [8] w) x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] w) x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] w) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)
// result: (MOVWstoreidx ptr0 idx0 (REVW w) mem)
for {
if auxIntToInt32(v.AuxInt) != 3 {
break
}
s := auxToSym(v.Aux)
p := v_0
w := v_1
x0 := v_2
if x0.Op != OpARM64MOVBstore || auxIntToInt32(x0.AuxInt) != 2 || auxToSym(x0.Aux) != s {
break
}
_ = x0.Args[2]
if p != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64SRLconst || auxIntToInt64(x0_1.AuxInt) != 8 || w != x0_1.Args[0] {
break
}
x1 := x0.Args[2]
if x1.Op != OpARM64MOVBstore || auxIntToInt32(x1.AuxInt) != 1 || auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[2]
p1 := x1.Args[0]
if p1.Op != OpARM64ADD {
break
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64SRLconst || auxIntToInt64(x1_1.AuxInt) != 16 || w != x1_1.Args[0] {
continue
}
x2 := x1.Args[2]
if x2.Op != OpARM64MOVBstoreidx {
continue
}
mem := x2.Args[3]
ptr0 := x2.Args[0]
idx0 := x2.Args[1]
x2_2 := x2.Args[2]
if x2_2.Op != OpARM64SRLconst || auxIntToInt64(x2_2.AuxInt) != 24 || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2)) {
continue
}
v.reset(OpARM64MOVWstoreidx)
v0 := b.NewValue0(x1.Pos, OpARM64REVW, typ.UInt32)
v0.AddArg(w)
v.AddArg4(ptr0, idx0, v0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVHstore [i-1] {s} ptr (REV16W w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr := v_0
w := v_1
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
if ptr != x.Args[0] {
break
}
x_1 := x.Args[1]
if x_1.Op != OpARM64SRLconst || auxIntToInt64(x_1.AuxInt) != 8 || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v0 := b.NewValue0(x.Pos, OpARM64REV16W, typ.UInt16)
v0.AddArg(w)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] w) mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr0 idx0 (REV16W w) mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr1 := v_0_0
idx1 := v_0_1
w := v_1
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr0 := x.Args[0]
idx0 := x.Args[1]
x_2 := x.Args[2]
if x_2.Op != OpARM64SRLconst || auxIntToInt64(x_2.AuxInt) != 8 || w != x_2.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
v0.AddArg(w)
v.AddArg4(ptr0, idx0, v0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 8)] w) mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVHstore [i-1] {s} ptr (REV16W w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr := v_0
w := v_1
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
if ptr != x.Args[0] {
break
}
x_1 := x.Args[1]
if x_1.Op != OpARM64UBFX || auxIntToArm64BitField(x_1.AuxInt) != armBFAuxInt(8, 8) || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v0 := b.NewValue0(x.Pos, OpARM64REV16W, typ.UInt16)
v0.AddArg(w)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 8)] w) mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr0 idx0 (REV16W w) mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr1 := v_0_0
idx1 := v_0_1
w := v_1
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr0 := x.Args[0]
idx0 := x.Args[1]
x_2 := x.Args[2]
if x_2.Op != OpARM64UBFX || auxIntToArm64BitField(x_2.AuxInt) != armBFAuxInt(8, 8) || w != x_2.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
v0.AddArg(w)
v.AddArg4(ptr0, idx0, v0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVHstore [i-1] {s} ptr (REV16W w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr := v_0
w := v_1
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
if ptr != x.Args[0] {
break
}
x_1 := x.Args[1]
if x_1.Op != OpARM64SRLconst || auxIntToInt64(x_1.AuxInt) != 8 {
break
}
x_1_0 := x_1.Args[0]
if x_1_0.Op != OpARM64MOVDreg || w != x_1_0.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v0 := b.NewValue0(x.Pos, OpARM64REV16W, typ.UInt16)
v0.AddArg(w)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] (MOVDreg w)) mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr0 idx0 (REV16W w) mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr1 := v_0_0
idx1 := v_0_1
w := v_1
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr0 := x.Args[0]
idx0 := x.Args[1]
x_2 := x.Args[2]
if x_2.Op != OpARM64SRLconst || auxIntToInt64(x_2.AuxInt) != 8 {
continue
}
x_2_0 := x_2.Args[0]
if x_2_0.Op != OpARM64MOVDreg || w != x_2_0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
v0.AddArg(w)
v.AddArg4(ptr0, idx0, v0, mem)
return true
}
break
}
// match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVHstore [i-1] {s} ptr (REV16W w) mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr := v_0
w := v_1
x := v_2
if x.Op != OpARM64MOVBstore || auxIntToInt32(x.AuxInt) != i-1 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
if ptr != x.Args[0] {
break
}
x_1 := x.Args[1]
if x_1.Op != OpARM64UBFX || auxIntToArm64BitField(x_1.AuxInt) != armBFAuxInt(8, 24) || w != x_1.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(i - 1)
v.Aux = symToAux(s)
v0 := b.NewValue0(x.Pos, OpARM64REV16W, typ.UInt16)
v0.AddArg(w)
v.AddArg3(ptr, v0, mem)
return true
}
// match: (MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 24)] w) mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstoreidx ptr0 idx0 (REV16W w) mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr1 := v_0_0
idx1 := v_0_1
w := v_1
x := v_2
if x.Op != OpARM64MOVBstoreidx {
continue
}
mem := x.Args[3]
ptr0 := x.Args[0]
idx0 := x.Args[1]
x_2 := x.Args[2]
if x_2.Op != OpARM64UBFX || auxIntToArm64BitField(x_2.AuxInt) != armBFAuxInt(8, 24) || w != x_2.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
v0.AddArg(w)
v.AddArg4(ptr0, idx0, v0, mem)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64MOVBstoreidx(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (MOVBstoreidx ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c)
// result: (MOVBstore [int32(c)] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVBstoreidx (MOVDconst [c]) idx val mem)
// cond: is32Bit(c)
// result: (MOVBstore [int32(c)] idx val mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVBstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(idx, val, mem)
return true
}
// match: (MOVBstoreidx ptr idx (MOVDconst [0]) mem)
// result: (MOVBstorezeroidx ptr idx mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
break
}
mem := v_3
v.reset(OpARM64MOVBstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVBstoreidx ptr idx (MOVBreg x) mem)
// result: (MOVBstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVBreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVBstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVBstoreidx ptr idx (MOVBUreg x) mem)
// result: (MOVBstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVBUreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVBstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVBstoreidx ptr idx (MOVHreg x) mem)
// result: (MOVBstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVBstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVBstoreidx ptr idx (MOVHUreg x) mem)
// result: (MOVBstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHUreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVBstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVBstoreidx ptr idx (MOVWreg x) mem)
// result: (MOVBstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVBstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVBstoreidx ptr idx (MOVWUreg x) mem)
// result: (MOVBstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWUreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVBstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVBstoreidx ptr (ADDconst [1] idx) (SRLconst [8] w) x:(MOVBstoreidx ptr idx w mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVHstoreidx ptr idx w mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
idx := v_1.Args[0]
if v_2.Op != OpARM64SRLconst || auxIntToInt64(v_2.AuxInt) != 8 {
break
}
w := v_2.Args[0]
x := v_3
if x.Op != OpARM64MOVBstoreidx {
break
}
mem := x.Args[3]
if ptr != x.Args[0] || idx != x.Args[1] || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr, idx, w, mem)
return true
}
// match: (MOVBstoreidx ptr (ADDconst [3] idx) w x0:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(24, 8)] w) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
// result: (MOVWstoreidx ptr idx (REVW w) mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 3 {
break
}
idx := v_1.Args[0]
w := v_2
x0 := v_3
if x0.Op != OpARM64MOVBstoreidx {
break
}
_ = x0.Args[3]
if ptr != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 2 || idx != x0_1.Args[0] {
break
}
x0_2 := x0.Args[2]
if x0_2.Op != OpARM64UBFX || auxIntToArm64BitField(x0_2.AuxInt) != armBFAuxInt(8, 24) || w != x0_2.Args[0] {
break
}
x1 := x0.Args[3]
if x1.Op != OpARM64MOVBstoreidx {
break
}
_ = x1.Args[3]
if ptr != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 1 || idx != x1_1.Args[0] {
break
}
x1_2 := x1.Args[2]
if x1_2.Op != OpARM64UBFX || auxIntToArm64BitField(x1_2.AuxInt) != armBFAuxInt(16, 16) || w != x1_2.Args[0] {
break
}
x2 := x1.Args[3]
if x2.Op != OpARM64MOVBstoreidx {
break
}
mem := x2.Args[3]
if ptr != x2.Args[0] || idx != x2.Args[1] {
break
}
x2_2 := x2.Args[2]
if x2_2.Op != OpARM64UBFX || auxIntToArm64BitField(x2_2.AuxInt) != armBFAuxInt(24, 8) || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
break
}
v.reset(OpARM64MOVWstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64REVW, typ.UInt32)
v0.AddArg(w)
v.AddArg4(ptr, idx, v0, mem)
return true
}
// match: (MOVBstoreidx ptr idx w x0:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstoreidx ptr (ADDconst [3] idx) (UBFX [armBFAuxInt(24, 8)] w) mem))))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)
// result: (MOVWstoreidx ptr idx w mem)
for {
ptr := v_0
idx := v_1
w := v_2
x0 := v_3
if x0.Op != OpARM64MOVBstoreidx {
break
}
_ = x0.Args[3]
if ptr != x0.Args[0] {
break
}
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 1 || idx != x0_1.Args[0] {
break
}
x0_2 := x0.Args[2]
if x0_2.Op != OpARM64UBFX || auxIntToArm64BitField(x0_2.AuxInt) != armBFAuxInt(8, 24) || w != x0_2.Args[0] {
break
}
x1 := x0.Args[3]
if x1.Op != OpARM64MOVBstoreidx {
break
}
_ = x1.Args[3]
if ptr != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 2 || idx != x1_1.Args[0] {
break
}
x1_2 := x1.Args[2]
if x1_2.Op != OpARM64UBFX || auxIntToArm64BitField(x1_2.AuxInt) != armBFAuxInt(16, 16) || w != x1_2.Args[0] {
break
}
x2 := x1.Args[3]
if x2.Op != OpARM64MOVBstoreidx {
break
}
mem := x2.Args[3]
if ptr != x2.Args[0] {
break
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 3 || idx != x2_1.Args[0] {
break
}
x2_2 := x2.Args[2]
if x2_2.Op != OpARM64UBFX || auxIntToArm64BitField(x2_2.AuxInt) != armBFAuxInt(24, 8) || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0, x1, x2)) {
break
}
v.reset(OpARM64MOVWstoreidx)
v.AddArg4(ptr, idx, w, mem)
return true
}
// match: (MOVBstoreidx ptr (ADDconst [1] idx) w x:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(8, 8)] w) mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVHstoreidx ptr idx (REV16W w) mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
idx := v_1.Args[0]
w := v_2
x := v_3
if x.Op != OpARM64MOVBstoreidx {
break
}
mem := x.Args[3]
if ptr != x.Args[0] || idx != x.Args[1] {
break
}
x_2 := x.Args[2]
if x_2.Op != OpARM64UBFX || auxIntToArm64BitField(x_2.AuxInt) != armBFAuxInt(8, 8) || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVHstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64REV16W, typ.UInt16)
v0.AddArg(w)
v.AddArg4(ptr, idx, v0, mem)
return true
}
// match: (MOVBstoreidx ptr idx w x:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 8)] w) mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVHstoreidx ptr idx w mem)
for {
ptr := v_0
idx := v_1
w := v_2
x := v_3
if x.Op != OpARM64MOVBstoreidx {
break
}
mem := x.Args[3]
if ptr != x.Args[0] {
break
}
x_1 := x.Args[1]
if x_1.Op != OpARM64ADDconst || auxIntToInt64(x_1.AuxInt) != 1 || idx != x_1.Args[0] {
break
}
x_2 := x.Args[2]
if x_2.Op != OpARM64UBFX || auxIntToArm64BitField(x_2.AuxInt) != armBFAuxInt(8, 8) || w != x_2.Args[0] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr, idx, w, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVBstorezero)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVBstorezero)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBstorezero [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVBstorezeroidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVBstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVBstorezero [i] {s} ptr0 x:(MOVBstorezero [j] {s} ptr1 mem))
// cond: x.Uses == 1 && areAdjacentOffsets(int64(i),int64(j),1) && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVHstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
x := v_1
if x.Op != OpARM64MOVBstorezero {
break
}
j := auxIntToInt32(x.AuxInt)
if auxToSym(x.Aux) != s {
break
}
mem := x.Args[1]
ptr1 := x.Args[0]
if !(x.Uses == 1 && areAdjacentOffsets(int64(i), int64(j), 1) && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVHstorezero)
v.AuxInt = int32ToAuxInt(int32(min(int64(i), int64(j))))
v.Aux = symToAux(s)
v.AddArg2(ptr0, mem)
return true
}
// match: (MOVBstorezero [1] {s} (ADD ptr0 idx0) x:(MOVBstorezeroidx ptr1 idx1 mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVHstorezeroidx ptr1 idx1 mem)
for {
if auxIntToInt32(v.AuxInt) != 1 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
x := v_1
if x.Op != OpARM64MOVBstorezeroidx {
continue
}
mem := x.Args[2]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVHstorezeroidx)
v.AddArg3(ptr1, idx1, mem)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64MOVBstorezeroidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVBstorezeroidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVBstorezero [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVBstorezero)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVBstorezeroidx (MOVDconst [c]) idx mem)
// cond: is32Bit(c)
// result: (MOVBstorezero [int32(c)] idx mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVBstorezero)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(idx, mem)
return true
}
// match: (MOVBstorezeroidx ptr (ADDconst [1] idx) x:(MOVBstorezeroidx ptr idx mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVHstorezeroidx ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
idx := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVBstorezeroidx {
break
}
mem := x.Args[2]
if ptr != x.Args[0] || idx != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVHstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr val _))
// result: (FMOVDfpgp val)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64FMOVDstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
break
}
val := v_1.Args[1]
if ptr != v_1.Args[0] {
break
}
v.reset(OpARM64FMOVDfpgp)
v.AddArg(val)
return true
}
// match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVDload [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVDload)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVDload [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVDloadidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVDloadidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVDload [off] {sym} (ADDshiftLL [3] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVDloadidx8 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVDloadidx8)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVDload)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVDload [off] {sym} ptr (MOVDstorezero [off2] {sym2} ptr2 _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVDconst [0])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVDstorezero {
break
}
off2 := auxIntToInt32(v_1.AuxInt)
sym2 := auxToSym(v_1.Aux)
ptr2 := v_1.Args[0]
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (MOVDload [off] {sym} (SB) _)
// cond: symIsRO(sym)
// result: (MOVDconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpSB || !(symIsRO(sym)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder)))
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDloadidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVDloadidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVDload [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVDload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVDloadidx (MOVDconst [c]) ptr mem)
// cond: is32Bit(c)
// result: (MOVDload [int32(c)] ptr mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
ptr := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVDload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVDloadidx ptr (SLLconst [3] idx) mem)
// result: (MOVDloadidx8 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVDloadidx8)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVDloadidx (SLLconst [3] idx) ptr mem)
// result: (MOVDloadidx8 ptr idx mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[0]
ptr := v_1
mem := v_2
v.reset(OpARM64MOVDloadidx8)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVDloadidx ptr idx (MOVDstorezeroidx ptr2 idx2 _))
// cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVDstorezeroidx {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDloadidx8(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVDloadidx8 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<3)
// result: (MOVDload [int32(c)<<3] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 3)) {
break
}
v.reset(OpARM64MOVDload)
v.AuxInt = int32ToAuxInt(int32(c) << 3)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVDloadidx8 ptr idx (MOVDstorezeroidx8 ptr2 idx2 _))
// cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVDstorezeroidx8 {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDnop(v *Value) bool {
v_0 := v.Args[0]
// match: (MOVDnop (MOVDconst [c]))
// result: (MOVDconst [c])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDreg(v *Value) bool {
v_0 := v.Args[0]
// match: (MOVDreg x)
// cond: x.Uses == 1
// result: (MOVDnop x)
for {
x := v_0
if !(x.Uses == 1) {
break
}
v.reset(OpARM64MOVDnop)
v.AddArg(x)
return true
}
// match: (MOVDreg (MOVDconst [c]))
// result: (MOVDconst [c])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVDstore [off] {sym} ptr (FMOVDfpgp val) mem)
// result: (FMOVDstore [off] {sym} ptr val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64FMOVDfpgp {
break
}
val := v_1.Args[0]
mem := v_2
v.reset(OpARM64FMOVDstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVDstore)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVDstore [off] {sym} (ADD ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (MOVDstoreidx ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVDstoreidx)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (MOVDstoreidx8 ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVDstoreidx8)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVDstore)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVDstore [off] {sym} ptr (MOVDconst [0]) mem)
// result: (MOVDstorezero [off] {sym} ptr mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
mem := v_2
v.reset(OpARM64MOVDstorezero)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDstoreidx(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVDstoreidx ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c)
// result: (MOVDstore [int32(c)] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVDstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVDstoreidx (MOVDconst [c]) idx val mem)
// cond: is32Bit(c)
// result: (MOVDstore [int32(c)] idx val mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVDstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(idx, val, mem)
return true
}
// match: (MOVDstoreidx ptr (SLLconst [3] idx) val mem)
// result: (MOVDstoreidx8 ptr idx val mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
break
}
idx := v_1.Args[0]
val := v_2
mem := v_3
v.reset(OpARM64MOVDstoreidx8)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVDstoreidx (SLLconst [3] idx) ptr val mem)
// result: (MOVDstoreidx8 ptr idx val mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[0]
ptr := v_1
val := v_2
mem := v_3
v.reset(OpARM64MOVDstoreidx8)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVDstoreidx ptr idx (MOVDconst [0]) mem)
// result: (MOVDstorezeroidx ptr idx mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
break
}
mem := v_3
v.reset(OpARM64MOVDstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDstoreidx8(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVDstoreidx8 ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c<<3)
// result: (MOVDstore [int32(c)<<3] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c << 3)) {
break
}
v.reset(OpARM64MOVDstore)
v.AuxInt = int32ToAuxInt(int32(c) << 3)
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVDstoreidx8 ptr idx (MOVDconst [0]) mem)
// result: (MOVDstorezeroidx8 ptr idx mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
break
}
mem := v_3
v.reset(OpARM64MOVDstorezeroidx8)
v.AddArg3(ptr, idx, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVDstorezero)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVDstorezero)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVDstorezero [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVDstorezeroidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVDstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVDstorezero [off] {sym} (ADDshiftLL [3] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVDstorezeroidx8 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVDstorezeroidx8)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVDstorezero [i] {s} ptr0 x:(MOVDstorezero [j] {s} ptr1 mem))
// cond: x.Uses == 1 && areAdjacentOffsets(int64(i),int64(j),8) && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVQstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
x := v_1
if x.Op != OpARM64MOVDstorezero {
break
}
j := auxIntToInt32(x.AuxInt)
if auxToSym(x.Aux) != s {
break
}
mem := x.Args[1]
ptr1 := x.Args[0]
if !(x.Uses == 1 && areAdjacentOffsets(int64(i), int64(j), 8) && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVQstorezero)
v.AuxInt = int32ToAuxInt(int32(min(int64(i), int64(j))))
v.Aux = symToAux(s)
v.AddArg2(ptr0, mem)
return true
}
// match: (MOVDstorezero [8] {s} p0:(ADD ptr0 idx0) x:(MOVDstorezeroidx ptr1 idx1 mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVQstorezero [0] {s} p0 mem)
for {
if auxIntToInt32(v.AuxInt) != 8 {
break
}
s := auxToSym(v.Aux)
p0 := v_0
if p0.Op != OpARM64ADD {
break
}
_ = p0.Args[1]
p0_0 := p0.Args[0]
p0_1 := p0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p0_0, p0_1 = _i0+1, p0_1, p0_0 {
ptr0 := p0_0
idx0 := p0_1
x := v_1
if x.Op != OpARM64MOVDstorezeroidx {
continue
}
mem := x.Args[2]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVQstorezero)
v.AuxInt = int32ToAuxInt(0)
v.Aux = symToAux(s)
v.AddArg2(p0, mem)
return true
}
break
}
// match: (MOVDstorezero [8] {s} p0:(ADDshiftLL [3] ptr0 idx0) x:(MOVDstorezeroidx8 ptr1 idx1 mem))
// cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
// result: (MOVQstorezero [0] {s} p0 mem)
for {
if auxIntToInt32(v.AuxInt) != 8 {
break
}
s := auxToSym(v.Aux)
p0 := v_0
if p0.Op != OpARM64ADDshiftLL || auxIntToInt64(p0.AuxInt) != 3 {
break
}
idx0 := p0.Args[1]
ptr0 := p0.Args[0]
x := v_1
if x.Op != OpARM64MOVDstorezeroidx8 {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
break
}
v.reset(OpARM64MOVQstorezero)
v.AuxInt = int32ToAuxInt(0)
v.Aux = symToAux(s)
v.AddArg2(p0, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDstorezeroidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVDstorezeroidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVDstorezero [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVDstorezero)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVDstorezeroidx (MOVDconst [c]) idx mem)
// cond: is32Bit(c)
// result: (MOVDstorezero [int32(c)] idx mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVDstorezero)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(idx, mem)
return true
}
// match: (MOVDstorezeroidx ptr (SLLconst [3] idx) mem)
// result: (MOVDstorezeroidx8 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 3 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVDstorezeroidx8)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVDstorezeroidx (SLLconst [3] idx) ptr mem)
// result: (MOVDstorezeroidx8 ptr idx mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 3 {
break
}
idx := v_0.Args[0]
ptr := v_1
mem := v_2
v.reset(OpARM64MOVDstorezeroidx8)
v.AddArg3(ptr, idx, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVDstorezeroidx8(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVDstorezeroidx8 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<3)
// result: (MOVDstorezero [int32(c<<3)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 3)) {
break
}
v.reset(OpARM64MOVDstorezero)
v.AuxInt = int32ToAuxInt(int32(c << 3))
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHUload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVHUload [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVHUload)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHUload [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVHUloadidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVHUloadidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHUload [off] {sym} (ADDshiftLL [1] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVHUloadidx2 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVHUloadidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVHUload)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHUload [off] {sym} ptr (MOVHstorezero [off2] {sym2} ptr2 _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVDconst [0])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVHstorezero {
break
}
off2 := auxIntToInt32(v_1.AuxInt)
sym2 := auxToSym(v_1.Aux)
ptr2 := v_1.Args[0]
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (MOVHUload [off] {sym} (SB) _)
// cond: symIsRO(sym)
// result: (MOVDconst [int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpSB || !(symIsRO(sym)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder)))
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHUloadidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVHUloadidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVHUload [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVHUload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHUloadidx (MOVDconst [c]) ptr mem)
// cond: is32Bit(c)
// result: (MOVHUload [int32(c)] ptr mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
ptr := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVHUload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHUloadidx ptr (SLLconst [1] idx) mem)
// result: (MOVHUloadidx2 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVHUloadidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHUloadidx ptr (ADD idx idx) mem)
// result: (MOVHUloadidx2 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADD {
break
}
idx := v_1.Args[1]
if idx != v_1.Args[0] {
break
}
mem := v_2
v.reset(OpARM64MOVHUloadidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHUloadidx (ADD idx idx) ptr mem)
// result: (MOVHUloadidx2 ptr idx mem)
for {
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
if idx != v_0.Args[0] {
break
}
ptr := v_1
mem := v_2
v.reset(OpARM64MOVHUloadidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHUloadidx ptr idx (MOVHstorezeroidx ptr2 idx2 _))
// cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHstorezeroidx {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHUloadidx2(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVHUloadidx2 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<1)
// result: (MOVHUload [int32(c)<<1] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 1)) {
break
}
v.reset(OpARM64MOVHUload)
v.AuxInt = int32ToAuxInt(int32(c) << 1)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHUloadidx2 ptr idx (MOVHstorezeroidx2 ptr2 idx2 _))
// cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHstorezeroidx2 {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHUreg(v *Value) bool {
v_0 := v.Args[0]
// match: (MOVHUreg x:(MOVBUload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHUreg x:(MOVHUload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHUreg x:(MOVBUloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHUreg x:(MOVHUloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHUreg x:(MOVHUloadidx2 _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUloadidx2 {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHUreg x:(MOVBUreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHUreg x:(MOVHUreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHUreg (ANDconst [c] x))
// result: (ANDconst [c&(1<<16-1)] x)
for {
if v_0.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c & (1<<16 - 1))
v.AddArg(x)
return true
}
// match: (MOVHUreg (MOVDconst [c]))
// result: (MOVDconst [int64(uint16(c))])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(uint16(c)))
return true
}
// match: (MOVHUreg (SLLconst [lc] x))
// cond: lc >= 16
// result: (MOVDconst [0])
for {
if v_0.Op != OpARM64SLLconst {
break
}
lc := auxIntToInt64(v_0.AuxInt)
if !(lc >= 16) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (MOVHUreg (SLLconst [lc] x))
// cond: lc < 16
// result: (UBFIZ [armBFAuxInt(lc, 16-lc)] x)
for {
if v_0.Op != OpARM64SLLconst {
break
}
lc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(lc < 16) {
break
}
v.reset(OpARM64UBFIZ)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 16-lc))
v.AddArg(x)
return true
}
// match: (MOVHUreg (SRLconst [rc] x))
// cond: rc < 16
// result: (UBFX [armBFAuxInt(rc, 16)] x)
for {
if v_0.Op != OpARM64SRLconst {
break
}
rc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(rc < 16) {
break
}
v.reset(OpARM64UBFX)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 16))
v.AddArg(x)
return true
}
// match: (MOVHUreg (UBFX [bfc] x))
// cond: bfc.getARM64BFwidth() <= 16
// result: (UBFX [bfc] x)
for {
if v_0.Op != OpARM64UBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
if !(bfc.getARM64BFwidth() <= 16) {
break
}
v.reset(OpARM64UBFX)
v.AuxInt = arm64BitFieldToAuxInt(bfc)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVHload [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVHload)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHload [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVHloadidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVHloadidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHload [off] {sym} (ADDshiftLL [1] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVHloadidx2 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVHloadidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVHload)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHload [off] {sym} ptr (MOVHstorezero [off2] {sym2} ptr2 _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVDconst [0])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVHstorezero {
break
}
off2 := auxIntToInt32(v_1.AuxInt)
sym2 := auxToSym(v_1.Aux)
ptr2 := v_1.Args[0]
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHloadidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVHloadidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVHload [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVHload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHloadidx (MOVDconst [c]) ptr mem)
// cond: is32Bit(c)
// result: (MOVHload [int32(c)] ptr mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
ptr := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVHload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHloadidx ptr (SLLconst [1] idx) mem)
// result: (MOVHloadidx2 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVHloadidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHloadidx ptr (ADD idx idx) mem)
// result: (MOVHloadidx2 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADD {
break
}
idx := v_1.Args[1]
if idx != v_1.Args[0] {
break
}
mem := v_2
v.reset(OpARM64MOVHloadidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHloadidx (ADD idx idx) ptr mem)
// result: (MOVHloadidx2 ptr idx mem)
for {
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
if idx != v_0.Args[0] {
break
}
ptr := v_1
mem := v_2
v.reset(OpARM64MOVHloadidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHloadidx ptr idx (MOVHstorezeroidx ptr2 idx2 _))
// cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHstorezeroidx {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHloadidx2(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVHloadidx2 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<1)
// result: (MOVHload [int32(c)<<1] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 1)) {
break
}
v.reset(OpARM64MOVHload)
v.AuxInt = int32ToAuxInt(int32(c) << 1)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHloadidx2 ptr idx (MOVHstorezeroidx2 ptr2 idx2 _))
// cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHstorezeroidx2 {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHreg(v *Value) bool {
v_0 := v.Args[0]
// match: (MOVHreg x:(MOVBload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVBUload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVHload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVBloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVBUloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVHloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVHloadidx2 _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHloadidx2 {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVBreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVBUreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVHreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg (MOVDconst [c]))
// result: (MOVDconst [int64(int16(c))])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(int16(c)))
return true
}
// match: (MOVHreg (ANDconst x [c]))
// cond: uint64(c) & uint64(0xffffffffffff8000) == 0
// result: (ANDconst x [c])
for {
t := v.Type
if v_0.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(uint64(c)&uint64(0xffffffffffff8000) == 0) {
break
}
v.reset(OpARM64ANDconst)
v.Type = t
v.AuxInt = int64ToAuxInt(c)
v.AddArg(x)
return true
}
// match: (MOVHreg (SLLconst [lc] x))
// cond: lc < 16
// result: (SBFIZ [armBFAuxInt(lc, 16-lc)] x)
for {
if v_0.Op != OpARM64SLLconst {
break
}
lc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(lc < 16) {
break
}
v.reset(OpARM64SBFIZ)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 16-lc))
v.AddArg(x)
return true
}
// match: (MOVHreg (SBFX [bfc] x))
// cond: bfc.getARM64BFwidth() <= 16
// result: (SBFX [bfc] x)
for {
if v_0.Op != OpARM64SBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
if !(bfc.getARM64BFwidth() <= 16) {
break
}
v.reset(OpARM64SBFX)
v.AuxInt = arm64BitFieldToAuxInt(bfc)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVHstore [off1+int32(off2)] {sym} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVHstore [off] {sym} (ADD ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (MOVHstoreidx ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVHstore [off] {sym} (ADDshiftLL [1] ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (MOVHstoreidx2 ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVHstoreidx2)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVHstore [off] {sym} ptr (MOVDconst [0]) mem)
// result: (MOVHstorezero [off] {sym} ptr mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
mem := v_2
v.reset(OpARM64MOVHstorezero)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHstore [off] {sym} ptr (MOVHreg x) mem)
// result: (MOVHstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVHreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVHstore [off] {sym} ptr (MOVHUreg x) mem)
// result: (MOVHstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVHUreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVHstore [off] {sym} ptr (MOVWreg x) mem)
// result: (MOVHstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVWreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVHstore [off] {sym} ptr (MOVWUreg x) mem)
// result: (MOVHstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVWUreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVHstore [i] {s} ptr0 (SRLconst [16] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVWstore [i-2] {s} ptr0 w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
break
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(i - 2)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w, mem)
return true
}
// match: (MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVWstoreidx ptr1 idx1 w mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
continue
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVWstoreidx)
v.AddArg4(ptr1, idx1, w, mem)
return true
}
break
}
// match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
// result: (MOVWstoreidx ptr1 (SLLconst [1] idx1) w mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx0 := v_0.Args[1]
ptr0 := v_0.Args[0]
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
break
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstoreidx2 {
break
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
v0.AuxInt = int64ToAuxInt(1)
v0.AddArg(idx1)
v.AddArg4(ptr1, v0, w, mem)
return true
}
// match: (MOVHstore [i] {s} ptr0 (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVWstore [i-2] {s} ptr0 w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(16, 16) {
break
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(i - 2)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w, mem)
return true
}
// match: (MOVHstore [2] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVWstoreidx ptr1 idx1 w mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(16, 16) {
continue
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVWstoreidx)
v.AddArg4(ptr1, idx1, w, mem)
return true
}
break
}
// match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
// result: (MOVWstoreidx ptr1 (SLLconst [1] idx1) w mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx0 := v_0.Args[1]
ptr0 := v_0.Args[0]
if v_1.Op != OpARM64UBFX || auxIntToArm64BitField(v_1.AuxInt) != armBFAuxInt(16, 16) {
break
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstoreidx2 {
break
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
v0.AuxInt = int64ToAuxInt(1)
v0.AddArg(idx1)
v.AddArg4(ptr1, v0, w, mem)
return true
}
// match: (MOVHstore [i] {s} ptr0 (SRLconst [16] (MOVDreg w)) x:(MOVHstore [i-2] {s} ptr1 w mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVWstore [i-2] {s} ptr0 w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
break
}
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64MOVDreg {
break
}
w := v_1_0.Args[0]
x := v_2
if x.Op != OpARM64MOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(i - 2)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w, mem)
return true
}
// match: (MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVWstoreidx ptr1 idx1 w mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
continue
}
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64MOVDreg {
continue
}
w := v_1_0.Args[0]
x := v_2
if x.Op != OpARM64MOVHstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVWstoreidx)
v.AddArg4(ptr1, idx1, w, mem)
return true
}
break
}
// match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx2 ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
// result: (MOVWstoreidx ptr1 (SLLconst [1] idx1) w mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx0 := v_0.Args[1]
ptr0 := v_0.Args[0]
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 16 {
break
}
v_1_0 := v_1.Args[0]
if v_1_0.Op != OpARM64MOVDreg {
break
}
w := v_1_0.Args[0]
x := v_2
if x.Op != OpARM64MOVHstoreidx2 {
break
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
v0.AuxInt = int64ToAuxInt(1)
v0.AddArg(idx1)
v.AddArg4(ptr1, v0, w, mem)
return true
}
// match: (MOVHstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVHstore [i-2] {s} ptr1 w0:(SRLconst [j-16] w) mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVWstore [i-2] {s} ptr0 w0 mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64SRLconst {
break
}
j := auxIntToInt64(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstore || auxIntToInt32(x.AuxInt) != i-2 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
w0 := x.Args[1]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(i - 2)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w0, mem)
return true
}
// match: (MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx ptr1 idx1 w0:(SRLconst [j-16] w) mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVWstoreidx ptr1 idx1 w0 mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64SRLconst {
continue
}
j := auxIntToInt64(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
w0 := x.Args[2]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVWstoreidx)
v.AddArg4(ptr1, idx1, w0, mem)
return true
}
break
}
// match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx2 ptr1 idx1 w0:(SRLconst [j-16] w) mem))
// cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
// result: (MOVWstoreidx ptr1 (SLLconst [1] idx1) w0 mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx0 := v_0.Args[1]
ptr0 := v_0.Args[0]
if v_1.Op != OpARM64SRLconst {
break
}
j := auxIntToInt64(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstoreidx2 {
break
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
w0 := x.Args[2]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-16 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
v0.AuxInt = int64ToAuxInt(1)
v0.AddArg(idx1)
v.AddArg4(ptr1, v0, w0, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHstoreidx(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVHstoreidx ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c)
// result: (MOVHstore [int32(c)] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVHstoreidx (MOVDconst [c]) idx val mem)
// cond: is32Bit(c)
// result: (MOVHstore [int32(c)] idx val mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(idx, val, mem)
return true
}
// match: (MOVHstoreidx ptr (SLLconst [1] idx) val mem)
// result: (MOVHstoreidx2 ptr idx val mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
idx := v_1.Args[0]
val := v_2
mem := v_3
v.reset(OpARM64MOVHstoreidx2)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVHstoreidx ptr (ADD idx idx) val mem)
// result: (MOVHstoreidx2 ptr idx val mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADD {
break
}
idx := v_1.Args[1]
if idx != v_1.Args[0] {
break
}
val := v_2
mem := v_3
v.reset(OpARM64MOVHstoreidx2)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVHstoreidx (SLLconst [1] idx) ptr val mem)
// result: (MOVHstoreidx2 ptr idx val mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx := v_0.Args[0]
ptr := v_1
val := v_2
mem := v_3
v.reset(OpARM64MOVHstoreidx2)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVHstoreidx (ADD idx idx) ptr val mem)
// result: (MOVHstoreidx2 ptr idx val mem)
for {
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
if idx != v_0.Args[0] {
break
}
ptr := v_1
val := v_2
mem := v_3
v.reset(OpARM64MOVHstoreidx2)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVHstoreidx ptr idx (MOVDconst [0]) mem)
// result: (MOVHstorezeroidx ptr idx mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
break
}
mem := v_3
v.reset(OpARM64MOVHstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHstoreidx ptr idx (MOVHreg x) mem)
// result: (MOVHstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVHstoreidx ptr idx (MOVHUreg x) mem)
// result: (MOVHstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHUreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVHstoreidx ptr idx (MOVWreg x) mem)
// result: (MOVHstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVHstoreidx ptr idx (MOVWUreg x) mem)
// result: (MOVHstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWUreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVHstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVHstoreidx ptr (ADDconst [2] idx) (SRLconst [16] w) x:(MOVHstoreidx ptr idx w mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVWstoreidx ptr idx w mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 2 {
break
}
idx := v_1.Args[0]
if v_2.Op != OpARM64SRLconst || auxIntToInt64(v_2.AuxInt) != 16 {
break
}
w := v_2.Args[0]
x := v_3
if x.Op != OpARM64MOVHstoreidx {
break
}
mem := x.Args[3]
if ptr != x.Args[0] || idx != x.Args[1] || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVWstoreidx)
v.AddArg4(ptr, idx, w, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHstoreidx2(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVHstoreidx2 ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c<<1)
// result: (MOVHstore [int32(c)<<1] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c << 1)) {
break
}
v.reset(OpARM64MOVHstore)
v.AuxInt = int32ToAuxInt(int32(c) << 1)
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVHstoreidx2 ptr idx (MOVDconst [0]) mem)
// result: (MOVHstorezeroidx2 ptr idx mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
break
}
mem := v_3
v.reset(OpARM64MOVHstorezeroidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHstoreidx2 ptr idx (MOVHreg x) mem)
// result: (MOVHstoreidx2 ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVHstoreidx2)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVHstoreidx2 ptr idx (MOVHUreg x) mem)
// result: (MOVHstoreidx2 ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVHUreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVHstoreidx2)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVHstoreidx2 ptr idx (MOVWreg x) mem)
// result: (MOVHstoreidx2 ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVHstoreidx2)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVHstoreidx2 ptr idx (MOVWUreg x) mem)
// result: (MOVHstoreidx2 ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWUreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVHstoreidx2)
v.AddArg4(ptr, idx, x, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHstorezero(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVHstorezero)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVHstorezero)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHstorezero [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVHstorezeroidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVHstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHstorezero [off] {sym} (ADDshiftLL [1] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVHstorezeroidx2 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVHstorezeroidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHstorezero [i] {s} ptr0 x:(MOVHstorezero [j] {s} ptr1 mem))
// cond: x.Uses == 1 && areAdjacentOffsets(int64(i),int64(j),2) && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVWstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
x := v_1
if x.Op != OpARM64MOVHstorezero {
break
}
j := auxIntToInt32(x.AuxInt)
if auxToSym(x.Aux) != s {
break
}
mem := x.Args[1]
ptr1 := x.Args[0]
if !(x.Uses == 1 && areAdjacentOffsets(int64(i), int64(j), 2) && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstorezero)
v.AuxInt = int32ToAuxInt(int32(min(int64(i), int64(j))))
v.Aux = symToAux(s)
v.AddArg2(ptr0, mem)
return true
}
// match: (MOVHstorezero [2] {s} (ADD ptr0 idx0) x:(MOVHstorezeroidx ptr1 idx1 mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVWstorezeroidx ptr1 idx1 mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
x := v_1
if x.Op != OpARM64MOVHstorezeroidx {
continue
}
mem := x.Args[2]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVWstorezeroidx)
v.AddArg3(ptr1, idx1, mem)
return true
}
break
}
// match: (MOVHstorezero [2] {s} (ADDshiftLL [1] ptr0 idx0) x:(MOVHstorezeroidx2 ptr1 idx1 mem))
// cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
// result: (MOVWstorezeroidx ptr1 (SLLconst [1] idx1) mem)
for {
if auxIntToInt32(v.AuxInt) != 2 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx0 := v_0.Args[1]
ptr0 := v_0.Args[0]
x := v_1
if x.Op != OpARM64MOVHstorezeroidx2 {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
break
}
v.reset(OpARM64MOVWstorezeroidx)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
v0.AuxInt = int64ToAuxInt(1)
v0.AddArg(idx1)
v.AddArg3(ptr1, v0, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHstorezeroidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVHstorezeroidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVHstorezero [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVHstorezero)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVHstorezeroidx (MOVDconst [c]) idx mem)
// cond: is32Bit(c)
// result: (MOVHstorezero [int32(c)] idx mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVHstorezero)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(idx, mem)
return true
}
// match: (MOVHstorezeroidx ptr (SLLconst [1] idx) mem)
// result: (MOVHstorezeroidx2 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVHstorezeroidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHstorezeroidx ptr (ADD idx idx) mem)
// result: (MOVHstorezeroidx2 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADD {
break
}
idx := v_1.Args[1]
if idx != v_1.Args[0] {
break
}
mem := v_2
v.reset(OpARM64MOVHstorezeroidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHstorezeroidx (SLLconst [1] idx) ptr mem)
// result: (MOVHstorezeroidx2 ptr idx mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 1 {
break
}
idx := v_0.Args[0]
ptr := v_1
mem := v_2
v.reset(OpARM64MOVHstorezeroidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHstorezeroidx (ADD idx idx) ptr mem)
// result: (MOVHstorezeroidx2 ptr idx mem)
for {
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
if idx != v_0.Args[0] {
break
}
ptr := v_1
mem := v_2
v.reset(OpARM64MOVHstorezeroidx2)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVHstorezeroidx ptr (ADDconst [2] idx) x:(MOVHstorezeroidx ptr idx mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVWstorezeroidx ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 2 {
break
}
idx := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVHstorezeroidx {
break
}
mem := x.Args[2]
if ptr != x.Args[0] || idx != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVWstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVHstorezeroidx2(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVHstorezeroidx2 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<1)
// result: (MOVHstorezero [int32(c<<1)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 1)) {
break
}
v.reset(OpARM64MOVHstorezero)
v.AuxInt = int32ToAuxInt(int32(c << 1))
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVQstorezero(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVQstorezero [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVQstorezero)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVQstorezero)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWUload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVWUload [off] {sym} ptr (FMOVSstore [off] {sym} ptr val _))
// result: (FMOVSfpgp val)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64FMOVSstore || auxIntToInt32(v_1.AuxInt) != off || auxToSym(v_1.Aux) != sym {
break
}
val := v_1.Args[1]
if ptr != v_1.Args[0] {
break
}
v.reset(OpARM64FMOVSfpgp)
v.AddArg(val)
return true
}
// match: (MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVWUload [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVWUload)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWUload [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVWUloadidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVWUloadidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWUload [off] {sym} (ADDshiftLL [2] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVWUloadidx4 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVWUloadidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVWUload)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWUload [off] {sym} ptr (MOVWstorezero [off2] {sym2} ptr2 _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVDconst [0])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVWstorezero {
break
}
off2 := auxIntToInt32(v_1.AuxInt)
sym2 := auxToSym(v_1.Aux)
ptr2 := v_1.Args[0]
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (MOVWUload [off] {sym} (SB) _)
// cond: symIsRO(sym)
// result: (MOVDconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpSB || !(symIsRO(sym)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder)))
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWUloadidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVWUloadidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVWUload [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVWUload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWUloadidx (MOVDconst [c]) ptr mem)
// cond: is32Bit(c)
// result: (MOVWUload [int32(c)] ptr mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
ptr := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVWUload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWUloadidx ptr (SLLconst [2] idx) mem)
// result: (MOVWUloadidx4 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVWUloadidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWUloadidx (SLLconst [2] idx) ptr mem)
// result: (MOVWUloadidx4 ptr idx mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[0]
ptr := v_1
mem := v_2
v.reset(OpARM64MOVWUloadidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWUloadidx ptr idx (MOVWstorezeroidx ptr2 idx2 _))
// cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWstorezeroidx {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWUloadidx4(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVWUloadidx4 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<2)
// result: (MOVWUload [int32(c)<<2] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 2)) {
break
}
v.reset(OpARM64MOVWUload)
v.AuxInt = int32ToAuxInt(int32(c) << 2)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWUloadidx4 ptr idx (MOVWstorezeroidx4 ptr2 idx2 _))
// cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWstorezeroidx4 {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWUreg(v *Value) bool {
v_0 := v.Args[0]
// match: (MOVWUreg x:(MOVBUload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVHUload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVWUload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVWUload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVBUloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVHUloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVWUloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVWUloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVHUloadidx2 _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUloadidx2 {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVWUloadidx4 _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVWUloadidx4 {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVBUreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVHUreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg x:(MOVWUreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVWUreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWUreg (ANDconst [c] x))
// result: (ANDconst [c&(1<<32-1)] x)
for {
if v_0.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpARM64ANDconst)
v.AuxInt = int64ToAuxInt(c & (1<<32 - 1))
v.AddArg(x)
return true
}
// match: (MOVWUreg (MOVDconst [c]))
// result: (MOVDconst [int64(uint32(c))])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(uint32(c)))
return true
}
// match: (MOVWUreg x)
// cond: zeroUpper32Bits(x, 3)
// result: x
for {
x := v_0
if !(zeroUpper32Bits(x, 3)) {
break
}
v.copyOf(x)
return true
}
// match: (MOVWUreg (SLLconst [lc] x))
// cond: lc >= 32
// result: (MOVDconst [0])
for {
if v_0.Op != OpARM64SLLconst {
break
}
lc := auxIntToInt64(v_0.AuxInt)
if !(lc >= 32) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (MOVWUreg (SLLconst [lc] x))
// cond: lc < 32
// result: (UBFIZ [armBFAuxInt(lc, 32-lc)] x)
for {
if v_0.Op != OpARM64SLLconst {
break
}
lc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(lc < 32) {
break
}
v.reset(OpARM64UBFIZ)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 32-lc))
v.AddArg(x)
return true
}
// match: (MOVWUreg (SRLconst [rc] x))
// cond: rc < 32
// result: (UBFX [armBFAuxInt(rc, 32)] x)
for {
if v_0.Op != OpARM64SRLconst {
break
}
rc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(rc < 32) {
break
}
v.reset(OpARM64UBFX)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(rc, 32))
v.AddArg(x)
return true
}
// match: (MOVWUreg (UBFX [bfc] x))
// cond: bfc.getARM64BFwidth() <= 32
// result: (UBFX [bfc] x)
for {
if v_0.Op != OpARM64UBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
if !(bfc.getARM64BFwidth() <= 32) {
break
}
v.reset(OpARM64UBFX)
v.AuxInt = arm64BitFieldToAuxInt(bfc)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWload(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVWload [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVWload)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWload [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVWloadidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVWloadidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWload [off] {sym} (ADDshiftLL [2] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVWloadidx4 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVWloadidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVWload)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWload [off] {sym} ptr (MOVWstorezero [off2] {sym2} ptr2 _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
// result: (MOVDconst [0])
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVWstorezero {
break
}
off2 := auxIntToInt32(v_1.AuxInt)
sym2 := auxToSym(v_1.Aux)
ptr2 := v_1.Args[0]
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWloadidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVWloadidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVWload [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVWload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWloadidx (MOVDconst [c]) ptr mem)
// cond: is32Bit(c)
// result: (MOVWload [int32(c)] ptr mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
ptr := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVWload)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWloadidx ptr (SLLconst [2] idx) mem)
// result: (MOVWloadidx4 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVWloadidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWloadidx (SLLconst [2] idx) ptr mem)
// result: (MOVWloadidx4 ptr idx mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[0]
ptr := v_1
mem := v_2
v.reset(OpARM64MOVWloadidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWloadidx ptr idx (MOVWstorezeroidx ptr2 idx2 _))
// cond: (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2))
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWstorezeroidx {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWloadidx4(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVWloadidx4 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<2)
// result: (MOVWload [int32(c)<<2] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 2)) {
break
}
v.reset(OpARM64MOVWload)
v.AuxInt = int32ToAuxInt(int32(c) << 2)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWloadidx4 ptr idx (MOVWstorezeroidx4 ptr2 idx2 _))
// cond: isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)
// result: (MOVDconst [0])
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWstorezeroidx4 {
break
}
idx2 := v_2.Args[1]
ptr2 := v_2.Args[0]
if !(isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2)) {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWreg(v *Value) bool {
v_0 := v.Args[0]
// match: (MOVWreg x:(MOVBload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVBUload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHUload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVWload _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVWload {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVBloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVBUloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHUloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVWloadidx _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVWloadidx {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHloadidx2 _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHloadidx2 {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHUloadidx2 _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHUloadidx2 {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVWloadidx4 _ _ _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVWloadidx4 {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVBreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVBUreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVBUreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVHreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVWreg _))
// result: (MOVDreg x)
for {
x := v_0
if x.Op != OpARM64MOVWreg {
break
}
v.reset(OpARM64MOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg (MOVDconst [c]))
// result: (MOVDconst [int64(int32(c))])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(int32(c)))
return true
}
// match: (MOVWreg (ANDconst x [c]))
// cond: uint64(c) & uint64(0xffffffff80000000) == 0
// result: (ANDconst x [c])
for {
t := v.Type
if v_0.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(uint64(c)&uint64(0xffffffff80000000) == 0) {
break
}
v.reset(OpARM64ANDconst)
v.Type = t
v.AuxInt = int64ToAuxInt(c)
v.AddArg(x)
return true
}
// match: (MOVWreg (SLLconst [lc] x))
// cond: lc < 32
// result: (SBFIZ [armBFAuxInt(lc, 32-lc)] x)
for {
if v_0.Op != OpARM64SLLconst {
break
}
lc := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(lc < 32) {
break
}
v.reset(OpARM64SBFIZ)
v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(lc, 32-lc))
v.AddArg(x)
return true
}
// match: (MOVWreg (SBFX [bfc] x))
// cond: bfc.getARM64BFwidth() <= 32
// result: (SBFX [bfc] x)
for {
if v_0.Op != OpARM64SBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
if !(bfc.getARM64BFwidth() <= 32) {
break
}
v.reset(OpARM64SBFX)
v.AuxInt = arm64BitFieldToAuxInt(bfc)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVWstore [off] {sym} ptr (FMOVSfpgp val) mem)
// result: (FMOVSstore [off] {sym} ptr val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64FMOVSfpgp {
break
}
val := v_1.Args[0]
mem := v_2
v.reset(OpARM64FMOVSstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVWstore [off] {sym} (ADD ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (MOVWstoreidx ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVWstoreidx)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVWstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem)
// cond: off == 0 && sym == nil
// result: (MOVWstoreidx4 ptr idx val mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVWstoreidx4)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
val := v_1
mem := v_2
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVWstore [off] {sym} ptr (MOVDconst [0]) mem)
// result: (MOVWstorezero [off] {sym} ptr mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
mem := v_2
v.reset(OpARM64MOVWstorezero)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWstore [off] {sym} ptr (MOVWreg x) mem)
// result: (MOVWstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVWreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVWstore [off] {sym} ptr (MOVWUreg x) mem)
// result: (MOVWstore [off] {sym} ptr x mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
ptr := v_0
if v_1.Op != OpARM64MOVWUreg {
break
}
x := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(off)
v.Aux = symToAux(sym)
v.AddArg3(ptr, x, mem)
return true
}
// match: (MOVWstore [i] {s} ptr0 (SRLconst [32] w) x:(MOVWstore [i-4] {s} ptr1 w mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVDstore [i-4] {s} ptr0 w mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 32 {
break
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
if w != x.Args[1] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVDstore)
v.AuxInt = int32ToAuxInt(i - 4)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w, mem)
return true
}
// match: (MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVDstoreidx ptr1 idx1 w mem)
for {
if auxIntToInt32(v.AuxInt) != 4 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 32 {
continue
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVWstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVDstoreidx)
v.AddArg4(ptr1, idx1, w, mem)
return true
}
break
}
// match: (MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx4 ptr1 idx1 w mem))
// cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
// result: (MOVDstoreidx ptr1 (SLLconst [2] idx1) w mem)
for {
if auxIntToInt32(v.AuxInt) != 4 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx0 := v_0.Args[1]
ptr0 := v_0.Args[0]
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != 32 {
break
}
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVWstoreidx4 {
break
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if w != x.Args[2] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
break
}
v.reset(OpARM64MOVDstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg(idx1)
v.AddArg4(ptr1, v0, w, mem)
return true
}
// match: (MOVWstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVWstore [i-4] {s} ptr1 w0:(SRLconst [j-32] w) mem))
// cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVDstore [i-4] {s} ptr0 w0 mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
if v_1.Op != OpARM64SRLconst {
break
}
j := auxIntToInt64(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVWstore || auxIntToInt32(x.AuxInt) != i-4 || auxToSym(x.Aux) != s {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
w0 := x.Args[1]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVDstore)
v.AuxInt = int32ToAuxInt(i - 4)
v.Aux = symToAux(s)
v.AddArg3(ptr0, w0, mem)
return true
}
// match: (MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx ptr1 idx1 w0:(SRLconst [j-32] w) mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVDstoreidx ptr1 idx1 w0 mem)
for {
if auxIntToInt32(v.AuxInt) != 4 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
if v_1.Op != OpARM64SRLconst {
continue
}
j := auxIntToInt64(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVWstoreidx {
continue
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
w0 := x.Args[2]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVDstoreidx)
v.AddArg4(ptr1, idx1, w0, mem)
return true
}
break
}
// match: (MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx4 ptr1 idx1 w0:(SRLconst [j-32] w) mem))
// cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
// result: (MOVDstoreidx ptr1 (SLLconst [2] idx1) w0 mem)
for {
if auxIntToInt32(v.AuxInt) != 4 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx0 := v_0.Args[1]
ptr0 := v_0.Args[0]
if v_1.Op != OpARM64SRLconst {
break
}
j := auxIntToInt64(v_1.AuxInt)
w := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVWstoreidx4 {
break
}
mem := x.Args[3]
ptr1 := x.Args[0]
idx1 := x.Args[1]
w0 := x.Args[2]
if w0.Op != OpARM64SRLconst || auxIntToInt64(w0.AuxInt) != j-32 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
break
}
v.reset(OpARM64MOVDstoreidx)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg(idx1)
v.AddArg4(ptr1, v0, w0, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWstoreidx(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVWstoreidx ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c)
// result: (MOVWstore [int32(c)] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVWstoreidx (MOVDconst [c]) idx val mem)
// cond: is32Bit(c)
// result: (MOVWstore [int32(c)] idx val mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
val := v_2
mem := v_3
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg3(idx, val, mem)
return true
}
// match: (MOVWstoreidx ptr (SLLconst [2] idx) val mem)
// result: (MOVWstoreidx4 ptr idx val mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
break
}
idx := v_1.Args[0]
val := v_2
mem := v_3
v.reset(OpARM64MOVWstoreidx4)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVWstoreidx (SLLconst [2] idx) ptr val mem)
// result: (MOVWstoreidx4 ptr idx val mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[0]
ptr := v_1
val := v_2
mem := v_3
v.reset(OpARM64MOVWstoreidx4)
v.AddArg4(ptr, idx, val, mem)
return true
}
// match: (MOVWstoreidx ptr idx (MOVDconst [0]) mem)
// result: (MOVWstorezeroidx ptr idx mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
break
}
mem := v_3
v.reset(OpARM64MOVWstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWstoreidx ptr idx (MOVWreg x) mem)
// result: (MOVWstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVWstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVWstoreidx ptr idx (MOVWUreg x) mem)
// result: (MOVWstoreidx ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWUreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVWstoreidx)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVWstoreidx ptr (ADDconst [4] idx) (SRLconst [32] w) x:(MOVWstoreidx ptr idx w mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVDstoreidx ptr idx w mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 4 {
break
}
idx := v_1.Args[0]
if v_2.Op != OpARM64SRLconst || auxIntToInt64(v_2.AuxInt) != 32 {
break
}
w := v_2.Args[0]
x := v_3
if x.Op != OpARM64MOVWstoreidx {
break
}
mem := x.Args[3]
if ptr != x.Args[0] || idx != x.Args[1] || w != x.Args[2] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVDstoreidx)
v.AddArg4(ptr, idx, w, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWstoreidx4(v *Value) bool {
v_3 := v.Args[3]
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVWstoreidx4 ptr (MOVDconst [c]) val mem)
// cond: is32Bit(c<<2)
// result: (MOVWstore [int32(c)<<2] ptr val mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
val := v_2
mem := v_3
if !(is32Bit(c << 2)) {
break
}
v.reset(OpARM64MOVWstore)
v.AuxInt = int32ToAuxInt(int32(c) << 2)
v.AddArg3(ptr, val, mem)
return true
}
// match: (MOVWstoreidx4 ptr idx (MOVDconst [0]) mem)
// result: (MOVWstorezeroidx4 ptr idx mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
break
}
mem := v_3
v.reset(OpARM64MOVWstorezeroidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWstoreidx4 ptr idx (MOVWreg x) mem)
// result: (MOVWstoreidx4 ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVWstoreidx4)
v.AddArg4(ptr, idx, x, mem)
return true
}
// match: (MOVWstoreidx4 ptr idx (MOVWUreg x) mem)
// result: (MOVWstoreidx4 ptr idx x mem)
for {
ptr := v_0
idx := v_1
if v_2.Op != OpARM64MOVWUreg {
break
}
x := v_2.Args[0]
mem := v_3
v.reset(OpARM64MOVWstoreidx4)
v.AddArg4(ptr, idx, x, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWstorezero(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
config := b.Func.Config
// match: (MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDconst {
break
}
off2 := auxIntToInt64(v_0.AuxInt)
ptr := v_0.Args[0]
mem := v_1
if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVWstorezero)
v.AuxInt = int32ToAuxInt(off1 + int32(off2))
v.Aux = symToAux(sym)
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
// result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := auxIntToInt32(v.AuxInt)
sym1 := auxToSym(v.Aux)
if v_0.Op != OpARM64MOVDaddr {
break
}
off2 := auxIntToInt32(v_0.AuxInt)
sym2 := auxToSym(v_0.Aux)
ptr := v_0.Args[0]
mem := v_1
if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
break
}
v.reset(OpARM64MOVWstorezero)
v.AuxInt = int32ToAuxInt(off1 + off2)
v.Aux = symToAux(mergeSym(sym1, sym2))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWstorezero [off] {sym} (ADD ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVWstorezeroidx ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVWstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWstorezero [off] {sym} (ADDshiftLL [2] ptr idx) mem)
// cond: off == 0 && sym == nil
// result: (MOVWstorezeroidx4 ptr idx mem)
for {
off := auxIntToInt32(v.AuxInt)
sym := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[1]
ptr := v_0.Args[0]
mem := v_1
if !(off == 0 && sym == nil) {
break
}
v.reset(OpARM64MOVWstorezeroidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWstorezero [i] {s} ptr0 x:(MOVWstorezero [j] {s} ptr1 mem))
// cond: x.Uses == 1 && areAdjacentOffsets(int64(i),int64(j),4) && isSamePtr(ptr0, ptr1) && clobber(x)
// result: (MOVDstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
for {
i := auxIntToInt32(v.AuxInt)
s := auxToSym(v.Aux)
ptr0 := v_0
x := v_1
if x.Op != OpARM64MOVWstorezero {
break
}
j := auxIntToInt32(x.AuxInt)
if auxToSym(x.Aux) != s {
break
}
mem := x.Args[1]
ptr1 := x.Args[0]
if !(x.Uses == 1 && areAdjacentOffsets(int64(i), int64(j), 4) && isSamePtr(ptr0, ptr1) && clobber(x)) {
break
}
v.reset(OpARM64MOVDstorezero)
v.AuxInt = int32ToAuxInt(int32(min(int64(i), int64(j))))
v.Aux = symToAux(s)
v.AddArg2(ptr0, mem)
return true
}
// match: (MOVWstorezero [4] {s} (ADD ptr0 idx0) x:(MOVWstorezeroidx ptr1 idx1 mem))
// cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)
// result: (MOVDstorezeroidx ptr1 idx1 mem)
for {
if auxIntToInt32(v.AuxInt) != 4 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADD {
break
}
_ = v_0.Args[1]
v_0_0 := v_0.Args[0]
v_0_1 := v_0.Args[1]
for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
ptr0 := v_0_0
idx0 := v_0_1
x := v_1
if x.Op != OpARM64MOVWstorezeroidx {
continue
}
mem := x.Args[2]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) {
continue
}
v.reset(OpARM64MOVDstorezeroidx)
v.AddArg3(ptr1, idx1, mem)
return true
}
break
}
// match: (MOVWstorezero [4] {s} (ADDshiftLL [2] ptr0 idx0) x:(MOVWstorezeroidx4 ptr1 idx1 mem))
// cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)
// result: (MOVDstorezeroidx ptr1 (SLLconst [2] idx1) mem)
for {
if auxIntToInt32(v.AuxInt) != 4 {
break
}
s := auxToSym(v.Aux)
if v_0.Op != OpARM64ADDshiftLL || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx0 := v_0.Args[1]
ptr0 := v_0.Args[0]
x := v_1
if x.Op != OpARM64MOVWstorezeroidx4 {
break
}
mem := x.Args[2]
ptr1 := x.Args[0]
idx1 := x.Args[1]
if !(x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x)) {
break
}
v.reset(OpARM64MOVDstorezeroidx)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg(idx1)
v.AddArg3(ptr1, v0, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWstorezeroidx(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVWstorezeroidx ptr (MOVDconst [c]) mem)
// cond: is32Bit(c)
// result: (MOVWstorezero [int32(c)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVWstorezero)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(ptr, mem)
return true
}
// match: (MOVWstorezeroidx (MOVDconst [c]) idx mem)
// cond: is32Bit(c)
// result: (MOVWstorezero [int32(c)] idx mem)
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
idx := v_1
mem := v_2
if !(is32Bit(c)) {
break
}
v.reset(OpARM64MOVWstorezero)
v.AuxInt = int32ToAuxInt(int32(c))
v.AddArg2(idx, mem)
return true
}
// match: (MOVWstorezeroidx ptr (SLLconst [2] idx) mem)
// result: (MOVWstorezeroidx4 ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64SLLconst || auxIntToInt64(v_1.AuxInt) != 2 {
break
}
idx := v_1.Args[0]
mem := v_2
v.reset(OpARM64MOVWstorezeroidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWstorezeroidx (SLLconst [2] idx) ptr mem)
// result: (MOVWstorezeroidx4 ptr idx mem)
for {
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 2 {
break
}
idx := v_0.Args[0]
ptr := v_1
mem := v_2
v.reset(OpARM64MOVWstorezeroidx4)
v.AddArg3(ptr, idx, mem)
return true
}
// match: (MOVWstorezeroidx ptr (ADDconst [4] idx) x:(MOVWstorezeroidx ptr idx mem))
// cond: x.Uses == 1 && clobber(x)
// result: (MOVDstorezeroidx ptr idx mem)
for {
ptr := v_0
if v_1.Op != OpARM64ADDconst || auxIntToInt64(v_1.AuxInt) != 4 {
break
}
idx := v_1.Args[0]
x := v_2
if x.Op != OpARM64MOVWstorezeroidx {
break
}
mem := x.Args[2]
if ptr != x.Args[0] || idx != x.Args[1] || !(x.Uses == 1 && clobber(x)) {
break
}
v.reset(OpARM64MOVDstorezeroidx)
v.AddArg3(ptr, idx, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MOVWstorezeroidx4(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MOVWstorezeroidx4 ptr (MOVDconst [c]) mem)
// cond: is32Bit(c<<2)
// result: (MOVWstorezero [int32(c<<2)] ptr mem)
for {
ptr := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
mem := v_2
if !(is32Bit(c << 2)) {
break
}
v.reset(OpARM64MOVWstorezero)
v.AuxInt = int32ToAuxInt(int32(c << 2))
v.AddArg2(ptr, mem)
return true
}
return false
}
func rewriteValueARM64_OpARM64MSUB(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (MSUB a x (MOVDconst [-1]))
// result: (ADD a x)
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != -1 {
break
}
v.reset(OpARM64ADD)
v.AddArg2(a, x)
return true
}
// match: (MSUB a _ (MOVDconst [0]))
// result: a
for {
a := v_0
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 0 {
break
}
v.copyOf(a)
return true
}
// match: (MSUB a x (MOVDconst [1]))
// result: (SUB a x)
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst || auxIntToInt64(v_2.AuxInt) != 1 {
break
}
v.reset(OpARM64SUB)
v.AddArg2(a, x)
return true
}
// match: (MSUB a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c)
// result: (SUBshiftLL a x [log64(c)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg2(a, x)
return true
}
// match: (MSUB a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c-1) && c>=3
// result: (SUB a (ADDshiftLL x x [log64(c-1)]))
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c-1) && c >= 3) {
break
}
v.reset(OpARM64SUB)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c+1) && c>=7
// result: (ADD a (SUBshiftLL x x [log64(c+1)]))
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c+1) && c >= 7) {
break
}
v.reset(OpARM64ADD)
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo64(c/3)
// result: (ADDshiftLL a (SUBshiftLL x x [2]) [log64(c/3)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a x (MOVDconst [c]))
// cond: c%5 == 0 && isPowerOfTwo64(c/5)
// result: (SUBshiftLL a (ADDshiftLL x x [2]) [log64(c/5)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo64(c/7)
// result: (ADDshiftLL a (SUBshiftLL x x [3]) [log64(c/7)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a x (MOVDconst [c]))
// cond: c%9 == 0 && isPowerOfTwo64(c/9)
// result: (SUBshiftLL a (ADDshiftLL x x [3]) [log64(c/9)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a (MOVDconst [-1]) x)
// result: (ADD a x)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
break
}
x := v_2
v.reset(OpARM64ADD)
v.AddArg2(a, x)
return true
}
// match: (MSUB a (MOVDconst [0]) _)
// result: a
for {
a := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
break
}
v.copyOf(a)
return true
}
// match: (MSUB a (MOVDconst [1]) x)
// result: (SUB a x)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
break
}
x := v_2
v.reset(OpARM64SUB)
v.AddArg2(a, x)
return true
}
// match: (MSUB a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c)
// result: (SUBshiftLL a x [log64(c)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg2(a, x)
return true
}
// match: (MSUB a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c-1) && c>=3
// result: (SUB a (ADDshiftLL x x [log64(c-1)]))
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c-1) && c >= 3) {
break
}
v.reset(OpARM64SUB)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c+1) && c>=7
// result: (ADD a (SUBshiftLL x x [log64(c+1)]))
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c+1) && c >= 7) {
break
}
v.reset(OpARM64ADD)
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a (MOVDconst [c]) x)
// cond: c%3 == 0 && isPowerOfTwo64(c/3)
// result: (ADDshiftLL a (SUBshiftLL x x [2]) [log64(c/3)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a (MOVDconst [c]) x)
// cond: c%5 == 0 && isPowerOfTwo64(c/5)
// result: (SUBshiftLL a (ADDshiftLL x x [2]) [log64(c/5)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a (MOVDconst [c]) x)
// cond: c%7 == 0 && isPowerOfTwo64(c/7)
// result: (ADDshiftLL a (SUBshiftLL x x [3]) [log64(c/7)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB a (MOVDconst [c]) x)
// cond: c%9 == 0 && isPowerOfTwo64(c/9)
// result: (SUBshiftLL a (ADDshiftLL x x [3]) [log64(c/9)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUB (MOVDconst [c]) x y)
// result: (ADDconst [c] (MNEG x y))
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
y := v_2
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64MNEG, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (MSUB a (MOVDconst [c]) (MOVDconst [d]))
// result: (SUBconst [c*d] a)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
if v_2.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_2.AuxInt)
v.reset(OpARM64SUBconst)
v.AuxInt = int64ToAuxInt(c * d)
v.AddArg(a)
return true
}
return false
}
func rewriteValueARM64_OpARM64MSUBW(v *Value) bool {
v_2 := v.Args[2]
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (MSUBW a x (MOVDconst [c]))
// cond: int32(c)==-1
// result: (ADD a x)
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(int32(c) == -1) {
break
}
v.reset(OpARM64ADD)
v.AddArg2(a, x)
return true
}
// match: (MSUBW a _ (MOVDconst [c]))
// cond: int32(c)==0
// result: a
for {
a := v_0
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(int32(c) == 0) {
break
}
v.copyOf(a)
return true
}
// match: (MSUBW a x (MOVDconst [c]))
// cond: int32(c)==1
// result: (SUB a x)
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(int32(c) == 1) {
break
}
v.reset(OpARM64SUB)
v.AddArg2(a, x)
return true
}
// match: (MSUBW a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c)
// result: (SUBshiftLL a x [log64(c)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg2(a, x)
return true
}
// match: (MSUBW a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c-1) && int32(c)>=3
// result: (SUB a (ADDshiftLL x x [log64(c-1)]))
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
break
}
v.reset(OpARM64SUB)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a x (MOVDconst [c]))
// cond: isPowerOfTwo64(c+1) && int32(c)>=7
// result: (ADD a (SUBshiftLL x x [log64(c+1)]))
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
break
}
v.reset(OpARM64ADD)
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
// result: (ADDshiftLL a (SUBshiftLL x x [2]) [log64(c/3)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a x (MOVDconst [c]))
// cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
// result: (SUBshiftLL a (ADDshiftLL x x [2]) [log64(c/5)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
// result: (ADDshiftLL a (SUBshiftLL x x [3]) [log64(c/7)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a x (MOVDconst [c]))
// cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
// result: (SUBshiftLL a (ADDshiftLL x x [3]) [log64(c/9)])
for {
a := v_0
x := v_1
if v_2.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_2.AuxInt)
if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a (MOVDconst [c]) x)
// cond: int32(c)==-1
// result: (ADD a x)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(int32(c) == -1) {
break
}
v.reset(OpARM64ADD)
v.AddArg2(a, x)
return true
}
// match: (MSUBW a (MOVDconst [c]) _)
// cond: int32(c)==0
// result: a
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
if !(int32(c) == 0) {
break
}
v.copyOf(a)
return true
}
// match: (MSUBW a (MOVDconst [c]) x)
// cond: int32(c)==1
// result: (SUB a x)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(int32(c) == 1) {
break
}
v.reset(OpARM64SUB)
v.AddArg2(a, x)
return true
}
// match: (MSUBW a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c)
// result: (SUBshiftLL a x [log64(c)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg2(a, x)
return true
}
// match: (MSUBW a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c-1) && int32(c)>=3
// result: (SUB a (ADDshiftLL x x [log64(c-1)]))
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
break
}
v.reset(OpARM64SUB)
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c - 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a (MOVDconst [c]) x)
// cond: isPowerOfTwo64(c+1) && int32(c)>=7
// result: (ADD a (SUBshiftLL x x [log64(c+1)]))
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
break
}
v.reset(OpARM64ADD)
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(log64(c + 1))
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a (MOVDconst [c]) x)
// cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
// result: (ADDshiftLL a (SUBshiftLL x x [2]) [log64(c/3)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a (MOVDconst [c]) x)
// cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
// result: (SUBshiftLL a (ADDshiftLL x x [2]) [log64(c/5)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a (MOVDconst [c]) x)
// cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
// result: (ADDshiftLL a (SUBshiftLL x x [3]) [log64(c/7)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
break
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64SUBshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW a (MOVDconst [c]) x)
// cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
// result: (SUBshiftLL a (ADDshiftLL x x [3]) [log64(c/9)])
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
x := v_2
if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
break
}
v.reset(OpARM64SUBshiftLL)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg2(a, v0)
return true
}
// match: (MSUBW (MOVDconst [c]) x y)
// result: (ADDconst [c] (MNEGW x y))
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
y := v_2
v.reset(OpARM64ADDconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64MNEGW, x.Type)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (MSUBW a (MOVDconst [c]) (MOVDconst [d]))
// result: (SUBconst [int64(int32(c)*int32(d))] a)
for {
a := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
if v_2.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_2.AuxInt)
v.reset(OpARM64SUBconst)
v.AuxInt = int64ToAuxInt(int64(int32(c) * int32(d)))
v.AddArg(a)
return true
}
return false
}
func rewriteValueARM64_OpARM64MUL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (MUL (NEG x) y)
// result: (MNEG x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64NEG {
continue
}
x := v_0.Args[0]
y := v_1
v.reset(OpARM64MNEG)
v.AddArg2(x, y)
return true
}
break
}
// match: (MUL x (MOVDconst [-1]))
// result: (NEG x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 {
continue
}
v.reset(OpARM64NEG)
v.AddArg(x)
return true
}
break
}
// match: (MUL _ (MOVDconst [0]))
// result: (MOVDconst [0])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
continue
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
break
}
// match: (MUL x (MOVDconst [1]))
// result: x
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst || auxIntToInt64(v_1.AuxInt) != 1 {
continue
}
v.copyOf(x)
return true
}
break
}
// match: (MUL x (MOVDconst [c]))
// cond: isPowerOfTwo64(c)
// result: (SLLconst [log64(c)] x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg(x)
return true
}
break
}
// match: (MUL x (MOVDconst [c]))
// cond: isPowerOfTwo64(c-1) && c >= 3
// result: (ADDshiftLL x x [log64(c-1)])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c-1) && c >= 3) {
continue
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c - 1))
v.AddArg2(x, x)
return true
}
break
}
// match: (MUL x (MOVDconst [c]))
// cond: isPowerOfTwo64(c+1) && c >= 7
// result: (ADDshiftLL (NEG x) x [log64(c+1)])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c+1) && c >= 7) {
continue
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c + 1))
v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
break
}
// match: (MUL x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo64(c/3)
// result: (SLLconst [log64(c/3)] (ADDshiftLL x x [1]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%3 == 0 && isPowerOfTwo64(c/3)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(1)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MUL x (MOVDconst [c]))
// cond: c%5 == 0 && isPowerOfTwo64(c/5)
// result: (SLLconst [log64(c/5)] (ADDshiftLL x x [2]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%5 == 0 && isPowerOfTwo64(c/5)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MUL x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo64(c/7)
// result: (SLLconst [log64(c/7)] (ADDshiftLL (NEG x) x [3]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%7 == 0 && isPowerOfTwo64(c/7)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
v1.AddArg(x)
v0.AddArg2(v1, x)
v.AddArg(v0)
return true
}
break
}
// match: (MUL x (MOVDconst [c]))
// cond: c%9 == 0 && isPowerOfTwo64(c/9)
// result: (SLLconst [log64(c/9)] (ADDshiftLL x x [3]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%9 == 0 && isPowerOfTwo64(c/9)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MUL (MOVDconst [c]) (MOVDconst [d]))
// result: (MOVDconst [c*d])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_0.AuxInt)
if v_1.Op != OpARM64MOVDconst {
continue
}
d := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c * d)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64MULW(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (MULW (NEG x) y)
// result: (MNEGW x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64NEG {
continue
}
x := v_0.Args[0]
y := v_1
v.reset(OpARM64MNEGW)
v.AddArg2(x, y)
return true
}
break
}
// match: (MULW x (MOVDconst [c]))
// cond: int32(c)==-1
// result: (NEG x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(int32(c) == -1) {
continue
}
v.reset(OpARM64NEG)
v.AddArg(x)
return true
}
break
}
// match: (MULW _ (MOVDconst [c]))
// cond: int32(c)==0
// result: (MOVDconst [0])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(int32(c) == 0) {
continue
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
break
}
// match: (MULW x (MOVDconst [c]))
// cond: int32(c)==1
// result: x
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(int32(c) == 1) {
continue
}
v.copyOf(x)
return true
}
break
}
// match: (MULW x (MOVDconst [c]))
// cond: isPowerOfTwo64(c)
// result: (SLLconst [log64(c)] x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c))
v.AddArg(x)
return true
}
break
}
// match: (MULW x (MOVDconst [c]))
// cond: isPowerOfTwo64(c-1) && int32(c) >= 3
// result: (ADDshiftLL x x [log64(c-1)])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c-1) && int32(c) >= 3) {
continue
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c - 1))
v.AddArg2(x, x)
return true
}
break
}
// match: (MULW x (MOVDconst [c]))
// cond: isPowerOfTwo64(c+1) && int32(c) >= 7
// result: (ADDshiftLL (NEG x) x [log64(c+1)])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(isPowerOfTwo64(c+1) && int32(c) >= 7) {
continue
}
v.reset(OpARM64ADDshiftLL)
v.AuxInt = int64ToAuxInt(log64(c + 1))
v0 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
v0.AddArg(x)
v.AddArg2(v0, x)
return true
}
break
}
// match: (MULW x (MOVDconst [c]))
// cond: c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)
// result: (SLLconst [log64(c/3)] (ADDshiftLL x x [1]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c / 3))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(1)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MULW x (MOVDconst [c]))
// cond: c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)
// result: (SLLconst [log64(c/5)] (ADDshiftLL x x [2]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c / 5))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(2)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MULW x (MOVDconst [c]))
// cond: c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)
// result: (SLLconst [log64(c/7)] (ADDshiftLL (NEG x) x [3]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c / 7))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v1 := b.NewValue0(v.Pos, OpARM64NEG, x.Type)
v1.AddArg(x)
v0.AddArg2(v1, x)
v.AddArg(v0)
return true
}
break
}
// match: (MULW x (MOVDconst [c]))
// cond: c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)
// result: (SLLconst [log64(c/9)] (ADDshiftLL x x [3]))
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
if !(c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c)) {
continue
}
v.reset(OpARM64SLLconst)
v.AuxInt = int64ToAuxInt(log64(c / 9))
v0 := b.NewValue0(v.Pos, OpARM64ADDshiftLL, x.Type)
v0.AuxInt = int64ToAuxInt(3)
v0.AddArg2(x, x)
v.AddArg(v0)
return true
}
break
}
// match: (MULW (MOVDconst [c]) (MOVDconst [d]))
// result: (MOVDconst [int64(int32(c)*int32(d))])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_0.AuxInt)
if v_1.Op != OpARM64MOVDconst {
continue
}
d := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(int64(int32(c) * int32(d)))
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64MVN(v *Value) bool {
v_0 := v.Args[0]
// match: (MVN (XOR x y))
// result: (EON x y)
for {
if v_0.Op != OpARM64XOR {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
v.reset(OpARM64EON)
v.AddArg2(x, y)
return true
}
// match: (MVN (MOVDconst [c]))
// result: (MOVDconst [^c])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(^c)
return true
}
// match: (MVN x:(SLLconst [c] y))
// cond: clobberIfDead(x)
// result: (MVNshiftLL [c] y)
for {
x := v_0
if x.Op != OpARM64SLLconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(clobberIfDead(x)) {
break
}
v.reset(OpARM64MVNshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(y)
return true
}
// match: (MVN x:(SRLconst [c] y))
// cond: clobberIfDead(x)
// result: (MVNshiftRL [c] y)
for {
x := v_0
if x.Op != OpARM64SRLconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(clobberIfDead(x)) {
break
}
v.reset(OpARM64MVNshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(y)
return true
}
// match: (MVN x:(SRAconst [c] y))
// cond: clobberIfDead(x)
// result: (MVNshiftRA [c] y)
for {
x := v_0
if x.Op != OpARM64SRAconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(clobberIfDead(x)) {
break
}
v.reset(OpARM64MVNshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(y)
return true
}
// match: (MVN x:(RORconst [c] y))
// cond: clobberIfDead(x)
// result: (MVNshiftRO [c] y)
for {
x := v_0
if x.Op != OpARM64RORconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(clobberIfDead(x)) {
break
}
v.reset(OpARM64MVNshiftRO)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(y)
return true
}
return false
}
func rewriteValueARM64_OpARM64MVNshiftLL(v *Value) bool {
v_0 := v.Args[0]
// match: (MVNshiftLL (MOVDconst [c]) [d])
// result: (MOVDconst [^int64(uint64(c)<>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(^(c >> uint64(d)))
return true
}
return false
}
func rewriteValueARM64_OpARM64MVNshiftRL(v *Value) bool {
v_0 := v.Args[0]
// match: (MVNshiftRL (MOVDconst [c]) [d])
// result: (MOVDconst [^int64(uint64(c)>>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(^int64(uint64(c) >> uint64(d)))
return true
}
return false
}
func rewriteValueARM64_OpARM64MVNshiftRO(v *Value) bool {
v_0 := v.Args[0]
// match: (MVNshiftRO (MOVDconst [c]) [d])
// result: (MOVDconst [^rotateRight64(c, d)])
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
return true
}
return false
}
func rewriteValueARM64_OpARM64NEG(v *Value) bool {
v_0 := v.Args[0]
// match: (NEG (MUL x y))
// result: (MNEG x y)
for {
if v_0.Op != OpARM64MUL {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
v.reset(OpARM64MNEG)
v.AddArg2(x, y)
return true
}
// match: (NEG (MULW x y))
// result: (MNEGW x y)
for {
if v_0.Op != OpARM64MULW {
break
}
y := v_0.Args[1]
x := v_0.Args[0]
v.reset(OpARM64MNEGW)
v.AddArg2(x, y)
return true
}
// match: (NEG (NEG x))
// result: x
for {
if v_0.Op != OpARM64NEG {
break
}
x := v_0.Args[0]
v.copyOf(x)
return true
}
// match: (NEG (MOVDconst [c]))
// result: (MOVDconst [-c])
for {
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-c)
return true
}
// match: (NEG x:(SLLconst [c] y))
// cond: clobberIfDead(x)
// result: (NEGshiftLL [c] y)
for {
x := v_0
if x.Op != OpARM64SLLconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(clobberIfDead(x)) {
break
}
v.reset(OpARM64NEGshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(y)
return true
}
// match: (NEG x:(SRLconst [c] y))
// cond: clobberIfDead(x)
// result: (NEGshiftRL [c] y)
for {
x := v_0
if x.Op != OpARM64SRLconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(clobberIfDead(x)) {
break
}
v.reset(OpARM64NEGshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(y)
return true
}
// match: (NEG x:(SRAconst [c] y))
// cond: clobberIfDead(x)
// result: (NEGshiftRA [c] y)
for {
x := v_0
if x.Op != OpARM64SRAconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(clobberIfDead(x)) {
break
}
v.reset(OpARM64NEGshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(y)
return true
}
return false
}
func rewriteValueARM64_OpARM64NEGshiftLL(v *Value) bool {
v_0 := v.Args[0]
// match: (NEGshiftLL (MOVDconst [c]) [d])
// result: (MOVDconst [-int64(uint64(c)<>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-(c >> uint64(d)))
return true
}
return false
}
func rewriteValueARM64_OpARM64NEGshiftRL(v *Value) bool {
v_0 := v.Args[0]
// match: (NEGshiftRL (MOVDconst [c]) [d])
// result: (MOVDconst [-int64(uint64(c)>>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-int64(uint64(c) >> uint64(d)))
return true
}
return false
}
func rewriteValueARM64_OpARM64NotEqual(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (NotEqual (CMPconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (NotEqual (TST x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPWconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (NotEqual (TSTWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPWconst [0] z:(AND x y)))
// cond: z.Uses == 1
// result: (NotEqual (TSTW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64AND {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPconst [0] x:(ANDconst [c] y)))
// cond: x.Uses == 1
// result: (NotEqual (TSTconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ANDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMP x z:(NEG y)))
// cond: z.Uses == 1
// result: (NotEqual (CMN x y))
for {
if v_0.Op != OpARM64CMP {
break
}
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPW x z:(NEG y)))
// cond: z.Uses == 1
// result: (NotEqual (CMNW x y))
for {
if v_0.Op != OpARM64CMPW {
break
}
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPconst [0] x:(ADDconst [c] y)))
// cond: x.Uses == 1
// result: (NotEqual (CMNconst [c] y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ADDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
v0.AuxInt = int64ToAuxInt(c)
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPWconst [0] x:(ADDconst [c] y)))
// cond: x.Uses == 1
// result: (NotEqual (CMNWconst [int32(c)] y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
if x.Op != OpARM64ADDconst {
break
}
c := auxIntToInt64(x.AuxInt)
y := x.Args[0]
if !(x.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
v0.AuxInt = int32ToAuxInt(int32(c))
v0.AddArg(y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPconst [0] z:(ADD x y)))
// cond: z.Uses == 1
// result: (NotEqual (CMN x y))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64ADD {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPWconst [0] z:(ADD x y)))
// cond: z.Uses == 1
// result: (NotEqual (CMNW x y))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64ADD {
break
}
y := z.Args[1]
x := z.Args[0]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPconst [0] z:(MADD a x y)))
// cond: z.Uses == 1
// result: (NotEqual (CMN a (MUL x y)))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MADD {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPconst [0] z:(MSUB a x y)))
// cond: z.Uses == 1
// result: (NotEqual (CMP a (MUL x y)))
for {
if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MSUB {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPWconst [0] z:(MADDW a x y)))
// cond: z.Uses == 1
// result: (NotEqual (CMNW a (MULW x y)))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MADDW {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (NotEqual (CMPWconst [0] z:(MSUBW a x y)))
// cond: z.Uses == 1
// result: (NotEqual (CMPW a (MULW x y)))
for {
if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
break
}
z := v_0.Args[0]
if z.Op != OpARM64MSUBW {
break
}
y := z.Args[2]
a := z.Args[0]
x := z.Args[1]
if !(z.Uses == 1) {
break
}
v.reset(OpARM64NotEqual)
v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
v1.AddArg2(x, y)
v0.AddArg2(a, v1)
v.AddArg(v0)
return true
}
// match: (NotEqual (FlagConstant [fc]))
// result: (MOVDconst [b2i(fc.ne())])
for {
if v_0.Op != OpARM64FlagConstant {
break
}
fc := auxIntToFlagConstant(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(b2i(fc.ne()))
return true
}
// match: (NotEqual (InvertFlags x))
// result: (NotEqual x)
for {
if v_0.Op != OpARM64InvertFlags {
break
}
x := v_0.Args[0]
v.reset(OpARM64NotEqual)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64OR(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
// match: (OR x (MOVDconst [c]))
// result: (ORconst [c] x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MOVDconst {
continue
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ORconst)
v.AuxInt = int64ToAuxInt(c)
v.AddArg(x)
return true
}
break
}
// match: (OR x x)
// result: x
for {
x := v_0
if x != v_1 {
break
}
v.copyOf(x)
return true
}
// match: (OR x (MVN y))
// result: (ORN x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x := v_0
if v_1.Op != OpARM64MVN {
continue
}
y := v_1.Args[0]
v.reset(OpARM64ORN)
v.AddArg2(x, y)
return true
}
break
}
// match: (OR x0 x1:(SLLconst [c] y))
// cond: clobberIfDead(x1)
// result: (ORshiftLL x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SLLconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ORshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (OR x0 x1:(SRLconst [c] y))
// cond: clobberIfDead(x1)
// result: (ORshiftRL x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRLconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ORshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (OR x0 x1:(SRAconst [c] y))
// cond: clobberIfDead(x1)
// result: (ORshiftRA x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRAconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ORshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (OR x0 x1:(RORconst [c] y))
// cond: clobberIfDead(x1)
// result: (ORshiftRO x0 y [c])
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64RORconst {
continue
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
continue
}
v.reset(OpARM64ORshiftRO)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
break
}
// match: (OR (UBFIZ [bfc] x) (ANDconst [ac] y))
// cond: ac == ^((1< o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [i3] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i1] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i0] {s} p mem)))
// cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
// result: @mergePoint(b,x0,x1,x2,x3) (MOVWUload {s} (OffPtr [int64(i0)] p) mem)
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
s0 := o1.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUload {
continue
}
i3 := auxIntToInt32(x0.AuxInt)
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o1.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload {
continue
}
i2 := auxIntToInt32(x1.AuxInt)
if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] {
continue
}
y2 := o0.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload {
continue
}
i1 := auxIntToInt32(x2.AuxInt)
if auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
if p != x2.Args[0] || mem != x2.Args[1] {
continue
}
y3 := v_1
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload {
continue
}
i0 := auxIntToInt32(x3.AuxInt)
if auxToSym(x3.Aux) != s {
continue
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] || !(i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3)
v0 := b.NewValue0(x3.Pos, OpARM64MOVWUload, t)
v.copyOf(v0)
v0.Aux = symToAux(s)
v1 := b.NewValue0(x3.Pos, OpOffPtr, p.Type)
v1.AuxInt = int64ToAuxInt(int64(i0))
v1.AddArg(p)
v0.AddArg2(v1, mem)
return true
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [3] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [2] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr0 idx0 mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
// result: @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx ptr0 idx0 mem)
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
s0 := o1.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUload || auxIntToInt32(x0.AuxInt) != 3 {
continue
}
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o1.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 2 || auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] {
continue
}
y2 := o0.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 1 || auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
p1 := x2.Args[0]
if p1.Op != OpARM64ADD {
continue
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i1 := 0; _i1 <= 1; _i1, p1_0, p1_1 = _i1+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
if mem != x2.Args[1] {
continue
}
y3 := v_1
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUloadidx {
continue
}
_ = x3.Args[2]
ptr0 := x3.Args[0]
idx0 := x3.Args[1]
if mem != x3.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3)
v0 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr0, idx0, mem)
return true
}
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr idx mem)))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
// result: @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx ptr idx mem)
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
s0 := o1.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUloadidx {
continue
}
mem := x0.Args[2]
ptr := x0.Args[0]
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 3 {
continue
}
idx := x0_1.Args[0]
y1 := o1.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUloadidx {
continue
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
continue
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 2 || idx != x1_1.Args[0] || mem != x1.Args[2] {
continue
}
y2 := o0.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUloadidx {
continue
}
_ = x2.Args[2]
if ptr != x2.Args[0] {
continue
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 1 || idx != x2_1.Args[0] || mem != x2.Args[2] {
continue
}
y3 := v_1
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUloadidx {
continue
}
_ = x3.Args[2]
if ptr != x3.Args[0] || idx != x3.Args[1] || mem != x3.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3)
v0 := b.NewValue0(v.Pos, OpARM64MOVWUloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr, idx, mem)
return true
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [i7] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i6] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i4] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i3] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [i2] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [i1] {s} p mem))) y7:(MOVDnop x7:(MOVBUload [i0] {s} p mem)))
// cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload {s} (OffPtr [int64(i0)] p) mem)
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
continue
}
_ = o2.Args[1]
o3 := o2.Args[0]
if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
continue
}
_ = o3.Args[1]
o4 := o3.Args[0]
if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
continue
}
_ = o4.Args[1]
o5 := o4.Args[0]
if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
continue
}
_ = o5.Args[1]
s0 := o5.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUload {
continue
}
i7 := auxIntToInt32(x0.AuxInt)
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o5.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload {
continue
}
i6 := auxIntToInt32(x1.AuxInt)
if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] {
continue
}
y2 := o4.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload {
continue
}
i5 := auxIntToInt32(x2.AuxInt)
if auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
if p != x2.Args[0] || mem != x2.Args[1] {
continue
}
y3 := o3.Args[1]
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload {
continue
}
i4 := auxIntToInt32(x3.AuxInt)
if auxToSym(x3.Aux) != s {
continue
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] {
continue
}
y4 := o2.Args[1]
if y4.Op != OpARM64MOVDnop {
continue
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUload {
continue
}
i3 := auxIntToInt32(x4.AuxInt)
if auxToSym(x4.Aux) != s {
continue
}
_ = x4.Args[1]
if p != x4.Args[0] || mem != x4.Args[1] {
continue
}
y5 := o1.Args[1]
if y5.Op != OpARM64MOVDnop {
continue
}
x5 := y5.Args[0]
if x5.Op != OpARM64MOVBUload {
continue
}
i2 := auxIntToInt32(x5.AuxInt)
if auxToSym(x5.Aux) != s {
continue
}
_ = x5.Args[1]
if p != x5.Args[0] || mem != x5.Args[1] {
continue
}
y6 := o0.Args[1]
if y6.Op != OpARM64MOVDnop {
continue
}
x6 := y6.Args[0]
if x6.Op != OpARM64MOVBUload {
continue
}
i1 := auxIntToInt32(x6.AuxInt)
if auxToSym(x6.Aux) != s {
continue
}
_ = x6.Args[1]
if p != x6.Args[0] || mem != x6.Args[1] {
continue
}
y7 := v_1
if y7.Op != OpARM64MOVDnop {
continue
}
x7 := y7.Args[0]
if x7.Op != OpARM64MOVBUload {
continue
}
i0 := auxIntToInt32(x7.AuxInt)
if auxToSym(x7.Aux) != s {
continue
}
_ = x7.Args[1]
if p != x7.Args[0] || mem != x7.Args[1] || !(i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
v0 := b.NewValue0(x7.Pos, OpARM64MOVDload, t)
v.copyOf(v0)
v0.Aux = symToAux(s)
v1 := b.NewValue0(x7.Pos, OpOffPtr, p.Type)
v1.AuxInt = int64ToAuxInt(int64(i0))
v1.AddArg(p)
v0.AddArg2(v1, mem)
return true
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [7] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [6] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [4] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [3] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [2] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y7:(MOVDnop x7:(MOVBUloadidx ptr0 idx0 mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx ptr0 idx0 mem)
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
continue
}
_ = o2.Args[1]
o3 := o2.Args[0]
if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
continue
}
_ = o3.Args[1]
o4 := o3.Args[0]
if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
continue
}
_ = o4.Args[1]
o5 := o4.Args[0]
if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
continue
}
_ = o5.Args[1]
s0 := o5.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUload || auxIntToInt32(x0.AuxInt) != 7 {
continue
}
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o5.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 6 || auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] {
continue
}
y2 := o4.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 5 || auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
if p != x2.Args[0] || mem != x2.Args[1] {
continue
}
y3 := o3.Args[1]
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 4 || auxToSym(x3.Aux) != s {
continue
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] {
continue
}
y4 := o2.Args[1]
if y4.Op != OpARM64MOVDnop {
continue
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUload || auxIntToInt32(x4.AuxInt) != 3 || auxToSym(x4.Aux) != s {
continue
}
_ = x4.Args[1]
if p != x4.Args[0] || mem != x4.Args[1] {
continue
}
y5 := o1.Args[1]
if y5.Op != OpARM64MOVDnop {
continue
}
x5 := y5.Args[0]
if x5.Op != OpARM64MOVBUload || auxIntToInt32(x5.AuxInt) != 2 || auxToSym(x5.Aux) != s {
continue
}
_ = x5.Args[1]
if p != x5.Args[0] || mem != x5.Args[1] {
continue
}
y6 := o0.Args[1]
if y6.Op != OpARM64MOVDnop {
continue
}
x6 := y6.Args[0]
if x6.Op != OpARM64MOVBUload || auxIntToInt32(x6.AuxInt) != 1 || auxToSym(x6.Aux) != s {
continue
}
_ = x6.Args[1]
p1 := x6.Args[0]
if p1.Op != OpARM64ADD {
continue
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i1 := 0; _i1 <= 1; _i1, p1_0, p1_1 = _i1+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
if mem != x6.Args[1] {
continue
}
y7 := v_1
if y7.Op != OpARM64MOVDnop {
continue
}
x7 := y7.Args[0]
if x7.Op != OpARM64MOVBUloadidx {
continue
}
_ = x7.Args[2]
ptr0 := x7.Args[0]
idx0 := x7.Args[1]
if mem != x7.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
v0 := b.NewValue0(x6.Pos, OpARM64MOVDloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr0, idx0, mem)
return true
}
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [7] idx) mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [6] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [4] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y7:(MOVDnop x7:(MOVBUloadidx ptr idx mem)))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx ptr idx mem)
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
continue
}
_ = o2.Args[1]
o3 := o2.Args[0]
if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
continue
}
_ = o3.Args[1]
o4 := o3.Args[0]
if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
continue
}
_ = o4.Args[1]
o5 := o4.Args[0]
if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
continue
}
_ = o5.Args[1]
s0 := o5.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUloadidx {
continue
}
mem := x0.Args[2]
ptr := x0.Args[0]
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 7 {
continue
}
idx := x0_1.Args[0]
y1 := o5.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUloadidx {
continue
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
continue
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 6 || idx != x1_1.Args[0] || mem != x1.Args[2] {
continue
}
y2 := o4.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUloadidx {
continue
}
_ = x2.Args[2]
if ptr != x2.Args[0] {
continue
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 5 || idx != x2_1.Args[0] || mem != x2.Args[2] {
continue
}
y3 := o3.Args[1]
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUloadidx {
continue
}
_ = x3.Args[2]
if ptr != x3.Args[0] {
continue
}
x3_1 := x3.Args[1]
if x3_1.Op != OpARM64ADDconst || auxIntToInt64(x3_1.AuxInt) != 4 || idx != x3_1.Args[0] || mem != x3.Args[2] {
continue
}
y4 := o2.Args[1]
if y4.Op != OpARM64MOVDnop {
continue
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUloadidx {
continue
}
_ = x4.Args[2]
if ptr != x4.Args[0] {
continue
}
x4_1 := x4.Args[1]
if x4_1.Op != OpARM64ADDconst || auxIntToInt64(x4_1.AuxInt) != 3 || idx != x4_1.Args[0] || mem != x4.Args[2] {
continue
}
y5 := o1.Args[1]
if y5.Op != OpARM64MOVDnop {
continue
}
x5 := y5.Args[0]
if x5.Op != OpARM64MOVBUloadidx {
continue
}
_ = x5.Args[2]
if ptr != x5.Args[0] {
continue
}
x5_1 := x5.Args[1]
if x5_1.Op != OpARM64ADDconst || auxIntToInt64(x5_1.AuxInt) != 2 || idx != x5_1.Args[0] || mem != x5.Args[2] {
continue
}
y6 := o0.Args[1]
if y6.Op != OpARM64MOVDnop {
continue
}
x6 := y6.Args[0]
if x6.Op != OpARM64MOVBUloadidx {
continue
}
_ = x6.Args[2]
if ptr != x6.Args[0] {
continue
}
x6_1 := x6.Args[1]
if x6_1.Op != OpARM64ADDconst || auxIntToInt64(x6_1.AuxInt) != 1 || idx != x6_1.Args[0] || mem != x6.Args[2] {
continue
}
y7 := v_1
if y7.Op != OpARM64MOVDnop {
continue
}
x7 := y7.Args[0]
if x7.Op != OpARM64MOVBUloadidx {
continue
}
_ = x7.Args[2]
if ptr != x7.Args[0] || idx != x7.Args[1] || mem != x7.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
v0 := b.NewValue0(v.Pos, OpARM64MOVDloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr, idx, mem)
return true
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem)))
// cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
// result: @mergePoint(b,x0,x1,x2,x3) (REVW (MOVWUload {s} (OffPtr [int64(i0)] p) mem))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
s0 := o1.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUload {
continue
}
i0 := auxIntToInt32(x0.AuxInt)
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o1.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload {
continue
}
i1 := auxIntToInt32(x1.AuxInt)
if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] {
continue
}
y2 := o0.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload {
continue
}
i2 := auxIntToInt32(x2.AuxInt)
if auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
if p != x2.Args[0] || mem != x2.Args[1] {
continue
}
y3 := v_1
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload {
continue
}
i3 := auxIntToInt32(x3.AuxInt)
if auxToSym(x3.Aux) != s {
continue
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] || !(i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3)
v0 := b.NewValue0(x3.Pos, OpARM64REVW, t)
v.copyOf(v0)
v1 := b.NewValue0(x3.Pos, OpARM64MOVWUload, t)
v1.Aux = symToAux(s)
v2 := b.NewValue0(x3.Pos, OpOffPtr, p.Type)
v2.AuxInt = int64ToAuxInt(int64(i0))
v2.AddArg(p)
v1.AddArg2(v2, mem)
v0.AddArg(v1)
return true
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
// result: @mergePoint(b,x0,x1,x2,x3) (REVW (MOVWUloadidx ptr0 idx0 mem))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
s0 := o1.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUloadidx {
continue
}
mem := x0.Args[2]
ptr0 := x0.Args[0]
idx0 := x0.Args[1]
y1 := o1.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 1 {
continue
}
s := auxToSym(x1.Aux)
_ = x1.Args[1]
p1 := x1.Args[0]
if p1.Op != OpARM64ADD {
continue
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i1 := 0; _i1 <= 1; _i1, p1_0, p1_1 = _i1+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
if mem != x1.Args[1] {
continue
}
y2 := o0.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 2 || auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
p := x2.Args[0]
if mem != x2.Args[1] {
continue
}
y3 := v_1
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 3 || auxToSym(x3.Aux) != s {
continue
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3)
v0 := b.NewValue0(x3.Pos, OpARM64REVW, t)
v.copyOf(v0)
v1 := b.NewValue0(x3.Pos, OpARM64MOVWUloadidx, t)
v1.AddArg3(ptr0, idx0, mem)
v0.AddArg(v1)
return true
}
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
// result: @mergePoint(b,x0,x1,x2,x3) (REVW (MOVWUloadidx ptr idx mem))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
s0 := o1.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 24 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUloadidx {
continue
}
mem := x0.Args[2]
ptr := x0.Args[0]
idx := x0.Args[1]
y1 := o1.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUloadidx {
continue
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
continue
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] {
continue
}
y2 := o0.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUloadidx {
continue
}
_ = x2.Args[2]
if ptr != x2.Args[0] {
continue
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 2 || idx != x2_1.Args[0] || mem != x2.Args[2] {
continue
}
y3 := v_1
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUloadidx {
continue
}
_ = x3.Args[2]
if ptr != x3.Args[0] {
continue
}
x3_1 := x3.Args[1]
if x3_1.Op != OpARM64ADDconst || auxIntToInt64(x3_1.AuxInt) != 3 || idx != x3_1.Args[0] || mem != x3.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3)
v0 := b.NewValue0(v.Pos, OpARM64REVW, t)
v.copyOf(v0)
v1 := b.NewValue0(v.Pos, OpARM64MOVWUloadidx, t)
v1.AddArg3(ptr, idx, mem)
v0.AddArg(v1)
return true
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [i5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [i6] {s} p mem))) y7:(MOVDnop x7:(MOVBUload [i7] {s} p mem)))
// cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV (MOVDload {s} (OffPtr [int64(i0)] p) mem))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
continue
}
_ = o2.Args[1]
o3 := o2.Args[0]
if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
continue
}
_ = o3.Args[1]
o4 := o3.Args[0]
if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
continue
}
_ = o4.Args[1]
o5 := o4.Args[0]
if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
continue
}
_ = o5.Args[1]
s0 := o5.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUload {
continue
}
i0 := auxIntToInt32(x0.AuxInt)
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o5.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload {
continue
}
i1 := auxIntToInt32(x1.AuxInt)
if auxToSym(x1.Aux) != s {
continue
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] {
continue
}
y2 := o4.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload {
continue
}
i2 := auxIntToInt32(x2.AuxInt)
if auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
if p != x2.Args[0] || mem != x2.Args[1] {
continue
}
y3 := o3.Args[1]
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload {
continue
}
i3 := auxIntToInt32(x3.AuxInt)
if auxToSym(x3.Aux) != s {
continue
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] {
continue
}
y4 := o2.Args[1]
if y4.Op != OpARM64MOVDnop {
continue
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUload {
continue
}
i4 := auxIntToInt32(x4.AuxInt)
if auxToSym(x4.Aux) != s {
continue
}
_ = x4.Args[1]
if p != x4.Args[0] || mem != x4.Args[1] {
continue
}
y5 := o1.Args[1]
if y5.Op != OpARM64MOVDnop {
continue
}
x5 := y5.Args[0]
if x5.Op != OpARM64MOVBUload {
continue
}
i5 := auxIntToInt32(x5.AuxInt)
if auxToSym(x5.Aux) != s {
continue
}
_ = x5.Args[1]
if p != x5.Args[0] || mem != x5.Args[1] {
continue
}
y6 := o0.Args[1]
if y6.Op != OpARM64MOVDnop {
continue
}
x6 := y6.Args[0]
if x6.Op != OpARM64MOVBUload {
continue
}
i6 := auxIntToInt32(x6.AuxInt)
if auxToSym(x6.Aux) != s {
continue
}
_ = x6.Args[1]
if p != x6.Args[0] || mem != x6.Args[1] {
continue
}
y7 := v_1
if y7.Op != OpARM64MOVDnop {
continue
}
x7 := y7.Args[0]
if x7.Op != OpARM64MOVBUload {
continue
}
i7 := auxIntToInt32(x7.AuxInt)
if auxToSym(x7.Aux) != s {
continue
}
_ = x7.Args[1]
if p != x7.Args[0] || mem != x7.Args[1] || !(i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
v0 := b.NewValue0(x7.Pos, OpARM64REV, t)
v.copyOf(v0)
v1 := b.NewValue0(x7.Pos, OpARM64MOVDload, t)
v1.Aux = symToAux(s)
v2 := b.NewValue0(x7.Pos, OpOffPtr, p.Type)
v2.AuxInt = int64ToAuxInt(int64(i0))
v2.AddArg(p)
v1.AddArg2(v2, mem)
v0.AddArg(v1)
return true
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [6] {s} p mem))) y7:(MOVDnop x7:(MOVBUload [7] {s} p mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV (MOVDloadidx ptr0 idx0 mem))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
continue
}
_ = o2.Args[1]
o3 := o2.Args[0]
if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
continue
}
_ = o3.Args[1]
o4 := o3.Args[0]
if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
continue
}
_ = o4.Args[1]
o5 := o4.Args[0]
if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
continue
}
_ = o5.Args[1]
s0 := o5.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUloadidx {
continue
}
mem := x0.Args[2]
ptr0 := x0.Args[0]
idx0 := x0.Args[1]
y1 := o5.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 1 {
continue
}
s := auxToSym(x1.Aux)
_ = x1.Args[1]
p1 := x1.Args[0]
if p1.Op != OpARM64ADD {
continue
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i1 := 0; _i1 <= 1; _i1, p1_0, p1_1 = _i1+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
if mem != x1.Args[1] {
continue
}
y2 := o4.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 2 || auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
p := x2.Args[0]
if mem != x2.Args[1] {
continue
}
y3 := o3.Args[1]
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 3 || auxToSym(x3.Aux) != s {
continue
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] {
continue
}
y4 := o2.Args[1]
if y4.Op != OpARM64MOVDnop {
continue
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUload || auxIntToInt32(x4.AuxInt) != 4 || auxToSym(x4.Aux) != s {
continue
}
_ = x4.Args[1]
if p != x4.Args[0] || mem != x4.Args[1] {
continue
}
y5 := o1.Args[1]
if y5.Op != OpARM64MOVDnop {
continue
}
x5 := y5.Args[0]
if x5.Op != OpARM64MOVBUload || auxIntToInt32(x5.AuxInt) != 5 || auxToSym(x5.Aux) != s {
continue
}
_ = x5.Args[1]
if p != x5.Args[0] || mem != x5.Args[1] {
continue
}
y6 := o0.Args[1]
if y6.Op != OpARM64MOVDnop {
continue
}
x6 := y6.Args[0]
if x6.Op != OpARM64MOVBUload || auxIntToInt32(x6.AuxInt) != 6 || auxToSym(x6.Aux) != s {
continue
}
_ = x6.Args[1]
if p != x6.Args[0] || mem != x6.Args[1] {
continue
}
y7 := v_1
if y7.Op != OpARM64MOVDnop {
continue
}
x7 := y7.Args[0]
if x7.Op != OpARM64MOVBUload || auxIntToInt32(x7.AuxInt) != 7 || auxToSym(x7.Aux) != s {
continue
}
_ = x7.Args[1]
if p != x7.Args[0] || mem != x7.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
v0 := b.NewValue0(x7.Pos, OpARM64REV, t)
v.copyOf(v0)
v1 := b.NewValue0(x7.Pos, OpARM64MOVDloadidx, t)
v1.AddArg3(ptr0, idx0, mem)
v0.AddArg(v1)
return true
}
}
break
}
// match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [4] idx) mem))) y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [5] idx) mem))) y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [6] idx) mem))) y7:(MOVDnop x7:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
// result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV (MOVDloadidx ptr idx mem))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 8 {
continue
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 16 {
continue
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 24 {
continue
}
_ = o2.Args[1]
o3 := o2.Args[0]
if o3.Op != OpARM64ORshiftLL || auxIntToInt64(o3.AuxInt) != 32 {
continue
}
_ = o3.Args[1]
o4 := o3.Args[0]
if o4.Op != OpARM64ORshiftLL || auxIntToInt64(o4.AuxInt) != 40 {
continue
}
_ = o4.Args[1]
o5 := o4.Args[0]
if o5.Op != OpARM64ORshiftLL || auxIntToInt64(o5.AuxInt) != 48 {
continue
}
_ = o5.Args[1]
s0 := o5.Args[0]
if s0.Op != OpARM64SLLconst || auxIntToInt64(s0.AuxInt) != 56 {
continue
}
y0 := s0.Args[0]
if y0.Op != OpARM64MOVDnop {
continue
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUloadidx {
continue
}
mem := x0.Args[2]
ptr := x0.Args[0]
idx := x0.Args[1]
y1 := o5.Args[1]
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUloadidx {
continue
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
continue
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] {
continue
}
y2 := o4.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUloadidx {
continue
}
_ = x2.Args[2]
if ptr != x2.Args[0] {
continue
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 2 || idx != x2_1.Args[0] || mem != x2.Args[2] {
continue
}
y3 := o3.Args[1]
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUloadidx {
continue
}
_ = x3.Args[2]
if ptr != x3.Args[0] {
continue
}
x3_1 := x3.Args[1]
if x3_1.Op != OpARM64ADDconst || auxIntToInt64(x3_1.AuxInt) != 3 || idx != x3_1.Args[0] || mem != x3.Args[2] {
continue
}
y4 := o2.Args[1]
if y4.Op != OpARM64MOVDnop {
continue
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUloadidx {
continue
}
_ = x4.Args[2]
if ptr != x4.Args[0] {
continue
}
x4_1 := x4.Args[1]
if x4_1.Op != OpARM64ADDconst || auxIntToInt64(x4_1.AuxInt) != 4 || idx != x4_1.Args[0] || mem != x4.Args[2] {
continue
}
y5 := o1.Args[1]
if y5.Op != OpARM64MOVDnop {
continue
}
x5 := y5.Args[0]
if x5.Op != OpARM64MOVBUloadidx {
continue
}
_ = x5.Args[2]
if ptr != x5.Args[0] {
continue
}
x5_1 := x5.Args[1]
if x5_1.Op != OpARM64ADDconst || auxIntToInt64(x5_1.AuxInt) != 5 || idx != x5_1.Args[0] || mem != x5.Args[2] {
continue
}
y6 := o0.Args[1]
if y6.Op != OpARM64MOVDnop {
continue
}
x6 := y6.Args[0]
if x6.Op != OpARM64MOVBUloadidx {
continue
}
_ = x6.Args[2]
if ptr != x6.Args[0] {
continue
}
x6_1 := x6.Args[1]
if x6_1.Op != OpARM64ADDconst || auxIntToInt64(x6_1.AuxInt) != 6 || idx != x6_1.Args[0] || mem != x6.Args[2] {
continue
}
y7 := v_1
if y7.Op != OpARM64MOVDnop {
continue
}
x7 := y7.Args[0]
if x7.Op != OpARM64MOVBUloadidx {
continue
}
_ = x7.Args[2]
if ptr != x7.Args[0] {
continue
}
x7_1 := x7.Args[1]
if x7_1.Op != OpARM64ADDconst || auxIntToInt64(x7_1.AuxInt) != 7 || idx != x7_1.Args[0] || mem != x7.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
v0 := b.NewValue0(v.Pos, OpARM64REV, t)
v.copyOf(v0)
v1 := b.NewValue0(v.Pos, OpARM64MOVDloadidx, t)
v1.AddArg3(ptr, idx, mem)
v0.AddArg(v1)
return true
}
break
}
return false
}
func rewriteValueARM64_OpARM64ORN(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ORN x (MOVDconst [c]))
// result: (ORconst [^c] x)
for {
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ORconst)
v.AuxInt = int64ToAuxInt(^c)
v.AddArg(x)
return true
}
// match: (ORN x x)
// result: (MOVDconst [-1])
for {
x := v_0
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
// match: (ORN x0 x1:(SLLconst [c] y))
// cond: clobberIfDead(x1)
// result: (ORNshiftLL x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SLLconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64ORNshiftLL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (ORN x0 x1:(SRLconst [c] y))
// cond: clobberIfDead(x1)
// result: (ORNshiftRL x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRLconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64ORNshiftRL)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (ORN x0 x1:(SRAconst [c] y))
// cond: clobberIfDead(x1)
// result: (ORNshiftRA x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64SRAconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64ORNshiftRA)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
// match: (ORN x0 x1:(RORconst [c] y))
// cond: clobberIfDead(x1)
// result: (ORNshiftRO x0 y [c])
for {
x0 := v_0
x1 := v_1
if x1.Op != OpARM64RORconst {
break
}
c := auxIntToInt64(x1.AuxInt)
y := x1.Args[0]
if !(clobberIfDead(x1)) {
break
}
v.reset(OpARM64ORNshiftRO)
v.AuxInt = int64ToAuxInt(c)
v.AddArg2(x0, y)
return true
}
return false
}
func rewriteValueARM64_OpARM64ORNshiftLL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ORNshiftLL x (MOVDconst [c]) [d])
// result: (ORconst x [^int64(uint64(c)<>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ORconst)
v.AuxInt = int64ToAuxInt(^(c >> uint64(d)))
v.AddArg(x)
return true
}
// match: (ORNshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
return false
}
func rewriteValueARM64_OpARM64ORNshiftRL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ORNshiftRL x (MOVDconst [c]) [d])
// result: (ORconst x [^int64(uint64(c)>>uint64(d))])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ORconst)
v.AuxInt = int64ToAuxInt(^int64(uint64(c) >> uint64(d)))
v.AddArg(x)
return true
}
// match: (ORNshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
return false
}
func rewriteValueARM64_OpARM64ORNshiftRO(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ORNshiftRO x (MOVDconst [c]) [d])
// result: (ORconst x [^rotateRight64(c, d)])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_1.AuxInt)
v.reset(OpARM64ORconst)
v.AuxInt = int64ToAuxInt(^rotateRight64(c, d))
v.AddArg(x)
return true
}
// match: (ORNshiftRO (RORconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64RORconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
return false
}
func rewriteValueARM64_OpARM64ORconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ORconst [0] x)
// result: x
for {
if auxIntToInt64(v.AuxInt) != 0 {
break
}
x := v_0
v.copyOf(x)
return true
}
// match: (ORconst [-1] _)
// result: (MOVDconst [-1])
for {
if auxIntToInt64(v.AuxInt) != -1 {
break
}
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(-1)
return true
}
// match: (ORconst [c] (MOVDconst [d]))
// result: (MOVDconst [c|d])
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
d := auxIntToInt64(v_0.AuxInt)
v.reset(OpARM64MOVDconst)
v.AuxInt = int64ToAuxInt(c | d)
return true
}
// match: (ORconst [c] (ORconst [d] x))
// result: (ORconst [c|d] x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64ORconst {
break
}
d := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
v.reset(OpARM64ORconst)
v.AuxInt = int64ToAuxInt(c | d)
v.AddArg(x)
return true
}
// match: (ORconst [c1] (ANDconst [c2] x))
// cond: c2|c1 == ^0
// result: (ORconst [c1] x)
for {
c1 := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64ANDconst {
break
}
c2 := auxIntToInt64(v_0.AuxInt)
x := v_0.Args[0]
if !(c2|c1 == ^0) {
break
}
v.reset(OpARM64ORconst)
v.AuxInt = int64ToAuxInt(c1)
v.AddArg(x)
return true
}
return false
}
func rewriteValueARM64_OpARM64ORshiftLL(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (ORshiftLL (MOVDconst [c]) x [d])
// result: (ORconst [c] (SLLconst x [d]))
for {
d := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64MOVDconst {
break
}
c := auxIntToInt64(v_0.AuxInt)
x := v_1
v.reset(OpARM64ORconst)
v.AuxInt = int64ToAuxInt(c)
v0 := b.NewValue0(v.Pos, OpARM64SLLconst, x.Type)
v0.AuxInt = int64ToAuxInt(d)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: (ORshiftLL x (MOVDconst [c]) [d])
// result: (ORconst x [int64(uint64(c)< [8] (UBFX [armBFAuxInt(8, 8)] x) x)
// result: (REV16W x)
for {
if v.Type != typ.UInt16 || auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || v_0.Type != typ.UInt16 || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 8) {
break
}
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64REV16W)
v.AddArg(x)
return true
}
// match: (ORshiftLL [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
// cond: uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
// result: (REV16W x)
for {
if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64UBFX || auxIntToArm64BitField(v_0.AuxInt) != armBFAuxInt(8, 24) {
break
}
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpARM64ANDconst {
break
}
c1 := auxIntToInt64(v_0_0.AuxInt)
x := v_0_0.Args[0]
if v_1.Op != OpARM64ANDconst {
break
}
c2 := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff) {
break
}
v.reset(OpARM64REV16W)
v.AddArg(x)
return true
}
// match: (ORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
// cond: (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
// result: (REV16 x)
for {
if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
break
}
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpARM64ANDconst {
break
}
c1 := auxIntToInt64(v_0_0.AuxInt)
x := v_0_0.Args[0]
if v_1.Op != OpARM64ANDconst {
break
}
c2 := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff) {
break
}
v.reset(OpARM64REV16)
v.AddArg(x)
return true
}
// match: (ORshiftLL [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
// cond: (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
// result: (REV16 (ANDconst [0xffffffff] x))
for {
if auxIntToInt64(v.AuxInt) != 8 || v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 8 {
break
}
v_0_0 := v_0.Args[0]
if v_0_0.Op != OpARM64ANDconst {
break
}
c1 := auxIntToInt64(v_0_0.AuxInt)
x := v_0_0.Args[0]
if v_1.Op != OpARM64ANDconst {
break
}
c2 := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) {
break
}
v.reset(OpARM64REV16)
v0 := b.NewValue0(v.Pos, OpARM64ANDconst, x.Type)
v0.AuxInt = int64ToAuxInt(0xffffffff)
v0.AddArg(x)
v.AddArg(v0)
return true
}
// match: ( ORshiftLL [c] (SRLconst x [64-c]) x2)
// result: (EXTRconst [64-c] x2 x)
for {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
break
}
x := v_0.Args[0]
x2 := v_1
v.reset(OpARM64EXTRconst)
v.AuxInt = int64ToAuxInt(64 - c)
v.AddArg2(x2, x)
return true
}
// match: ( ORshiftLL [c] (UBFX [bfc] x) x2)
// cond: c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
// result: (EXTRWconst [32-c] x2 x)
for {
t := v.Type
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64UBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
x2 := v_1
if !(c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)) {
break
}
v.reset(OpARM64EXTRWconst)
v.AuxInt = int64ToAuxInt(32 - c)
v.AddArg2(x2, x)
return true
}
// match: (ORshiftLL [sc] (UBFX [bfc] x) (SRLconst [sc] y))
// cond: sc == bfc.getARM64BFwidth()
// result: (BFXIL [bfc] y x)
for {
sc := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64UBFX {
break
}
bfc := auxIntToArm64BitField(v_0.AuxInt)
x := v_0.Args[0]
if v_1.Op != OpARM64SRLconst || auxIntToInt64(v_1.AuxInt) != sc {
break
}
y := v_1.Args[0]
if !(sc == bfc.getARM64BFwidth()) {
break
}
v.reset(OpARM64BFXIL)
v.AuxInt = arm64BitFieldToAuxInt(bfc)
v.AddArg2(y, x)
return true
}
// match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
// cond: i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, y0, y1)
// result: @mergePoint(b,x0,x1) (MOVHUload {s} (OffPtr [int64(i0)] p) mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 8 {
break
}
y0 := v_0
if y0.Op != OpARM64MOVDnop {
break
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUload {
break
}
i0 := auxIntToInt32(x0.AuxInt)
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := v_1
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload {
break
}
i1 := auxIntToInt32(x1.AuxInt)
if auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, y0, y1)) {
break
}
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x1.Pos, OpARM64MOVHUload, t)
v.copyOf(v0)
v0.Aux = symToAux(s)
v1 := b.NewValue0(x1.Pos, OpOffPtr, p.Type)
v1.AuxInt = int64ToAuxInt(int64(i0))
v1.AddArg(p)
v0.AddArg2(v1, mem)
return true
}
// match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem)) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0, x1, y0, y1)
// result: @mergePoint(b,x0,x1) (MOVHUloadidx ptr0 idx0 mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 8 {
break
}
y0 := v_0
if y0.Op != OpARM64MOVDnop {
break
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUloadidx {
break
}
mem := x0.Args[2]
ptr0 := x0.Args[0]
idx0 := x0.Args[1]
y1 := v_1
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 1 {
break
}
s := auxToSym(x1.Aux)
_ = x1.Args[1]
p1 := x1.Args[0]
if p1.Op != OpARM64ADD {
break
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
if mem != x1.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0, x1, y0, y1)) {
continue
}
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x1.Pos, OpARM64MOVHUloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr0, idx0, mem)
return true
}
break
}
// match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
// cond: x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, y0, y1)
// result: @mergePoint(b,x0,x1) (MOVHUloadidx ptr idx mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 8 {
break
}
y0 := v_0
if y0.Op != OpARM64MOVDnop {
break
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUloadidx {
break
}
mem := x0.Args[2]
ptr := x0.Args[0]
idx := x0.Args[1]
y1 := v_1
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUloadidx {
break
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, y0, y1)) {
break
}
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(v.Pos, OpARM64MOVHUloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr, idx, mem)
return true
}
// match: (ORshiftLL [24] o0:(ORshiftLL [16] x0:(MOVHUload [i0] {s} p mem) y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i3] {s} p mem)))
// cond: i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, y1, y2, o0)
// result: @mergePoint(b,x0,x1,x2) (MOVWUload {s} (OffPtr [int64(i0)] p) mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 24 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
break
}
_ = o0.Args[1]
x0 := o0.Args[0]
if x0.Op != OpARM64MOVHUload {
break
}
i0 := auxIntToInt32(x0.AuxInt)
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o0.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload {
break
}
i2 := auxIntToInt32(x1.AuxInt)
if auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] {
break
}
y2 := v_1
if y2.Op != OpARM64MOVDnop {
break
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload {
break
}
i3 := auxIntToInt32(x2.AuxInt)
if auxToSym(x2.Aux) != s {
break
}
_ = x2.Args[1]
if p != x2.Args[0] || mem != x2.Args[1] || !(i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, y1, y2, o0)) {
break
}
b = mergePoint(b, x0, x1, x2)
v0 := b.NewValue0(x2.Pos, OpARM64MOVWUload, t)
v.copyOf(v0)
v0.Aux = symToAux(s)
v1 := b.NewValue0(x2.Pos, OpOffPtr, p.Type)
v1.AuxInt = int64ToAuxInt(int64(i0))
v1.AddArg(p)
v0.AddArg2(v1, mem)
return true
}
// match: (ORshiftLL [24] o0:(ORshiftLL [16] x0:(MOVHUloadidx ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, y1, y2, o0)
// result: @mergePoint(b,x0,x1,x2) (MOVWUloadidx ptr0 idx0 mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 24 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
break
}
_ = o0.Args[1]
x0 := o0.Args[0]
if x0.Op != OpARM64MOVHUloadidx {
break
}
mem := x0.Args[2]
ptr0 := x0.Args[0]
idx0 := x0.Args[1]
y1 := o0.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 2 {
break
}
s := auxToSym(x1.Aux)
_ = x1.Args[1]
p1 := x1.Args[0]
if p1.Op != OpARM64ADD {
break
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
if mem != x1.Args[1] {
continue
}
y2 := v_1
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 3 || auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
p := x2.Args[0]
if mem != x2.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, y1, y2, o0)) {
continue
}
b = mergePoint(b, x0, x1, x2)
v0 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr0, idx0, mem)
return true
}
break
}
// match: (ORshiftLL [24] o0:(ORshiftLL [16] x0:(MOVHUloadidx ptr idx mem) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, y1, y2, o0)
// result: @mergePoint(b,x0,x1,x2) (MOVWUloadidx ptr idx mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 24 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
break
}
_ = o0.Args[1]
x0 := o0.Args[0]
if x0.Op != OpARM64MOVHUloadidx {
break
}
mem := x0.Args[2]
ptr := x0.Args[0]
idx := x0.Args[1]
y1 := o0.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUloadidx {
break
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 2 || idx != x1_1.Args[0] || mem != x1.Args[2] {
break
}
y2 := v_1
if y2.Op != OpARM64MOVDnop {
break
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUloadidx {
break
}
_ = x2.Args[2]
if ptr != x2.Args[0] {
break
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 3 || idx != x2_1.Args[0] || mem != x2.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, y1, y2, o0)) {
break
}
b = mergePoint(b, x0, x1, x2)
v0 := b.NewValue0(v.Pos, OpARM64MOVWUloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr, idx, mem)
return true
}
// match: (ORshiftLL [24] o0:(ORshiftLL [16] x0:(MOVHUloadidx2 ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADDshiftLL [1] ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && isSamePtr(p1, p) && clobber(x0, x1, x2, y1, y2, o0)
// result: @mergePoint(b,x0,x1,x2) (MOVWUloadidx ptr0 (SLLconst [1] idx0) mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 24 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
break
}
_ = o0.Args[1]
x0 := o0.Args[0]
if x0.Op != OpARM64MOVHUloadidx2 {
break
}
mem := x0.Args[2]
ptr0 := x0.Args[0]
idx0 := x0.Args[1]
y1 := o0.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 2 {
break
}
s := auxToSym(x1.Aux)
_ = x1.Args[1]
p1 := x1.Args[0]
if p1.Op != OpARM64ADDshiftLL || auxIntToInt64(p1.AuxInt) != 1 {
break
}
idx1 := p1.Args[1]
ptr1 := p1.Args[0]
if mem != x1.Args[1] {
break
}
y2 := v_1
if y2.Op != OpARM64MOVDnop {
break
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 3 || auxToSym(x2.Aux) != s {
break
}
_ = x2.Args[1]
p := x2.Args[0]
if mem != x2.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && isSamePtr(p1, p) && clobber(x0, x1, x2, y1, y2, o0)) {
break
}
b = mergePoint(b, x0, x1, x2)
v0 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t)
v.copyOf(v0)
v1 := b.NewValue0(x2.Pos, OpARM64SLLconst, idx0.Type)
v1.AuxInt = int64ToAuxInt(1)
v1.AddArg(idx0)
v0.AddArg3(ptr0, v1, mem)
return true
}
// match: (ORshiftLL [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUload [i0] {s} p mem) y1:(MOVDnop x1:(MOVBUload [i4] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i6] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i7] {s} p mem)))
// cond: i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
// result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDload {s} (OffPtr [int64(i0)] p) mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 56 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
break
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
break
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
break
}
_ = o2.Args[1]
x0 := o2.Args[0]
if x0.Op != OpARM64MOVWUload {
break
}
i0 := auxIntToInt32(x0.AuxInt)
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o2.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload {
break
}
i4 := auxIntToInt32(x1.AuxInt)
if auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] {
break
}
y2 := o1.Args[1]
if y2.Op != OpARM64MOVDnop {
break
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload {
break
}
i5 := auxIntToInt32(x2.AuxInt)
if auxToSym(x2.Aux) != s {
break
}
_ = x2.Args[1]
if p != x2.Args[0] || mem != x2.Args[1] {
break
}
y3 := o0.Args[1]
if y3.Op != OpARM64MOVDnop {
break
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload {
break
}
i6 := auxIntToInt32(x3.AuxInt)
if auxToSym(x3.Aux) != s {
break
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] {
break
}
y4 := v_1
if y4.Op != OpARM64MOVDnop {
break
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUload {
break
}
i7 := auxIntToInt32(x4.AuxInt)
if auxToSym(x4.Aux) != s {
break
}
_ = x4.Args[1]
if p != x4.Args[0] || mem != x4.Args[1] || !(i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)) {
break
}
b = mergePoint(b, x0, x1, x2, x3, x4)
v0 := b.NewValue0(x4.Pos, OpARM64MOVDload, t)
v.copyOf(v0)
v0.Aux = symToAux(s)
v1 := b.NewValue0(x4.Pos, OpOffPtr, p.Type)
v1.AuxInt = int64ToAuxInt(int64(i0))
v1.AddArg(p)
v0.AddArg2(v1, mem)
return true
}
// match: (ORshiftLL [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [6] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
// result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx ptr0 idx0 mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 56 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
break
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
break
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
break
}
_ = o2.Args[1]
x0 := o2.Args[0]
if x0.Op != OpARM64MOVWUloadidx {
break
}
mem := x0.Args[2]
ptr0 := x0.Args[0]
idx0 := x0.Args[1]
y1 := o2.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 4 {
break
}
s := auxToSym(x1.Aux)
_ = x1.Args[1]
p1 := x1.Args[0]
if p1.Op != OpARM64ADD {
break
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
if mem != x1.Args[1] {
continue
}
y2 := o1.Args[1]
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 5 || auxToSym(x2.Aux) != s {
continue
}
_ = x2.Args[1]
p := x2.Args[0]
if mem != x2.Args[1] {
continue
}
y3 := o0.Args[1]
if y3.Op != OpARM64MOVDnop {
continue
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 6 || auxToSym(x3.Aux) != s {
continue
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] {
continue
}
y4 := v_1
if y4.Op != OpARM64MOVDnop {
continue
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUload || auxIntToInt32(x4.AuxInt) != 7 || auxToSym(x4.Aux) != s {
continue
}
_ = x4.Args[1]
if p != x4.Args[0] || mem != x4.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)) {
continue
}
b = mergePoint(b, x0, x1, x2, x3, x4)
v0 := b.NewValue0(x4.Pos, OpARM64MOVDloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr0, idx0, mem)
return true
}
break
}
// match: (ORshiftLL [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx4 ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADDshiftLL [2] ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [6] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
// result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx ptr0 (SLLconst [2] idx0) mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 56 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
break
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
break
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
break
}
_ = o2.Args[1]
x0 := o2.Args[0]
if x0.Op != OpARM64MOVWUloadidx4 {
break
}
mem := x0.Args[2]
ptr0 := x0.Args[0]
idx0 := x0.Args[1]
y1 := o2.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 4 {
break
}
s := auxToSym(x1.Aux)
_ = x1.Args[1]
p1 := x1.Args[0]
if p1.Op != OpARM64ADDshiftLL || auxIntToInt64(p1.AuxInt) != 2 {
break
}
idx1 := p1.Args[1]
ptr1 := p1.Args[0]
if mem != x1.Args[1] {
break
}
y2 := o1.Args[1]
if y2.Op != OpARM64MOVDnop {
break
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload || auxIntToInt32(x2.AuxInt) != 5 || auxToSym(x2.Aux) != s {
break
}
_ = x2.Args[1]
p := x2.Args[0]
if mem != x2.Args[1] {
break
}
y3 := o0.Args[1]
if y3.Op != OpARM64MOVDnop {
break
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUload || auxIntToInt32(x3.AuxInt) != 6 || auxToSym(x3.Aux) != s {
break
}
_ = x3.Args[1]
if p != x3.Args[0] || mem != x3.Args[1] {
break
}
y4 := v_1
if y4.Op != OpARM64MOVDnop {
break
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUload || auxIntToInt32(x4.AuxInt) != 7 || auxToSym(x4.Aux) != s {
break
}
_ = x4.Args[1]
if p != x4.Args[0] || mem != x4.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && isSamePtr(p1, p) && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)) {
break
}
b = mergePoint(b, x0, x1, x2, x3, x4)
v0 := b.NewValue0(x4.Pos, OpARM64MOVDloadidx, t)
v.copyOf(v0)
v1 := b.NewValue0(x4.Pos, OpARM64SLLconst, idx0.Type)
v1.AuxInt = int64ToAuxInt(2)
v1.AddArg(idx0)
v0.AddArg3(ptr0, v1, mem)
return true
}
// match: (ORshiftLL [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx ptr idx mem) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [4] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [6] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
// result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx ptr idx mem)
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 56 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 48 {
break
}
_ = o0.Args[1]
o1 := o0.Args[0]
if o1.Op != OpARM64ORshiftLL || auxIntToInt64(o1.AuxInt) != 40 {
break
}
_ = o1.Args[1]
o2 := o1.Args[0]
if o2.Op != OpARM64ORshiftLL || auxIntToInt64(o2.AuxInt) != 32 {
break
}
_ = o2.Args[1]
x0 := o2.Args[0]
if x0.Op != OpARM64MOVWUloadidx {
break
}
mem := x0.Args[2]
ptr := x0.Args[0]
idx := x0.Args[1]
y1 := o2.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUloadidx {
break
}
_ = x1.Args[2]
if ptr != x1.Args[0] {
break
}
x1_1 := x1.Args[1]
if x1_1.Op != OpARM64ADDconst || auxIntToInt64(x1_1.AuxInt) != 4 || idx != x1_1.Args[0] || mem != x1.Args[2] {
break
}
y2 := o1.Args[1]
if y2.Op != OpARM64MOVDnop {
break
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUloadidx {
break
}
_ = x2.Args[2]
if ptr != x2.Args[0] {
break
}
x2_1 := x2.Args[1]
if x2_1.Op != OpARM64ADDconst || auxIntToInt64(x2_1.AuxInt) != 5 || idx != x2_1.Args[0] || mem != x2.Args[2] {
break
}
y3 := o0.Args[1]
if y3.Op != OpARM64MOVDnop {
break
}
x3 := y3.Args[0]
if x3.Op != OpARM64MOVBUloadidx {
break
}
_ = x3.Args[2]
if ptr != x3.Args[0] {
break
}
x3_1 := x3.Args[1]
if x3_1.Op != OpARM64ADDconst || auxIntToInt64(x3_1.AuxInt) != 6 || idx != x3_1.Args[0] || mem != x3.Args[2] {
break
}
y4 := v_1
if y4.Op != OpARM64MOVDnop {
break
}
x4 := y4.Args[0]
if x4.Op != OpARM64MOVBUloadidx {
break
}
_ = x4.Args[2]
if ptr != x4.Args[0] {
break
}
x4_1 := x4.Args[1]
if x4_1.Op != OpARM64ADDconst || auxIntToInt64(x4_1.AuxInt) != 7 || idx != x4_1.Args[0] || mem != x4.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)) {
break
}
b = mergePoint(b, x0, x1, x2, x3, x4)
v0 := b.NewValue0(v.Pos, OpARM64MOVDloadidx, t)
v.copyOf(v0)
v0.AddArg3(ptr, idx, mem)
return true
}
// match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUload [i1] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [i0] {s} p mem)))
// cond: i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, y0, y1)
// result: @mergePoint(b,x0,x1) (REV16W (MOVHUload [i0] {s} p mem))
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 8 {
break
}
y0 := v_0
if y0.Op != OpARM64MOVDnop {
break
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUload {
break
}
i1 := auxIntToInt32(x0.AuxInt)
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := v_1
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload {
break
}
i0 := auxIntToInt32(x1.AuxInt)
if auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] || !(i1 == i0+1 && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, y0, y1)) {
break
}
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x1.Pos, OpARM64REV16W, t)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpARM64MOVHUload, t)
v1.AuxInt = int32ToAuxInt(i0)
v1.Aux = symToAux(s)
v1.AddArg2(p, mem)
v0.AddArg(v1)
return true
}
// match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr0 idx0 mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0, x1, y0, y1)
// result: @mergePoint(b,x0,x1) (REV16W (MOVHUloadidx ptr0 idx0 mem))
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 8 {
break
}
y0 := v_0
if y0.Op != OpARM64MOVDnop {
break
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUload || auxIntToInt32(x0.AuxInt) != 1 {
break
}
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p1 := x0.Args[0]
if p1.Op != OpARM64ADD {
break
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
y1 := v_1
if y1.Op != OpARM64MOVDnop {
continue
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUloadidx {
continue
}
_ = x1.Args[2]
ptr0 := x1.Args[0]
idx0 := x1.Args[1]
if mem != x1.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0, x1, y0, y1)) {
continue
}
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(x0.Pos, OpARM64REV16W, t)
v.copyOf(v0)
v1 := b.NewValue0(x0.Pos, OpARM64MOVHUloadidx, t)
v1.AddArg3(ptr0, idx0, mem)
v0.AddArg(v1)
return true
}
break
}
// match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [1] idx) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr idx mem)))
// cond: x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0, x1, y0, y1)
// result: @mergePoint(b,x0,x1) (REV16W (MOVHUloadidx ptr idx mem))
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 8 {
break
}
y0 := v_0
if y0.Op != OpARM64MOVDnop {
break
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVBUloadidx {
break
}
mem := x0.Args[2]
ptr := x0.Args[0]
x0_1 := x0.Args[1]
if x0_1.Op != OpARM64ADDconst || auxIntToInt64(x0_1.AuxInt) != 1 {
break
}
idx := x0_1.Args[0]
y1 := v_1
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUloadidx {
break
}
_ = x1.Args[2]
if ptr != x1.Args[0] || idx != x1.Args[1] || mem != x1.Args[2] || !(x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && clobber(x0, x1, y0, y1)) {
break
}
b = mergePoint(b, x0, x1)
v0 := b.NewValue0(v.Pos, OpARM64REV16W, t)
v.copyOf(v0)
v1 := b.NewValue0(v.Pos, OpARM64MOVHUloadidx, t)
v1.AddArg3(ptr, idx, mem)
v0.AddArg(v1)
return true
}
// match: (ORshiftLL [24] o0:(ORshiftLL [16] y0:(REV16W x0:(MOVHUload [i2] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i0] {s} p mem)))
// cond: i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, y0, y1, y2, o0)
// result: @mergePoint(b,x0,x1,x2) (REVW (MOVWUload {s} (OffPtr [int64(i0)] p) mem))
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 24 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
break
}
_ = o0.Args[1]
y0 := o0.Args[0]
if y0.Op != OpARM64REV16W {
break
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVHUload {
break
}
i2 := auxIntToInt32(x0.AuxInt)
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o0.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload {
break
}
i1 := auxIntToInt32(x1.AuxInt)
if auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[1]
if p != x1.Args[0] || mem != x1.Args[1] {
break
}
y2 := v_1
if y2.Op != OpARM64MOVDnop {
break
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUload {
break
}
i0 := auxIntToInt32(x2.AuxInt)
if auxToSym(x2.Aux) != s {
break
}
_ = x2.Args[1]
if p != x2.Args[0] || mem != x2.Args[1] || !(i1 == i0+1 && i2 == i0+2 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && clobber(x0, x1, x2, y0, y1, y2, o0)) {
break
}
b = mergePoint(b, x0, x1, x2)
v0 := b.NewValue0(x2.Pos, OpARM64REVW, t)
v.copyOf(v0)
v1 := b.NewValue0(x2.Pos, OpARM64MOVWUload, t)
v1.Aux = symToAux(s)
v2 := b.NewValue0(x2.Pos, OpOffPtr, p.Type)
v2.AuxInt = int64ToAuxInt(int64(i0))
v2.AddArg(p)
v1.AddArg2(v2, mem)
v0.AddArg(v1)
return true
}
// match: (ORshiftLL [24] o0:(ORshiftLL [16] y0:(REV16W x0:(MOVHUload [2] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr0 idx0 mem)))
// cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, y0, y1, y2, o0)
// result: @mergePoint(b,x0,x1,x2) (REVW (MOVWUloadidx ptr0 idx0 mem))
for {
t := v.Type
if auxIntToInt64(v.AuxInt) != 24 {
break
}
o0 := v_0
if o0.Op != OpARM64ORshiftLL || auxIntToInt64(o0.AuxInt) != 16 {
break
}
_ = o0.Args[1]
y0 := o0.Args[0]
if y0.Op != OpARM64REV16W {
break
}
x0 := y0.Args[0]
if x0.Op != OpARM64MOVHUload || auxIntToInt32(x0.AuxInt) != 2 {
break
}
s := auxToSym(x0.Aux)
mem := x0.Args[1]
p := x0.Args[0]
y1 := o0.Args[1]
if y1.Op != OpARM64MOVDnop {
break
}
x1 := y1.Args[0]
if x1.Op != OpARM64MOVBUload || auxIntToInt32(x1.AuxInt) != 1 || auxToSym(x1.Aux) != s {
break
}
_ = x1.Args[1]
p1 := x1.Args[0]
if p1.Op != OpARM64ADD {
break
}
_ = p1.Args[1]
p1_0 := p1.Args[0]
p1_1 := p1.Args[1]
for _i0 := 0; _i0 <= 1; _i0, p1_0, p1_1 = _i0+1, p1_1, p1_0 {
ptr1 := p1_0
idx1 := p1_1
if mem != x1.Args[1] {
continue
}
y2 := v_1
if y2.Op != OpARM64MOVDnop {
continue
}
x2 := y2.Args[0]
if x2.Op != OpARM64MOVBUloadidx {
continue
}
_ = x2.Args[2]
ptr0 := x2.Args[0]
idx0 := x2.Args[1]
if mem != x2.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0, x1, x2, y0, y1, y2, o0)) {
continue
}
b = mergePoint(b, x0, x1, x2)
v0 := b.NewValue0(x1.Pos, OpARM64REVW, t)
v.copyOf(v0)
v1 := b.NewValue0(x1.Pos, OpARM64MOVWUloadidx, t)
v1.AddArg3(ptr0, idx0, mem)
v0.AddArg(v1)
return true
}
break
}
// match: (ORshiftLL [24] o0:(ORshiftLL [16] y0:(REV16W x0:(MOVHUloadidx ptr (ADDconst [2] idx) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr idx mem)))
// cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0, x1, x2, y0, y1, y2, o0)
// result: @mergePoint(b,x0,x1,x2) (REVW (MOVWUloadidx