mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-08-09 21:37:42 +02:00
[chore]: Bump github.com/gin-contrib/gzip from 1.0.0 to 1.0.1 (#2899)
Bumps [github.com/gin-contrib/gzip](https://github.com/gin-contrib/gzip) from 1.0.0 to 1.0.1. - [Release notes](https://github.com/gin-contrib/gzip/releases) - [Changelog](https://github.com/gin-contrib/gzip/blob/master/.goreleaser.yaml) - [Commits](https://github.com/gin-contrib/gzip/compare/v1.0.0...v1.0.1) --- updated-dependencies: - dependency-name: github.com/gin-contrib/gzip dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
30
vendor/github.com/cloudwego/base64x/.gitignore
generated
vendored
Normal file
30
vendor/github.com/cloudwego/base64x/.gitignore
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# the result of the go build
|
||||
output*
|
||||
output/*
|
||||
|
||||
# Files generated by IDEs
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
# Vim swap files
|
||||
*.swp
|
||||
|
||||
# Vscode files
|
||||
.vscode
|
||||
|
37
vendor/github.com/cloudwego/base64x/.golangci.yaml
generated
vendored
Normal file
37
vendor/github.com/cloudwego/base64x/.golangci.yaml
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
# Options for analysis running.
|
||||
run:
|
||||
# include `vendor` `third_party` `testdata` `examples` `Godeps` `builtin`
|
||||
skip-dirs-use-default: true
|
||||
skip-dirs:
|
||||
- kitex_gen
|
||||
skip-files:
|
||||
- ".*\\.mock\\.go$"
|
||||
# output configuration options
|
||||
output:
|
||||
# Format: colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions
|
||||
format: colored-line-number
|
||||
# All available settings of specific linters.
|
||||
# Refer to https://golangci-lint.run/usage/linters
|
||||
linters-settings:
|
||||
gofumpt:
|
||||
# Choose whether to use the extra rules.
|
||||
# Default: false
|
||||
extra-rules: true
|
||||
govet:
|
||||
# Disable analyzers by name.
|
||||
# Run `go tool vet help` to see all analyzers.
|
||||
disable:
|
||||
- stdmethods
|
||||
linters:
|
||||
enable:
|
||||
- gofumpt
|
||||
- goimports
|
||||
- gofmt
|
||||
disable:
|
||||
- errcheck
|
||||
- typecheck
|
||||
- deadcode
|
||||
- varcheck
|
||||
- staticcheck
|
||||
issues:
|
||||
exclude-use-default: true
|
14
vendor/github.com/cloudwego/base64x/.licenserc.yaml
generated
vendored
Normal file
14
vendor/github.com/cloudwego/base64x/.licenserc.yaml
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
header:
|
||||
license:
|
||||
spdx-id: Apache-2.0
|
||||
copyright-owner: CloudWeGo Authors
|
||||
|
||||
paths:
|
||||
- '**/*.go'
|
||||
- '**/*.s'
|
||||
|
||||
paths-ignore:
|
||||
- 'native_subr_amd64.go'
|
||||
- 'native_text_amd64.go'
|
||||
|
||||
comment: on-failure
|
128
vendor/github.com/cloudwego/base64x/CODE_OF_CONDUCT.md
generated
vendored
Normal file
128
vendor/github.com/cloudwego/base64x/CODE_OF_CONDUCT.md
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
conduct@cloudwego.io.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
55
vendor/github.com/cloudwego/base64x/CONTRIBUTING.md
generated
vendored
Normal file
55
vendor/github.com/cloudwego/base64x/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
# How to Contribute
|
||||
|
||||
## Your First Pull Request
|
||||
We use github for our codebase. You can start by reading [How To Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests).
|
||||
|
||||
## Branch Organization
|
||||
We use [git-flow](https://nvie.com/posts/a-successful-git-branching-model/) as our branch organization, as known as [FDD](https://en.wikipedia.org/wiki/Feature-driven_development)
|
||||
|
||||
## Bugs
|
||||
### 1. How to Find Known Issues
|
||||
We are using [Github Issues](https://github.com/cloudwego/kitex/issues) for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn’t already exist.
|
||||
|
||||
### 2. Reporting New Issues
|
||||
Providing a reduced test code is a recommended way for reporting issues. Then can placed in:
|
||||
- Just in issues
|
||||
- [Golang Playground](https://play.golang.org/)
|
||||
|
||||
### 3. Security Bugs
|
||||
Please do not report the safe disclosure of bugs to public issues. Contact us by [Support Email](mailto:conduct@cloudwego.io)
|
||||
|
||||
## How to Get in Touch
|
||||
- [Email](mailto:conduct@cloudwego.io)
|
||||
|
||||
## Submit a Pull Request
|
||||
Before you submit your Pull Request (PR) consider the following guidelines:
|
||||
1. Search [GitHub](https://github.com/cloudwego/kitex/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate existing efforts.
|
||||
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add. Discussing the design upfront helps to ensure that we're ready to accept your work.
|
||||
3. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the cloudwego/kitex repo.
|
||||
4. In your forked repository, make your changes in a new git branch:
|
||||
```
|
||||
git checkout -b my-fix-branch develop
|
||||
```
|
||||
5. Create your patch, including appropriate test cases.
|
||||
6. Follow our [Style Guides](#code-style-guides).
|
||||
7. Commit your changes using a descriptive commit message that follows [AngularJS Git Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit).
|
||||
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
|
||||
8. Push your branch to GitHub:
|
||||
```
|
||||
git push origin my-fix-branch
|
||||
```
|
||||
9. In GitHub, send a pull request to `kitex:develop`
|
||||
|
||||
## Contribution Prerequisites
|
||||
- Our development environment keeps up with [Go Official](https://golang.org/project/).
|
||||
- You need fully checking with lint tools before submit your pull request. [gofmt](https://golang.org/pkg/cmd/gofmt/) and [golangci-lint](https://github.com/golangci/golangci-lint)
|
||||
- You are familiar with [Github](https://github.com)
|
||||
- Maybe you need familiar with [Actions](https://github.com/features/actions)(our default workflow tool).
|
||||
|
||||
## Code Style Guides
|
||||
Also see [Pingcap General advice](https://pingcap.github.io/style-guide/general.html).
|
||||
|
||||
Good resources:
|
||||
- [Effective Go](https://golang.org/doc/effective_go)
|
||||
- [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
|
||||
- [Uber Go Style Guide](https://github.com/uber-go/guide/blob/master/style.md)
|
201
vendor/github.com/cloudwego/base64x/LICENSE
generated
vendored
Normal file
201
vendor/github.com/cloudwego/base64x/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
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.
|
177
vendor/github.com/cloudwego/base64x/LICENSE-APACHE
generated
vendored
Normal file
177
vendor/github.com/cloudwego/base64x/LICENSE-APACHE
generated
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
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
|
||||
|
29
vendor/github.com/cloudwego/base64x/Makefile
generated
vendored
Normal file
29
vendor/github.com/cloudwego/base64x/Makefile
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
.PHONY: all clean
|
||||
|
||||
CFLAGS := -mavx
|
||||
CFLAGS += -mavx2
|
||||
CFLAGS += -mno-bmi
|
||||
CFLAGS += -mno-red-zone
|
||||
CFLAGS += -fno-asynchronous-unwind-tables
|
||||
CFLAGS += -fno-stack-protector
|
||||
CFLAGS += -fno-exceptions
|
||||
CFLAGS += -fno-builtin
|
||||
CFLAGS += -fno-rtti
|
||||
CFLAGS += -nostdlib
|
||||
CFLAGS += -O3
|
||||
|
||||
NATIVE_ASM := $(wildcard native/*.S)
|
||||
NATIVE_SRC := $(wildcard native/*.h)
|
||||
NATIVE_SRC += $(wildcard native/*.c)
|
||||
|
||||
all: native_amd64.s
|
||||
|
||||
clean:
|
||||
rm -vf native_text_amd64.go native_subr_amd64.go output/*.s
|
||||
|
||||
native_amd64.s: ${NATIVE_SRC} ${NATIVE_ASM} native_amd64.go
|
||||
mkdir -p output
|
||||
clang ${CFLAGS} -S -o output/native.s native/native.c
|
||||
python3 tools/asm2asm/asm2asm.py -r native_amd64.go output/native.s ${NATIVE_ASM}
|
||||
awk '{gsub(/Text__native_entry__/, "text__native_entry__")}1' native_text_amd64.go > native_text_amd64.go.tmp && mv native_text_amd64.go.tmp native_text_amd64.go
|
||||
awk '{gsub(/Funcs/, "funcs")}1' native_subr_amd64.go > native_subr_amd64.go.tmp && mv native_subr_amd64.go.tmp native_subr_amd64.go
|
4
vendor/github.com/cloudwego/base64x/README.md
generated
vendored
Normal file
4
vendor/github.com/cloudwego/base64x/README.md
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# base64x
|
||||
|
||||
High performance drop-in replacement of the `encoding/base64` library.
|
||||
|
4
vendor/github.com/cloudwego/base64x/_typos.toml
generated
vendored
Normal file
4
vendor/github.com/cloudwego/base64x/_typos.toml
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Typo check: https://github.com/crate-ci/typos
|
||||
|
||||
[files]
|
||||
extend-exclude = ["go.mod", "go.sum", "check_branch_name.sh"]
|
167
vendor/github.com/cloudwego/base64x/base64x.go
generated
vendored
Normal file
167
vendor/github.com/cloudwego/base64x/base64x.go
generated
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2024 CloudWeGo Authors
|
||||
*
|
||||
* 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 base64x
|
||||
|
||||
import (
|
||||
`encoding/base64`
|
||||
)
|
||||
|
||||
// An Encoding is a radix 64 encoding/decoding scheme, defined by a
|
||||
// 64-character alphabet. The most common encoding is the "base64"
|
||||
// encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM
|
||||
// (RFC 1421). RFC 4648 also defines an alternate encoding, which is
|
||||
// the standard encoding with - and _ substituted for + and /.
|
||||
type Encoding int
|
||||
|
||||
const (
|
||||
_MODE_URL = 1 << 0
|
||||
_MODE_RAW = 1 << 1
|
||||
_MODE_AVX2 = 1 << 2
|
||||
_MODE_JSON = 1 << 3
|
||||
)
|
||||
|
||||
// StdEncoding is the standard base64 encoding, as defined in
|
||||
// RFC 4648.
|
||||
const StdEncoding Encoding = 0
|
||||
|
||||
// URLEncoding is the alternate base64 encoding defined in RFC 4648.
|
||||
// It is typically used in URLs and file names.
|
||||
const URLEncoding Encoding = _MODE_URL
|
||||
|
||||
// RawStdEncoding is the standard raw, unpadded base64 encoding,
|
||||
// as defined in RFC 4648 section 3.2.
|
||||
//
|
||||
// This is the same as StdEncoding but omits padding characters.
|
||||
const RawStdEncoding Encoding = _MODE_RAW
|
||||
|
||||
// RawURLEncoding is the unpadded alternate base64 encoding defined in RFC 4648.
|
||||
// It is typically used in URLs and file names.
|
||||
//
|
||||
// This is the same as URLEncoding but omits padding characters.
|
||||
const RawURLEncoding Encoding = _MODE_RAW | _MODE_URL
|
||||
|
||||
// JSONStdEncoding is the StdEncoding and encoded as JSON string as RFC 8259.
|
||||
const JSONStdEncoding Encoding = _MODE_JSON;
|
||||
|
||||
var (
|
||||
archFlags = 0
|
||||
)
|
||||
|
||||
/** Encoder Functions **/
|
||||
|
||||
// Encode encodes src using the specified encoding, writing
|
||||
// EncodedLen(len(src)) bytes to out.
|
||||
//
|
||||
// The encoding pads the output to a multiple of 4 bytes,
|
||||
// so Encode is not appropriate for use on individual blocks
|
||||
// of a large data stream.
|
||||
//
|
||||
// If out is not large enough to contain the encoded result,
|
||||
// it will panic.
|
||||
func (self Encoding) Encode(out []byte, src []byte) {
|
||||
if len(src) != 0 {
|
||||
if buf := out[:0:len(out)]; self.EncodedLen(len(src)) <= len(out) {
|
||||
self.EncodeUnsafe(&buf, src)
|
||||
} else {
|
||||
panic("encoder output buffer is too small")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EncodeUnsafe behaves like Encode, except it does NOT check if
|
||||
// out is large enough to contain the encoded result.
|
||||
//
|
||||
// It will also update the length of out.
|
||||
func (self Encoding) EncodeUnsafe(out *[]byte, src []byte) {
|
||||
b64encode(out, &src, int(self) | archFlags)
|
||||
}
|
||||
|
||||
// EncodeToString returns the base64 encoding of src.
|
||||
func (self Encoding) EncodeToString(src []byte) string {
|
||||
nbs := len(src)
|
||||
ret := make([]byte, 0, self.EncodedLen(nbs))
|
||||
|
||||
/* encode in native code */
|
||||
self.EncodeUnsafe(&ret, src)
|
||||
return mem2str(ret)
|
||||
}
|
||||
|
||||
// EncodedLen returns the length in bytes of the base64 encoding
|
||||
// of an input buffer of length n.
|
||||
func (self Encoding) EncodedLen(n int) int {
|
||||
if (self & _MODE_RAW) == 0 {
|
||||
return (n + 2) / 3 * 4
|
||||
} else {
|
||||
return (n * 8 + 5) / 6
|
||||
}
|
||||
}
|
||||
|
||||
/** Decoder Functions **/
|
||||
|
||||
// Decode decodes src using the encoding enc. It writes at most
|
||||
// DecodedLen(len(src)) bytes to out and returns the number of bytes
|
||||
// written. If src contains invalid base64 data, it will return the
|
||||
// number of bytes successfully written and base64.CorruptInputError.
|
||||
//
|
||||
// New line characters (\r and \n) are ignored.
|
||||
//
|
||||
// If out is not large enough to contain the encoded result,
|
||||
// it will panic.
|
||||
func (self Encoding) Decode(out []byte, src []byte) (int, error) {
|
||||
if len(src) == 0 {
|
||||
return 0, nil
|
||||
} else if buf := out[:0:len(out)]; self.DecodedLen(len(src)) <= len(out) {
|
||||
return self.DecodeUnsafe(&buf, src)
|
||||
} else {
|
||||
panic("decoder output buffer is too small")
|
||||
}
|
||||
}
|
||||
|
||||
// DecodeUnsafe behaves like Decode, except it does NOT check if
|
||||
// out is large enough to contain the decoded result.
|
||||
//
|
||||
// It will also update the length of out.
|
||||
func (self Encoding) DecodeUnsafe(out *[]byte, src []byte) (int, error) {
|
||||
if n := b64decode(out, mem2addr(src), len(src), int(self) | archFlags); n >= 0 {
|
||||
return n, nil
|
||||
} else {
|
||||
return 0, base64.CorruptInputError(-n - 1)
|
||||
}
|
||||
}
|
||||
|
||||
// DecodeString returns the bytes represented by the base64 string s.
|
||||
func (self Encoding) DecodeString(s string) ([]byte, error) {
|
||||
src := str2mem(s)
|
||||
ret := make([]byte, 0, self.DecodedLen(len(s)))
|
||||
|
||||
/* decode into the allocated buffer */
|
||||
if _, err := self.DecodeUnsafe(&ret, src); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return ret, nil
|
||||
}
|
||||
}
|
||||
|
||||
// DecodedLen returns the maximum length in bytes of the decoded data
|
||||
// corresponding to n bytes of base64-encoded data.
|
||||
func (self Encoding) DecodedLen(n int) int {
|
||||
if (self & _MODE_RAW) == 0 {
|
||||
return n / 4 * 3
|
||||
} else {
|
||||
return n * 6 / 8
|
||||
}
|
||||
}
|
10
vendor/github.com/cloudwego/base64x/check_branch_name.sh
generated
vendored
Normal file
10
vendor/github.com/cloudwego/base64x/check_branch_name.sh
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
current=$(git status | head -n1 | sed 's/On branch //')
|
||||
name=${1:-$current}
|
||||
if [[ ! $name =~ ^(((opt(imize)?|feat(ure)?|(bug|hot)?fix|test|refact(or)?|ci)/.+)|(main|develop)|(release-v[0-9]+\.[0-9]+)|(release/v[0-9]+\.[0-9]+\.[0-9]+(-[a-z0-9.]+(\+[a-z0-9.]+)?)?)|revert-[a-z0-9]+)$ ]]; then
|
||||
echo "branch name '$name' is invalid"
|
||||
exit 1
|
||||
else
|
||||
echo "branch name '$name' is valid"
|
||||
fi
|
33
vendor/github.com/cloudwego/base64x/cpuid.go
generated
vendored
Normal file
33
vendor/github.com/cloudwego/base64x/cpuid.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2024 CloudWeGo Authors
|
||||
*
|
||||
* 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 base64x
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
`os`
|
||||
|
||||
`github.com/klauspost/cpuid/v2`
|
||||
)
|
||||
|
||||
func hasAVX2() bool {
|
||||
switch v := os.Getenv("B64X_MODE"); v {
|
||||
case "" : fallthrough
|
||||
case "auto" : return cpuid.CPU.Has(cpuid.AVX2)
|
||||
case "noavx2" : return false
|
||||
default : panic(fmt.Sprintf("invalid mode: '%s', should be one of 'auto', 'noavx2'", v))
|
||||
}
|
||||
}
|
51
vendor/github.com/cloudwego/base64x/faststr.go
generated
vendored
Normal file
51
vendor/github.com/cloudwego/base64x/faststr.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2024 CloudWeGo Authors
|
||||
*
|
||||
* 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 base64x
|
||||
|
||||
import (
|
||||
`reflect`
|
||||
`unsafe`
|
||||
)
|
||||
|
||||
func mem2str(v []byte) (s string) {
|
||||
(*reflect.StringHeader)(unsafe.Pointer(&s)).Len = (*reflect.SliceHeader)(unsafe.Pointer(&v)).Len
|
||||
(*reflect.StringHeader)(unsafe.Pointer(&s)).Data = (*reflect.SliceHeader)(unsafe.Pointer(&v)).Data
|
||||
return
|
||||
}
|
||||
|
||||
func str2mem(s string) (v []byte) {
|
||||
(*reflect.SliceHeader)(unsafe.Pointer(&v)).Cap = (*reflect.StringHeader)(unsafe.Pointer(&s)).Len
|
||||
(*reflect.SliceHeader)(unsafe.Pointer(&v)).Len = (*reflect.StringHeader)(unsafe.Pointer(&s)).Len
|
||||
(*reflect.SliceHeader)(unsafe.Pointer(&v)).Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
|
||||
return
|
||||
}
|
||||
|
||||
func mem2addr(v []byte) unsafe.Pointer {
|
||||
return *(*unsafe.Pointer)(unsafe.Pointer(&v))
|
||||
}
|
||||
|
||||
// NoEscape hides a pointer from escape analysis. NoEscape is
|
||||
// the identity function but escape analysis doesn't think the
|
||||
// output depends on the input. NoEscape is inlined and currently
|
||||
// compiles down to zero instructions.
|
||||
// USE CAREFULLY!
|
||||
//go:nosplit
|
||||
//goland:noinspection GoVetUnsafePointer
|
||||
func noEscape(p unsafe.Pointer) unsafe.Pointer {
|
||||
x := uintptr(p)
|
||||
return unsafe.Pointer(x ^ 0)
|
||||
}
|
58
vendor/github.com/cloudwego/base64x/native_amd64.go
generated
vendored
Normal file
58
vendor/github.com/cloudwego/base64x/native_amd64.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2024 CloudWeGo Authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//go:generate make
|
||||
package base64x
|
||||
|
||||
import (
|
||||
`unsafe`
|
||||
|
||||
`github.com/bytedance/sonic/loader`
|
||||
)
|
||||
|
||||
//go:nosplit
|
||||
func b64encode(out *[]byte, src *[]byte, mode int) {
|
||||
__b64encode(noEscape(unsafe.Pointer(out)), noEscape(unsafe.Pointer(src)), mode)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func b64decode(out *[]byte, src unsafe.Pointer, len int, mode int) (ret int) {
|
||||
return __b64decode(noEscape(unsafe.Pointer(out)), noEscape(unsafe.Pointer(src)), len, mode)
|
||||
}
|
||||
|
||||
// asm2asm templates
|
||||
var (
|
||||
__b64encode func(out unsafe.Pointer, src unsafe.Pointer, mod int)
|
||||
__b64decode func(out unsafe.Pointer, src unsafe.Pointer, len int, mod int) (ret int)
|
||||
)
|
||||
|
||||
// directly jump PCs
|
||||
var (
|
||||
_subr__b64encode uintptr
|
||||
_subr__b64decode uintptr
|
||||
)
|
||||
|
||||
var stubs = []loader.GoC{
|
||||
{"_b64encode", &_subr__b64encode, &__b64encode},
|
||||
{"_b64decode", &_subr__b64decode, &__b64decode},
|
||||
}
|
||||
|
||||
func init() {
|
||||
if hasAVX2() {
|
||||
archFlags = _MODE_AVX2
|
||||
}
|
||||
loader.WrapGoC(text__native_entry__, funcs, stubs, "base64x", "base64x/native.c")
|
||||
}
|
63
vendor/github.com/cloudwego/base64x/native_subr_amd64.go
generated
vendored
Normal file
63
vendor/github.com/cloudwego/base64x/native_subr_amd64.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
// +build !noasm !appengine
|
||||
// Code generated by asm2asm, DO NOT EDIT.
|
||||
|
||||
package base64x
|
||||
|
||||
import (
|
||||
`github.com/bytedance/sonic/loader`
|
||||
)
|
||||
|
||||
const (
|
||||
_entry__b64decode = 1328
|
||||
_entry__b64encode = 256
|
||||
)
|
||||
|
||||
const (
|
||||
_stack__b64decode = 152
|
||||
_stack__b64encode = 40
|
||||
)
|
||||
|
||||
const (
|
||||
_size__b64decode = 17616
|
||||
_size__b64encode = 864
|
||||
)
|
||||
|
||||
var (
|
||||
_pcsp__b64decode = [][2]uint32{
|
||||
{1, 0},
|
||||
{4, 8},
|
||||
{6, 16},
|
||||
{8, 24},
|
||||
{10, 32},
|
||||
{12, 40},
|
||||
{13, 48},
|
||||
{17560, 152},
|
||||
{17564, 48},
|
||||
{17565, 40},
|
||||
{17567, 32},
|
||||
{17569, 24},
|
||||
{17571, 16},
|
||||
{17573, 8},
|
||||
{17577, 0},
|
||||
{17608, 152},
|
||||
}
|
||||
_pcsp__b64encode = [][2]uint32{
|
||||
{1, 0},
|
||||
{4, 8},
|
||||
{6, 16},
|
||||
{8, 24},
|
||||
{10, 32},
|
||||
{852, 40},
|
||||
{853, 32},
|
||||
{855, 24},
|
||||
{857, 16},
|
||||
{859, 8},
|
||||
{864, 0},
|
||||
}
|
||||
)
|
||||
|
||||
var funcs = []loader.CFunc{
|
||||
{"__native_entry__", 0, 67, 0, nil},
|
||||
{"_b64decode", _entry__b64decode, _size__b64decode, _stack__b64decode, _pcsp__b64decode},
|
||||
{"_b64encode", _entry__b64encode, _size__b64encode, _stack__b64encode, _pcsp__b64encode},
|
||||
}
|
5305
vendor/github.com/cloudwego/base64x/native_text_amd64.go
generated
vendored
Normal file
5305
vendor/github.com/cloudwego/base64x/native_text_amd64.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
177
vendor/github.com/cloudwego/iasm/LICENSE-APACHE
generated
vendored
Normal file
177
vendor/github.com/cloudwego/iasm/LICENSE-APACHE
generated
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
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
|
||||
|
261
vendor/github.com/cloudwego/iasm/expr/ast.go
generated
vendored
Normal file
261
vendor/github.com/cloudwego/iasm/expr/ast.go
generated
vendored
Normal file
@ -0,0 +1,261 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
)
|
||||
|
||||
// Type is tyep expression type.
|
||||
type Type int
|
||||
|
||||
const (
|
||||
// CONST indicates that the expression is a constant.
|
||||
CONST Type = iota
|
||||
|
||||
// TERM indicates that the expression is a Term reference.
|
||||
TERM
|
||||
|
||||
// EXPR indicates that the expression is a unary or binary expression.
|
||||
EXPR
|
||||
)
|
||||
|
||||
var typeNames = map[Type]string {
|
||||
EXPR : "Expr",
|
||||
TERM : "Term",
|
||||
CONST : "Const",
|
||||
}
|
||||
|
||||
// String returns the string representation of a Type.
|
||||
func (self Type) String() string {
|
||||
if v, ok := typeNames[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
return fmt.Sprintf("expr.Type(%d)", self)
|
||||
}
|
||||
}
|
||||
|
||||
// Operator represents an operation to perform when Type is EXPR.
|
||||
type Operator uint8
|
||||
|
||||
const (
|
||||
// ADD performs "Add Expr.Left and Expr.Right".
|
||||
ADD Operator = iota
|
||||
|
||||
// SUB performs "Subtract Expr.Left by Expr.Right".
|
||||
SUB
|
||||
|
||||
// MUL performs "Multiply Expr.Left by Expr.Right".
|
||||
MUL
|
||||
|
||||
// DIV performs "Divide Expr.Left by Expr.Right".
|
||||
DIV
|
||||
|
||||
// MOD performs "Modulo Expr.Left by Expr.Right".
|
||||
MOD
|
||||
|
||||
// AND performs "Bitwise AND Expr.Left and Expr.Right".
|
||||
AND
|
||||
|
||||
// OR performs "Bitwise OR Expr.Left and Expr.Right".
|
||||
OR
|
||||
|
||||
// XOR performs "Bitwise XOR Expr.Left and Expr.Right".
|
||||
XOR
|
||||
|
||||
// SHL performs "Bitwise Shift Expr.Left to the Left by Expr.Right Bits".
|
||||
SHL
|
||||
|
||||
// SHR performs "Bitwise Shift Expr.Left to the Right by Expr.Right Bits".
|
||||
SHR
|
||||
|
||||
// POW performs "Raise Expr.Left to the power of Expr.Right"
|
||||
POW
|
||||
|
||||
// NOT performs "Bitwise Invert Expr.Left".
|
||||
NOT
|
||||
|
||||
// NEG performs "Negate Expr.Left".
|
||||
NEG
|
||||
)
|
||||
|
||||
var operatorNames = map[Operator]string {
|
||||
ADD : "Add",
|
||||
SUB : "Subtract",
|
||||
MUL : "Multiply",
|
||||
DIV : "Divide",
|
||||
MOD : "Modulo",
|
||||
AND : "And",
|
||||
OR : "Or",
|
||||
XOR : "ExclusiveOr",
|
||||
SHL : "ShiftLeft",
|
||||
SHR : "ShiftRight",
|
||||
POW : "Power",
|
||||
NOT : "Invert",
|
||||
NEG : "Negate",
|
||||
}
|
||||
|
||||
// String returns the string representation of a Type.
|
||||
func (self Operator) String() string {
|
||||
if v, ok := operatorNames[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
return fmt.Sprintf("expr.Operator(%d)", self)
|
||||
}
|
||||
}
|
||||
|
||||
// Expr represents an expression node.
|
||||
type Expr struct {
|
||||
Type Type
|
||||
Term Term
|
||||
Op Operator
|
||||
Left *Expr
|
||||
Right *Expr
|
||||
Const int64
|
||||
}
|
||||
|
||||
// Ref creates an expression from a Term.
|
||||
func Ref(t Term) (p *Expr) {
|
||||
p = newExpression()
|
||||
p.Term = t
|
||||
p.Type = TERM
|
||||
return
|
||||
}
|
||||
|
||||
// Int creates an expression from an integer.
|
||||
func Int(v int64) (p *Expr) {
|
||||
p = newExpression()
|
||||
p.Type = CONST
|
||||
p.Const = v
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Expr) clear() {
|
||||
if self.Term != nil { self.Term.Free() }
|
||||
if self.Left != nil { self.Left.Free() }
|
||||
if self.Right != nil { self.Right.Free() }
|
||||
}
|
||||
|
||||
// Free returns the Expr into pool.
|
||||
// Any operation performed after Free is undefined behavior.
|
||||
func (self *Expr) Free() {
|
||||
self.clear()
|
||||
freeExpression(self)
|
||||
}
|
||||
|
||||
// Evaluate evaluates the expression into an integer.
|
||||
// It also implements the Term interface.
|
||||
func (self *Expr) Evaluate() (int64, error) {
|
||||
switch self.Type {
|
||||
case EXPR : return self.eval()
|
||||
case TERM : return self.Term.Evaluate()
|
||||
case CONST : return self.Const, nil
|
||||
default : panic("invalid expression type: " + self.Type.String())
|
||||
}
|
||||
}
|
||||
|
||||
/** Expression Combinator **/
|
||||
|
||||
func combine(a *Expr, op Operator, b *Expr) (r *Expr) {
|
||||
r = newExpression()
|
||||
r.Op = op
|
||||
r.Type = EXPR
|
||||
r.Left = a
|
||||
r.Right = b
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Expr) Add(v *Expr) *Expr { return combine(self, ADD, v) }
|
||||
func (self *Expr) Sub(v *Expr) *Expr { return combine(self, SUB, v) }
|
||||
func (self *Expr) Mul(v *Expr) *Expr { return combine(self, MUL, v) }
|
||||
func (self *Expr) Div(v *Expr) *Expr { return combine(self, DIV, v) }
|
||||
func (self *Expr) Mod(v *Expr) *Expr { return combine(self, MOD, v) }
|
||||
func (self *Expr) And(v *Expr) *Expr { return combine(self, AND, v) }
|
||||
func (self *Expr) Or (v *Expr) *Expr { return combine(self, OR , v) }
|
||||
func (self *Expr) Xor(v *Expr) *Expr { return combine(self, XOR, v) }
|
||||
func (self *Expr) Shl(v *Expr) *Expr { return combine(self, SHL, v) }
|
||||
func (self *Expr) Shr(v *Expr) *Expr { return combine(self, SHR, v) }
|
||||
func (self *Expr) Pow(v *Expr) *Expr { return combine(self, POW, v) }
|
||||
func (self *Expr) Not() *Expr { return combine(self, NOT, nil) }
|
||||
func (self *Expr) Neg() *Expr { return combine(self, NEG, nil) }
|
||||
|
||||
/** Expression Evaluator **/
|
||||
|
||||
var binaryEvaluators = [256]func(int64, int64) (int64, error) {
|
||||
ADD: func(a, b int64) (int64, error) { return a + b, nil },
|
||||
SUB: func(a, b int64) (int64, error) { return a - b, nil },
|
||||
MUL: func(a, b int64) (int64, error) { return a * b, nil },
|
||||
DIV: idiv,
|
||||
MOD: imod,
|
||||
AND: func(a, b int64) (int64, error) { return a & b, nil },
|
||||
OR: func(a, b int64) (int64, error) { return a | b, nil },
|
||||
XOR: func(a, b int64) (int64, error) { return a ^ b, nil },
|
||||
SHL: func(a, b int64) (int64, error) { return a << b, nil },
|
||||
SHR: func(a, b int64) (int64, error) { return a >> b, nil },
|
||||
POW: ipow,
|
||||
}
|
||||
|
||||
func (self *Expr) eval() (int64, error) {
|
||||
var lhs int64
|
||||
var rhs int64
|
||||
var err error
|
||||
var vfn func(int64, int64) (int64, error)
|
||||
|
||||
/* evaluate LHS */
|
||||
if lhs, err = self.Left.Evaluate(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
/* check for unary operators */
|
||||
switch self.Op {
|
||||
case NOT: return self.unaryNot(lhs)
|
||||
case NEG: return self.unaryNeg(lhs)
|
||||
}
|
||||
|
||||
/* check for operators */
|
||||
if vfn = binaryEvaluators[self.Op]; vfn == nil {
|
||||
panic("invalid operator: " + self.Op.String())
|
||||
}
|
||||
|
||||
/* must be a binary expression */
|
||||
if self.Right == nil {
|
||||
panic("operator " + self.Op.String() + " is a binary operator")
|
||||
}
|
||||
|
||||
/* evaluate RHS, and call the operator */
|
||||
if rhs, err = self.Right.Evaluate(); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return vfn(lhs, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Expr) unaryNot(v int64) (int64, error) {
|
||||
if self.Right == nil {
|
||||
return ^v, nil
|
||||
} else {
|
||||
panic("operator Invert is an unary operator")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Expr) unaryNeg(v int64) (int64, error) {
|
||||
if self.Right == nil {
|
||||
return -v, nil
|
||||
} else {
|
||||
panic("operator Negate is an unary operator")
|
||||
}
|
||||
}
|
53
vendor/github.com/cloudwego/iasm/expr/errors.go
generated
vendored
Normal file
53
vendor/github.com/cloudwego/iasm/expr/errors.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
)
|
||||
|
||||
// SyntaxError represents a syntax error in the expression.
|
||||
type SyntaxError struct {
|
||||
Pos int
|
||||
Reason string
|
||||
}
|
||||
|
||||
func newSyntaxError(pos int, reason string) *SyntaxError {
|
||||
return &SyntaxError {
|
||||
Pos : pos,
|
||||
Reason : reason,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SyntaxError) Error() string {
|
||||
return fmt.Sprintf("Syntax error at position %d: %s", self.Pos, self.Reason)
|
||||
}
|
||||
|
||||
// RuntimeError is an error which would occure at run time.
|
||||
type RuntimeError struct {
|
||||
Reason string
|
||||
}
|
||||
|
||||
func newRuntimeError(reason string) *RuntimeError {
|
||||
return &RuntimeError {
|
||||
Reason: reason,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *RuntimeError) Error() string {
|
||||
return "Runtime error: " + self.Reason
|
||||
}
|
67
vendor/github.com/cloudwego/iasm/expr/ops.go
generated
vendored
Normal file
67
vendor/github.com/cloudwego/iasm/expr/ops.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
)
|
||||
|
||||
func idiv(v int64, d int64) (int64, error) {
|
||||
if d != 0 {
|
||||
return v / d, nil
|
||||
} else {
|
||||
return 0, newRuntimeError("division by zero")
|
||||
}
|
||||
}
|
||||
|
||||
func imod(v int64, d int64) (int64, error) {
|
||||
if d != 0 {
|
||||
return v % d, nil
|
||||
} else {
|
||||
return 0, newRuntimeError("division by zero")
|
||||
}
|
||||
}
|
||||
|
||||
func ipow(v int64, e int64) (int64, error) {
|
||||
mul := v
|
||||
ret := int64(1)
|
||||
|
||||
/* value must be 0 or positive */
|
||||
if v < 0 {
|
||||
return 0, newRuntimeError(fmt.Sprintf("negative base value: %d", v))
|
||||
}
|
||||
|
||||
/* exponent must be non-negative */
|
||||
if e < 0 {
|
||||
return 0, newRuntimeError(fmt.Sprintf("negative exponent: %d", e))
|
||||
}
|
||||
|
||||
/* fast power first round */
|
||||
if (e & 1) != 0 {
|
||||
ret *= mul
|
||||
}
|
||||
|
||||
/* fast power remaining rounds */
|
||||
for e >>= 1; e != 0; e >>= 1 {
|
||||
if mul *= mul; (e & 1) != 0 {
|
||||
ret *= mul
|
||||
}
|
||||
}
|
||||
|
||||
/* all done */
|
||||
return ret, nil
|
||||
}
|
329
vendor/github.com/cloudwego/iasm/expr/parser.go
generated
vendored
Normal file
329
vendor/github.com/cloudwego/iasm/expr/parser.go
generated
vendored
Normal file
@ -0,0 +1,329 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
`strconv`
|
||||
`unicode`
|
||||
`unsafe`
|
||||
)
|
||||
|
||||
type _TokenKind uint8
|
||||
|
||||
const (
|
||||
_T_end _TokenKind = iota + 1
|
||||
_T_int
|
||||
_T_punc
|
||||
_T_name
|
||||
)
|
||||
|
||||
const (
|
||||
_OP2 = 0x80
|
||||
_POW = _OP2 | '*'
|
||||
_SHL = _OP2 | '<'
|
||||
_SHR = _OP2 | '>'
|
||||
)
|
||||
|
||||
type _Slice struct {
|
||||
p unsafe.Pointer
|
||||
n int
|
||||
c int
|
||||
}
|
||||
|
||||
type _Token struct {
|
||||
pos int
|
||||
ptr *rune
|
||||
u64 uint64
|
||||
tag _TokenKind
|
||||
}
|
||||
|
||||
func (self _Token) str() (v string) {
|
||||
return string(self.rbuf())
|
||||
}
|
||||
|
||||
func (self _Token) rbuf() (v []rune) {
|
||||
(*_Slice)(unsafe.Pointer(&v)).c = int(self.u64)
|
||||
(*_Slice)(unsafe.Pointer(&v)).n = int(self.u64)
|
||||
(*_Slice)(unsafe.Pointer(&v)).p = unsafe.Pointer(self.ptr)
|
||||
return
|
||||
}
|
||||
|
||||
func tokenEnd(p int) _Token {
|
||||
return _Token {
|
||||
pos: p,
|
||||
tag: _T_end,
|
||||
}
|
||||
}
|
||||
|
||||
func tokenInt(p int, v uint64) _Token {
|
||||
return _Token {
|
||||
pos: p,
|
||||
u64: v,
|
||||
tag: _T_int,
|
||||
}
|
||||
}
|
||||
|
||||
func tokenPunc(p int, v rune) _Token {
|
||||
return _Token {
|
||||
pos: p,
|
||||
tag: _T_punc,
|
||||
u64: uint64(v),
|
||||
}
|
||||
}
|
||||
|
||||
func tokenName(p int, v []rune) _Token {
|
||||
return _Token {
|
||||
pos: p,
|
||||
ptr: &v[0],
|
||||
tag: _T_name,
|
||||
u64: uint64(len(v)),
|
||||
}
|
||||
}
|
||||
|
||||
// Repository represents a repository of Term's.
|
||||
type Repository interface {
|
||||
Get(name string) (Term, error)
|
||||
}
|
||||
|
||||
// Parser parses an expression string to it's AST representation.
|
||||
type Parser struct {
|
||||
pos int
|
||||
src []rune
|
||||
}
|
||||
|
||||
var binaryOps = [...]func(*Expr, *Expr) *Expr {
|
||||
'+' : (*Expr).Add,
|
||||
'-' : (*Expr).Sub,
|
||||
'*' : (*Expr).Mul,
|
||||
'/' : (*Expr).Div,
|
||||
'%' : (*Expr).Mod,
|
||||
'&' : (*Expr).And,
|
||||
'^' : (*Expr).Xor,
|
||||
'|' : (*Expr).Or,
|
||||
_SHL : (*Expr).Shl,
|
||||
_SHR : (*Expr).Shr,
|
||||
_POW : (*Expr).Pow,
|
||||
}
|
||||
|
||||
var precedence = [...]map[int]bool {
|
||||
{_SHL: true, _SHR: true},
|
||||
{'|' : true},
|
||||
{'^' : true},
|
||||
{'&' : true},
|
||||
{'+' : true, '-': true},
|
||||
{'*' : true, '/': true, '%': true},
|
||||
{_POW: true},
|
||||
}
|
||||
|
||||
func (self *Parser) ch() rune {
|
||||
return self.src[self.pos]
|
||||
}
|
||||
|
||||
func (self *Parser) eof() bool {
|
||||
return self.pos >= len(self.src)
|
||||
}
|
||||
|
||||
func (self *Parser) rch() (v rune) {
|
||||
v, self.pos = self.src[self.pos], self.pos + 1
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Parser) hex(ss []rune) bool {
|
||||
if len(ss) == 1 && ss[0] == '0' {
|
||||
return unicode.ToLower(self.ch()) == 'x'
|
||||
} else if len(ss) <= 1 || unicode.ToLower(ss[1]) != 'x' {
|
||||
return unicode.IsDigit(self.ch())
|
||||
} else {
|
||||
return ishexdigit(self.ch())
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) int(p int, ss []rune) (_Token, error) {
|
||||
var err error
|
||||
var val uint64
|
||||
|
||||
/* find all the digits */
|
||||
for !self.eof() && self.hex(ss) {
|
||||
ss = append(ss, self.rch())
|
||||
}
|
||||
|
||||
/* parse the value */
|
||||
if val, err = strconv.ParseUint(string(ss), 0, 64); err != nil {
|
||||
return _Token{}, err
|
||||
} else {
|
||||
return tokenInt(p, val), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) name(p int, ss []rune) _Token {
|
||||
for !self.eof() && isident(self.ch()) { ss = append(ss, self.rch()) }
|
||||
return tokenName(p, ss)
|
||||
}
|
||||
|
||||
func (self *Parser) read(p int, ch rune) (_Token, error) {
|
||||
if isdigit(ch) {
|
||||
return self.int(p, []rune { ch })
|
||||
} else if isident0(ch) {
|
||||
return self.name(p, []rune { ch }), nil
|
||||
} else if isop2ch(ch) && !self.eof() && self.ch() == ch {
|
||||
return tokenPunc(p, _OP2 | self.rch()), nil
|
||||
} else if isop1ch(ch) {
|
||||
return tokenPunc(p, ch), nil
|
||||
} else {
|
||||
return _Token{}, newSyntaxError(self.pos, "invalid character " + strconv.QuoteRuneToASCII(ch))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) next() (_Token, error) {
|
||||
for {
|
||||
var p int
|
||||
var c rune
|
||||
|
||||
/* check for EOF */
|
||||
if self.eof() {
|
||||
return tokenEnd(self.pos), nil
|
||||
}
|
||||
|
||||
/* read the next char */
|
||||
p = self.pos
|
||||
c = self.rch()
|
||||
|
||||
/* parse the token if not a space */
|
||||
if !unicode.IsSpace(c) {
|
||||
return self.read(p, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) grab(tk _Token, repo Repository) (*Expr, error) {
|
||||
if repo == nil {
|
||||
return nil, newSyntaxError(tk.pos, "unresolved symbol: " + tk.str())
|
||||
} else if term, err := repo.Get(tk.str()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return Ref(term), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) nest(nest int, repo Repository) (*Expr, error) {
|
||||
var err error
|
||||
var ret *Expr
|
||||
var ntk _Token
|
||||
|
||||
/* evaluate the nested expression */
|
||||
if ret, err = self.expr(0, nest + 1, repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* must follows with a ')' */
|
||||
if ntk, err = self.next(); err != nil {
|
||||
return nil, err
|
||||
} else if ntk.tag != _T_punc || ntk.u64 != ')' {
|
||||
return nil, newSyntaxError(ntk.pos, "')' expected")
|
||||
} else {
|
||||
return ret, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) unit(nest int, repo Repository) (*Expr, error) {
|
||||
if tk, err := self.next(); err != nil {
|
||||
return nil, err
|
||||
} else if tk.tag == _T_int {
|
||||
return Int(int64(tk.u64)), nil
|
||||
} else if tk.tag == _T_name {
|
||||
return self.grab(tk, repo)
|
||||
} else if tk.tag == _T_punc && tk.u64 == '(' {
|
||||
return self.nest(nest, repo)
|
||||
} else if tk.tag == _T_punc && tk.u64 == '+' {
|
||||
return self.unit(nest, repo)
|
||||
} else if tk.tag == _T_punc && tk.u64 == '-' {
|
||||
return neg2(self.unit(nest, repo))
|
||||
} else if tk.tag == _T_punc && tk.u64 == '~' {
|
||||
return not2(self.unit(nest, repo))
|
||||
} else {
|
||||
return nil, newSyntaxError(tk.pos, "integer, unary operator or nested expression expected")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) term(prec int, nest int, repo Repository) (*Expr, error) {
|
||||
var err error
|
||||
var val *Expr
|
||||
|
||||
/* parse the LHS operand */
|
||||
if val, err = self.expr(prec + 1, nest, repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* parse all the operators of the same precedence */
|
||||
for {
|
||||
var op int
|
||||
var rv *Expr
|
||||
var tk _Token
|
||||
|
||||
/* peek the next token */
|
||||
pp := self.pos
|
||||
tk, err = self.next()
|
||||
|
||||
/* check for errors */
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* encountered EOF */
|
||||
if tk.tag == _T_end {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
/* must be an operator */
|
||||
if tk.tag != _T_punc {
|
||||
return nil, newSyntaxError(tk.pos, "operators expected")
|
||||
}
|
||||
|
||||
/* check for the operator precedence */
|
||||
if op = int(tk.u64); !precedence[prec][op] {
|
||||
self.pos = pp
|
||||
return val, nil
|
||||
}
|
||||
|
||||
/* evaluate the RHS operand, and combine the value */
|
||||
if rv, err = self.expr(prec + 1, nest, repo); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
val = binaryOps[op](val, rv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Parser) expr(prec int, nest int, repo Repository) (*Expr, error) {
|
||||
if prec >= len(precedence) {
|
||||
return self.unit(nest, repo)
|
||||
} else {
|
||||
return self.term(prec, nest, repo)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse parses the expression, and returns it's AST tree.
|
||||
func (self *Parser) Parse(repo Repository) (*Expr, error) {
|
||||
return self.expr(0, 0, repo)
|
||||
}
|
||||
|
||||
// SetSource resets the expression parser and sets the expression source.
|
||||
func (self *Parser) SetSource(src string) *Parser {
|
||||
self.pos = 0
|
||||
self.src = []rune(src)
|
||||
return self
|
||||
}
|
42
vendor/github.com/cloudwego/iasm/expr/pools.go
generated
vendored
Normal file
42
vendor/github.com/cloudwego/iasm/expr/pools.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 expr
|
||||
|
||||
import (
|
||||
`sync`
|
||||
)
|
||||
|
||||
var (
|
||||
expressionPool sync.Pool
|
||||
)
|
||||
|
||||
func newExpression() *Expr {
|
||||
if v := expressionPool.Get(); v == nil {
|
||||
return new(Expr)
|
||||
} else {
|
||||
return resetExpression(v.(*Expr))
|
||||
}
|
||||
}
|
||||
|
||||
func freeExpression(p *Expr) {
|
||||
expressionPool.Put(p)
|
||||
}
|
||||
|
||||
func resetExpression(p *Expr) *Expr {
|
||||
*p = Expr{}
|
||||
return p
|
||||
}
|
23
vendor/github.com/cloudwego/iasm/expr/term.go
generated
vendored
Normal file
23
vendor/github.com/cloudwego/iasm/expr/term.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 expr
|
||||
|
||||
// Term represents a value that can Evaluate() into an integer.
|
||||
type Term interface {
|
||||
Free()
|
||||
Evaluate() (int64, error)
|
||||
}
|
77
vendor/github.com/cloudwego/iasm/expr/utils.go
generated
vendored
Normal file
77
vendor/github.com/cloudwego/iasm/expr/utils.go
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 expr
|
||||
|
||||
var op1ch = [...]bool {
|
||||
'+': true,
|
||||
'-': true,
|
||||
'*': true,
|
||||
'/': true,
|
||||
'%': true,
|
||||
'&': true,
|
||||
'|': true,
|
||||
'^': true,
|
||||
'~': true,
|
||||
'(': true,
|
||||
')': true,
|
||||
}
|
||||
|
||||
var op2ch = [...]bool {
|
||||
'*': true,
|
||||
'<': true,
|
||||
'>': true,
|
||||
}
|
||||
|
||||
func neg2(v *Expr, err error) (*Expr, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return v.Neg(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func not2(v *Expr, err error) (*Expr, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return v.Not(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func isop1ch(ch rune) bool {
|
||||
return ch >= 0 && int(ch) < len(op1ch) && op1ch[ch]
|
||||
}
|
||||
|
||||
func isop2ch(ch rune) bool {
|
||||
return ch >= 0 && int(ch) < len(op2ch) && op2ch[ch]
|
||||
}
|
||||
|
||||
func isdigit(ch rune) bool {
|
||||
return ch >= '0' && ch <= '9'
|
||||
}
|
||||
|
||||
func isident(ch rune) bool {
|
||||
return isdigit(ch) || isident0(ch)
|
||||
}
|
||||
|
||||
func isident0(ch rune) bool {
|
||||
return (ch == '_') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
|
||||
}
|
||||
|
||||
func ishexdigit(ch rune) bool {
|
||||
return isdigit(ch) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')
|
||||
}
|
251
vendor/github.com/cloudwego/iasm/x86_64/arch.go
generated
vendored
Normal file
251
vendor/github.com/cloudwego/iasm/x86_64/arch.go
generated
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
)
|
||||
|
||||
// ISA represents an extension to x86-64 instruction set.
|
||||
type ISA uint64
|
||||
|
||||
const (
|
||||
ISA_CPUID ISA = 1 << iota
|
||||
ISA_RDTSC
|
||||
ISA_RDTSCP
|
||||
ISA_CMOV
|
||||
ISA_MOVBE
|
||||
ISA_POPCNT
|
||||
ISA_LZCNT
|
||||
ISA_TBM
|
||||
ISA_BMI
|
||||
ISA_BMI2
|
||||
ISA_ADX
|
||||
ISA_MMX
|
||||
ISA_MMX_PLUS
|
||||
ISA_FEMMS
|
||||
ISA_3DNOW
|
||||
ISA_3DNOW_PLUS
|
||||
ISA_SSE
|
||||
ISA_SSE2
|
||||
ISA_SSE3
|
||||
ISA_SSSE3
|
||||
ISA_SSE4A
|
||||
ISA_SSE4_1
|
||||
ISA_SSE4_2
|
||||
ISA_FMA3
|
||||
ISA_FMA4
|
||||
ISA_XOP
|
||||
ISA_F16C
|
||||
ISA_AVX
|
||||
ISA_AVX2
|
||||
ISA_AVX512F
|
||||
ISA_AVX512BW
|
||||
ISA_AVX512DQ
|
||||
ISA_AVX512VL
|
||||
ISA_AVX512PF
|
||||
ISA_AVX512ER
|
||||
ISA_AVX512CD
|
||||
ISA_AVX512VBMI
|
||||
ISA_AVX512IFMA
|
||||
ISA_AVX512VPOPCNTDQ
|
||||
ISA_AVX512_4VNNIW
|
||||
ISA_AVX512_4FMAPS
|
||||
ISA_PREFETCH
|
||||
ISA_PREFETCHW
|
||||
ISA_PREFETCHWT1
|
||||
ISA_CLFLUSH
|
||||
ISA_CLFLUSHOPT
|
||||
ISA_CLWB
|
||||
ISA_CLZERO
|
||||
ISA_RDRAND
|
||||
ISA_RDSEED
|
||||
ISA_PCLMULQDQ
|
||||
ISA_AES
|
||||
ISA_SHA
|
||||
ISA_MONITOR
|
||||
ISA_MONITORX
|
||||
ISA_ALL = ^ISA(0)
|
||||
)
|
||||
|
||||
var _ISA_NAMES = map[ISA]string {
|
||||
ISA_CPUID : "CPUID",
|
||||
ISA_RDTSC : "RDTSC",
|
||||
ISA_RDTSCP : "RDTSCP",
|
||||
ISA_CMOV : "CMOV",
|
||||
ISA_MOVBE : "MOVBE",
|
||||
ISA_POPCNT : "POPCNT",
|
||||
ISA_LZCNT : "LZCNT",
|
||||
ISA_TBM : "TBM",
|
||||
ISA_BMI : "BMI",
|
||||
ISA_BMI2 : "BMI2",
|
||||
ISA_ADX : "ADX",
|
||||
ISA_MMX : "MMX",
|
||||
ISA_MMX_PLUS : "MMX+",
|
||||
ISA_FEMMS : "FEMMS",
|
||||
ISA_3DNOW : "3dnow!",
|
||||
ISA_3DNOW_PLUS : "3dnow!+",
|
||||
ISA_SSE : "SSE",
|
||||
ISA_SSE2 : "SSE2",
|
||||
ISA_SSE3 : "SSE3",
|
||||
ISA_SSSE3 : "SSSE3",
|
||||
ISA_SSE4A : "SSE4A",
|
||||
ISA_SSE4_1 : "SSE4.1",
|
||||
ISA_SSE4_2 : "SSE4.2",
|
||||
ISA_FMA3 : "FMA3",
|
||||
ISA_FMA4 : "FMA4",
|
||||
ISA_XOP : "XOP",
|
||||
ISA_F16C : "F16C",
|
||||
ISA_AVX : "AVX",
|
||||
ISA_AVX2 : "AVX2",
|
||||
ISA_AVX512F : "AVX512F",
|
||||
ISA_AVX512BW : "AVX512BW",
|
||||
ISA_AVX512DQ : "AVX512DQ",
|
||||
ISA_AVX512VL : "AVX512VL",
|
||||
ISA_AVX512PF : "AVX512PF",
|
||||
ISA_AVX512ER : "AVX512ER",
|
||||
ISA_AVX512CD : "AVX512CD",
|
||||
ISA_AVX512VBMI : "AVX512VBMI",
|
||||
ISA_AVX512IFMA : "AVX512IFMA",
|
||||
ISA_AVX512VPOPCNTDQ : "AVX512VPOPCNTDQ",
|
||||
ISA_AVX512_4VNNIW : "AVX512_4VNNIW",
|
||||
ISA_AVX512_4FMAPS : "AVX512_4FMAPS",
|
||||
ISA_PREFETCH : "PREFETCH",
|
||||
ISA_PREFETCHW : "PREFETCHW",
|
||||
ISA_PREFETCHWT1 : "PREFETCHWT1",
|
||||
ISA_CLFLUSH : "CLFLUSH",
|
||||
ISA_CLFLUSHOPT : "CLFLUSHOPT",
|
||||
ISA_CLWB : "CLWB",
|
||||
ISA_CLZERO : "CLZERO",
|
||||
ISA_RDRAND : "RDRAND",
|
||||
ISA_RDSEED : "RDSEED",
|
||||
ISA_PCLMULQDQ : "PCLMULQDQ",
|
||||
ISA_AES : "AES",
|
||||
ISA_SHA : "SHA",
|
||||
ISA_MONITOR : "MONITOR",
|
||||
ISA_MONITORX : "MONITORX",
|
||||
}
|
||||
|
||||
var _ISA_MAPPING = map[string]ISA {
|
||||
"CPUID" : ISA_CPUID,
|
||||
"RDTSC" : ISA_RDTSC,
|
||||
"RDTSCP" : ISA_RDTSCP,
|
||||
"CMOV" : ISA_CMOV,
|
||||
"MOVBE" : ISA_MOVBE,
|
||||
"POPCNT" : ISA_POPCNT,
|
||||
"LZCNT" : ISA_LZCNT,
|
||||
"TBM" : ISA_TBM,
|
||||
"BMI" : ISA_BMI,
|
||||
"BMI2" : ISA_BMI2,
|
||||
"ADX" : ISA_ADX,
|
||||
"MMX" : ISA_MMX,
|
||||
"MMX+" : ISA_MMX_PLUS,
|
||||
"FEMMS" : ISA_FEMMS,
|
||||
"3dnow!" : ISA_3DNOW,
|
||||
"3dnow!+" : ISA_3DNOW_PLUS,
|
||||
"SSE" : ISA_SSE,
|
||||
"SSE2" : ISA_SSE2,
|
||||
"SSE3" : ISA_SSE3,
|
||||
"SSSE3" : ISA_SSSE3,
|
||||
"SSE4A" : ISA_SSE4A,
|
||||
"SSE4.1" : ISA_SSE4_1,
|
||||
"SSE4.2" : ISA_SSE4_2,
|
||||
"FMA3" : ISA_FMA3,
|
||||
"FMA4" : ISA_FMA4,
|
||||
"XOP" : ISA_XOP,
|
||||
"F16C" : ISA_F16C,
|
||||
"AVX" : ISA_AVX,
|
||||
"AVX2" : ISA_AVX2,
|
||||
"AVX512F" : ISA_AVX512F,
|
||||
"AVX512BW" : ISA_AVX512BW,
|
||||
"AVX512DQ" : ISA_AVX512DQ,
|
||||
"AVX512VL" : ISA_AVX512VL,
|
||||
"AVX512PF" : ISA_AVX512PF,
|
||||
"AVX512ER" : ISA_AVX512ER,
|
||||
"AVX512CD" : ISA_AVX512CD,
|
||||
"AVX512VBMI" : ISA_AVX512VBMI,
|
||||
"AVX512IFMA" : ISA_AVX512IFMA,
|
||||
"AVX512VPOPCNTDQ" : ISA_AVX512VPOPCNTDQ,
|
||||
"AVX512_4VNNIW" : ISA_AVX512_4VNNIW,
|
||||
"AVX512_4FMAPS" : ISA_AVX512_4FMAPS,
|
||||
"PREFETCH" : ISA_PREFETCH,
|
||||
"PREFETCHW" : ISA_PREFETCHW,
|
||||
"PREFETCHWT1" : ISA_PREFETCHWT1,
|
||||
"CLFLUSH" : ISA_CLFLUSH,
|
||||
"CLFLUSHOPT" : ISA_CLFLUSHOPT,
|
||||
"CLWB" : ISA_CLWB,
|
||||
"CLZERO" : ISA_CLZERO,
|
||||
"RDRAND" : ISA_RDRAND,
|
||||
"RDSEED" : ISA_RDSEED,
|
||||
"PCLMULQDQ" : ISA_PCLMULQDQ,
|
||||
"AES" : ISA_AES,
|
||||
"SHA" : ISA_SHA,
|
||||
"MONITOR" : ISA_MONITOR,
|
||||
"MONITORX" : ISA_MONITORX,
|
||||
}
|
||||
|
||||
func (self ISA) String() string {
|
||||
if v, ok := _ISA_NAMES[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
return fmt.Sprintf("(invalid: %#x)", uint64(self))
|
||||
}
|
||||
}
|
||||
|
||||
// ParseISA parses name into ISA, it will panic if the name is invalid.
|
||||
func ParseISA(name string) ISA {
|
||||
if v, ok := _ISA_MAPPING[name]; ok {
|
||||
return v
|
||||
} else {
|
||||
panic("invalid ISA name: " + name)
|
||||
}
|
||||
}
|
||||
|
||||
// Arch represents the x86_64 architecture.
|
||||
type Arch struct {
|
||||
isa ISA
|
||||
}
|
||||
|
||||
// DefaultArch is the default architecture with all ISA enabled.
|
||||
var DefaultArch = CreateArch()
|
||||
|
||||
// CreateArch creates a new Arch with all ISA enabled.
|
||||
func CreateArch() *Arch {
|
||||
return new(Arch).EnableISA(ISA_ALL)
|
||||
}
|
||||
|
||||
// HasISA checks if a particular ISA was enabled.
|
||||
func (self *Arch) HasISA(isa ISA) bool {
|
||||
return (self.isa & isa) != 0
|
||||
}
|
||||
|
||||
// EnableISA enables a particular ISA.
|
||||
func (self *Arch) EnableISA(isa ISA) *Arch {
|
||||
self.isa |= isa
|
||||
return self
|
||||
}
|
||||
|
||||
// DisableISA disables a particular ISA.
|
||||
func (self *Arch) DisableISA(isa ISA) *Arch {
|
||||
self.isa &^= isa
|
||||
return self
|
||||
}
|
||||
|
||||
// CreateProgram creates a new empty program.
|
||||
func (self *Arch) CreateProgram() *Program {
|
||||
return newProgram(self)
|
||||
}
|
16
vendor/github.com/cloudwego/iasm/x86_64/asm.s
generated
vendored
Normal file
16
vendor/github.com/cloudwego/iasm/x86_64/asm.s
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
1819
vendor/github.com/cloudwego/iasm/x86_64/assembler.go
generated
vendored
Normal file
1819
vendor/github.com/cloudwego/iasm/x86_64/assembler.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
49
vendor/github.com/cloudwego/iasm/x86_64/assembler_alias.go
generated
vendored
Normal file
49
vendor/github.com/cloudwego/iasm/x86_64/assembler_alias.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 x86_64
|
||||
|
||||
func alias_INT3(p *Program, vv ...interface{}) *Instruction {
|
||||
if len(vv) == 0 {
|
||||
return p.INT(3)
|
||||
} else {
|
||||
panic("instruction INT3 takes no operands")
|
||||
}
|
||||
}
|
||||
|
||||
func alias_VCMPEQPS(p *Program, vv ...interface{}) *Instruction {
|
||||
if len(vv) >= 3 {
|
||||
return p.VCMPPS(0x00, vv[0], vv[1], vv[2], vv[3:]...)
|
||||
} else {
|
||||
panic("instruction VCMPEQPS takes 3 or 4 operands")
|
||||
}
|
||||
}
|
||||
|
||||
func alias_VCMPTRUEPS(p *Program, vv ...interface{}) *Instruction {
|
||||
if len(vv) >= 3 {
|
||||
return p.VCMPPS(0x0f, vv[0], vv[1], vv[2], vv[3:]...)
|
||||
} else {
|
||||
panic("instruction VCMPTRUEPS takes 3 or 4 operands")
|
||||
}
|
||||
}
|
||||
|
||||
var _InstructionAliases = map[string]_InstructionEncoder {
|
||||
"int3" : alias_INT3,
|
||||
"retq" : Instructions["ret"],
|
||||
"movabsq" : Instructions["movq"],
|
||||
"vcmpeqps" : alias_VCMPEQPS,
|
||||
"vcmptrueps" : alias_VCMPTRUEPS,
|
||||
}
|
79
vendor/github.com/cloudwego/iasm/x86_64/eface.go
generated
vendored
Normal file
79
vendor/github.com/cloudwego/iasm/x86_64/eface.go
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
`reflect`
|
||||
`unsafe`
|
||||
)
|
||||
|
||||
type _GoType struct {
|
||||
size uintptr
|
||||
pdata uintptr
|
||||
hash uint32
|
||||
flags uint8
|
||||
align uint8
|
||||
falign uint8
|
||||
kflags uint8
|
||||
traits unsafe.Pointer
|
||||
gcdata *byte
|
||||
str int32
|
||||
ptrx int32
|
||||
}
|
||||
|
||||
const (
|
||||
_KindMask = (1 << 5) - 1
|
||||
)
|
||||
|
||||
func (self *_GoType) kind() reflect.Kind {
|
||||
return reflect.Kind(self.kflags & _KindMask)
|
||||
}
|
||||
|
||||
type _GoSlice struct {
|
||||
ptr unsafe.Pointer
|
||||
len int
|
||||
cap int
|
||||
}
|
||||
|
||||
type _GoEface struct {
|
||||
vt *_GoType
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
func (self *_GoEface) kind() reflect.Kind {
|
||||
if self.vt != nil {
|
||||
return self.vt.kind()
|
||||
} else {
|
||||
return reflect.Invalid
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_GoEface) toInt64() int64 {
|
||||
if self.vt.size == 8 {
|
||||
return *(*int64)(self.ptr)
|
||||
} else if self.vt.size == 4 {
|
||||
return int64(*(*int32)(self.ptr))
|
||||
} else if self.vt.size == 2 {
|
||||
return int64(*(*int16)(self.ptr))
|
||||
} else {
|
||||
return int64(*(*int8)(self.ptr))
|
||||
}
|
||||
}
|
||||
|
||||
func efaceOf(v interface{}) _GoEface {
|
||||
return *(*_GoEface)(unsafe.Pointer(&v))
|
||||
}
|
691
vendor/github.com/cloudwego/iasm/x86_64/encodings.go
generated
vendored
Normal file
691
vendor/github.com/cloudwego/iasm/x86_64/encodings.go
generated
vendored
Normal file
@ -0,0 +1,691 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
`encoding/binary`
|
||||
`math`
|
||||
)
|
||||
|
||||
/** Operand Encoding Helpers **/
|
||||
|
||||
func imml(v interface{}) byte {
|
||||
return byte(toImmAny(v) & 0x0f)
|
||||
}
|
||||
|
||||
func relv(v interface{}) int64 {
|
||||
switch r := v.(type) {
|
||||
case *Label : return 0
|
||||
case RelativeOffset : return int64(r)
|
||||
default : panic("invalid relative offset")
|
||||
}
|
||||
}
|
||||
|
||||
func addr(v interface{}) interface{} {
|
||||
switch a := v.(*MemoryOperand).Addr; a.Type {
|
||||
case Memory : return a.Memory
|
||||
case Offset : return a.Offset
|
||||
case Reference : return a.Reference
|
||||
default : panic("invalid memory operand type")
|
||||
}
|
||||
}
|
||||
|
||||
func bcode(v interface{}) byte {
|
||||
if m, ok := v.(*MemoryOperand); !ok {
|
||||
panic("v is not a memory operand")
|
||||
} else if m.Broadcast == 0 {
|
||||
return 0
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func vcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case XMMRegister : return byte(r)
|
||||
case YMMRegister : return byte(r)
|
||||
case ZMMRegister : return byte(r)
|
||||
case MaskedRegister : return vcode(r.Reg)
|
||||
default : panic("v is not a vector register")
|
||||
}
|
||||
}
|
||||
|
||||
func kcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case KRegister : return byte(r)
|
||||
case XMMRegister : return 0
|
||||
case YMMRegister : return 0
|
||||
case ZMMRegister : return 0
|
||||
case RegisterMask : return byte(r.K)
|
||||
case MaskedRegister : return byte(r.Mask.K)
|
||||
case *MemoryOperand : return toKcodeMem(r)
|
||||
default : panic("v is not a maskable operand")
|
||||
}
|
||||
}
|
||||
|
||||
func zcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case KRegister : return 0
|
||||
case XMMRegister : return 0
|
||||
case YMMRegister : return 0
|
||||
case ZMMRegister : return 0
|
||||
case RegisterMask : return toZcodeRegM(r)
|
||||
case MaskedRegister : return toZcodeRegM(r.Mask)
|
||||
case *MemoryOperand : return toZcodeMem(r)
|
||||
default : panic("v is not a maskable operand")
|
||||
}
|
||||
}
|
||||
|
||||
func lcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return byte(r & 0x07)
|
||||
case Register16 : return byte(r & 0x07)
|
||||
case Register32 : return byte(r & 0x07)
|
||||
case Register64 : return byte(r & 0x07)
|
||||
case KRegister : return byte(r & 0x07)
|
||||
case MMRegister : return byte(r & 0x07)
|
||||
case XMMRegister : return byte(r & 0x07)
|
||||
case YMMRegister : return byte(r & 0x07)
|
||||
case ZMMRegister : return byte(r & 0x07)
|
||||
case MaskedRegister : return lcode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func hcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return byte(r >> 3) & 1
|
||||
case Register16 : return byte(r >> 3) & 1
|
||||
case Register32 : return byte(r >> 3) & 1
|
||||
case Register64 : return byte(r >> 3) & 1
|
||||
case KRegister : return byte(r >> 3) & 1
|
||||
case MMRegister : return byte(r >> 3) & 1
|
||||
case XMMRegister : return byte(r >> 3) & 1
|
||||
case YMMRegister : return byte(r >> 3) & 1
|
||||
case ZMMRegister : return byte(r >> 3) & 1
|
||||
case MaskedRegister : return hcode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func ecode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return byte(r >> 4) & 1
|
||||
case Register16 : return byte(r >> 4) & 1
|
||||
case Register32 : return byte(r >> 4) & 1
|
||||
case Register64 : return byte(r >> 4) & 1
|
||||
case KRegister : return byte(r >> 4) & 1
|
||||
case MMRegister : return byte(r >> 4) & 1
|
||||
case XMMRegister : return byte(r >> 4) & 1
|
||||
case YMMRegister : return byte(r >> 4) & 1
|
||||
case ZMMRegister : return byte(r >> 4) & 1
|
||||
case MaskedRegister : return ecode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func hlcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return toHLcodeReg8(r)
|
||||
case Register16 : return byte(r & 0x0f)
|
||||
case Register32 : return byte(r & 0x0f)
|
||||
case Register64 : return byte(r & 0x0f)
|
||||
case KRegister : return byte(r & 0x0f)
|
||||
case MMRegister : return byte(r & 0x0f)
|
||||
case XMMRegister : return byte(r & 0x0f)
|
||||
case YMMRegister : return byte(r & 0x0f)
|
||||
case ZMMRegister : return byte(r & 0x0f)
|
||||
case MaskedRegister : return hlcode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func ehcode(v interface{}) byte {
|
||||
switch r := v.(type) {
|
||||
case Register8 : return byte(r >> 3) & 0x03
|
||||
case Register16 : return byte(r >> 3) & 0x03
|
||||
case Register32 : return byte(r >> 3) & 0x03
|
||||
case Register64 : return byte(r >> 3) & 0x03
|
||||
case KRegister : return byte(r >> 3) & 0x03
|
||||
case MMRegister : return byte(r >> 3) & 0x03
|
||||
case XMMRegister : return byte(r >> 3) & 0x03
|
||||
case YMMRegister : return byte(r >> 3) & 0x03
|
||||
case ZMMRegister : return byte(r >> 3) & 0x03
|
||||
case MaskedRegister : return ehcode(r.Reg)
|
||||
default : panic("v is not a register")
|
||||
}
|
||||
}
|
||||
|
||||
func toImmAny(v interface{}) int64 {
|
||||
if x, ok := asInt64(v); ok {
|
||||
return x
|
||||
} else {
|
||||
panic("value is not an integer")
|
||||
}
|
||||
}
|
||||
|
||||
func toHcodeOpt(v interface{}) byte {
|
||||
if v == nil {
|
||||
return 0
|
||||
} else {
|
||||
return hcode(v)
|
||||
}
|
||||
}
|
||||
|
||||
func toEcodeVMM(v interface{}, x byte) byte {
|
||||
switch r := v.(type) {
|
||||
case XMMRegister : return ecode(r)
|
||||
case YMMRegister : return ecode(r)
|
||||
case ZMMRegister : return ecode(r)
|
||||
default : return x
|
||||
}
|
||||
}
|
||||
|
||||
func toKcodeMem(v *MemoryOperand) byte {
|
||||
if !v.Masked {
|
||||
return 0
|
||||
} else {
|
||||
return byte(v.Mask.K)
|
||||
}
|
||||
}
|
||||
|
||||
func toZcodeMem(v *MemoryOperand) byte {
|
||||
if !v.Masked || v.Mask.Z {
|
||||
return 0
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func toZcodeRegM(v RegisterMask) byte {
|
||||
if v.Z {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func toHLcodeReg8(v Register8) byte {
|
||||
switch v {
|
||||
case AH: fallthrough
|
||||
case BH: fallthrough
|
||||
case CH: fallthrough
|
||||
case DH: panic("ah/bh/ch/dh registers never use 4-bit encoding")
|
||||
default: return byte(v & 0x0f)
|
||||
}
|
||||
}
|
||||
|
||||
/** Instruction Encoding Helpers **/
|
||||
|
||||
const (
|
||||
_N_inst = 16
|
||||
)
|
||||
|
||||
const (
|
||||
_F_rel1 = 1 << iota
|
||||
_F_rel4
|
||||
)
|
||||
|
||||
type _Encoding struct {
|
||||
len int
|
||||
flags int
|
||||
bytes [_N_inst]byte
|
||||
encoder func(m *_Encoding, v []interface{})
|
||||
}
|
||||
|
||||
// buf ensures len + n <= len(bytes).
|
||||
func (self *_Encoding) buf(n int) []byte {
|
||||
if i := self.len; i + n > _N_inst {
|
||||
panic("instruction too long")
|
||||
} else {
|
||||
return self.bytes[i:]
|
||||
}
|
||||
}
|
||||
|
||||
// emit encodes a single byte.
|
||||
func (self *_Encoding) emit(v byte) {
|
||||
self.buf(1)[0] = v
|
||||
self.len++
|
||||
}
|
||||
|
||||
// imm1 encodes a single byte immediate value.
|
||||
func (self *_Encoding) imm1(v int64) {
|
||||
self.emit(byte(v))
|
||||
}
|
||||
|
||||
// imm2 encodes a two-byte immediate value in little-endian.
|
||||
func (self *_Encoding) imm2(v int64) {
|
||||
binary.LittleEndian.PutUint16(self.buf(2), uint16(v))
|
||||
self.len += 2
|
||||
}
|
||||
|
||||
// imm4 encodes a 4-byte immediate value in little-endian.
|
||||
func (self *_Encoding) imm4(v int64) {
|
||||
binary.LittleEndian.PutUint32(self.buf(4), uint32(v))
|
||||
self.len += 4
|
||||
}
|
||||
|
||||
// imm8 encodes an 8-byte immediate value in little-endian.
|
||||
func (self *_Encoding) imm8(v int64) {
|
||||
binary.LittleEndian.PutUint64(self.buf(8), uint64(v))
|
||||
self.len += 8
|
||||
}
|
||||
|
||||
// vex2 encodes a 2-byte or 3-byte VEX prefix.
|
||||
//
|
||||
// 2-byte VEX prefix:
|
||||
// Requires: VEX.W = 0, VEX.mmmmm = 0b00001 and VEX.B = VEX.X = 0
|
||||
// +----------------+
|
||||
// Byte 0: | Bits 0-7: 0xc5 |
|
||||
// +----------------+
|
||||
//
|
||||
// +-----------+----------------+----------+--------------+
|
||||
// Byte 1: | Bit 7: ~R | Bits 3-6 ~vvvv | Bit 2: L | Bits 0-1: pp |
|
||||
// +-----------+----------------+----------+--------------+
|
||||
//
|
||||
// 3-byte VEX prefix:
|
||||
// +----------------+
|
||||
// Byte 0: | Bits 0-7: 0xc4 |
|
||||
// +----------------+
|
||||
//
|
||||
// +-----------+-----------+-----------+-------------------+
|
||||
// Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: 0b00001 |
|
||||
// +-----------+-----------+-----------+-------------------+
|
||||
//
|
||||
// +----------+-----------------+----------+--------------+
|
||||
// Byte 2: | Bit 7: 0 | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
|
||||
// +----------+-----------------+----------+--------------+
|
||||
//
|
||||
func (self *_Encoding) vex2(lpp byte, r byte, rm interface{}, vvvv byte) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* VEX.R must be a single-bit mask */
|
||||
if r > 1 {
|
||||
panic("VEX.R must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* VEX.Lpp must be a 3-bit mask */
|
||||
if lpp &^ 0b111 != 0 {
|
||||
panic("VEX.Lpp must be a 3-bit mask")
|
||||
}
|
||||
|
||||
/* VEX.vvvv must be a 4-bit mask */
|
||||
if vvvv &^ 0b1111 != 0 {
|
||||
panic("VEX.vvvv must be a 4-bit mask")
|
||||
}
|
||||
|
||||
/* encode the RM bits if any */
|
||||
if rm != nil {
|
||||
switch v := rm.(type) {
|
||||
case *Label : break
|
||||
case Register : b = hcode(v)
|
||||
case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
}
|
||||
|
||||
/* if VEX.B and VEX.X are zeroes, 2-byte VEX prefix can be used */
|
||||
if x == 0 && b == 0 {
|
||||
self.emit(0xc5)
|
||||
self.emit(0xf8 ^ (r << 7) ^ (vvvv << 3) ^ lpp)
|
||||
} else {
|
||||
self.emit(0xc4)
|
||||
self.emit(0xe1 ^ (r << 7) ^ (x << 6) ^ (b << 5))
|
||||
self.emit(0x78 ^ (vvvv << 3) ^ lpp)
|
||||
}
|
||||
}
|
||||
|
||||
// vex3 encodes a 3-byte VEX or XOP prefix.
|
||||
//
|
||||
// 3-byte VEX/XOP prefix
|
||||
// +-----------------------------------+
|
||||
// Byte 0: | Bits 0-7: 0xc4 (VEX) / 0x8f (XOP) |
|
||||
// +-----------------------------------+
|
||||
//
|
||||
// +-----------+-----------+-----------+-----------------+
|
||||
// Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: mmmmm |
|
||||
// +-----------+-----------+-----------+-----------------+
|
||||
//
|
||||
// +----------+-----------------+----------+--------------+
|
||||
// Byte 2: | Bit 7: W | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
|
||||
// +----------+-----------------+----------+--------------+
|
||||
//
|
||||
func (self *_Encoding) vex3(esc byte, mmmmm byte, wlpp byte, r byte, rm interface{}, vvvv byte) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* VEX.R must be a single-bit mask */
|
||||
if r > 1 {
|
||||
panic("VEX.R must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* VEX.vvvv must be a 4-bit mask */
|
||||
if vvvv &^ 0b1111 != 0 {
|
||||
panic("VEX.vvvv must be a 4-bit mask")
|
||||
}
|
||||
|
||||
/* escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix */
|
||||
if esc != 0xc4 && esc != 0x8f {
|
||||
panic("escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix")
|
||||
}
|
||||
|
||||
/* VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7 */
|
||||
if wlpp &^ 0b10000111 != 0 {
|
||||
panic("VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7")
|
||||
}
|
||||
|
||||
/* VEX.m-mmmm is expected to be a 5-bit mask */
|
||||
if mmmmm &^ 0b11111 != 0 {
|
||||
panic("VEX.m-mmmm is expected to be a 5-bit mask")
|
||||
}
|
||||
|
||||
/* encode the RM bits */
|
||||
switch v := rm.(type) {
|
||||
case *Label : break
|
||||
case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
|
||||
/* encode the 3-byte VEX or XOP prefix */
|
||||
self.emit(esc)
|
||||
self.emit(0xe0 ^ (r << 7) ^ (x << 6) ^ (b << 5) ^ mmmmm)
|
||||
self.emit(0x78 ^ (vvvv << 3) ^ wlpp)
|
||||
}
|
||||
|
||||
// evex encodes a 4-byte EVEX prefix.
|
||||
func (self *_Encoding) evex(mm byte, w1pp byte, ll byte, rr byte, rm interface{}, vvvvv byte, aaa byte, zz byte, bb byte) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* EVEX.b must be a single-bit mask */
|
||||
if bb > 1 {
|
||||
panic("EVEX.b must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.z must be a single-bit mask */
|
||||
if zz > 1 {
|
||||
panic("EVEX.z must be a 1-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.mm must be a 2-bit mask */
|
||||
if mm &^ 0b11 != 0 {
|
||||
panic("EVEX.mm must be a 2-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.L'L must be a 2-bit mask */
|
||||
if ll &^ 0b11 != 0 {
|
||||
panic("EVEX.L'L must be a 2-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.R'R must be a 2-bit mask */
|
||||
if rr &^ 0b11 != 0 {
|
||||
panic("EVEX.R'R must be a 2-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.aaa must be a 3-bit mask */
|
||||
if aaa &^ 0b111 != 0 {
|
||||
panic("EVEX.aaa must be a 3-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.v'vvvv must be a 5-bit mask */
|
||||
if vvvvv &^ 0b11111 != 0 {
|
||||
panic("EVEX.v'vvvv must be a 5-bit mask")
|
||||
}
|
||||
|
||||
/* EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7 */
|
||||
if w1pp &^ 0b10000011 != 0b100 {
|
||||
panic("EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7")
|
||||
}
|
||||
|
||||
/* extract bits from EVEX.R'R and EVEX.v'vvvv */
|
||||
r1, r0 := rr >> 1, rr & 1
|
||||
v1, v0 := vvvvv >> 4, vvvvv & 0b1111
|
||||
|
||||
/* encode the RM bits if any */
|
||||
if rm != nil {
|
||||
switch m := rm.(type) {
|
||||
case *Label : break
|
||||
case Register : b, x = hcode(m), ecode(m)
|
||||
case MemoryAddress : b, x, v1 = toHcodeOpt(m.Base), toHcodeOpt(m.Index), toEcodeVMM(m.Index, v1)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
}
|
||||
|
||||
/* EVEX prefix bytes */
|
||||
p0 := (r0 << 7) | (x << 6) | (b << 5) | (r1 << 4) | mm
|
||||
p1 := (v0 << 3) | w1pp
|
||||
p2 := (zz << 7) | (ll << 5) | (b << 4) | (v1 << 3) | aaa
|
||||
|
||||
/* p0: invert RXBR' (bits 4-7)
|
||||
* p1: invert vvvv (bits 3-6)
|
||||
* p2: invert V' (bit 3) */
|
||||
self.emit(0x62)
|
||||
self.emit(p0 ^ 0xf0)
|
||||
self.emit(p1 ^ 0x78)
|
||||
self.emit(p2 ^ 0x08)
|
||||
}
|
||||
|
||||
// rexm encodes a mandatory REX prefix.
|
||||
func (self *_Encoding) rexm(w byte, r byte, rm interface{}) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* REX.R must be 0 or 1 */
|
||||
if r != 0 && r != 1 {
|
||||
panic("REX.R must be 0 or 1")
|
||||
}
|
||||
|
||||
/* REX.W must be 0 or 1 */
|
||||
if w != 0 && w != 1 {
|
||||
panic("REX.W must be 0 or 1")
|
||||
}
|
||||
|
||||
/* encode the RM bits */
|
||||
switch v := rm.(type) {
|
||||
case *Label : break
|
||||
case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
|
||||
/* encode the REX prefix */
|
||||
self.emit(0x40 | (w << 3) | (r << 2) | (x << 1) | b)
|
||||
}
|
||||
|
||||
// rexo encodes an optional REX prefix.
|
||||
func (self *_Encoding) rexo(r byte, rm interface{}, force bool) {
|
||||
var b byte
|
||||
var x byte
|
||||
|
||||
/* REX.R must be 0 or 1 */
|
||||
if r != 0 && r != 1 {
|
||||
panic("REX.R must be 0 or 1")
|
||||
}
|
||||
|
||||
/* encode the RM bits */
|
||||
switch v := rm.(type) {
|
||||
case *Label : break
|
||||
case Register : b = hcode(v)
|
||||
case MemoryAddress : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
|
||||
case RelativeOffset : break
|
||||
default : panic("rm is expected to be a register or a memory address")
|
||||
}
|
||||
|
||||
/* if REX.R, REX.X, and REX.B are all zeroes, REX prefix can be omitted */
|
||||
if force || r != 0 || x != 0 || b != 0 {
|
||||
self.emit(0x40 | (r << 2) | (x << 1) | b)
|
||||
}
|
||||
}
|
||||
|
||||
// mrsd encodes ModR/M, SIB and Displacement.
|
||||
//
|
||||
// ModR/M byte
|
||||
// +----------------+---------------+---------------+
|
||||
// | Bits 6-7: Mode | Bits 3-5: Reg | Bits 0-2: R/M |
|
||||
// +----------------+---------------+---------------+
|
||||
//
|
||||
// SIB byte
|
||||
// +-----------------+-----------------+----------------+
|
||||
// | Bits 6-7: Scale | Bits 3-5: Index | Bits 0-2: Base |
|
||||
// +-----------------+-----------------+----------------+
|
||||
//
|
||||
func (self *_Encoding) mrsd(reg byte, rm interface{}, disp8v int32) {
|
||||
var ok bool
|
||||
var mm MemoryAddress
|
||||
var ro RelativeOffset
|
||||
|
||||
/* ModRM encodes the lower 3-bit of the register */
|
||||
if reg > 7 {
|
||||
panic("invalid register bits")
|
||||
}
|
||||
|
||||
/* check the displacement scale */
|
||||
switch disp8v {
|
||||
case 1: break
|
||||
case 2: break
|
||||
case 4: break
|
||||
case 8: break
|
||||
case 16: break
|
||||
case 32: break
|
||||
case 64: break
|
||||
default: panic("invalid displacement size")
|
||||
}
|
||||
|
||||
/* special case: unresolved labels, assuming a zero offset */
|
||||
if _, ok = rm.(*Label); ok {
|
||||
self.emit(0x05 | (reg << 3))
|
||||
self.imm4(0)
|
||||
return
|
||||
}
|
||||
|
||||
/* special case: RIP-relative offset
|
||||
* ModRM.Mode == 0 and ModeRM.R/M == 5 indicates (rip + disp32) addressing */
|
||||
if ro, ok = rm.(RelativeOffset); ok {
|
||||
self.emit(0x05 | (reg << 3))
|
||||
self.imm4(int64(ro))
|
||||
return
|
||||
}
|
||||
|
||||
/* must be a generic memory address */
|
||||
if mm, ok = rm.(MemoryAddress); !ok {
|
||||
panic("rm must be a memory address")
|
||||
}
|
||||
|
||||
/* absolute addressing, encoded as disp(%rbp,%rsp,1) */
|
||||
if mm.Base == nil && mm.Index == nil {
|
||||
self.emit(0x04 | (reg << 3))
|
||||
self.emit(0x25)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
return
|
||||
}
|
||||
|
||||
/* no SIB byte */
|
||||
if mm.Index == nil && lcode(mm.Base) != 0b100 {
|
||||
cc := lcode(mm.Base)
|
||||
dv := mm.Displacement
|
||||
|
||||
/* ModRM.Mode == 0 (no displacement) */
|
||||
if dv == 0 && mm.Base != RBP && mm.Base != R13 {
|
||||
if cc == 0b101 {
|
||||
panic("rbp/r13 is not encodable as a base register (interpreted as disp32 address)")
|
||||
} else {
|
||||
self.emit((reg << 3) | cc)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 1 (8-bit displacement) */
|
||||
if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv % disp8v == 0 {
|
||||
self.emit(0x40 | (reg << 3) | cc)
|
||||
self.imm1(int64(dq))
|
||||
return
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 2 (32-bit displacement) */
|
||||
self.emit(0x80 | (reg << 3) | cc)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
return
|
||||
}
|
||||
|
||||
/* all encodings below use ModRM.R/M = 4 (0b100) to indicate the presence of SIB */
|
||||
if mm.Index == RSP {
|
||||
panic("rsp is not encodable as an index register (interpreted as no index)")
|
||||
}
|
||||
|
||||
/* index = 4 (0b100) denotes no-index encoding */
|
||||
var scale byte
|
||||
var index byte = 0x04
|
||||
|
||||
/* encode the scale byte */
|
||||
if mm.Scale != 0 {
|
||||
switch mm.Scale {
|
||||
case 1 : scale = 0
|
||||
case 2 : scale = 1
|
||||
case 4 : scale = 2
|
||||
case 8 : scale = 3
|
||||
default : panic("invalid scale value")
|
||||
}
|
||||
}
|
||||
|
||||
/* encode the index byte */
|
||||
if mm.Index != nil {
|
||||
index = lcode(mm.Index)
|
||||
}
|
||||
|
||||
/* SIB.Base = 5 (0b101) and ModRM.Mode = 0 indicates no-base encoding with disp32 */
|
||||
if mm.Base == nil {
|
||||
self.emit((reg << 3) | 0b100)
|
||||
self.emit((scale << 6) | (index << 3) | 0b101)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
return
|
||||
}
|
||||
|
||||
/* base L-code & displacement value */
|
||||
cc := lcode(mm.Base)
|
||||
dv := mm.Displacement
|
||||
|
||||
/* ModRM.Mode == 0 (no displacement) */
|
||||
if dv == 0 && cc != 0b101 {
|
||||
self.emit((reg << 3) | 0b100)
|
||||
self.emit((scale << 6) | (index << 3) | cc)
|
||||
return
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 1 (8-bit displacement) */
|
||||
if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv % disp8v == 0 {
|
||||
self.emit(0x44 | (reg << 3))
|
||||
self.emit((scale << 6) | (index << 3) | cc)
|
||||
self.imm1(int64(dq))
|
||||
return
|
||||
}
|
||||
|
||||
/* ModRM.Mode == 2 (32-bit displacement) */
|
||||
self.emit(0x84 | (reg << 3))
|
||||
self.emit((scale << 6) | (index << 3) | cc)
|
||||
self.imm4(int64(mm.Displacement))
|
||||
}
|
||||
|
||||
// encode invokes the encoder to encode this instruction.
|
||||
func (self *_Encoding) encode(v []interface{}) int {
|
||||
self.len = 0
|
||||
self.encoder(self, v)
|
||||
return self.len
|
||||
}
|
97210
vendor/github.com/cloudwego/iasm/x86_64/instructions.go
generated
vendored
Normal file
97210
vendor/github.com/cloudwego/iasm/x86_64/instructions.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12307
vendor/github.com/cloudwego/iasm/x86_64/instructions_table.go
generated
vendored
Normal file
12307
vendor/github.com/cloudwego/iasm/x86_64/instructions_table.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
665
vendor/github.com/cloudwego/iasm/x86_64/operands.go
generated
vendored
Normal file
665
vendor/github.com/cloudwego/iasm/x86_64/operands.go
generated
vendored
Normal file
@ -0,0 +1,665 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// RelativeOffset represents an RIP-relative offset.
|
||||
type RelativeOffset int32
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self RelativeOffset) String() string {
|
||||
if self == 0 {
|
||||
return "(%rip)"
|
||||
} else {
|
||||
return fmt.Sprintf("%d(%%rip)", self)
|
||||
}
|
||||
}
|
||||
|
||||
// RoundingControl represents a floating-point rounding option.
|
||||
type RoundingControl uint8
|
||||
|
||||
const (
|
||||
// RN_SAE represents "Round Nearest", which is the default rounding option.
|
||||
RN_SAE RoundingControl = iota
|
||||
|
||||
// RD_SAE represents "Round Down".
|
||||
RD_SAE
|
||||
|
||||
// RU_SAE represents "Round Up".
|
||||
RU_SAE
|
||||
|
||||
// RZ_SAE represents "Round towards Zero".
|
||||
RZ_SAE
|
||||
)
|
||||
|
||||
var _RC_NAMES = map[RoundingControl]string{
|
||||
RN_SAE: "rn-sae",
|
||||
RD_SAE: "rd-sae",
|
||||
RU_SAE: "ru-sae",
|
||||
RZ_SAE: "rz-sae",
|
||||
}
|
||||
|
||||
func (self RoundingControl) String() string {
|
||||
if v, ok := _RC_NAMES[self]; ok {
|
||||
return v
|
||||
} else {
|
||||
panic("invalid RoundingControl value")
|
||||
}
|
||||
}
|
||||
|
||||
// ExceptionControl represents the "Suppress All Exceptions" flag.
|
||||
type ExceptionControl uint8
|
||||
|
||||
const (
|
||||
// SAE represents the flag "Suppress All Exceptions" for floating point operations.
|
||||
SAE ExceptionControl = iota
|
||||
)
|
||||
|
||||
func (ExceptionControl) String() string {
|
||||
return "sae"
|
||||
}
|
||||
|
||||
// AddressType indicates which kind of value that an Addressable object contains.
|
||||
type AddressType uint
|
||||
|
||||
const (
|
||||
// None indicates the Addressable does not contain any addressable value.
|
||||
None AddressType = iota
|
||||
|
||||
// Memory indicates the Addressable contains a memory address.
|
||||
Memory
|
||||
|
||||
// Offset indicates the Addressable contains an RIP-relative offset.
|
||||
Offset
|
||||
|
||||
// Reference indicates the Addressable contains a label reference.
|
||||
Reference
|
||||
)
|
||||
|
||||
// Disposable is a type of object that can be Free'd manually.
|
||||
type Disposable interface {
|
||||
Free()
|
||||
}
|
||||
|
||||
// Label represents a location within the program.
|
||||
type Label struct {
|
||||
refs int64
|
||||
Name string
|
||||
Dest *Instruction
|
||||
}
|
||||
|
||||
func (self *Label) offset(p uintptr, n int) RelativeOffset {
|
||||
if self.Dest == nil {
|
||||
panic("unresolved label: " + self.Name)
|
||||
} else {
|
||||
return RelativeOffset(self.Dest.pc - p - uintptr(n))
|
||||
}
|
||||
}
|
||||
|
||||
// Free decreases the reference count of a Label, if the
|
||||
// refcount drops to 0, the Label will be recycled.
|
||||
func (self *Label) Free() {
|
||||
if atomic.AddInt64(&self.refs, -1) == 0 {
|
||||
//freeLabel(self)
|
||||
}
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self *Label) String() string {
|
||||
if self.Dest == nil {
|
||||
return fmt.Sprintf("%s(%%rip)", self.Name)
|
||||
} else {
|
||||
return fmt.Sprintf("%s(%%rip)@%#x", self.Name, self.Dest.pc)
|
||||
}
|
||||
}
|
||||
|
||||
// Retain increases the reference count of a Label.
|
||||
func (self *Label) Retain() *Label {
|
||||
atomic.AddInt64(&self.refs, 1)
|
||||
return self
|
||||
}
|
||||
|
||||
// Evaluate implements the interface expr.Term.
|
||||
func (self *Label) Evaluate() (int64, error) {
|
||||
if self.Dest != nil {
|
||||
return int64(self.Dest.pc), nil
|
||||
} else {
|
||||
return 0, errors.New("unresolved label: " + self.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Addressable is a union to represent an addressable operand.
|
||||
type Addressable struct {
|
||||
Type AddressType
|
||||
Memory MemoryAddress
|
||||
Offset RelativeOffset
|
||||
Reference *Label
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self *Addressable) String() string {
|
||||
switch self.Type {
|
||||
case None:
|
||||
return "(not addressable)"
|
||||
case Memory:
|
||||
return self.Memory.String()
|
||||
case Offset:
|
||||
return self.Offset.String()
|
||||
case Reference:
|
||||
return self.Reference.String()
|
||||
default:
|
||||
return "(invalid addressable)"
|
||||
}
|
||||
}
|
||||
|
||||
// MemoryOperand represents a memory operand for an instruction.
|
||||
type MemoryOperand struct {
|
||||
refs int64
|
||||
Size int
|
||||
Addr Addressable
|
||||
Mask RegisterMask
|
||||
Masked bool
|
||||
Broadcast uint8
|
||||
}
|
||||
|
||||
const (
|
||||
_Sizes = 0b10000000100010111 // bit-mask for valid sizes (0, 1, 2, 4, 8, 16)
|
||||
)
|
||||
|
||||
func (self *MemoryOperand) isVMX(evex bool) bool {
|
||||
return self.Addr.Type == Memory && self.Addr.Memory.isVMX(evex)
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) isVMY(evex bool) bool {
|
||||
return self.Addr.Type == Memory && self.Addr.Memory.isVMY(evex)
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) isVMZ() bool {
|
||||
return self.Addr.Type == Memory && self.Addr.Memory.isVMZ()
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) isMem() bool {
|
||||
if (_Sizes & (1 << self.Broadcast)) == 0 {
|
||||
return false
|
||||
} else if self.Addr.Type == Memory {
|
||||
return self.Addr.Memory.isMem()
|
||||
} else if self.Addr.Type == Offset {
|
||||
return true
|
||||
} else if self.Addr.Type == Reference {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) isSize(n int) bool {
|
||||
return self.Size == 0 || self.Size == n
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) isBroadcast(n int, b uint8) bool {
|
||||
return self.Size == n && self.Broadcast == b
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) formatMask() string {
|
||||
if !self.Masked {
|
||||
return ""
|
||||
} else {
|
||||
return self.Mask.String()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) formatBroadcast() string {
|
||||
if self.Broadcast == 0 {
|
||||
return ""
|
||||
} else {
|
||||
return fmt.Sprintf("{1to%d}", self.Broadcast)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) ensureAddrValid() {
|
||||
switch self.Addr.Type {
|
||||
case None:
|
||||
break
|
||||
case Memory:
|
||||
self.Addr.Memory.EnsureValid()
|
||||
case Offset:
|
||||
break
|
||||
case Reference:
|
||||
break
|
||||
default:
|
||||
panic("invalid address type")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) ensureSizeValid() {
|
||||
if (_Sizes & (1 << self.Size)) == 0 {
|
||||
panic("invalid memory operand size")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *MemoryOperand) ensureBroadcastValid() {
|
||||
if (_Sizes & (1 << self.Broadcast)) == 0 {
|
||||
panic("invalid memory operand broadcast")
|
||||
}
|
||||
}
|
||||
|
||||
// Free decreases the reference count of a MemoryOperand, if the
|
||||
// refcount drops to 0, the Label will be recycled.
|
||||
func (self *MemoryOperand) Free() {
|
||||
if atomic.AddInt64(&self.refs, -1) == 0 {
|
||||
//freeMemoryOperand(self)
|
||||
}
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self *MemoryOperand) String() string {
|
||||
return self.Addr.String() + self.formatMask() + self.formatBroadcast()
|
||||
}
|
||||
|
||||
// Retain increases the reference count of a MemoryOperand.
|
||||
func (self *MemoryOperand) Retain() *MemoryOperand {
|
||||
atomic.AddInt64(&self.refs, 1)
|
||||
return self
|
||||
}
|
||||
|
||||
// EnsureValid checks if the memory operand is valid, if not, it panics.
|
||||
func (self *MemoryOperand) EnsureValid() {
|
||||
self.ensureAddrValid()
|
||||
self.ensureSizeValid()
|
||||
self.ensureBroadcastValid()
|
||||
}
|
||||
|
||||
// MemoryAddress represents a memory address.
|
||||
type MemoryAddress struct {
|
||||
Base Register
|
||||
Index Register
|
||||
Scale uint8
|
||||
Displacement int32
|
||||
}
|
||||
|
||||
const (
|
||||
_Scales = 0b100010111 // bit-mask for valid scales (0, 1, 2, 4, 8)
|
||||
)
|
||||
|
||||
func (self *MemoryAddress) isVMX(evex bool) bool {
|
||||
return self.isMemBase() && (self.Index == nil || isXMM(self.Index) || (evex && isEVEXXMM(self.Index)))
|
||||
}
|
||||
|
||||
func (self *MemoryAddress) isVMY(evex bool) bool {
|
||||
return self.isMemBase() && (self.Index == nil || isYMM(self.Index) || (evex && isEVEXYMM(self.Index)))
|
||||
}
|
||||
|
||||
func (self *MemoryAddress) isVMZ() bool {
|
||||
return self.isMemBase() && (self.Index == nil || isZMM(self.Index))
|
||||
}
|
||||
|
||||
func (self *MemoryAddress) isMem() bool {
|
||||
return self.isMemBase() && (self.Index == nil || isReg64(self.Index))
|
||||
}
|
||||
|
||||
func (self *MemoryAddress) isMemBase() bool {
|
||||
return (self.Base == nil || isReg64(self.Base)) && // `Base` must be 64-bit if present
|
||||
(self.Scale == 0) == (self.Index == nil) && // `Scale` and `Index` depends on each other
|
||||
(_Scales&(1<<self.Scale)) != 0 // `Scale` can only be 0, 1, 2, 4 or 8
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self *MemoryAddress) String() string {
|
||||
var dp int
|
||||
var sb strings.Builder
|
||||
|
||||
/* the displacement part */
|
||||
if dp = int(self.Displacement); dp != 0 {
|
||||
sb.WriteString(strconv.Itoa(dp))
|
||||
}
|
||||
|
||||
/* the base register */
|
||||
if sb.WriteByte('('); self.Base != nil {
|
||||
sb.WriteByte('%')
|
||||
sb.WriteString(self.Base.String())
|
||||
}
|
||||
|
||||
/* index is optional */
|
||||
if self.Index != nil {
|
||||
sb.WriteString(",%")
|
||||
sb.WriteString(self.Index.String())
|
||||
|
||||
/* scale is also optional */
|
||||
if self.Scale >= 2 {
|
||||
sb.WriteByte(',')
|
||||
sb.WriteString(strconv.Itoa(int(self.Scale)))
|
||||
}
|
||||
}
|
||||
|
||||
/* close the bracket */
|
||||
sb.WriteByte(')')
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// EnsureValid checks if the memory address is valid, if not, it panics.
|
||||
func (self *MemoryAddress) EnsureValid() {
|
||||
if !self.isMemBase() || (self.Index != nil && !isIndexable(self.Index)) {
|
||||
panic("not a valid memory address")
|
||||
}
|
||||
}
|
||||
|
||||
// Ref constructs a memory reference to a label.
|
||||
func Ref(ref *Label) (v *MemoryOperand) {
|
||||
v = CreateMemoryOperand()
|
||||
v.Addr.Type = Reference
|
||||
v.Addr.Reference = ref
|
||||
return
|
||||
}
|
||||
|
||||
// Abs construct a simple memory address that represents absolute addressing.
|
||||
func Abs(disp int32) *MemoryOperand {
|
||||
return Sib(nil, nil, 0, disp)
|
||||
}
|
||||
|
||||
// Ptr constructs a simple memory operand with base and displacement.
|
||||
func Ptr(base Register, disp int32) *MemoryOperand {
|
||||
return Sib(base, nil, 0, disp)
|
||||
}
|
||||
|
||||
// Sib constructs a simple memory operand that represents a complete memory address.
|
||||
func Sib(base Register, index Register, scale uint8, disp int32) (v *MemoryOperand) {
|
||||
v = CreateMemoryOperand()
|
||||
v.Addr.Type = Memory
|
||||
v.Addr.Memory.Base = base
|
||||
v.Addr.Memory.Index = index
|
||||
v.Addr.Memory.Scale = scale
|
||||
v.Addr.Memory.Displacement = disp
|
||||
v.EnsureValid()
|
||||
return
|
||||
}
|
||||
|
||||
/** Operand Matching Helpers **/
|
||||
|
||||
const _IntMask = (1 << reflect.Int) |
|
||||
(1 << reflect.Int8) |
|
||||
(1 << reflect.Int16) |
|
||||
(1 << reflect.Int32) |
|
||||
(1 << reflect.Int64) |
|
||||
(1 << reflect.Uint) |
|
||||
(1 << reflect.Uint8) |
|
||||
(1 << reflect.Uint16) |
|
||||
(1 << reflect.Uint32) |
|
||||
(1 << reflect.Uint64) |
|
||||
(1 << reflect.Uintptr)
|
||||
|
||||
func isInt(k reflect.Kind) bool {
|
||||
return (_IntMask & (1 << k)) != 0
|
||||
}
|
||||
|
||||
func asInt64(v interface{}) (int64, bool) {
|
||||
if isSpecial(v) {
|
||||
return 0, false
|
||||
} else if x := efaceOf(v); isInt(x.kind()) {
|
||||
return x.toInt64(), true
|
||||
} else {
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
func inRange(v interface{}, low int64, high int64) bool {
|
||||
x, ok := asInt64(v)
|
||||
return ok && x >= low && x <= high
|
||||
}
|
||||
|
||||
func isSpecial(v interface{}) bool {
|
||||
switch v.(type) {
|
||||
case Register8:
|
||||
return true
|
||||
case Register16:
|
||||
return true
|
||||
case Register32:
|
||||
return true
|
||||
case Register64:
|
||||
return true
|
||||
case KRegister:
|
||||
return true
|
||||
case MMRegister:
|
||||
return true
|
||||
case XMMRegister:
|
||||
return true
|
||||
case YMMRegister:
|
||||
return true
|
||||
case ZMMRegister:
|
||||
return true
|
||||
case RelativeOffset:
|
||||
return true
|
||||
case RoundingControl:
|
||||
return true
|
||||
case ExceptionControl:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isIndexable(v interface{}) bool {
|
||||
return isZMM(v) || isReg64(v) || isEVEXXMM(v) || isEVEXYMM(v)
|
||||
}
|
||||
|
||||
func isImm4(v interface{}) bool { return inRange(v, 0, 15) }
|
||||
func isImm8(v interface{}) bool { return inRange(v, math.MinInt8, math.MaxUint8) }
|
||||
func isImm16(v interface{}) bool { return inRange(v, math.MinInt16, math.MaxUint16) }
|
||||
func isImm32(v interface{}) bool { return inRange(v, math.MinInt32, math.MaxUint32) }
|
||||
func isImm64(v interface{}) bool { _, r := asInt64(v); return r }
|
||||
func isConst1(v interface{}) bool { x, r := asInt64(v); return r && x == 1 }
|
||||
func isConst3(v interface{}) bool { x, r := asInt64(v); return r && x == 3 }
|
||||
func isRel8(v interface{}) bool {
|
||||
x, r := v.(RelativeOffset)
|
||||
return r && x >= math.MinInt8 && x <= math.MaxInt8
|
||||
}
|
||||
func isRel32(v interface{}) bool { _, r := v.(RelativeOffset); return r }
|
||||
func isLabel(v interface{}) bool { _, r := v.(*Label); return r }
|
||||
func isReg8(v interface{}) bool { _, r := v.(Register8); return r }
|
||||
func isReg8REX(v interface{}) bool {
|
||||
x, r := v.(Register8)
|
||||
return r && (x&0x80) == 0 && x >= SPL
|
||||
}
|
||||
func isReg16(v interface{}) bool { _, r := v.(Register16); return r }
|
||||
func isReg32(v interface{}) bool { _, r := v.(Register32); return r }
|
||||
func isReg64(v interface{}) bool { _, r := v.(Register64); return r }
|
||||
func isMM(v interface{}) bool { _, r := v.(MMRegister); return r }
|
||||
func isXMM(v interface{}) bool { x, r := v.(XMMRegister); return r && x <= XMM15 }
|
||||
func isEVEXXMM(v interface{}) bool { _, r := v.(XMMRegister); return r }
|
||||
func isXMMk(v interface{}) bool {
|
||||
x, r := v.(MaskedRegister)
|
||||
return isXMM(v) || (r && isXMM(x.Reg) && !x.Mask.Z)
|
||||
}
|
||||
func isXMMkz(v interface{}) bool {
|
||||
x, r := v.(MaskedRegister)
|
||||
return isXMM(v) || (r && isXMM(x.Reg))
|
||||
}
|
||||
func isYMM(v interface{}) bool { x, r := v.(YMMRegister); return r && x <= YMM15 }
|
||||
func isEVEXYMM(v interface{}) bool { _, r := v.(YMMRegister); return r }
|
||||
func isYMMk(v interface{}) bool {
|
||||
x, r := v.(MaskedRegister)
|
||||
return isYMM(v) || (r && isYMM(x.Reg) && !x.Mask.Z)
|
||||
}
|
||||
func isYMMkz(v interface{}) bool {
|
||||
x, r := v.(MaskedRegister)
|
||||
return isYMM(v) || (r && isYMM(x.Reg))
|
||||
}
|
||||
func isZMM(v interface{}) bool { _, r := v.(ZMMRegister); return r }
|
||||
func isZMMk(v interface{}) bool {
|
||||
x, r := v.(MaskedRegister)
|
||||
return isZMM(v) || (r && isZMM(x.Reg) && !x.Mask.Z)
|
||||
}
|
||||
func isZMMkz(v interface{}) bool {
|
||||
x, r := v.(MaskedRegister)
|
||||
return isZMM(v) || (r && isZMM(x.Reg))
|
||||
}
|
||||
func isK(v interface{}) bool { _, r := v.(KRegister); return r }
|
||||
func isKk(v interface{}) bool {
|
||||
x, r := v.(MaskedRegister)
|
||||
return isK(v) || (r && isK(x.Reg) && !x.Mask.Z)
|
||||
}
|
||||
func isM(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && x.isMem() && x.Broadcast == 0 && !x.Masked
|
||||
}
|
||||
func isMk(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && x.isMem() && x.Broadcast == 0 && !(x.Masked && x.Mask.Z)
|
||||
}
|
||||
func isMkz(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && x.isMem() && x.Broadcast == 0
|
||||
}
|
||||
func isM8(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isM(v) && x.isSize(1)
|
||||
}
|
||||
func isM16(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isM(v) && x.isSize(2)
|
||||
}
|
||||
func isM16kz(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isMkz(v) && x.isSize(2)
|
||||
}
|
||||
func isM32(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isM(v) && x.isSize(4)
|
||||
}
|
||||
func isM32k(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isMk(v) && x.isSize(4)
|
||||
}
|
||||
func isM32kz(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isMkz(v) && x.isSize(4)
|
||||
}
|
||||
func isM64(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isM(v) && x.isSize(8)
|
||||
}
|
||||
func isM64k(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isMk(v) && x.isSize(8)
|
||||
}
|
||||
func isM64kz(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isMkz(v) && x.isSize(8)
|
||||
}
|
||||
func isM128(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isM(v) && x.isSize(16)
|
||||
}
|
||||
func isM128kz(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isMkz(v) && x.isSize(16)
|
||||
}
|
||||
func isM256(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isM(v) && x.isSize(32)
|
||||
}
|
||||
func isM256kz(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isMkz(v) && x.isSize(32)
|
||||
}
|
||||
func isM512(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isM(v) && x.isSize(64)
|
||||
}
|
||||
func isM512kz(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && isMkz(v) && x.isSize(64)
|
||||
}
|
||||
func isM64M32bcst(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return isM64(v) || (r && x.isBroadcast(4, 2))
|
||||
}
|
||||
func isM128M32bcst(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return isM128(v) || (r && x.isBroadcast(4, 4))
|
||||
}
|
||||
func isM256M32bcst(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return isM256(v) || (r && x.isBroadcast(4, 8))
|
||||
}
|
||||
func isM512M32bcst(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return isM512(v) || (r && x.isBroadcast(4, 16))
|
||||
}
|
||||
func isM128M64bcst(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return isM128(v) || (r && x.isBroadcast(8, 2))
|
||||
}
|
||||
func isM256M64bcst(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return isM256(v) || (r && x.isBroadcast(8, 4))
|
||||
}
|
||||
func isM512M64bcst(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return isM512(v) || (r && x.isBroadcast(8, 8))
|
||||
}
|
||||
func isVMX(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && x.isVMX(false) && !x.Masked
|
||||
}
|
||||
func isEVEXVMX(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && x.isVMX(true) && !x.Masked
|
||||
}
|
||||
func isVMXk(v interface{}) bool { x, r := v.(*MemoryOperand); return r && x.isVMX(true) }
|
||||
func isVMY(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && x.isVMY(false) && !x.Masked
|
||||
}
|
||||
func isEVEXVMY(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && x.isVMY(true) && !x.Masked
|
||||
}
|
||||
func isVMYk(v interface{}) bool { x, r := v.(*MemoryOperand); return r && x.isVMY(true) }
|
||||
func isVMZ(v interface{}) bool {
|
||||
x, r := v.(*MemoryOperand)
|
||||
return r && x.isVMZ() && !x.Masked
|
||||
}
|
||||
func isVMZk(v interface{}) bool { x, r := v.(*MemoryOperand); return r && x.isVMZ() }
|
||||
func isSAE(v interface{}) bool { _, r := v.(ExceptionControl); return r }
|
||||
func isER(v interface{}) bool { _, r := v.(RoundingControl); return r }
|
||||
|
||||
func isImmExt(v interface{}, ext int, min int64, max int64) bool {
|
||||
if x, ok := asInt64(v); !ok {
|
||||
return false
|
||||
} else if m := int64(1) << (8 * ext); x < m && x >= m+min {
|
||||
return true
|
||||
} else {
|
||||
return x <= max && x >= min
|
||||
}
|
||||
}
|
||||
|
||||
func isImm8Ext(v interface{}, ext int) bool {
|
||||
return isImmExt(v, ext, math.MinInt8, math.MaxInt8)
|
||||
}
|
||||
|
||||
func isImm32Ext(v interface{}, ext int) bool {
|
||||
return isImmExt(v, ext, math.MinInt32, math.MaxInt32)
|
||||
}
|
54
vendor/github.com/cloudwego/iasm/x86_64/pools.go
generated
vendored
Normal file
54
vendor/github.com/cloudwego/iasm/x86_64/pools.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 x86_64
|
||||
|
||||
// CreateLabel creates a new Label, it may allocate a new one or grab one from a pool.
|
||||
func CreateLabel(name string) *Label {
|
||||
p := new(Label)
|
||||
|
||||
/* initialize the label */
|
||||
p.refs = 1
|
||||
p.Name = name
|
||||
return p
|
||||
}
|
||||
|
||||
func newProgram(arch *Arch) *Program {
|
||||
p := new(Program)
|
||||
|
||||
/* initialize the program */
|
||||
p.arch = arch
|
||||
return p
|
||||
}
|
||||
|
||||
func newInstruction(name string, argc int, argv Operands) *Instruction {
|
||||
p := new(Instruction)
|
||||
|
||||
/* initialize the instruction */
|
||||
p.name = name
|
||||
p.argc = argc
|
||||
p.argv = argv
|
||||
return p
|
||||
}
|
||||
|
||||
// CreateMemoryOperand creates a new MemoryOperand, it may allocate a new one or grab one from a pool.
|
||||
func CreateMemoryOperand() *MemoryOperand {
|
||||
p := new(MemoryOperand)
|
||||
|
||||
/* initialize the memory operand */
|
||||
p.refs = 1
|
||||
return p
|
||||
}
|
584
vendor/github.com/cloudwego/iasm/x86_64/program.go
generated
vendored
Normal file
584
vendor/github.com/cloudwego/iasm/x86_64/program.go
generated
vendored
Normal file
@ -0,0 +1,584 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/bits"
|
||||
|
||||
"github.com/cloudwego/iasm/expr"
|
||||
)
|
||||
|
||||
type (
|
||||
_PseudoType int
|
||||
_InstructionEncoder func(*Program, ...interface{}) *Instruction
|
||||
)
|
||||
|
||||
const (
|
||||
_PseudoNop _PseudoType = iota + 1
|
||||
_PseudoByte
|
||||
_PseudoWord
|
||||
_PseudoLong
|
||||
_PseudoQuad
|
||||
_PseudoData
|
||||
_PseudoAlign
|
||||
)
|
||||
|
||||
func (self _PseudoType) String() string {
|
||||
switch self {
|
||||
case _PseudoNop:
|
||||
return ".nop"
|
||||
case _PseudoByte:
|
||||
return ".byte"
|
||||
case _PseudoWord:
|
||||
return ".word"
|
||||
case _PseudoLong:
|
||||
return ".long"
|
||||
case _PseudoQuad:
|
||||
return ".quad"
|
||||
case _PseudoData:
|
||||
return ".data"
|
||||
case _PseudoAlign:
|
||||
return ".align"
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
||||
type _Pseudo struct {
|
||||
kind _PseudoType
|
||||
data []byte
|
||||
uint uint64
|
||||
expr *expr.Expr
|
||||
}
|
||||
|
||||
func (self *_Pseudo) free() {
|
||||
if self.expr != nil {
|
||||
self.expr.Free()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_Pseudo) encode(m *[]byte, pc uintptr) int {
|
||||
switch self.kind {
|
||||
case _PseudoNop:
|
||||
return 0
|
||||
case _PseudoByte:
|
||||
self.encodeByte(m)
|
||||
return 1
|
||||
case _PseudoWord:
|
||||
self.encodeWord(m)
|
||||
return 2
|
||||
case _PseudoLong:
|
||||
self.encodeLong(m)
|
||||
return 4
|
||||
case _PseudoQuad:
|
||||
self.encodeQuad(m)
|
||||
return 8
|
||||
case _PseudoData:
|
||||
self.encodeData(m)
|
||||
return len(self.data)
|
||||
case _PseudoAlign:
|
||||
self.encodeAlign(m, pc)
|
||||
return self.alignSize(pc)
|
||||
default:
|
||||
panic("invalid pseudo instruction")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_Pseudo) evalExpr(low int64, high int64) int64 {
|
||||
if v, err := self.expr.Evaluate(); err != nil {
|
||||
panic(err)
|
||||
} else if v < low || v > high {
|
||||
panic(fmt.Sprintf("expression out of range [%d, %d]: %d", low, high, v))
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_Pseudo) alignSize(pc uintptr) int {
|
||||
if !ispow2(self.uint) {
|
||||
panic(fmt.Sprintf("aligment should be a power of 2, not %d", self.uint))
|
||||
} else {
|
||||
return align(int(pc), bits.TrailingZeros64(self.uint)) - int(pc)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_Pseudo) encodeData(m *[]byte) {
|
||||
if m != nil {
|
||||
*m = append(*m, self.data...)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_Pseudo) encodeByte(m *[]byte) {
|
||||
if m != nil {
|
||||
append8(m, byte(self.evalExpr(math.MinInt8, math.MaxUint8)))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_Pseudo) encodeWord(m *[]byte) {
|
||||
if m != nil {
|
||||
append16(m, uint16(self.evalExpr(math.MinInt16, math.MaxUint16)))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_Pseudo) encodeLong(m *[]byte) {
|
||||
if m != nil {
|
||||
append32(m, uint32(self.evalExpr(math.MinInt32, math.MaxUint32)))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_Pseudo) encodeQuad(m *[]byte) {
|
||||
if m != nil {
|
||||
if v, err := self.expr.Evaluate(); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
append64(m, uint64(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_Pseudo) encodeAlign(m *[]byte, pc uintptr) {
|
||||
if m != nil {
|
||||
if self.expr == nil {
|
||||
expandmm(m, self.alignSize(pc), 0)
|
||||
} else {
|
||||
expandmm(m, self.alignSize(pc), byte(self.evalExpr(math.MinInt8, math.MaxUint8)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operands represents a sequence of operand required by an instruction.
|
||||
type Operands [_N_args]interface{}
|
||||
|
||||
// InstructionDomain represents the domain of an instruction.
|
||||
type InstructionDomain uint8
|
||||
|
||||
const (
|
||||
DomainGeneric InstructionDomain = iota
|
||||
DomainMMXSSE
|
||||
DomainAVX
|
||||
DomainFMA
|
||||
DomainCrypto
|
||||
DomainMask
|
||||
DomainAMDSpecific
|
||||
DomainMisc
|
||||
DomainPseudo
|
||||
)
|
||||
|
||||
type (
|
||||
_BranchType uint8
|
||||
)
|
||||
|
||||
const (
|
||||
_B_none _BranchType = iota
|
||||
_B_conditional
|
||||
_B_unconditional
|
||||
)
|
||||
|
||||
// Instruction represents an unencoded instruction.
|
||||
type Instruction struct {
|
||||
next *Instruction
|
||||
pc uintptr
|
||||
nb int
|
||||
len int
|
||||
argc int
|
||||
name string
|
||||
argv Operands
|
||||
forms [_N_forms]_Encoding
|
||||
pseudo _Pseudo
|
||||
branch _BranchType
|
||||
domain InstructionDomain
|
||||
prefix []byte
|
||||
}
|
||||
|
||||
func (self *Instruction) add(flags int, encoder func(m *_Encoding, v []interface{})) {
|
||||
self.forms[self.len].flags = flags
|
||||
self.forms[self.len].encoder = encoder
|
||||
self.len++
|
||||
}
|
||||
|
||||
func (self *Instruction) free() {
|
||||
self.clear()
|
||||
self.pseudo.free()
|
||||
//freeInstruction(self)
|
||||
}
|
||||
|
||||
func (self *Instruction) clear() {
|
||||
for i := 0; i < self.argc; i++ {
|
||||
if v, ok := self.argv[i].(Disposable); ok {
|
||||
v.Free()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Instruction) check(e *_Encoding) bool {
|
||||
if (e.flags & _F_rel1) != 0 {
|
||||
return isRel8(self.argv[0])
|
||||
} else if (e.flags & _F_rel4) != 0 {
|
||||
return isRel32(self.argv[0]) || isLabel(self.argv[0])
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Instruction) encode(m *[]byte) int {
|
||||
n := math.MaxInt64
|
||||
p := (*_Encoding)(nil)
|
||||
|
||||
/* encode prefixes if any */
|
||||
if self.nb = len(self.prefix); m != nil {
|
||||
*m = append(*m, self.prefix...)
|
||||
}
|
||||
|
||||
/* check for pseudo-instructions */
|
||||
if self.pseudo.kind != 0 {
|
||||
self.nb += self.pseudo.encode(m, self.pc)
|
||||
return self.nb
|
||||
}
|
||||
|
||||
/* find the shortest encoding */
|
||||
for i := 0; i < self.len; i++ {
|
||||
if e := &self.forms[i]; self.check(e) {
|
||||
if v := e.encode(self.argv[:self.argc]); v < n {
|
||||
n = v
|
||||
p = e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add to buffer if needed */
|
||||
if m != nil {
|
||||
*m = append(*m, p.bytes[:n]...)
|
||||
}
|
||||
|
||||
/* update the instruction length */
|
||||
self.nb += n
|
||||
return self.nb
|
||||
}
|
||||
|
||||
/** Instruction Prefixes **/
|
||||
|
||||
const (
|
||||
_P_cs = 0x2e
|
||||
_P_ds = 0x3e
|
||||
_P_es = 0x26
|
||||
_P_fs = 0x64
|
||||
_P_gs = 0x65
|
||||
_P_ss = 0x36
|
||||
_P_lock = 0xf0
|
||||
)
|
||||
|
||||
// CS overrides the memory operation of this instruction to CS.
|
||||
func (self *Instruction) CS() *Instruction {
|
||||
self.prefix = append(self.prefix, _P_cs)
|
||||
return self
|
||||
}
|
||||
|
||||
// DS overrides the memory operation of this instruction to DS,
|
||||
// this is the default section for most instructions if not specified.
|
||||
func (self *Instruction) DS() *Instruction {
|
||||
self.prefix = append(self.prefix, _P_ds)
|
||||
return self
|
||||
}
|
||||
|
||||
// ES overrides the memory operation of this instruction to ES.
|
||||
func (self *Instruction) ES() *Instruction {
|
||||
self.prefix = append(self.prefix, _P_es)
|
||||
return self
|
||||
}
|
||||
|
||||
// FS overrides the memory operation of this instruction to FS.
|
||||
func (self *Instruction) FS() *Instruction {
|
||||
self.prefix = append(self.prefix, _P_fs)
|
||||
return self
|
||||
}
|
||||
|
||||
// GS overrides the memory operation of this instruction to GS.
|
||||
func (self *Instruction) GS() *Instruction {
|
||||
self.prefix = append(self.prefix, _P_gs)
|
||||
return self
|
||||
}
|
||||
|
||||
// SS overrides the memory operation of this instruction to SS.
|
||||
func (self *Instruction) SS() *Instruction {
|
||||
self.prefix = append(self.prefix, _P_ss)
|
||||
return self
|
||||
}
|
||||
|
||||
// LOCK causes the processor's LOCK# signal to be asserted during execution of
|
||||
// the accompanying instruction (turns the instruction into an atomic instruction).
|
||||
// In a multiprocessor environment, the LOCK# signal insures that the processor
|
||||
// has exclusive use of any shared memory while the signal is asserted.
|
||||
func (self *Instruction) LOCK() *Instruction {
|
||||
self.prefix = append(self.prefix, _P_lock)
|
||||
return self
|
||||
}
|
||||
|
||||
/** Basic Instruction Properties **/
|
||||
|
||||
// Name returns the instruction name.
|
||||
func (self *Instruction) Name() string {
|
||||
return self.name
|
||||
}
|
||||
|
||||
// Domain returns the domain of this instruction.
|
||||
func (self *Instruction) Domain() InstructionDomain {
|
||||
return self.domain
|
||||
}
|
||||
|
||||
// Operands returns the operands of this instruction.
|
||||
func (self *Instruction) Operands() []interface{} {
|
||||
return self.argv[:self.argc]
|
||||
}
|
||||
|
||||
// Program represents a sequence of instructions.
|
||||
type Program struct {
|
||||
arch *Arch
|
||||
head *Instruction
|
||||
tail *Instruction
|
||||
}
|
||||
|
||||
const (
|
||||
_N_near = 2 // near-branch (-128 ~ +127) takes 2 bytes to encode
|
||||
_N_far_cond = 6 // conditional far-branch takes 6 bytes to encode
|
||||
_N_far_uncond = 5 // unconditional far-branch takes 5 bytes to encode
|
||||
)
|
||||
|
||||
func (self *Program) clear() {
|
||||
for p, q := self.head, self.head; p != nil; p = q {
|
||||
q = p.next
|
||||
p.free()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Program) alloc(name string, argc int, argv Operands) *Instruction {
|
||||
p := self.tail
|
||||
q := newInstruction(name, argc, argv)
|
||||
|
||||
/* attach to tail if any */
|
||||
if p != nil {
|
||||
p.next = q
|
||||
} else {
|
||||
self.head = q
|
||||
}
|
||||
|
||||
/* set the new tail */
|
||||
self.tail = q
|
||||
return q
|
||||
}
|
||||
|
||||
func (self *Program) pseudo(kind _PseudoType) (p *Instruction) {
|
||||
p = self.alloc(kind.String(), 0, Operands{})
|
||||
p.domain = DomainPseudo
|
||||
p.pseudo.kind = kind
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Program) require(isa ISA) {
|
||||
if !self.arch.HasISA(isa) {
|
||||
panic("ISA '" + isa.String() + "' was not enabled")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Program) branchSize(p *Instruction) int {
|
||||
switch p.branch {
|
||||
case _B_none:
|
||||
panic("p is not a branch")
|
||||
case _B_conditional:
|
||||
return _N_far_cond
|
||||
case _B_unconditional:
|
||||
return _N_far_uncond
|
||||
default:
|
||||
panic("invalid instruction")
|
||||
}
|
||||
}
|
||||
|
||||
/** Pseudo-Instructions **/
|
||||
|
||||
// Byte is a pseudo-instruction to add raw byte to the assembled code.
|
||||
func (self *Program) Byte(v *expr.Expr) (p *Instruction) {
|
||||
p = self.pseudo(_PseudoByte)
|
||||
p.pseudo.expr = v
|
||||
return
|
||||
}
|
||||
|
||||
// Word is a pseudo-instruction to add raw uint16 as little-endian to the assembled code.
|
||||
func (self *Program) Word(v *expr.Expr) (p *Instruction) {
|
||||
p = self.pseudo(_PseudoWord)
|
||||
p.pseudo.expr = v
|
||||
return
|
||||
}
|
||||
|
||||
// Long is a pseudo-instruction to add raw uint32 as little-endian to the assembled code.
|
||||
func (self *Program) Long(v *expr.Expr) (p *Instruction) {
|
||||
p = self.pseudo(_PseudoLong)
|
||||
p.pseudo.expr = v
|
||||
return
|
||||
}
|
||||
|
||||
// Quad is a pseudo-instruction to add raw uint64 as little-endian to the assembled code.
|
||||
func (self *Program) Quad(v *expr.Expr) (p *Instruction) {
|
||||
p = self.pseudo(_PseudoQuad)
|
||||
p.pseudo.expr = v
|
||||
return
|
||||
}
|
||||
|
||||
// Data is a pseudo-instruction to add raw bytes to the assembled code.
|
||||
func (self *Program) Data(v []byte) (p *Instruction) {
|
||||
p = self.pseudo(_PseudoData)
|
||||
p.pseudo.data = v
|
||||
return
|
||||
}
|
||||
|
||||
// Align is a pseudo-instruction to ensure the PC is aligned to a certain value.
|
||||
func (self *Program) Align(align uint64, padding *expr.Expr) (p *Instruction) {
|
||||
p = self.pseudo(_PseudoAlign)
|
||||
p.pseudo.uint = align
|
||||
p.pseudo.expr = padding
|
||||
return
|
||||
}
|
||||
|
||||
/** Program Assembler **/
|
||||
|
||||
// Free returns the Program object into pool.
|
||||
// Any operation performed after Free is undefined behavior.
|
||||
//
|
||||
// NOTE: This also frees all the instructions, labels, memory
|
||||
//
|
||||
// operands and expressions associated with this program.
|
||||
func (self *Program) Free() {
|
||||
self.clear()
|
||||
//freeProgram(self)
|
||||
}
|
||||
|
||||
// Link pins a label at the current position.
|
||||
func (self *Program) Link(p *Label) {
|
||||
if p.Dest != nil {
|
||||
panic("lable was alreay linked")
|
||||
} else {
|
||||
p.Dest = self.pseudo(_PseudoNop)
|
||||
}
|
||||
}
|
||||
|
||||
// Assemble assembles and links the entire program into machine code.
|
||||
func (self *Program) Assemble(pc uintptr) (ret []byte) {
|
||||
orig := pc
|
||||
next := true
|
||||
offs := uintptr(0)
|
||||
|
||||
/* Pass 0: PC-precompute, assume all labeled branches are far-branches. */
|
||||
for p := self.head; p != nil; p = p.next {
|
||||
if p.pc = pc; !isLabel(p.argv[0]) || p.branch == _B_none {
|
||||
pc += uintptr(p.encode(nil))
|
||||
} else {
|
||||
pc += uintptr(self.branchSize(p))
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate space for the machine code */
|
||||
nb := int(pc - orig)
|
||||
ret = make([]byte, 0, nb)
|
||||
|
||||
/* Pass 1: adjust all the jumps */
|
||||
for next {
|
||||
next = false
|
||||
offs = uintptr(0)
|
||||
|
||||
/* scan all the branches */
|
||||
for p := self.head; p != nil; p = p.next {
|
||||
var ok bool
|
||||
var lb *Label
|
||||
|
||||
/* re-calculate the alignment here */
|
||||
if nb = p.nb; p.pseudo.kind == _PseudoAlign {
|
||||
p.pc -= offs
|
||||
offs += uintptr(nb - p.encode(nil))
|
||||
continue
|
||||
}
|
||||
|
||||
/* adjust the program counter */
|
||||
p.pc -= offs
|
||||
lb, ok = p.argv[0].(*Label)
|
||||
|
||||
/* only care about labeled far-branches */
|
||||
if !ok || p.nb == _N_near || p.branch == _B_none {
|
||||
continue
|
||||
}
|
||||
|
||||
/* calculate the jump offset */
|
||||
size := self.branchSize(p)
|
||||
diff := lb.offset(p.pc, size)
|
||||
|
||||
/* too far to be a near jump */
|
||||
if diff > 127 || diff < -128 {
|
||||
p.nb = size
|
||||
continue
|
||||
}
|
||||
|
||||
/* a far jump becomes a near jump, calculate
|
||||
* the PC adjustment value and assemble again */
|
||||
next = true
|
||||
p.nb = _N_near
|
||||
offs += uintptr(size - _N_near)
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass 3: link all the cross-references */
|
||||
for p := self.head; p != nil; p = p.next {
|
||||
for i := 0; i < p.argc; i++ {
|
||||
var ok bool
|
||||
var lb *Label
|
||||
var op *MemoryOperand
|
||||
|
||||
/* resolve labels */
|
||||
if lb, ok = p.argv[i].(*Label); ok {
|
||||
p.argv[i] = lb.offset(p.pc, p.nb)
|
||||
continue
|
||||
}
|
||||
|
||||
/* check for memory operands */
|
||||
if op, ok = p.argv[i].(*MemoryOperand); !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
/* check for label references */
|
||||
if op.Addr.Type != Reference {
|
||||
continue
|
||||
}
|
||||
|
||||
/* replace the label with the real offset */
|
||||
op.Addr.Type = Offset
|
||||
op.Addr.Offset = op.Addr.Reference.offset(p.pc, p.nb)
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass 4: actually encode all the instructions */
|
||||
for p := self.head; p != nil; p = p.next {
|
||||
p.encode(&ret)
|
||||
}
|
||||
|
||||
/* all done */
|
||||
return ret
|
||||
}
|
||||
|
||||
// AssembleAndFree is like Assemble, but it frees the Program after assembling.
|
||||
func (self *Program) AssembleAndFree(pc uintptr) (ret []byte) {
|
||||
ret = self.Assemble(pc)
|
||||
self.Free()
|
||||
return
|
||||
}
|
693
vendor/github.com/cloudwego/iasm/x86_64/registers.go
generated
vendored
Normal file
693
vendor/github.com/cloudwego/iasm/x86_64/registers.go
generated
vendored
Normal file
@ -0,0 +1,693 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
)
|
||||
|
||||
// Register represents a hardware register.
|
||||
type Register interface {
|
||||
fmt.Stringer
|
||||
implRegister()
|
||||
}
|
||||
|
||||
type (
|
||||
Register8 byte
|
||||
Register16 byte
|
||||
Register32 byte
|
||||
Register64 byte
|
||||
)
|
||||
|
||||
type (
|
||||
KRegister byte
|
||||
MMRegister byte
|
||||
XMMRegister byte
|
||||
YMMRegister byte
|
||||
ZMMRegister byte
|
||||
)
|
||||
|
||||
// RegisterMask is a KRegister used to mask another register.
|
||||
type RegisterMask struct {
|
||||
Z bool
|
||||
K KRegister
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self RegisterMask) String() string {
|
||||
if !self.Z {
|
||||
return fmt.Sprintf("{%%%s}", self.K)
|
||||
} else {
|
||||
return fmt.Sprintf("{%%%s}{z}", self.K)
|
||||
}
|
||||
}
|
||||
|
||||
// MaskedRegister is a Register masked by a RegisterMask.
|
||||
type MaskedRegister struct {
|
||||
Reg Register
|
||||
Mask RegisterMask
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (self MaskedRegister) String() string {
|
||||
return self.Reg.String() + self.Mask.String()
|
||||
}
|
||||
|
||||
const (
|
||||
AL Register8 = iota
|
||||
CL
|
||||
DL
|
||||
BL
|
||||
SPL
|
||||
BPL
|
||||
SIL
|
||||
DIL
|
||||
R8b
|
||||
R9b
|
||||
R10b
|
||||
R11b
|
||||
R12b
|
||||
R13b
|
||||
R14b
|
||||
R15b
|
||||
)
|
||||
|
||||
const (
|
||||
AH = SPL | 0x80
|
||||
CH = BPL | 0x80
|
||||
DH = SIL | 0x80
|
||||
BH = DIL | 0x80
|
||||
)
|
||||
|
||||
const (
|
||||
AX Register16 = iota
|
||||
CX
|
||||
DX
|
||||
BX
|
||||
SP
|
||||
BP
|
||||
SI
|
||||
DI
|
||||
R8w
|
||||
R9w
|
||||
R10w
|
||||
R11w
|
||||
R12w
|
||||
R13w
|
||||
R14w
|
||||
R15w
|
||||
)
|
||||
|
||||
const (
|
||||
EAX Register32 = iota
|
||||
ECX
|
||||
EDX
|
||||
EBX
|
||||
ESP
|
||||
EBP
|
||||
ESI
|
||||
EDI
|
||||
R8d
|
||||
R9d
|
||||
R10d
|
||||
R11d
|
||||
R12d
|
||||
R13d
|
||||
R14d
|
||||
R15d
|
||||
)
|
||||
|
||||
const (
|
||||
RAX Register64 = iota
|
||||
RCX
|
||||
RDX
|
||||
RBX
|
||||
RSP
|
||||
RBP
|
||||
RSI
|
||||
RDI
|
||||
R8
|
||||
R9
|
||||
R10
|
||||
R11
|
||||
R12
|
||||
R13
|
||||
R14
|
||||
R15
|
||||
)
|
||||
|
||||
const (
|
||||
K0 KRegister = iota
|
||||
K1
|
||||
K2
|
||||
K3
|
||||
K4
|
||||
K5
|
||||
K6
|
||||
K7
|
||||
)
|
||||
|
||||
const (
|
||||
MM0 MMRegister = iota
|
||||
MM1
|
||||
MM2
|
||||
MM3
|
||||
MM4
|
||||
MM5
|
||||
MM6
|
||||
MM7
|
||||
)
|
||||
|
||||
const (
|
||||
XMM0 XMMRegister = iota
|
||||
XMM1
|
||||
XMM2
|
||||
XMM3
|
||||
XMM4
|
||||
XMM5
|
||||
XMM6
|
||||
XMM7
|
||||
XMM8
|
||||
XMM9
|
||||
XMM10
|
||||
XMM11
|
||||
XMM12
|
||||
XMM13
|
||||
XMM14
|
||||
XMM15
|
||||
XMM16
|
||||
XMM17
|
||||
XMM18
|
||||
XMM19
|
||||
XMM20
|
||||
XMM21
|
||||
XMM22
|
||||
XMM23
|
||||
XMM24
|
||||
XMM25
|
||||
XMM26
|
||||
XMM27
|
||||
XMM28
|
||||
XMM29
|
||||
XMM30
|
||||
XMM31
|
||||
)
|
||||
|
||||
const (
|
||||
YMM0 YMMRegister = iota
|
||||
YMM1
|
||||
YMM2
|
||||
YMM3
|
||||
YMM4
|
||||
YMM5
|
||||
YMM6
|
||||
YMM7
|
||||
YMM8
|
||||
YMM9
|
||||
YMM10
|
||||
YMM11
|
||||
YMM12
|
||||
YMM13
|
||||
YMM14
|
||||
YMM15
|
||||
YMM16
|
||||
YMM17
|
||||
YMM18
|
||||
YMM19
|
||||
YMM20
|
||||
YMM21
|
||||
YMM22
|
||||
YMM23
|
||||
YMM24
|
||||
YMM25
|
||||
YMM26
|
||||
YMM27
|
||||
YMM28
|
||||
YMM29
|
||||
YMM30
|
||||
YMM31
|
||||
)
|
||||
|
||||
const (
|
||||
ZMM0 ZMMRegister = iota
|
||||
ZMM1
|
||||
ZMM2
|
||||
ZMM3
|
||||
ZMM4
|
||||
ZMM5
|
||||
ZMM6
|
||||
ZMM7
|
||||
ZMM8
|
||||
ZMM9
|
||||
ZMM10
|
||||
ZMM11
|
||||
ZMM12
|
||||
ZMM13
|
||||
ZMM14
|
||||
ZMM15
|
||||
ZMM16
|
||||
ZMM17
|
||||
ZMM18
|
||||
ZMM19
|
||||
ZMM20
|
||||
ZMM21
|
||||
ZMM22
|
||||
ZMM23
|
||||
ZMM24
|
||||
ZMM25
|
||||
ZMM26
|
||||
ZMM27
|
||||
ZMM28
|
||||
ZMM29
|
||||
ZMM30
|
||||
ZMM31
|
||||
)
|
||||
|
||||
func (self Register8) implRegister() {}
|
||||
func (self Register16) implRegister() {}
|
||||
func (self Register32) implRegister() {}
|
||||
func (self Register64) implRegister() {}
|
||||
|
||||
func (self KRegister) implRegister() {}
|
||||
func (self MMRegister) implRegister() {}
|
||||
func (self XMMRegister) implRegister() {}
|
||||
func (self YMMRegister) implRegister() {}
|
||||
func (self ZMMRegister) implRegister() {}
|
||||
|
||||
func (self Register8) String() string { if int(self) >= len(r8names) { return "???" } else { return r8names[self] } }
|
||||
func (self Register16) String() string { if int(self) >= len(r16names) { return "???" } else { return r16names[self] } }
|
||||
func (self Register32) String() string { if int(self) >= len(r32names) { return "???" } else { return r32names[self] } }
|
||||
func (self Register64) String() string { if int(self) >= len(r64names) { return "???" } else { return r64names[self] } }
|
||||
|
||||
func (self KRegister) String() string { if int(self) >= len(knames) { return "???" } else { return knames[self] } }
|
||||
func (self MMRegister) String() string { if int(self) >= len(mmnames) { return "???" } else { return mmnames[self] } }
|
||||
func (self XMMRegister) String() string { if int(self) >= len(xmmnames) { return "???" } else { return xmmnames[self] } }
|
||||
func (self YMMRegister) String() string { if int(self) >= len(ymmnames) { return "???" } else { return ymmnames[self] } }
|
||||
func (self ZMMRegister) String() string { if int(self) >= len(zmmnames) { return "???" } else { return zmmnames[self] } }
|
||||
|
||||
// Registers maps register name into Register instances.
|
||||
var Registers = map[string]Register {
|
||||
"al" : AL,
|
||||
"cl" : CL,
|
||||
"dl" : DL,
|
||||
"bl" : BL,
|
||||
"spl" : SPL,
|
||||
"bpl" : BPL,
|
||||
"sil" : SIL,
|
||||
"dil" : DIL,
|
||||
"r8b" : R8b,
|
||||
"r9b" : R9b,
|
||||
"r10b" : R10b,
|
||||
"r11b" : R11b,
|
||||
"r12b" : R12b,
|
||||
"r13b" : R13b,
|
||||
"r14b" : R14b,
|
||||
"r15b" : R15b,
|
||||
"ah" : AH,
|
||||
"ch" : CH,
|
||||
"dh" : DH,
|
||||
"bh" : BH,
|
||||
"ax" : AX,
|
||||
"cx" : CX,
|
||||
"dx" : DX,
|
||||
"bx" : BX,
|
||||
"sp" : SP,
|
||||
"bp" : BP,
|
||||
"si" : SI,
|
||||
"di" : DI,
|
||||
"r8w" : R8w,
|
||||
"r9w" : R9w,
|
||||
"r10w" : R10w,
|
||||
"r11w" : R11w,
|
||||
"r12w" : R12w,
|
||||
"r13w" : R13w,
|
||||
"r14w" : R14w,
|
||||
"r15w" : R15w,
|
||||
"eax" : EAX,
|
||||
"ecx" : ECX,
|
||||
"edx" : EDX,
|
||||
"ebx" : EBX,
|
||||
"esp" : ESP,
|
||||
"ebp" : EBP,
|
||||
"esi" : ESI,
|
||||
"edi" : EDI,
|
||||
"r8d" : R8d,
|
||||
"r9d" : R9d,
|
||||
"r10d" : R10d,
|
||||
"r11d" : R11d,
|
||||
"r12d" : R12d,
|
||||
"r13d" : R13d,
|
||||
"r14d" : R14d,
|
||||
"r15d" : R15d,
|
||||
"rax" : RAX,
|
||||
"rcx" : RCX,
|
||||
"rdx" : RDX,
|
||||
"rbx" : RBX,
|
||||
"rsp" : RSP,
|
||||
"rbp" : RBP,
|
||||
"rsi" : RSI,
|
||||
"rdi" : RDI,
|
||||
"r8" : R8,
|
||||
"r9" : R9,
|
||||
"r10" : R10,
|
||||
"r11" : R11,
|
||||
"r12" : R12,
|
||||
"r13" : R13,
|
||||
"r14" : R14,
|
||||
"r15" : R15,
|
||||
"k0" : K0,
|
||||
"k1" : K1,
|
||||
"k2" : K2,
|
||||
"k3" : K3,
|
||||
"k4" : K4,
|
||||
"k5" : K5,
|
||||
"k6" : K6,
|
||||
"k7" : K7,
|
||||
"mm0" : MM0,
|
||||
"mm1" : MM1,
|
||||
"mm2" : MM2,
|
||||
"mm3" : MM3,
|
||||
"mm4" : MM4,
|
||||
"mm5" : MM5,
|
||||
"mm6" : MM6,
|
||||
"mm7" : MM7,
|
||||
"xmm0" : XMM0,
|
||||
"xmm1" : XMM1,
|
||||
"xmm2" : XMM2,
|
||||
"xmm3" : XMM3,
|
||||
"xmm4" : XMM4,
|
||||
"xmm5" : XMM5,
|
||||
"xmm6" : XMM6,
|
||||
"xmm7" : XMM7,
|
||||
"xmm8" : XMM8,
|
||||
"xmm9" : XMM9,
|
||||
"xmm10" : XMM10,
|
||||
"xmm11" : XMM11,
|
||||
"xmm12" : XMM12,
|
||||
"xmm13" : XMM13,
|
||||
"xmm14" : XMM14,
|
||||
"xmm15" : XMM15,
|
||||
"xmm16" : XMM16,
|
||||
"xmm17" : XMM17,
|
||||
"xmm18" : XMM18,
|
||||
"xmm19" : XMM19,
|
||||
"xmm20" : XMM20,
|
||||
"xmm21" : XMM21,
|
||||
"xmm22" : XMM22,
|
||||
"xmm23" : XMM23,
|
||||
"xmm24" : XMM24,
|
||||
"xmm25" : XMM25,
|
||||
"xmm26" : XMM26,
|
||||
"xmm27" : XMM27,
|
||||
"xmm28" : XMM28,
|
||||
"xmm29" : XMM29,
|
||||
"xmm30" : XMM30,
|
||||
"xmm31" : XMM31,
|
||||
"ymm0" : YMM0,
|
||||
"ymm1" : YMM1,
|
||||
"ymm2" : YMM2,
|
||||
"ymm3" : YMM3,
|
||||
"ymm4" : YMM4,
|
||||
"ymm5" : YMM5,
|
||||
"ymm6" : YMM6,
|
||||
"ymm7" : YMM7,
|
||||
"ymm8" : YMM8,
|
||||
"ymm9" : YMM9,
|
||||
"ymm10" : YMM10,
|
||||
"ymm11" : YMM11,
|
||||
"ymm12" : YMM12,
|
||||
"ymm13" : YMM13,
|
||||
"ymm14" : YMM14,
|
||||
"ymm15" : YMM15,
|
||||
"ymm16" : YMM16,
|
||||
"ymm17" : YMM17,
|
||||
"ymm18" : YMM18,
|
||||
"ymm19" : YMM19,
|
||||
"ymm20" : YMM20,
|
||||
"ymm21" : YMM21,
|
||||
"ymm22" : YMM22,
|
||||
"ymm23" : YMM23,
|
||||
"ymm24" : YMM24,
|
||||
"ymm25" : YMM25,
|
||||
"ymm26" : YMM26,
|
||||
"ymm27" : YMM27,
|
||||
"ymm28" : YMM28,
|
||||
"ymm29" : YMM29,
|
||||
"ymm30" : YMM30,
|
||||
"ymm31" : YMM31,
|
||||
"zmm0" : ZMM0,
|
||||
"zmm1" : ZMM1,
|
||||
"zmm2" : ZMM2,
|
||||
"zmm3" : ZMM3,
|
||||
"zmm4" : ZMM4,
|
||||
"zmm5" : ZMM5,
|
||||
"zmm6" : ZMM6,
|
||||
"zmm7" : ZMM7,
|
||||
"zmm8" : ZMM8,
|
||||
"zmm9" : ZMM9,
|
||||
"zmm10" : ZMM10,
|
||||
"zmm11" : ZMM11,
|
||||
"zmm12" : ZMM12,
|
||||
"zmm13" : ZMM13,
|
||||
"zmm14" : ZMM14,
|
||||
"zmm15" : ZMM15,
|
||||
"zmm16" : ZMM16,
|
||||
"zmm17" : ZMM17,
|
||||
"zmm18" : ZMM18,
|
||||
"zmm19" : ZMM19,
|
||||
"zmm20" : ZMM20,
|
||||
"zmm21" : ZMM21,
|
||||
"zmm22" : ZMM22,
|
||||
"zmm23" : ZMM23,
|
||||
"zmm24" : ZMM24,
|
||||
"zmm25" : ZMM25,
|
||||
"zmm26" : ZMM26,
|
||||
"zmm27" : ZMM27,
|
||||
"zmm28" : ZMM28,
|
||||
"zmm29" : ZMM29,
|
||||
"zmm30" : ZMM30,
|
||||
"zmm31" : ZMM31,
|
||||
}
|
||||
|
||||
/** Register Name Tables **/
|
||||
|
||||
var r8names = [...]string {
|
||||
AL : "al",
|
||||
CL : "cl",
|
||||
DL : "dl",
|
||||
BL : "bl",
|
||||
SPL : "spl",
|
||||
BPL : "bpl",
|
||||
SIL : "sil",
|
||||
DIL : "dil",
|
||||
R8b : "r8b",
|
||||
R9b : "r9b",
|
||||
R10b : "r10b",
|
||||
R11b : "r11b",
|
||||
R12b : "r12b",
|
||||
R13b : "r13b",
|
||||
R14b : "r14b",
|
||||
R15b : "r15b",
|
||||
AH : "ah",
|
||||
CH : "ch",
|
||||
DH : "dh",
|
||||
BH : "bh",
|
||||
}
|
||||
|
||||
var r16names = [...]string {
|
||||
AX : "ax",
|
||||
CX : "cx",
|
||||
DX : "dx",
|
||||
BX : "bx",
|
||||
SP : "sp",
|
||||
BP : "bp",
|
||||
SI : "si",
|
||||
DI : "di",
|
||||
R8w : "r8w",
|
||||
R9w : "r9w",
|
||||
R10w : "r10w",
|
||||
R11w : "r11w",
|
||||
R12w : "r12w",
|
||||
R13w : "r13w",
|
||||
R14w : "r14w",
|
||||
R15w : "r15w",
|
||||
}
|
||||
|
||||
var r32names = [...]string {
|
||||
EAX : "eax",
|
||||
ECX : "ecx",
|
||||
EDX : "edx",
|
||||
EBX : "ebx",
|
||||
ESP : "esp",
|
||||
EBP : "ebp",
|
||||
ESI : "esi",
|
||||
EDI : "edi",
|
||||
R8d : "r8d",
|
||||
R9d : "r9d",
|
||||
R10d : "r10d",
|
||||
R11d : "r11d",
|
||||
R12d : "r12d",
|
||||
R13d : "r13d",
|
||||
R14d : "r14d",
|
||||
R15d : "r15d",
|
||||
}
|
||||
|
||||
var r64names = [...]string {
|
||||
RAX : "rax",
|
||||
RCX : "rcx",
|
||||
RDX : "rdx",
|
||||
RBX : "rbx",
|
||||
RSP : "rsp",
|
||||
RBP : "rbp",
|
||||
RSI : "rsi",
|
||||
RDI : "rdi",
|
||||
R8 : "r8",
|
||||
R9 : "r9",
|
||||
R10 : "r10",
|
||||
R11 : "r11",
|
||||
R12 : "r12",
|
||||
R13 : "r13",
|
||||
R14 : "r14",
|
||||
R15 : "r15",
|
||||
}
|
||||
|
||||
var knames = [...]string {
|
||||
K0: "k0",
|
||||
K1: "k1",
|
||||
K2: "k2",
|
||||
K3: "k3",
|
||||
K4: "k4",
|
||||
K5: "k5",
|
||||
K6: "k6",
|
||||
K7: "k7",
|
||||
}
|
||||
|
||||
var mmnames = [...]string {
|
||||
MM0: "mm0",
|
||||
MM1: "mm1",
|
||||
MM2: "mm2",
|
||||
MM3: "mm3",
|
||||
MM4: "mm4",
|
||||
MM5: "mm5",
|
||||
MM6: "mm6",
|
||||
MM7: "mm7",
|
||||
}
|
||||
|
||||
var xmmnames = [...]string {
|
||||
XMM0 : "xmm0",
|
||||
XMM1 : "xmm1",
|
||||
XMM2 : "xmm2",
|
||||
XMM3 : "xmm3",
|
||||
XMM4 : "xmm4",
|
||||
XMM5 : "xmm5",
|
||||
XMM6 : "xmm6",
|
||||
XMM7 : "xmm7",
|
||||
XMM8 : "xmm8",
|
||||
XMM9 : "xmm9",
|
||||
XMM10 : "xmm10",
|
||||
XMM11 : "xmm11",
|
||||
XMM12 : "xmm12",
|
||||
XMM13 : "xmm13",
|
||||
XMM14 : "xmm14",
|
||||
XMM15 : "xmm15",
|
||||
XMM16 : "xmm16",
|
||||
XMM17 : "xmm17",
|
||||
XMM18 : "xmm18",
|
||||
XMM19 : "xmm19",
|
||||
XMM20 : "xmm20",
|
||||
XMM21 : "xmm21",
|
||||
XMM22 : "xmm22",
|
||||
XMM23 : "xmm23",
|
||||
XMM24 : "xmm24",
|
||||
XMM25 : "xmm25",
|
||||
XMM26 : "xmm26",
|
||||
XMM27 : "xmm27",
|
||||
XMM28 : "xmm28",
|
||||
XMM29 : "xmm29",
|
||||
XMM30 : "xmm30",
|
||||
XMM31 : "xmm31",
|
||||
}
|
||||
|
||||
var ymmnames = [...]string {
|
||||
YMM0 : "ymm0",
|
||||
YMM1 : "ymm1",
|
||||
YMM2 : "ymm2",
|
||||
YMM3 : "ymm3",
|
||||
YMM4 : "ymm4",
|
||||
YMM5 : "ymm5",
|
||||
YMM6 : "ymm6",
|
||||
YMM7 : "ymm7",
|
||||
YMM8 : "ymm8",
|
||||
YMM9 : "ymm9",
|
||||
YMM10 : "ymm10",
|
||||
YMM11 : "ymm11",
|
||||
YMM12 : "ymm12",
|
||||
YMM13 : "ymm13",
|
||||
YMM14 : "ymm14",
|
||||
YMM15 : "ymm15",
|
||||
YMM16 : "ymm16",
|
||||
YMM17 : "ymm17",
|
||||
YMM18 : "ymm18",
|
||||
YMM19 : "ymm19",
|
||||
YMM20 : "ymm20",
|
||||
YMM21 : "ymm21",
|
||||
YMM22 : "ymm22",
|
||||
YMM23 : "ymm23",
|
||||
YMM24 : "ymm24",
|
||||
YMM25 : "ymm25",
|
||||
YMM26 : "ymm26",
|
||||
YMM27 : "ymm27",
|
||||
YMM28 : "ymm28",
|
||||
YMM29 : "ymm29",
|
||||
YMM30 : "ymm30",
|
||||
YMM31 : "ymm31",
|
||||
}
|
||||
|
||||
var zmmnames = [...]string {
|
||||
ZMM0 : "zmm0",
|
||||
ZMM1 : "zmm1",
|
||||
ZMM2 : "zmm2",
|
||||
ZMM3 : "zmm3",
|
||||
ZMM4 : "zmm4",
|
||||
ZMM5 : "zmm5",
|
||||
ZMM6 : "zmm6",
|
||||
ZMM7 : "zmm7",
|
||||
ZMM8 : "zmm8",
|
||||
ZMM9 : "zmm9",
|
||||
ZMM10 : "zmm10",
|
||||
ZMM11 : "zmm11",
|
||||
ZMM12 : "zmm12",
|
||||
ZMM13 : "zmm13",
|
||||
ZMM14 : "zmm14",
|
||||
ZMM15 : "zmm15",
|
||||
ZMM16 : "zmm16",
|
||||
ZMM17 : "zmm17",
|
||||
ZMM18 : "zmm18",
|
||||
ZMM19 : "zmm19",
|
||||
ZMM20 : "zmm20",
|
||||
ZMM21 : "zmm21",
|
||||
ZMM22 : "zmm22",
|
||||
ZMM23 : "zmm23",
|
||||
ZMM24 : "zmm24",
|
||||
ZMM25 : "zmm25",
|
||||
ZMM26 : "zmm26",
|
||||
ZMM27 : "zmm27",
|
||||
ZMM28 : "zmm28",
|
||||
ZMM29 : "zmm29",
|
||||
ZMM30 : "zmm30",
|
||||
ZMM31 : "zmm31",
|
||||
}
|
147
vendor/github.com/cloudwego/iasm/x86_64/utils.go
generated
vendored
Normal file
147
vendor/github.com/cloudwego/iasm/x86_64/utils.go
generated
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
//
|
||||
// Copyright 2024 CloudWeGo Authors
|
||||
//
|
||||
// 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 x86_64
|
||||
|
||||
import (
|
||||
`encoding/binary`
|
||||
`errors`
|
||||
`reflect`
|
||||
`strconv`
|
||||
`unicode/utf8`
|
||||
`unsafe`
|
||||
)
|
||||
|
||||
const (
|
||||
_CC_digit = 1 << iota
|
||||
_CC_ident
|
||||
_CC_ident0
|
||||
_CC_number
|
||||
)
|
||||
|
||||
func ispow2(v uint64) bool {
|
||||
return (v & (v - 1)) == 0
|
||||
}
|
||||
|
||||
func isdigit(cc rune) bool {
|
||||
return '0' <= cc && cc <= '9'
|
||||
}
|
||||
|
||||
func isalpha(cc rune) bool {
|
||||
return (cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z')
|
||||
}
|
||||
|
||||
func isident(cc rune) bool {
|
||||
return cc == '_' || isalpha(cc) || isdigit(cc)
|
||||
}
|
||||
|
||||
func isident0(cc rune) bool {
|
||||
return cc == '_' || isalpha(cc)
|
||||
}
|
||||
|
||||
func isnumber(cc rune) bool {
|
||||
return (cc == 'b' || cc == 'B') ||
|
||||
(cc == 'o' || cc == 'O') ||
|
||||
(cc == 'x' || cc == 'X') ||
|
||||
(cc >= '0' && cc <= '9') ||
|
||||
(cc >= 'a' && cc <= 'f') ||
|
||||
(cc >= 'A' && cc <= 'F')
|
||||
}
|
||||
|
||||
func align(v int, n int) int {
|
||||
return (((v - 1) >> n) + 1) << n
|
||||
}
|
||||
|
||||
func append8(m *[]byte, v byte) {
|
||||
*m = append(*m, v)
|
||||
}
|
||||
|
||||
func append16(m *[]byte, v uint16) {
|
||||
p := len(*m)
|
||||
*m = append(*m, 0, 0)
|
||||
binary.LittleEndian.PutUint16((*m)[p:], v)
|
||||
}
|
||||
|
||||
func append32(m *[]byte, v uint32) {
|
||||
p := len(*m)
|
||||
*m = append(*m, 0, 0, 0, 0)
|
||||
binary.LittleEndian.PutUint32((*m)[p:], v)
|
||||
}
|
||||
|
||||
func append64(m *[]byte, v uint64) {
|
||||
p := len(*m)
|
||||
*m = append(*m, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
binary.LittleEndian.PutUint64((*m)[p:], v)
|
||||
}
|
||||
|
||||
func expandmm(m *[]byte, n int, v byte) {
|
||||
sl := (*_GoSlice)(unsafe.Pointer(m))
|
||||
nb := sl.len + n
|
||||
|
||||
/* grow as needed */
|
||||
if nb > cap(*m) {
|
||||
*m = growslice(byteType, *m, nb)
|
||||
}
|
||||
|
||||
/* fill the new area */
|
||||
memset(unsafe.Pointer(uintptr(sl.ptr) + uintptr(sl.len)), v, uintptr(n))
|
||||
sl.len = nb
|
||||
}
|
||||
|
||||
func memset(p unsafe.Pointer, c byte, n uintptr) {
|
||||
if c != 0 {
|
||||
memsetv(p, c, n)
|
||||
} else {
|
||||
memclrNoHeapPointers(p, n)
|
||||
}
|
||||
}
|
||||
|
||||
func memsetv(p unsafe.Pointer, c byte, n uintptr) {
|
||||
for i := uintptr(0); i < n; i++ {
|
||||
*(*byte)(unsafe.Pointer(uintptr(p) + i)) = c
|
||||
}
|
||||
}
|
||||
|
||||
func literal64(v string) (uint64, error) {
|
||||
var nb int
|
||||
var ch rune
|
||||
var ex error
|
||||
var mm [12]byte
|
||||
|
||||
/* unquote the runes */
|
||||
for v != "" {
|
||||
if ch, _, v, ex = strconv.UnquoteChar(v, '\''); ex != nil {
|
||||
return 0, ex
|
||||
} else if nb += utf8.EncodeRune(mm[nb:], ch); nb > 8 {
|
||||
return 0, errors.New("multi-char constant too large")
|
||||
}
|
||||
}
|
||||
|
||||
/* convert to uint64 */
|
||||
return *(*uint64)(unsafe.Pointer(&mm)), nil
|
||||
}
|
||||
|
||||
var (
|
||||
byteWrap = reflect.TypeOf(byte(0))
|
||||
byteType = (*_GoType)(efaceOf(byteWrap).ptr)
|
||||
)
|
||||
|
||||
//go:linkname growslice runtime.growslice
|
||||
func growslice(_ *_GoType, _ []byte, _ int) []byte
|
||||
|
||||
//go:noescape
|
||||
//go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
|
||||
func memclrNoHeapPointers(_ unsafe.Pointer, _ uintptr)
|
Reference in New Issue
Block a user