From 1472d92a8d36bf1900c8f2887ecd4519649b8193 Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:42:31 +0000 Subject: [PATCH 01/16] [feature] Add `published` property to outgoing AP Actor representations (#3671) --- internal/typeutils/internaltoas.go | 6 ++++++ internal/typeutils/internaltoas_test.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/internal/typeutils/internaltoas.go b/internal/typeutils/internaltoas.go index 644d832f5..de1badb5c 100644 --- a/internal/typeutils/internaltoas.go +++ b/internal/typeutils/internaltoas.go @@ -53,6 +53,12 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab idProp.SetIRI(profileIDURI) person.SetJSONLDId(idProp) + // published + // The moment when the account was created. + publishedProp := streams.NewActivityStreamsPublishedProperty() + publishedProp.Set(a.CreatedAt) + person.SetActivityStreamsPublished(publishedProp) + // following // The URI for retrieving a list of accounts this user is following followingURI, err := url.Parse(a.FollowingURI) diff --git a/internal/typeutils/internaltoas_test.go b/internal/typeutils/internaltoas_test.go index c847cfc93..344a42798 100644 --- a/internal/typeutils/internaltoas_test.go +++ b/internal/typeutils/internaltoas_test.go @@ -86,6 +86,7 @@ func (suite *InternalToASTestSuite) TestAccountToAS() { "owner": "http://localhost:8080/users/the_mighty_zork", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXTcOAvM1Jiw5Ffpk0qn\nr0cwbNvFe/5zQ+Tp7tumK/ZnT37o7X0FUEXrxNi+dkhmeJ0gsaiN+JQGNUewvpSk\nPIAXKvi908aSfCGjs7bGlJCJCuDuL5d6m7hZnP9rt9fJc70GElPpG0jc9fXwlz7T\nlsPb2ecatmG05Y4jPwdC+oN4MNCv9yQzEvCVMzl76EJaM602kIHC1CISn0rDFmYd\n9rSN7XPlNJw1F6PbpJ/BWQ+pXHKw3OEwNTETAUNYiVGnZU+B7a7bZC9f6/aPbJuV\nt8Qmg+UnDvW1Y8gmfHnxaWG2f5TDBvCHmcYtucIZPLQD4trAozC4ryqlmCWQNKbt\n0wIDAQAB\n-----END PUBLIC KEY-----\n" }, + "published": "2022-05-20T11:09:18Z", "summary": "\u003cp\u003ehey yo this is my profile!\u003c/p\u003e", "tag": [], "type": "Person", @@ -150,6 +151,7 @@ func (suite *InternalToASTestSuite) TestAccountToASWithFields() { "owner": "http://localhost:8080/users/1happyturtle", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTc6Jpg6LrRPhVQG4KLz\n2+YqEUUtZPd4YR+TKXuCnwEG9ZNGhgP046xa9h3EWzrZXaOhXvkUQgJuRqPrAcfN\nvc8jBHV2xrUeD8pu/MWKEabAsA/tgCv3nUC47HQ3/c12aHfYoPz3ufWsGGnrkhci\nv8PaveJ3LohO5vjCn1yZ00v6osMJMViEZvZQaazyE9A8FwraIexXabDpoy7tkHRg\nA1fvSkg4FeSG1XMcIz2NN7xyUuFACD+XkuOk7UqzRd4cjPUPLxiDwIsTlcgGOd3E\nUFMWVlPxSGjY2hIKa3lEHytaYK9IMYdSuyCsJshd3/yYC9LqxZY2KdlKJ80VOVyh\nyQIDAQAB\n-----END PUBLIC KEY-----\n" }, + "published": "2022-06-04T13:12:00Z", "summary": "\u003cp\u003ei post about things that concern me\u003c/p\u003e", "tag": [], "type": "Person", @@ -231,6 +233,7 @@ func (suite *InternalToASTestSuite) TestAccountToASAliasedAndMoved() { "owner": "http://localhost:8080/users/the_mighty_zork", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXTcOAvM1Jiw5Ffpk0qn\nr0cwbNvFe/5zQ+Tp7tumK/ZnT37o7X0FUEXrxNi+dkhmeJ0gsaiN+JQGNUewvpSk\nPIAXKvi908aSfCGjs7bGlJCJCuDuL5d6m7hZnP9rt9fJc70GElPpG0jc9fXwlz7T\nlsPb2ecatmG05Y4jPwdC+oN4MNCv9yQzEvCVMzl76EJaM602kIHC1CISn0rDFmYd\n9rSN7XPlNJw1F6PbpJ/BWQ+pXHKw3OEwNTETAUNYiVGnZU+B7a7bZC9f6/aPbJuV\nt8Qmg+UnDvW1Y8gmfHnxaWG2f5TDBvCHmcYtucIZPLQD4trAozC4ryqlmCWQNKbt\n0wIDAQAB\n-----END PUBLIC KEY-----\n" }, + "published": "2022-05-20T11:09:18Z", "summary": "\u003cp\u003ehey yo this is my profile!\u003c/p\u003e", "tag": [], "type": "Person", @@ -292,6 +295,7 @@ func (suite *InternalToASTestSuite) TestAccountToASWithOneField() { "owner": "http://localhost:8080/users/1happyturtle", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTc6Jpg6LrRPhVQG4KLz\n2+YqEUUtZPd4YR+TKXuCnwEG9ZNGhgP046xa9h3EWzrZXaOhXvkUQgJuRqPrAcfN\nvc8jBHV2xrUeD8pu/MWKEabAsA/tgCv3nUC47HQ3/c12aHfYoPz3ufWsGGnrkhci\nv8PaveJ3LohO5vjCn1yZ00v6osMJMViEZvZQaazyE9A8FwraIexXabDpoy7tkHRg\nA1fvSkg4FeSG1XMcIz2NN7xyUuFACD+XkuOk7UqzRd4cjPUPLxiDwIsTlcgGOd3E\nUFMWVlPxSGjY2hIKa3lEHytaYK9IMYdSuyCsJshd3/yYC9LqxZY2KdlKJ80VOVyh\nyQIDAQAB\n-----END PUBLIC KEY-----\n" }, + "published": "2022-06-04T13:12:00Z", "summary": "\u003cp\u003ei post about things that concern me\u003c/p\u003e", "tag": [], "type": "Person", @@ -353,6 +357,7 @@ func (suite *InternalToASTestSuite) TestAccountToASWithEmoji() { "owner": "http://localhost:8080/users/the_mighty_zork", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXTcOAvM1Jiw5Ffpk0qn\nr0cwbNvFe/5zQ+Tp7tumK/ZnT37o7X0FUEXrxNi+dkhmeJ0gsaiN+JQGNUewvpSk\nPIAXKvi908aSfCGjs7bGlJCJCuDuL5d6m7hZnP9rt9fJc70GElPpG0jc9fXwlz7T\nlsPb2ecatmG05Y4jPwdC+oN4MNCv9yQzEvCVMzl76EJaM602kIHC1CISn0rDFmYd\n9rSN7XPlNJw1F6PbpJ/BWQ+pXHKw3OEwNTETAUNYiVGnZU+B7a7bZC9f6/aPbJuV\nt8Qmg+UnDvW1Y8gmfHnxaWG2f5TDBvCHmcYtucIZPLQD4trAozC4ryqlmCWQNKbt\n0wIDAQAB\n-----END PUBLIC KEY-----\n" }, + "published": "2022-05-20T11:09:18Z", "summary": "\u003cp\u003ehey yo this is my profile!\u003c/p\u003e", "tag": { "icon": { @@ -427,6 +432,7 @@ func (suite *InternalToASTestSuite) TestAccountToASWithSharedInbox() { "owner": "http://localhost:8080/users/the_mighty_zork", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXTcOAvM1Jiw5Ffpk0qn\nr0cwbNvFe/5zQ+Tp7tumK/ZnT37o7X0FUEXrxNi+dkhmeJ0gsaiN+JQGNUewvpSk\nPIAXKvi908aSfCGjs7bGlJCJCuDuL5d6m7hZnP9rt9fJc70GElPpG0jc9fXwlz7T\nlsPb2ecatmG05Y4jPwdC+oN4MNCv9yQzEvCVMzl76EJaM602kIHC1CISn0rDFmYd\n9rSN7XPlNJw1F6PbpJ/BWQ+pXHKw3OEwNTETAUNYiVGnZU+B7a7bZC9f6/aPbJuV\nt8Qmg+UnDvW1Y8gmfHnxaWG2f5TDBvCHmcYtucIZPLQD4trAozC4ryqlmCWQNKbt\n0wIDAQAB\n-----END PUBLIC KEY-----\n" }, + "published": "2022-05-20T11:09:18Z", "summary": "\u003cp\u003ehey yo this is my profile!\u003c/p\u003e", "tag": [], "type": "Person", From b42cb7a802096762cbffb0fa1177c8355898cc1c Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:48:09 +0000 Subject: [PATCH 02/16] [feature] Add warning about `trusted-proxies` to make config easier (#3675) * [feature] Add warning about `trusted-proxies` to make config easier * thank you linter, hugs and kisses to you --- docs/api/ratelimiting.md | 4 +- docs/configuration/general.md | 4 +- docs/configuration/trusted_proxies.md | 71 ++++++++++++++++++ docs/getting_started/reverse_proxy/index.md | 4 ++ example/docker-compose/docker-compose.yaml | 7 +- internal/api/util/template.go | 79 +++++++++++++++++++++ mkdocs.yml | 1 + web/source/css/page.css | 21 +++++- web/template/page_header.tmpl | 26 +++++++ 9 files changed, 208 insertions(+), 9 deletions(-) create mode 100644 docs/configuration/trusted_proxies.md diff --git a/docs/api/ratelimiting.md b/docs/api/ratelimiting.md index d99f4d379..a3ee7baca 100644 --- a/docs/api/ratelimiting.md +++ b/docs/api/ratelimiting.md @@ -24,11 +24,11 @@ In case the rate limit is exceeded, an [HTTP 429 Too Many Requests](https://deve ### My rate limit keeps being exceeded! Why? -If you find that your rate limit is regularly being exceeded (both for yourself and other callers) during normal use of your instance, it may be that GoToSocial can't tell the clients apart by IP address. You can investigate this by viewing the logs of your instance. If (almost) all logged IP addresses appear to be the same IP address (something like `172.x.x.x`), then the rate limiting will cause problems. +If you find that your rate limit is regularly being exceeded (both for yourself and other callers) during normal use of your instance, it may be that GoToSocial can't tell the clients apart by IP address. You can investigate this by viewing the logs of your instance. If (almost) all logged client IP addresses appear to be the same IP address (something like `172.x.x.x`), then the rate limiting will cause problems. This happens when your server is running inside NAT (port forwarding), or behind an HTTP proxy without the correct configuration, causing your instance to see all incoming IP addresses as the same address: namely, the IP address of your reverse proxy or gateway. This means that all incoming requests are *sharing the same rate limit*, rather than being split correctly per IP. -If you are using an HTTP proxy then it's likely that your `trusted-proxies` is not correctly configured. If this is the case, try adding the IP address of your reverse proxy to the list of `trusted-proxies`, and restarting your instance. +If you are using an HTTP proxy then it's likely that your `trusted-proxies` is not correctly configured. See the [trusted-proxies](../configuration/trusted_proxies.md) documentation for more info on how to resolve this. If you don't have an HTTP proxy, then it's likely caused by NAT. In this case you should disable rate limiting altogether. diff --git a/docs/configuration/general.md b/docs/configuration/general.md index 50b04bbe1..16589c842 100644 --- a/docs/configuration/general.md +++ b/docs/configuration/general.md @@ -1,8 +1,6 @@ # General -The top-level configuration for GoToSocial, including basic things like host, port, bind address and transport protocol. - -The only things you *really* need to set here are `host`, which should be the hostname where your instance is reachable, and probably `port`. +The top-level configuration for GoToSocial, including basic things like host, port, bind address, and trusted-proxies. ## Settings diff --git a/docs/configuration/trusted_proxies.md b/docs/configuration/trusted_proxies.md new file mode 100644 index 000000000..6852e22e1 --- /dev/null +++ b/docs/configuration/trusted_proxies.md @@ -0,0 +1,71 @@ +# Trusted Proxies + +To correctly enforce [rate limiting](../api/ratelimiting.md), GoToSocial relies on the concept of "trusted proxies" in order to accurately determine the IP address of clients accessing your server. + +A "trusted proxy" is an intermediate network hop that GoToSocial can be instructed to trust to provide a correct client IP address. + +For example, if you are running in a reverse proxy configuration with Docker + Nginx, then the Docker network address of Nginx should be configured as a trusted proxy, since all traffic from the wider internet will come into GoToSocial via Nginx. + +Without setting `trusted-proxies` correctly, GoToSocial will see all incoming client IP addresses as the same address, which leads to rate limiting issues, since GoToSocial uses client IP addresses to bucket rate limits. + +## tl;dr: How to set `trusted-proxies` correctly + +If your `trusted-proxies` setting is not correctly configured, you may see the following warning on the web view of your instance (v0.18.0 and above): + +> Warning! It looks like trusted-proxies is not set correctly in this instance's configuration. This may cause rate-limiting issues and, by extension, federation issues. +> +> If you are the instance admin, you should fix this by adding `SUGGESTED_IP_RANGE` to your trusted-proxies. + +To resolve this, copy the IP range in the message, and edit your `config.yaml` file to add the IP range to your `trusted-proxies`. + +!!! tip "You may be getting rate limited even if you don't see the above warning!" + If you're on a version of GoToSocial below v0.18.0, or you're running behind a CDN such as Cloudflare (not recommended), you won't see a warning message. Instead, you'll see in your GoToSocial logs that all client IPs are the same address. In this case, take the recurring client IP value as `SUGGESTED_IP_RANGE`. + +In this example, we assume `SUGGESTED_IP_RANGE` to be `172.17.0.1/16` (the default Docker bridge network subnet). + +Before (default config): + +```yaml +trusted-proxies: + - "127.0.0.1/32" + - "::1" +``` + +After (new config): + +```yaml +trusted-proxies: + - "172.17.0.1/16" + - "127.0.0.1/32" + - "::1" +``` + +If you are using [environment variables](../configuration/index.md#environment-variables) to configure your instance, you can configure `trusted-proxies` by setting the environment variable `GTS_TRUSTED_PROXIES` to a comma-separated list of IP ranges, like so: + +```env +GTS_TRUSTED_PROXIES="172.17.0.1/16,127.0.0.1/32,::1" +``` + +If you are using docker compose, your docker-compose.yaml file should look something like this after the change (note that yaml uses `: ` and not `=`): + +```yaml +################################ +# BLAH BLAH OTHER CONFIG STUFF # +################################ + environment: + ############################ + # BLAH BLAH OTHER ENV VARS # + ############################ + ## For reverse proxy setups: + GTS_TRUSTED_PROXIES: "172.17.0.1/16,127.0.0.1/32,::1" +################################ +# BLAH BLAH OTHER CONFIG STUFF # +################################ +``` + +Once you have made the necessary configuration changes, restart your instance and refresh the home page. If the message is gone, then the problem is resolved! + +If you still see the warning message but with a different suggested IP range to add to `trusted-proxies`, then follow the same steps as above again, including the new suggested IP range in your config in addition to the one you just added. + +!!! tip "Cloudflare IP Addresses" + If you are running with a CDN/proxy such as Cloudflare in front of your GoToSocial instance (not recommended), then you may need to add one or more of the Cloudflare IP addresses to your `trusted-proxies` in order to have rate limiting work properly. You can find a list of Cloudflare IP addresses here: https://www.cloudflare.com/ips/ diff --git a/docs/getting_started/reverse_proxy/index.md b/docs/getting_started/reverse_proxy/index.md index 927968df0..8b11f937a 100644 --- a/docs/getting_started/reverse_proxy/index.md +++ b/docs/getting_started/reverse_proxy/index.md @@ -41,3 +41,7 @@ We have guides available for the following servers: When using a reverse-proxy, special care must be taken to allow WebSockets to work too. This is necessary as many client applications use WebSockets to stream your timeline. WebSockets is not used as part of federation. Make sure you read the [WebSocket](websocket.md) documentation and configure your reverse proxy accordingly. + +## Trusted Proxies + +When using a reverse-proxy, you may run into issues with rate limiting and `trusted-proxies`. Check the [trusted proxies](../../configuration/trusted_proxies.md) documentation if you have any problems. diff --git a/example/docker-compose/docker-compose.yaml b/example/docker-compose/docker-compose.yaml index 05896d724..fbd9af8dd 100644 --- a/example/docker-compose/docker-compose.yaml +++ b/example/docker-compose/docker-compose.yaml @@ -1,5 +1,3 @@ -version: "3.3" - services: gotosocial: image: superseriousbusiness/gotosocial:latest @@ -24,7 +22,7 @@ services: # Wazero compilation cache will be stored. GTS_WAZERO_COMPILATION_CACHE: /gotosocial/.cache ## For reverse proxy setups: - # GTS_TRUSTED_PROXIES: "172.x.x.x" + GTS_TRUSTED_PROXIES: "172.18.0.1/16" ## Set the timezone of your server: #TZ: UTC ports: @@ -47,3 +45,6 @@ networks: gotosocial: ipam: driver: default + config: + - subnet: "172.18.0.0/16" + gateway: "172.18.0.1" diff --git a/internal/api/util/template.go b/internal/api/util/template.go index b8c710c3c..fcfd80956 100644 --- a/internal/api/util/template.go +++ b/internal/api/util/template.go @@ -18,6 +18,7 @@ package util import ( + "net" "net/http" "github.com/gin-gonic/gin" @@ -63,6 +64,11 @@ type WebPage struct { // ogMeta, stylesheets, javascript, and any extra // properties will be provided to the template if // set, but can all be nil. +// +// TemplateWebPage also checks whether the requesting +// clientIP is 127.0.0.1 or within a private IP range. +// If so, it injects a suggestion into the page header +// about setting trusted-proxies correctly. func TemplateWebPage( c *gin.Context, page WebPage, @@ -74,13 +80,86 @@ func TemplateWebPage( "javascript": page.Javascript, } + // Add extras to template object. for k, v := range page.Extra { obj[k] = v } + // Inject trustedProxiesRec to template + // object (or noop if not necessary). + injectTrustedProxiesRec(c, obj) + templatePage(c, page.Template, http.StatusOK, obj) } +func injectTrustedProxiesRec( + c *gin.Context, + obj map[string]any, +) { + clientIP := c.ClientIP() + if clientIP == "127.0.0.1" { + // Suggest precise 127.0.0.1/32. + trustedProxiesRec := clientIP + "/32" + obj["trustedProxiesRec"] = trustedProxiesRec + return + } + + // True if "X-Forwarded-For" + // or "X-Real-IP" were set. + var hasRemoteIPHeader bool + for _, k := range []string{ + "X-Forwarded-For", + "X-Real-IP", + } { + if v := c.GetHeader(k); v != "" { + hasRemoteIPHeader = true + break + } + } + + if !hasRemoteIPHeader { + // Upstream hasn't set a + // remote IP header, bail. + return + } + + ip := net.ParseIP(clientIP) + if !ip.IsPrivate() { + // Upstream set a remote IP + // header but final clientIP + // isn't private, so upstream + // is probably already trusted. + // Don't inject suggestion. + return + } + + // Private IP, guess if Docker. + if dockerSubnet.Contains(ip) { + // Suggest a CIDR that likely + // covers this Docker subnet, + // eg., 172.17.0.0 -> 172.17.255.255. + trustedProxiesRec := clientIP + "/16" + obj["trustedProxiesRec"] = trustedProxiesRec + return + } + + // Private IP but we don't know + // what it is. Suggest precise CIDR. + trustedProxiesRec := clientIP + "/32" + obj["trustedProxiesRec"] = trustedProxiesRec +} + +// dockerSubnet is a CIDR that lets one make hazy guesses +// as to whether an address is within the ranges Docker +// uses for subnets, ie., 172.16.0.0 -> 172.31.255.255. +var dockerSubnet = func() *net.IPNet { + _, subnet, err := net.ParseCIDR("172.16.0.0/12") + if err != nil { + panic(err) + } + return subnet +}() + // templateErrorPage renders the given // HTTP code, error, and request ID // within the standard error template. diff --git a/mkdocs.yml b/mkdocs.yml index 82bb03791..15c0a56f7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -98,6 +98,7 @@ nav: - "Configuration": - "configuration/index.md" - "configuration/general.md" + - "configuration/trusted_proxies.md" - "configuration/database.md" - "configuration/web.md" - "configuration/instance.md" diff --git a/web/source/css/page.css b/web/source/css/page.css index 642586048..752b264ee 100644 --- a/web/source/css/page.css +++ b/web/source/css/page.css @@ -42,7 +42,26 @@ padding: 1.5rem; gap: 1rem; - a { + .trusted-proxies-rec { + color: $info-fg; + background: $info-bg; + max-width: fit-content; + padding-left: 1rem; + padding-right: 1rem; + border-radius: $br; + text-align: center; + align-self: center; + + code { + background: $info-bg; + } + + a { + color: $info-fg; + } + } + + & > a { display: flex; flex-wrap: wrap; gap: 1rem; diff --git a/web/template/page_header.tmpl b/web/template/page_header.tmpl index 388587aaf..f2349581e 100644 --- a/web/template/page_header.tmpl +++ b/web/template/page_header.tmpl @@ -17,6 +17,29 @@ // along with this program. If not, see . */ -}} +{{- define "trustedProxiesRec" -}} +{{- .with }} +
+

+ Warning! It looks like trusted-proxies is not set correctly in this instance's configuration. + This may cause rate-limiting issues and, by extension, federation issues. +

+

+ If you are the instance admin, you should fix this by adding {{- .trustedProxiesRec -}} to your trusted-proxies. +

+

+ For more information, see + + the documentation + . +

+
+{{- end -}} + {{- define "thumbnailDescription" -}} {{- if .instance.ThumbnailDescription -}} {{- .instance.ThumbnailDescription -}} @@ -56,6 +79,9 @@ Instance Logo {{- end -}} {{- with . }} +{{- if .trustedProxiesRec }} +{{- template "trustedProxiesRec" . }} +{{- end }} {{- if .instance.ThumbnailStatic }} From 9333bbc4d0d5ae46c72fca1f5b1aacb3c0a7653e Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Thu, 23 Jan 2025 17:18:23 +0000 Subject: [PATCH 03/16] [feature] Serve bot accounts over AP as Service instead of Person (#3672) * pepis * oopsie doopsie * bollocks --- docs/federation/actors.md | 8 ++ internal/ap/activitystreams.go | 16 ++++ internal/ap/ap_test.go | 11 +-- internal/ap/interfaces.go | 2 + .../api/activitypub/users/inboxpost_test.go | 60 ++++-------- internal/federation/federator_test.go | 4 +- internal/processing/fedi/user.go | 13 ++- internal/processing/workers/federate.go | 23 ++--- internal/typeutils/internaltoas.go | 94 ++++++++++++------- internal/typeutils/internaltoas_test.go | 91 +++++++++++++++--- internal/typeutils/wrap.go | 71 +++++--------- internal/typeutils/wrap_test.go | 80 ++++++++++++++++ testrig/testmodels.go | 14 +-- testrig/transportcontroller.go | 3 +- 14 files changed, 315 insertions(+), 175 deletions(-) diff --git a/docs/federation/actors.md b/docs/federation/actors.md index d5dc61e19..ba2283ee9 100644 --- a/docs/federation/actors.md +++ b/docs/federation/actors.md @@ -1,5 +1,13 @@ # Actors and Actor Properties +## `Service` vs `Person` actors + +GoToSocial serves most accounts as the ActivityStreams `Person` type described [here](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-person). + +Accounts that users have selected to mark as bot accounts, however, will use the `Service` type described [here](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-service). + +This type distinction can be used by remote servers to distinguish between bot accounts and "regular" user accounts. + ## Inbox GoToSocial implements Inboxes for Actors following the ActivityPub specification [here](https://www.w3.org/TR/activitypub/#inbox). diff --git a/internal/ap/activitystreams.go b/internal/ap/activitystreams.go index 8c53ae501..50955ce2c 100644 --- a/internal/ap/activitystreams.go +++ b/internal/ap/activitystreams.go @@ -17,6 +17,22 @@ package ap +import ( + "net/url" + + "github.com/superseriousbusiness/activity/pub" +) + +// PublicURI returns a fresh copy of the *url.URL version of the +// magic ActivityPub URI https://www.w3.org/ns/activitystreams#Public +func PublicURI() *url.URL { + publicURI, err := url.Parse(pub.PublicActivityPubIRI) + if err != nil { + panic(err) + } + return publicURI +} + // https://www.w3.org/TR/activitystreams-vocabulary const ( ActivityAccept = "Accept" // ActivityStreamsAccept https://www.w3.org/TR/activitystreams-vocabulary/#dfn-accept diff --git a/internal/ap/ap_test.go b/internal/ap/ap_test.go index f982e4443..3738c8c9c 100644 --- a/internal/ap/ap_test.go +++ b/internal/ap/ap_test.go @@ -24,7 +24,6 @@ "io" "github.com/stretchr/testify/suite" - "github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/gotosocial/internal/ap" @@ -111,7 +110,7 @@ func noteWithMentions1() vocab.ActivityStreamsNote { // Anyone can like. canLikeAlwaysProp := streams.NewGoToSocialAlwaysProperty() - canLikeAlwaysProp.AppendIRI(testrig.URLMustParse(pub.PublicActivityPubIRI)) + canLikeAlwaysProp.AppendIRI(ap.PublicURI()) canLike.SetGoToSocialAlways(canLikeAlwaysProp) // Empty approvalRequired. @@ -128,7 +127,7 @@ func noteWithMentions1() vocab.ActivityStreamsNote { // Anyone can reply. canReplyAlwaysProp := streams.NewGoToSocialAlwaysProperty() - canReplyAlwaysProp.AppendIRI(testrig.URLMustParse(pub.PublicActivityPubIRI)) + canReplyAlwaysProp.AppendIRI(ap.PublicURI()) canReply.SetGoToSocialAlways(canReplyAlwaysProp) // Set empty approvalRequired. @@ -151,7 +150,7 @@ func noteWithMentions1() vocab.ActivityStreamsNote { // Public requires approval to announce. canAnnounceApprovalRequiredProp := streams.NewGoToSocialApprovalRequiredProperty() - canAnnounceApprovalRequiredProp.AppendIRI(testrig.URLMustParse(pub.PublicActivityPubIRI)) + canAnnounceApprovalRequiredProp.AppendIRI(ap.PublicURI()) canAnnounce.SetGoToSocialApprovalRequired(canAnnounceApprovalRequiredProp) // Set canAnnounce on the policy. @@ -266,7 +265,7 @@ func addressable1() ap.Addressable { note := streams.NewActivityStreamsNote() toProp := streams.NewActivityStreamsToProperty() - toProp.AppendIRI(testrig.URLMustParse(pub.PublicActivityPubIRI)) + toProp.AppendIRI(ap.PublicURI()) note.SetActivityStreamsTo(toProp) @@ -288,7 +287,7 @@ func addressable2() ap.Addressable { note.SetActivityStreamsTo(toProp) ccProp := streams.NewActivityStreamsCcProperty() - ccProp.AppendIRI(testrig.URLMustParse(pub.PublicActivityPubIRI)) + ccProp.AppendIRI(ap.PublicURI()) note.SetActivityStreamsCc(ccProp) diff --git a/internal/ap/interfaces.go b/internal/ap/interfaces.go index 1f08fde37..fdd5e4a0b 100644 --- a/internal/ap/interfaces.go +++ b/internal/ap/interfaces.go @@ -188,6 +188,7 @@ type Accountable interface { WithTag WithPublished WithUpdated + WithImage } // Statusable represents the minimum activitypub interface for representing a 'status'. @@ -439,6 +440,7 @@ type WithValue interface { // WithImage represents an activity with ActivityStreamsImageProperty type WithImage interface { GetActivityStreamsImage() vocab.ActivityStreamsImageProperty + SetActivityStreamsImage(vocab.ActivityStreamsImageProperty) } // WithSummary represents an activity with ActivityStreamsSummaryProperty diff --git a/internal/api/activitypub/users/inboxpost_test.go b/internal/api/activitypub/users/inboxpost_test.go index 64c9f7e6c..f87224d65 100644 --- a/internal/api/activitypub/users/inboxpost_test.go +++ b/internal/api/activitypub/users/inboxpost_test.go @@ -177,38 +177,6 @@ func (suite *InboxPostTestSuite) newUndo( return undo } -func (suite *InboxPostTestSuite) newUpdatePerson(person vocab.ActivityStreamsPerson, cc string, updateIRI string) vocab.ActivityStreamsUpdate { - // create an update - update := streams.NewActivityStreamsUpdate() - - // set the appropriate actor on it - updateActor := streams.NewActivityStreamsActorProperty() - updateActor.AppendIRI(person.GetJSONLDId().Get()) - update.SetActivityStreamsActor(updateActor) - - // Set the person as the 'object' property. - updateObject := streams.NewActivityStreamsObjectProperty() - updateObject.AppendActivityStreamsPerson(person) - update.SetActivityStreamsObject(updateObject) - - // Set the To of the update as public - updateTo := streams.NewActivityStreamsToProperty() - updateTo.AppendIRI(testrig.URLMustParse(pub.PublicActivityPubIRI)) - update.SetActivityStreamsTo(updateTo) - - // set the cc of the update to the receivingAccount - updateCC := streams.NewActivityStreamsCcProperty() - updateCC.AppendIRI(testrig.URLMustParse(cc)) - update.SetActivityStreamsCc(updateCC) - - // set some random-ass ID for the activity - updateID := streams.NewJSONLDIdProperty() - updateID.SetIRI(testrig.URLMustParse(updateIRI)) - update.SetJSONLDId(updateID) - - return update -} - func (suite *InboxPostTestSuite) newDelete(actorIRI string, objectIRI string, deleteIRI string) vocab.ActivityStreamsDelete { // create a delete delete := streams.NewActivityStreamsDelete() @@ -225,7 +193,7 @@ func (suite *InboxPostTestSuite) newDelete(actorIRI string, objectIRI string, de // Set the To of the delete as public deleteTo := streams.NewActivityStreamsToProperty() - deleteTo.AppendIRI(testrig.URLMustParse(pub.PublicActivityPubIRI)) + deleteTo.AppendIRI(ap.PublicURI()) delete.SetActivityStreamsTo(deleteTo) // set some random-ass ID for the activity @@ -329,7 +297,6 @@ func (suite *InboxPostTestSuite) TestPostUpdate() { var ( requestingAccount = new(gtsmodel.Account) targetAccount = suite.testAccounts["local_account_1"] - activityID = "http://fossbros-anonymous.io/72cc96a3-f742-4daf-b9f5-3407667260c5" updatedDisplayName = "updated display name!" ) @@ -348,11 +315,19 @@ func (suite *InboxPostTestSuite) TestPostUpdate() { requestingAccount.Emojis = []*gtsmodel.Emoji{testEmoji} // Create an update from the account. - asAccount, err := suite.tc.AccountToAS(context.Background(), requestingAccount) + accountable, err := suite.tc.AccountToAS(context.Background(), requestingAccount) if err != nil { suite.FailNow(err.Error()) } - update := suite.newUpdatePerson(asAccount, targetAccount.URI, activityID) + update, err := suite.tc.WrapAccountableInUpdate(accountable) + if err != nil { + suite.FailNow(err.Error()) + } + + // Set the ID to something from fossbros anonymous. + idProp := streams.NewJSONLDIdProperty() + idProp.SetIRI(testrig.URLMustParse("https://fossbros-anonymous.io/updates/waaaaaaaaaaaaaaaaa")) + update.SetJSONLDId(idProp) // Update. suite.inboxPost( @@ -540,17 +515,20 @@ func (suite *InboxPostTestSuite) TestPostFromBlockedAccount() { var ( requestingAccount = suite.testAccounts["remote_account_1"] targetAccount = suite.testAccounts["local_account_2"] - activityID = requestingAccount.URI + "/some-new-activity/01FG9C441MCTW3R2W117V2PQK3" ) - person, err := suite.tc.AccountToAS(context.Background(), requestingAccount) + // Create an update from the account. + accountable, err := suite.tc.AccountToAS(context.Background(), requestingAccount) + if err != nil { + suite.FailNow(err.Error()) + } + update, err := suite.tc.WrapAccountableInUpdate(accountable) if err != nil { suite.FailNow(err.Error()) } - // Post an update from foss satan to turtle, who blocks him. - update := suite.newUpdatePerson(person, targetAccount.URI, activityID) - + // Post an update from foss satan + // to turtle, who blocks him. suite.inboxPost( update, requestingAccount, diff --git a/internal/federation/federator_test.go b/internal/federation/federator_test.go index e10c7576c..a4f8c4683 100644 --- a/internal/federation/federator_test.go +++ b/internal/federation/federator_test.go @@ -75,12 +75,12 @@ func (suite *FederatorStandardTestSuite) SetupTest() { // Ensure it's possible to deref // main key of foss satan. - fossSatanPerson, err := suite.typeconverter.AccountToAS(context.Background(), suite.testAccounts["remote_account_1"]) + fossSatanAS, err := suite.typeconverter.AccountToAS(context.Background(), suite.testAccounts["remote_account_1"]) if err != nil { suite.FailNow(err.Error()) } - suite.httpClient = testrig.NewMockHTTPClient(nil, "../../testrig/media", fossSatanPerson) + suite.httpClient = testrig.NewMockHTTPClient(nil, "../../testrig/media", fossSatanAS) suite.httpClient.TestRemotePeople = testrig.NewTestFediPeople() suite.httpClient.TestRemoteStatuses = testrig.NewTestFediStatuses() diff --git a/internal/processing/fedi/user.go b/internal/processing/fedi/user.go index bf14554cf..79c1b4fdb 100644 --- a/internal/processing/fedi/user.go +++ b/internal/processing/fedi/user.go @@ -23,7 +23,6 @@ "fmt" "net/url" - "github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtserror" @@ -72,7 +71,7 @@ func (p *Processor) UserGet(ctx context.Context, requestedUsername string, reque } // Auth passed, generate the proper AP representation. - person, err := p.converter.AccountToAS(ctx, receiver) + accountable, err := p.converter.AccountToAS(ctx, receiver) if err != nil { err := gtserror.Newf("error converting account: %w", err) return nil, gtserror.NewErrorInternalError(err) @@ -91,7 +90,7 @@ func (p *Processor) UserGet(ctx context.Context, requestedUsername string, reque // Instead, we end up in an 'I'll show you mine if you show me // yours' situation, where we sort of agree to reveal each // other's profiles at the same time. - return data(person) + return data(accountable) } // Get requester from auth. @@ -107,13 +106,13 @@ func (p *Processor) UserGet(ctx context.Context, requestedUsername string, reque return nil, gtserror.NewErrorForbidden(errors.New(text)) } - return data(person) + return data(accountable) } -func data(requestedPerson vocab.ActivityStreamsPerson) (interface{}, gtserror.WithCode) { - data, err := ap.Serialize(requestedPerson) +func data(accountable ap.Accountable) (interface{}, gtserror.WithCode) { + data, err := ap.Serialize(accountable) if err != nil { - err := gtserror.Newf("error serializing person: %w", err) + err := gtserror.Newf("error serializing accountable: %w", err) return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/workers/federate.go b/internal/processing/workers/federate.go index 8c08c42b7..d6dec6691 100644 --- a/internal/processing/workers/federate.go +++ b/internal/processing/workers/federate.go @@ -21,7 +21,6 @@ "context" "net/url" - "github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/gotosocial/internal/ap" @@ -93,11 +92,6 @@ func (f *federate) DeleteAccount(ctx context.Context, account *gtsmodel.Account) return err } - publicIRI, err := parseURI(pub.PublicActivityPubIRI) - if err != nil { - return err - } - // Create a new delete. // todo: tc.AccountToASDelete delete := streams.NewActivityStreamsDelete() @@ -121,7 +115,7 @@ func (f *federate) DeleteAccount(ctx context.Context, account *gtsmodel.Account) // Address the delete CC public. deleteCC := streams.NewActivityStreamsCcProperty() - deleteCC.AppendIRI(publicIRI) + deleteCC.AppendIRI(ap.PublicURI()) delete.SetActivityStreamsCc(deleteCC) // Send the Delete via the Actor's outbox. @@ -877,14 +871,14 @@ func (f *federate) UpdateAccount(ctx context.Context, account *gtsmodel.Account) return err } - // Convert account to ActivityStreams Person. - person, err := f.converter.AccountToAS(ctx, account) + // Convert account to Accountable. + accountable, err := f.converter.AccountToAS(ctx, account) if err != nil { return gtserror.Newf("error converting account to Person: %w", err) } - // Use ActivityStreams Person as Object of Update. - update, err := f.converter.WrapPersonInUpdate(person, account) + // Use Accountable as Object of Update. + update, err := f.converter.WrapAccountableInUpdate(accountable) if err != nil { return gtserror.Newf("error wrapping Person in Update: %w", err) } @@ -1089,11 +1083,6 @@ func (f *federate) MoveAccount(ctx context.Context, account *gtsmodel.Account) e return err } - publicIRI, err := parseURI(pub.PublicActivityPubIRI) - if err != nil { - return err - } - // Create a new move. move := streams.NewActivityStreamsMove() @@ -1115,7 +1104,7 @@ func (f *federate) MoveAccount(ctx context.Context, account *gtsmodel.Account) e ap.AppendTo(move, followersIRI) // Address the move CC public. - ap.AppendCc(move, publicIRI) + ap.AppendCc(move, ap.PublicURI()) // Send the Move via the Actor's outbox. if _, err := f.FederatingActor().Send( diff --git a/internal/typeutils/internaltoas.go b/internal/typeutils/internaltoas.go index de1badb5c..ce5187bde 100644 --- a/internal/typeutils/internaltoas.go +++ b/internal/typeutils/internaltoas.go @@ -36,12 +36,24 @@ "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/log" "github.com/superseriousbusiness/gotosocial/internal/uris" + "github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/util/xslices" ) -// AccountToAS converts a gts model account into an activity streams person, suitable for federation -func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error) { - person := streams.NewActivityStreamsPerson() +// AccountToAS converts a gts model account +// into an activity streams person or service. +func (c *Converter) AccountToAS( + ctx context.Context, + a *gtsmodel.Account, +) (ap.Accountable, error) { + // accountable is a service if this + // is a bot account, otherwise a person. + var accountable ap.Accountable + if util.PtrOrZero(a.Bot) { + accountable = streams.NewActivityStreamsService() + } else { + accountable = streams.NewActivityStreamsPerson() + } // id should be the activitypub URI of this user // something like https://example.org/users/example_user @@ -51,13 +63,13 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab } idProp := streams.NewJSONLDIdProperty() idProp.SetIRI(profileIDURI) - person.SetJSONLDId(idProp) + accountable.SetJSONLDId(idProp) // published // The moment when the account was created. publishedProp := streams.NewActivityStreamsPublishedProperty() publishedProp.Set(a.CreatedAt) - person.SetActivityStreamsPublished(publishedProp) + accountable.SetActivityStreamsPublished(publishedProp) // following // The URI for retrieving a list of accounts this user is following @@ -67,7 +79,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab } followingProp := streams.NewActivityStreamsFollowingProperty() followingProp.SetIRI(followingURI) - person.SetActivityStreamsFollowing(followingProp) + accountable.SetActivityStreamsFollowing(followingProp) // followers // The URI for retrieving a list of this user's followers @@ -77,7 +89,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab } followersProp := streams.NewActivityStreamsFollowersProperty() followersProp.SetIRI(followersURI) - person.SetActivityStreamsFollowers(followersProp) + accountable.SetActivityStreamsFollowers(followersProp) // inbox // the activitypub inbox of this user for accepting messages @@ -87,7 +99,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab } inboxProp := streams.NewActivityStreamsInboxProperty() inboxProp.SetIRI(inboxURI) - person.SetActivityStreamsInbox(inboxProp) + accountable.SetActivityStreamsInbox(inboxProp) // shared inbox -- only add this if we know for sure it has one if a.SharedInboxURI != nil && *a.SharedInboxURI != "" { @@ -101,7 +113,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab sharedInboxProp.SetIRI(sharedInboxURI) endpoints.SetActivityStreamsSharedInbox(sharedInboxProp) endpointsProp.AppendActivityStreamsEndpoints(endpoints) - person.SetActivityStreamsEndpoints(endpointsProp) + accountable.SetActivityStreamsEndpoints(endpointsProp) } // outbox @@ -112,7 +124,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab } outboxProp := streams.NewActivityStreamsOutboxProperty() outboxProp.SetIRI(outboxURI) - person.SetActivityStreamsOutbox(outboxProp) + accountable.SetActivityStreamsOutbox(outboxProp) // featured posts // Pinned posts. @@ -122,7 +134,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab } featuredProp := streams.NewTootFeaturedProperty() featuredProp.SetIRI(featuredURI) - person.SetTootFeatured(featuredProp) + accountable.SetTootFeatured(featuredProp) // featuredTags // NOT IMPLEMENTED @@ -131,7 +143,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab // Used for Webfinger lookup. Must be unique on the domain, and must correspond to a Webfinger acct: URI. preferredUsernameProp := streams.NewActivityStreamsPreferredUsernameProperty() preferredUsernameProp.SetXMLSchemaString(a.Username) - person.SetActivityStreamsPreferredUsername(preferredUsernameProp) + accountable.SetActivityStreamsPreferredUsername(preferredUsernameProp) // name // Used as profile display name. @@ -141,14 +153,14 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab } else { nameProp.AppendXMLSchemaString(a.Username) } - person.SetActivityStreamsName(nameProp) + accountable.SetActivityStreamsName(nameProp) // summary // Used as profile bio. if a.Note != "" { summaryProp := streams.NewActivityStreamsSummaryProperty() summaryProp.AppendXMLSchemaString(a.Note) - person.SetActivityStreamsSummary(summaryProp) + accountable.SetActivityStreamsSummary(summaryProp) } // url @@ -159,19 +171,19 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab } urlProp := streams.NewActivityStreamsUrlProperty() urlProp.AppendIRI(profileURL) - person.SetActivityStreamsUrl(urlProp) + accountable.SetActivityStreamsUrl(urlProp) // manuallyApprovesFollowers // Will be shown as a locked account. manuallyApprovesFollowersProp := streams.NewActivityStreamsManuallyApprovesFollowersProperty() manuallyApprovesFollowersProp.Set(*a.Locked) - person.SetActivityStreamsManuallyApprovesFollowers(manuallyApprovesFollowersProp) + accountable.SetActivityStreamsManuallyApprovesFollowers(manuallyApprovesFollowersProp) // discoverable // Will be shown in the profile directory. discoverableProp := streams.NewTootDiscoverableProperty() discoverableProp.Set(*a.Discoverable) - person.SetTootDiscoverable(discoverableProp) + accountable.SetTootDiscoverable(discoverableProp) // devices // NOT IMPLEMENTED, probably won't implement @@ -189,7 +201,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab alsoKnownAsURIs[i] = uri } - ap.SetAlsoKnownAs(person, alsoKnownAsURIs) + ap.SetAlsoKnownAs(accountable, alsoKnownAsURIs) } // movedTo @@ -200,7 +212,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab return nil, err } - ap.SetMovedTo(person, movedTo) + ap.SetMovedTo(accountable, movedTo) } // publicKey @@ -241,7 +253,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab publicKeyProp.AppendW3IDSecurityV1PublicKey(publicKey) // set the public key property on the Person - person.SetW3IDSecurityV1PublicKey(publicKeyProp) + accountable.SetW3IDSecurityV1PublicKey(publicKeyProp) // tags tagProp := streams.NewActivityStreamsTagProperty() @@ -269,7 +281,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab // tag -- hashtags // TODO - person.SetActivityStreamsTag(tagProp) + accountable.SetActivityStreamsTag(tagProp) // attachment // Used for profile fields. @@ -290,7 +302,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab attachmentProp.AppendSchemaPropertyValue(propertyValue) } - person.SetActivityStreamsAttachment(attachmentProp) + accountable.SetActivityStreamsAttachment(attachmentProp) } // endpoints @@ -326,7 +338,7 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab iconImage.SetActivityStreamsUrl(avatarURLProperty) iconProperty.AppendActivityStreamsImage(iconImage) - person.SetActivityStreamsIcon(iconProperty) + accountable.SetActivityStreamsIcon(iconProperty) } } @@ -360,20 +372,32 @@ func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab headerImage.SetActivityStreamsUrl(headerURLProperty) headerProperty.AppendActivityStreamsImage(headerImage) - person.SetActivityStreamsImage(headerProperty) + accountable.SetActivityStreamsImage(headerProperty) } } - return person, nil + return accountable, nil } -// AccountToASMinimal converts a gts model account into an activity streams person, suitable for federation. +// AccountToASMinimal converts a gts model account +// into an activity streams person or service. // -// The returned account will just have the Type, Username, PublicKey, and ID properties set. This is -// suitable for serving to requesters to whom we want to give as little information as possible because -// we don't trust them (yet). -func (c *Converter) AccountToASMinimal(ctx context.Context, a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error) { - person := streams.NewActivityStreamsPerson() +// The returned account will just have the Type, Username, +// PublicKey, and ID properties set. This is suitable for +// serving to requesters to whom we want to give as little +// information as possible because we don't trust them (yet). +func (c *Converter) AccountToASMinimal( + ctx context.Context, + a *gtsmodel.Account, +) (ap.Accountable, error) { + // accountable is a service if this + // is a bot account, otherwise a person. + var accountable ap.Accountable + if util.PtrOrZero(a.Bot) { + accountable = streams.NewActivityStreamsService() + } else { + accountable = streams.NewActivityStreamsPerson() + } // id should be the activitypub URI of this user // something like https://example.org/users/example_user @@ -383,13 +407,13 @@ func (c *Converter) AccountToASMinimal(ctx context.Context, a *gtsmodel.Account) } idProp := streams.NewJSONLDIdProperty() idProp.SetIRI(profileIDURI) - person.SetJSONLDId(idProp) + accountable.SetJSONLDId(idProp) // preferredUsername // Used for Webfinger lookup. Must be unique on the domain, and must correspond to a Webfinger acct: URI. preferredUsernameProp := streams.NewActivityStreamsPreferredUsernameProperty() preferredUsernameProp.SetXMLSchemaString(a.Username) - person.SetActivityStreamsPreferredUsername(preferredUsernameProp) + accountable.SetActivityStreamsPreferredUsername(preferredUsernameProp) // publicKey // Required for signatures. @@ -429,9 +453,9 @@ func (c *Converter) AccountToASMinimal(ctx context.Context, a *gtsmodel.Account) publicKeyProp.AppendW3IDSecurityV1PublicKey(publicKey) // set the public key property on the Person - person.SetW3IDSecurityV1PublicKey(publicKeyProp) + accountable.SetW3IDSecurityV1PublicKey(publicKeyProp) - return person, nil + return accountable, nil } // StatusToAS converts a gts model status into an ActivityStreams Statusable implementation, suitable for federation diff --git a/internal/typeutils/internaltoas_test.go b/internal/typeutils/internaltoas_test.go index 344a42798..4d0d95641 100644 --- a/internal/typeutils/internaltoas_test.go +++ b/internal/typeutils/internaltoas_test.go @@ -27,6 +27,7 @@ "github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/testrig" ) @@ -38,10 +39,10 @@ func (suite *InternalToASTestSuite) TestAccountToAS() { testAccount := >smodel.Account{} *testAccount = *suite.testAccounts["local_account_1"] // take zork for this test - asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + accountable, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) suite.NoError(err) - ser, err := ap.Serialize(asPerson) + ser, err := ap.Serialize(accountable) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -94,14 +95,80 @@ func (suite *InternalToASTestSuite) TestAccountToAS() { }`, string(bytes)) } +func (suite *InternalToASTestSuite) TestAccountToASBot() { + testAccount := >smodel.Account{} + *testAccount = *suite.testAccounts["local_account_1"] // take zork for this test + + // Update zork to be a bot. + testAccount.Bot = util.Ptr(true) + if err := suite.state.DB.UpdateAccount(context.Background(), testAccount); err != nil { + suite.FailNow(err.Error()) + } + + accountable, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + suite.NoError(err) + + ser, err := ap.Serialize(accountable) + suite.NoError(err) + + bytes, err := json.MarshalIndent(ser, "", " ") + suite.NoError(err) + + suite.Equal(`{ + "@context": [ + "https://w3id.org/security/v1", + "https://www.w3.org/ns/activitystreams", + { + "discoverable": "toot:discoverable", + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "toot": "http://joinmastodon.org/ns#" + } + ], + "discoverable": true, + "featured": "http://localhost:8080/users/the_mighty_zork/collections/featured", + "followers": "http://localhost:8080/users/the_mighty_zork/followers", + "following": "http://localhost:8080/users/the_mighty_zork/following", + "icon": { + "mediaType": "image/jpeg", + "type": "Image", + "url": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/avatar/original/01F8MH58A357CV5K7R7TJMSH6S.jpg" + }, + "id": "http://localhost:8080/users/the_mighty_zork", + "image": { + "mediaType": "image/jpeg", + "type": "Image", + "url": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/original/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg" + }, + "inbox": "http://localhost:8080/users/the_mighty_zork/inbox", + "manuallyApprovesFollowers": false, + "name": "original zork (he/they)", + "outbox": "http://localhost:8080/users/the_mighty_zork/outbox", + "preferredUsername": "the_mighty_zork", + "publicKey": { + "id": "http://localhost:8080/users/the_mighty_zork/main-key", + "owner": "http://localhost:8080/users/the_mighty_zork", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXTcOAvM1Jiw5Ffpk0qn\nr0cwbNvFe/5zQ+Tp7tumK/ZnT37o7X0FUEXrxNi+dkhmeJ0gsaiN+JQGNUewvpSk\nPIAXKvi908aSfCGjs7bGlJCJCuDuL5d6m7hZnP9rt9fJc70GElPpG0jc9fXwlz7T\nlsPb2ecatmG05Y4jPwdC+oN4MNCv9yQzEvCVMzl76EJaM602kIHC1CISn0rDFmYd\n9rSN7XPlNJw1F6PbpJ/BWQ+pXHKw3OEwNTETAUNYiVGnZU+B7a7bZC9f6/aPbJuV\nt8Qmg+UnDvW1Y8gmfHnxaWG2f5TDBvCHmcYtucIZPLQD4trAozC4ryqlmCWQNKbt\n0wIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "published": "2022-05-20T11:09:18Z", + "summary": "\u003cp\u003ehey yo this is my profile!\u003c/p\u003e", + "tag": [], + "type": "Service", + "url": "http://localhost:8080/@the_mighty_zork" +}`, string(bytes)) +} + func (suite *InternalToASTestSuite) TestAccountToASWithFields() { testAccount := >smodel.Account{} *testAccount = *suite.testAccounts["local_account_2"] - asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + accountable, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) suite.NoError(err) - ser, err := ap.Serialize(asPerson) + ser, err := ap.Serialize(accountable) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -176,10 +243,10 @@ func (suite *InternalToASTestSuite) TestAccountToASAliasedAndMoved() { suite.FailNow(err.Error()) } - asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + accountable, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) suite.NoError(err) - ser, err := ap.Serialize(asPerson) + ser, err := ap.Serialize(accountable) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -246,10 +313,10 @@ func (suite *InternalToASTestSuite) TestAccountToASWithOneField() { *testAccount = *suite.testAccounts["local_account_2"] testAccount.Fields = testAccount.Fields[0:1] // Take only one field. - asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + accountable, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) suite.NoError(err) - ser, err := ap.Serialize(asPerson) + ser, err := ap.Serialize(accountable) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -308,10 +375,10 @@ func (suite *InternalToASTestSuite) TestAccountToASWithEmoji() { *testAccount = *suite.testAccounts["local_account_1"] // take zork for this test testAccount.Emojis = []*gtsmodel.Emoji{suite.testEmojis["rainbow"]} - asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + accountable, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) suite.NoError(err) - ser, err := ap.Serialize(asPerson) + ser, err := ap.Serialize(accountable) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -381,10 +448,10 @@ func (suite *InternalToASTestSuite) TestAccountToASWithSharedInbox() { sharedInbox := "http://localhost:8080/sharedInbox" testAccount.SharedInboxURI = &sharedInbox - asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + accountable, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) suite.NoError(err) - ser, err := ap.Serialize(asPerson) + ser, err := ap.Serialize(accountable) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") diff --git a/internal/typeutils/wrap.go b/internal/typeutils/wrap.go index 89bcdfc09..1230981d4 100644 --- a/internal/typeutils/wrap.go +++ b/internal/typeutils/wrap.go @@ -18,68 +18,45 @@ package typeutils import ( - "net/url" - - "github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/gotosocial/internal/ap" - "github.com/superseriousbusiness/gotosocial/internal/gtserror" - "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/id" + "github.com/superseriousbusiness/gotosocial/internal/log" "github.com/superseriousbusiness/gotosocial/internal/uris" ) -// WrapPersonInUpdate ... -func (c *Converter) WrapPersonInUpdate(person vocab.ActivityStreamsPerson, originAccount *gtsmodel.Account) (vocab.ActivityStreamsUpdate, error) { +// WrapAccountableInUpdate wraps the given accountable +// in an Update activity with the accountable as the object. +// +// The Update will be addressed to Public and bcc followers. +func (c *Converter) WrapAccountableInUpdate(accountable ap.Accountable) (vocab.ActivityStreamsUpdate, error) { update := streams.NewActivityStreamsUpdate() - // set the actor - actorURI, err := url.Parse(originAccount.URI) - if err != nil { - return nil, gtserror.Newf("error parsing url %s: %w", originAccount.URI, err) - } - actorProp := streams.NewActivityStreamsActorProperty() - actorProp.AppendIRI(actorURI) - update.SetActivityStreamsActor(actorProp) + // Set actor IRI to this accountable's IRI. + ap.AppendActorIRIs(update, ap.GetJSONLDId(accountable)) - // set the ID - newID, err := id.NewRandomULID() - if err != nil { - return nil, err - } + // Set the update ID + updateURI := uris.GenerateURIForUpdate(ap.ExtractPreferredUsername(accountable), id.NewULID()) + ap.MustSet(ap.SetJSONLDIdStr, ap.WithJSONLDId(update), updateURI) - idString := uris.GenerateURIForUpdate(originAccount.Username, newID) - idURI, err := url.Parse(idString) - if err != nil { - return nil, gtserror.Newf("error parsing url %s: %w", idString, err) - } - idProp := streams.NewJSONLDIdProperty() - idProp.SetIRI(idURI) - update.SetJSONLDId(idProp) - - // set the person as the object here + // Set the accountable as the object of the update. objectProp := streams.NewActivityStreamsObjectProperty() - objectProp.AppendActivityStreamsPerson(person) + switch t := accountable.(type) { + case vocab.ActivityStreamsPerson: + objectProp.AppendActivityStreamsPerson(t) + case vocab.ActivityStreamsService: + objectProp.AppendActivityStreamsService(t) + default: + log.Panicf(nil, "%T was neither person nor service", t) + } update.SetActivityStreamsObject(objectProp) - // to should be public - toURI, err := url.Parse(pub.PublicActivityPubIRI) - if err != nil { - return nil, gtserror.Newf("error parsing url %s: %w", pub.PublicActivityPubIRI, err) - } - toProp := streams.NewActivityStreamsToProperty() - toProp.AppendIRI(toURI) - update.SetActivityStreamsTo(toProp) + // to should be public. + ap.AppendTo(update, ap.PublicURI()) - // bcc followers - followersURI, err := url.Parse(originAccount.FollowersURI) - if err != nil { - return nil, gtserror.Newf("error parsing url %s: %w", originAccount.FollowersURI, err) - } - bccProp := streams.NewActivityStreamsBccProperty() - bccProp.AppendIRI(followersURI) - update.SetActivityStreamsBcc(bccProp) + // bcc should be followers. + ap.AppendBcc(update, ap.GetFollowers(accountable)) return update, nil } diff --git a/internal/typeutils/wrap_test.go b/internal/typeutils/wrap_test.go index 1085c8c66..8c8af7506 100644 --- a/internal/typeutils/wrap_test.go +++ b/internal/typeutils/wrap_test.go @@ -139,6 +139,86 @@ func (suite *WrapTestSuite) TestWrapNoteInCreate() { }`, string(bytes)) } +func (suite *WrapTestSuite) TestWrapAccountableInUpdate() { + testAccount := suite.testAccounts["local_account_1"] + + accountable, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + if err != nil { + suite.FailNow(err.Error()) + } + + create, err := suite.typeconverter.WrapAccountableInUpdate(accountable) + if err != nil { + suite.FailNow(err.Error()) + } + + createI, err := ap.Serialize(create) + if err != nil { + suite.FailNow(err.Error()) + } + + // Get the ID as it's not determinate. + createID := ap.GetJSONLDId(create) + + bytes, err := json.MarshalIndent(createI, "", " ") + if err != nil { + suite.FailNow(err.Error()) + } + + suite.Equal(`{ + "@context": [ + "https://w3id.org/security/v1", + "https://www.w3.org/ns/activitystreams", + { + "discoverable": "toot:discoverable", + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "toot": "http://joinmastodon.org/ns#" + } + ], + "actor": "http://localhost:8080/users/the_mighty_zork", + "bcc": "http://localhost:8080/users/the_mighty_zork/followers", + "id": "`+createID.String()+`", + "object": { + "discoverable": true, + "featured": "http://localhost:8080/users/the_mighty_zork/collections/featured", + "followers": "http://localhost:8080/users/the_mighty_zork/followers", + "following": "http://localhost:8080/users/the_mighty_zork/following", + "icon": { + "mediaType": "image/jpeg", + "type": "Image", + "url": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/avatar/original/01F8MH58A357CV5K7R7TJMSH6S.jpg" + }, + "id": "http://localhost:8080/users/the_mighty_zork", + "image": { + "mediaType": "image/jpeg", + "type": "Image", + "url": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/original/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg" + }, + "inbox": "http://localhost:8080/users/the_mighty_zork/inbox", + "manuallyApprovesFollowers": false, + "name": "original zork (he/they)", + "outbox": "http://localhost:8080/users/the_mighty_zork/outbox", + "preferredUsername": "the_mighty_zork", + "publicKey": { + "id": "http://localhost:8080/users/the_mighty_zork/main-key", + "owner": "http://localhost:8080/users/the_mighty_zork", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXTcOAvM1Jiw5Ffpk0qn\nr0cwbNvFe/5zQ+Tp7tumK/ZnT37o7X0FUEXrxNi+dkhmeJ0gsaiN+JQGNUewvpSk\nPIAXKvi908aSfCGjs7bGlJCJCuDuL5d6m7hZnP9rt9fJc70GElPpG0jc9fXwlz7T\nlsPb2ecatmG05Y4jPwdC+oN4MNCv9yQzEvCVMzl76EJaM602kIHC1CISn0rDFmYd\n9rSN7XPlNJw1F6PbpJ/BWQ+pXHKw3OEwNTETAUNYiVGnZU+B7a7bZC9f6/aPbJuV\nt8Qmg+UnDvW1Y8gmfHnxaWG2f5TDBvCHmcYtucIZPLQD4trAozC4ryqlmCWQNKbt\n0wIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "published": "2022-05-20T11:09:18Z", + "summary": "\u003cp\u003ehey yo this is my profile!\u003c/p\u003e", + "tag": [], + "type": "Person", + "url": "http://localhost:8080/@the_mighty_zork" + }, + "to": "https://www.w3.org/ns/activitystreams#Public", + "type": "Update" +}`, string(bytes)) +} + func TestWrapTestSuite(t *testing.T) { suite.Run(t, new(WrapTestSuite)) } diff --git a/testrig/testmodels.go b/testrig/testmodels.go index 81c3a85c5..da4202eed 100644 --- a/testrig/testmodels.go +++ b/testrig/testmodels.go @@ -2853,7 +2853,7 @@ func NewTestActivities(accounts map[string]*gtsmodel.Account) map[string]Activit "this is a public status, please forward it!", "", URLMustParse("http://example.org/users/Some_User"), - []*url.URL{URLMustParse(pub.PublicActivityPubIRI)}, + []*url.URL{ap.PublicURI()}, nil, false, []vocab.ActivityStreamsMention{}, @@ -3207,7 +3207,7 @@ func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote { "this is a public status, please forward it!", "", URLMustParse("http://example.org/users/Some_User"), - []*url.URL{URLMustParse(pub.PublicActivityPubIRI)}, + []*url.URL{ap.PublicURI()}, nil, false, []vocab.ActivityStreamsMention{}, @@ -3228,7 +3228,7 @@ func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote { "", URLMustParse("https://unknown-instance.com/users/brand_new_person"), []*url.URL{ - URLMustParse(pub.PublicActivityPubIRI), + ap.PublicURI(), }, []*url.URL{}, false, @@ -3244,7 +3244,7 @@ func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote { "", URLMustParse("https://unknown-instance.com/users/brand_new_person"), []*url.URL{ - URLMustParse(pub.PublicActivityPubIRI), + ap.PublicURI(), }, []*url.URL{}, false, @@ -3265,7 +3265,7 @@ func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote { "", URLMustParse("https://unknown-instance.com/users/brand_new_person"), []*url.URL{ - URLMustParse(pub.PublicActivityPubIRI), + ap.PublicURI(), }, []*url.URL{}, false, @@ -3286,7 +3286,7 @@ func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote { "", URLMustParse("https://turnip.farm/users/turniplover6969"), []*url.URL{ - URLMustParse(pub.PublicActivityPubIRI), + ap.PublicURI(), }, []*url.URL{}, false, @@ -3309,7 +3309,7 @@ func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote { "", URLMustParse("http://fossbros-anonymous.io/users/foss_satan"), []*url.URL{ - URLMustParse(pub.PublicActivityPubIRI), + ap.PublicURI(), }, []*url.URL{}, false, diff --git a/testrig/transportcontroller.go b/testrig/transportcontroller.go index 3bc8752e0..b886e5c40 100644 --- a/testrig/transportcontroller.go +++ b/testrig/transportcontroller.go @@ -29,6 +29,7 @@ "github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/activity/streams/vocab" + "github.com/superseriousbusiness/gotosocial/internal/ap" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" "github.com/superseriousbusiness/gotosocial/internal/federation" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" @@ -81,7 +82,7 @@ type MockHTTPClient struct { // to customize how the client is mocked. // // Note that you should never ever make ACTUAL http calls with this thing. -func NewMockHTTPClient(do func(req *http.Request) (*http.Response, error), relativeMediaPath string, extraPeople ...vocab.ActivityStreamsPerson) *MockHTTPClient { +func NewMockHTTPClient(do func(req *http.Request) (*http.Response, error), relativeMediaPath string, extraPeople ...ap.Accountable) *MockHTTPClient { mockHTTPClient := &MockHTTPClient{} if do != nil { From 5b765d734ee70f0a8a0790444d60969a727567f8 Mon Sep 17 00:00:00 2001 From: Vyr Cossont Date: Thu, 23 Jan 2025 16:47:30 -0800 Subject: [PATCH 04/16] [feature] Push notifications (#3587) * Update push subscription API model to be Mastodon 4.0 compatible * Add webpush-go dependency # Conflicts: # go.sum * Single-row table for storing instance's VAPID key pair * Generate VAPID key pair during startup * Add VAPID public key to instance info API * Return VAPID public key when registering an app * Store Web Push subscriptions in DB * Add Web Push sender (similar to email sender) * Add no-op push senders to most processor tests * Test Web Push notifications from workers * Delete Web Push subscriptions when account is deleted * Implement push subscription API * Linter fixes * Update Swagger * Fix enum to int migration * Fix GetVAPIDKeyPair * Create web push subscriptions table with indexes * Log Web Push server error messages * Send instance URL as Web Push JWT subject * Accept any 2xx code as a success * Fix malformed VAPID sub claim * Use packed notification flags * Remove unused date columns * Add notification type for update notifications Not used yet * Make GetVAPIDKeyPair idempotent and remove PutVAPIDKeyPair * Post-rebase fixes * go mod tidy * Special-case 400 errors other than 408/429 Most client errors should remove the subscription. * Improve titles, trim body to reasonable length * Disallow cleartext HTTP for Web Push servers * Fix lint * Remove redundant index on unique column Also removes redundant unique and notnull tags on ID column since these are implied by pk * Make realsender.go more readable * Use Tobi's style for wrapping errors * Restore treating all 5xx codes as temporary problems * Always load target account settings * Stub `policy` and `standard` * webpush.Sender: take type converter as ctor param * Move webpush.MockSender and noopSender into testrig --- cmd/gotosocial/action/server/server.go | 37 +- cmd/gotosocial/action/testrig/testrig.go | 3 +- docs/api/swagger.yaml | 402 ++ go.mod | 2 + go.sum | 16 + .../api/activitypub/emoji/emojiget_test.go | 8 +- internal/api/activitypub/users/user_test.go | 8 +- internal/api/auth/auth_test.go | 8 +- internal/api/client.go | 4 + internal/api/client/accounts/account_test.go | 8 +- internal/api/client/admin/admin_test.go | 8 +- .../api/client/bookmarks/bookmarks_test.go | 8 +- internal/api/client/exports/exports_test.go | 1 + .../api/client/favourites/favourites_test.go | 8 +- internal/api/client/filters/v1/filter_test.go | 8 +- internal/api/client/filters/v2/filter_test.go | 9 +- .../client/followedtags/followedtags_test.go | 8 +- .../followrequests/followrequest_test.go | 8 +- internal/api/client/import/import_test.go | 1 + internal/api/client/instance/instance_test.go | 8 +- internal/api/client/lists/lists_test.go | 8 +- internal/api/client/media/mediacreate_test.go | 8 +- internal/api/client/media/mediaupdate_test.go | 8 +- internal/api/client/mutes/mutes_test.go | 8 +- .../notifications/notifications_test.go | 8 +- internal/api/client/polls/polls_test.go | 25 +- internal/api/client/push/push.go | 49 + internal/api/client/push/push_test.go | 110 + .../api/client/push/pushsubscriptiondelete.go | 64 + .../push/pushsubscriptiondelete_test.go | 83 + .../api/client/push/pushsubscriptionget.go | 71 + .../client/push/pushsubscriptionget_test.go | 102 + .../api/client/push/pushsubscriptionpost.go | 284 ++ .../client/push/pushsubscriptionpost_test.go | 346 ++ .../api/client/push/pushsubscriptionput.go | 232 ++ .../client/push/pushsubscriptionput_test.go | 176 + internal/api/client/reports/reports_test.go | 8 +- internal/api/client/search/search_test.go | 8 +- internal/api/client/statuses/status_test.go | 8 +- .../api/client/streaming/streaming_test.go | 8 +- internal/api/client/tags/tags_test.go | 8 +- internal/api/client/user/emailchange_test.go | 3 +- internal/api/client/user/user_test.go | 17 +- internal/api/fileserver/fileserver_test.go | 17 +- internal/api/model/instancev2.go | 10 + internal/api/model/pushsubscription.go | 44 - internal/api/model/webpushnotification.go | 52 + internal/api/model/webpushsubscription.go | 157 + .../api/wellknown/webfinger/webfinger_test.go | 8 +- .../wellknown/webfinger/webfingerget_test.go | 1 + internal/cache/cache.go | 2 + internal/cache/db.go | 53 +- internal/cache/invalidate.go | 10 + internal/cache/size.go | 18 +- internal/config/config.go | 2 + internal/config/defaults.go | 2 + internal/config/helpers.gen.go | 58 + internal/db/application.go | 3 + internal/db/bundb/application.go | 10 + internal/db/bundb/bundb.go | 5 + .../20241121121623_enum_strings_to_ints.go | 4 +- .../20241124012635_add_vapid_key_pairs.go | 51 + ...241124012636_add_web_push_subscriptions.go | 61 + internal/db/bundb/notification_test.go | 2 +- internal/db/bundb/webpush.go | 270 ++ internal/db/bundb/webpush_test.go | 81 + internal/db/db.go | 1 + internal/db/webpush.go | 54 + internal/gtsmodel/notification.go | 29 +- internal/gtsmodel/vapidkeypair.go | 28 + internal/gtsmodel/webpushsubscription.go | 82 + internal/processing/account/delete.go | 6 +- internal/processing/admin/admin_test.go | 1 + internal/processing/processor.go | 10 + internal/processing/processor_test.go | 1 + internal/processing/push/create.go | 65 + internal/processing/push/delete.go | 39 + internal/processing/push/get.go | 47 + internal/processing/push/push.go | 85 + internal/processing/push/update.go | 63 + internal/processing/timeline/notification.go | 2 +- .../processing/workers/fromclientapi_test.go | 82 + .../processing/workers/fromfediapi_test.go | 4 +- internal/processing/workers/surface.go | 2 + internal/processing/workers/surfacenotify.go | 9 +- .../processing/workers/surfacenotify_test.go | 1 + internal/processing/workers/workers.go | 3 + internal/text/substring.go | 45 + internal/text/substring_test.go | 47 + internal/transport/transport_test.go | 8 +- internal/typeutils/converter_test.go | 3 +- internal/typeutils/internaltofrontend.go | 45 + internal/typeutils/internaltofrontend_test.go | 13 +- internal/webpush/realsender.go | 341 ++ internal/webpush/realsender_test.go | 263 ++ internal/webpush/sender.go | 54 + internal/workers/workers.go | 11 + test/envparsing.sh | 2 + testrig/db.go | 13 + testrig/processor.go | 3 + testrig/testmodels.go | 34 +- testrig/teststructs.go | 4 + testrig/util.go | 2 + testrig/webpush.go | 65 + .../SherClockHolmes/webpush-go/.gitignore | 4 + .../SherClockHolmes/webpush-go/LICENSE | 21 + .../SherClockHolmes/webpush-go/README.md | 63 + .../SherClockHolmes/webpush-go/urgency.go | 26 + .../SherClockHolmes/webpush-go/vapid.go | 117 + .../SherClockHolmes/webpush-go/webpush.go | 287 ++ vendor/github.com/rivo/uniseg/LICENSE.txt | 21 + vendor/github.com/rivo/uniseg/README.md | 137 + vendor/github.com/rivo/uniseg/doc.go | 108 + .../github.com/rivo/uniseg/eastasianwidth.go | 2588 ++++++++++++ .../rivo/uniseg/emojipresentation.go | 295 ++ .../github.com/rivo/uniseg/gen_breaktest.go | 215 + .../github.com/rivo/uniseg/gen_properties.go | 261 ++ vendor/github.com/rivo/uniseg/grapheme.go | 331 ++ .../rivo/uniseg/graphemeproperties.go | 1915 +++++++++ .../github.com/rivo/uniseg/graphemerules.go | 176 + vendor/github.com/rivo/uniseg/line.go | 134 + .../github.com/rivo/uniseg/lineproperties.go | 3554 +++++++++++++++++ vendor/github.com/rivo/uniseg/linerules.go | 626 +++ vendor/github.com/rivo/uniseg/properties.go | 208 + vendor/github.com/rivo/uniseg/sentence.go | 90 + .../rivo/uniseg/sentenceproperties.go | 2845 +++++++++++++ .../github.com/rivo/uniseg/sentencerules.go | 276 ++ vendor/github.com/rivo/uniseg/step.go | 242 ++ vendor/github.com/rivo/uniseg/width.go | 61 + vendor/github.com/rivo/uniseg/word.go | 89 + .../github.com/rivo/uniseg/wordproperties.go | 1883 +++++++++ vendor/github.com/rivo/uniseg/wordrules.go | 282 ++ vendor/golang.org/x/crypto/hkdf/hkdf.go | 95 + vendor/modules.txt | 7 + 134 files changed, 21525 insertions(+), 125 deletions(-) create mode 100644 internal/api/client/push/push.go create mode 100644 internal/api/client/push/push_test.go create mode 100644 internal/api/client/push/pushsubscriptiondelete.go create mode 100644 internal/api/client/push/pushsubscriptiondelete_test.go create mode 100644 internal/api/client/push/pushsubscriptionget.go create mode 100644 internal/api/client/push/pushsubscriptionget_test.go create mode 100644 internal/api/client/push/pushsubscriptionpost.go create mode 100644 internal/api/client/push/pushsubscriptionpost_test.go create mode 100644 internal/api/client/push/pushsubscriptionput.go create mode 100644 internal/api/client/push/pushsubscriptionput_test.go delete mode 100644 internal/api/model/pushsubscription.go create mode 100644 internal/api/model/webpushnotification.go create mode 100644 internal/api/model/webpushsubscription.go create mode 100644 internal/db/bundb/migrations/20241124012635_add_vapid_key_pairs.go create mode 100644 internal/db/bundb/migrations/20241124012636_add_web_push_subscriptions.go create mode 100644 internal/db/bundb/webpush.go create mode 100644 internal/db/bundb/webpush_test.go create mode 100644 internal/db/webpush.go create mode 100644 internal/gtsmodel/vapidkeypair.go create mode 100644 internal/gtsmodel/webpushsubscription.go create mode 100644 internal/processing/push/create.go create mode 100644 internal/processing/push/delete.go create mode 100644 internal/processing/push/get.go create mode 100644 internal/processing/push/push.go create mode 100644 internal/processing/push/update.go create mode 100644 internal/text/substring.go create mode 100644 internal/text/substring_test.go create mode 100644 internal/webpush/realsender.go create mode 100644 internal/webpush/realsender_test.go create mode 100644 internal/webpush/sender.go create mode 100644 testrig/webpush.go create mode 100644 vendor/github.com/SherClockHolmes/webpush-go/.gitignore create mode 100644 vendor/github.com/SherClockHolmes/webpush-go/LICENSE create mode 100644 vendor/github.com/SherClockHolmes/webpush-go/README.md create mode 100644 vendor/github.com/SherClockHolmes/webpush-go/urgency.go create mode 100644 vendor/github.com/SherClockHolmes/webpush-go/vapid.go create mode 100644 vendor/github.com/SherClockHolmes/webpush-go/webpush.go create mode 100644 vendor/github.com/rivo/uniseg/LICENSE.txt create mode 100644 vendor/github.com/rivo/uniseg/README.md create mode 100644 vendor/github.com/rivo/uniseg/doc.go create mode 100644 vendor/github.com/rivo/uniseg/eastasianwidth.go create mode 100644 vendor/github.com/rivo/uniseg/emojipresentation.go create mode 100644 vendor/github.com/rivo/uniseg/gen_breaktest.go create mode 100644 vendor/github.com/rivo/uniseg/gen_properties.go create mode 100644 vendor/github.com/rivo/uniseg/grapheme.go create mode 100644 vendor/github.com/rivo/uniseg/graphemeproperties.go create mode 100644 vendor/github.com/rivo/uniseg/graphemerules.go create mode 100644 vendor/github.com/rivo/uniseg/line.go create mode 100644 vendor/github.com/rivo/uniseg/lineproperties.go create mode 100644 vendor/github.com/rivo/uniseg/linerules.go create mode 100644 vendor/github.com/rivo/uniseg/properties.go create mode 100644 vendor/github.com/rivo/uniseg/sentence.go create mode 100644 vendor/github.com/rivo/uniseg/sentenceproperties.go create mode 100644 vendor/github.com/rivo/uniseg/sentencerules.go create mode 100644 vendor/github.com/rivo/uniseg/step.go create mode 100644 vendor/github.com/rivo/uniseg/width.go create mode 100644 vendor/github.com/rivo/uniseg/word.go create mode 100644 vendor/github.com/rivo/uniseg/wordproperties.go create mode 100644 vendor/github.com/rivo/uniseg/wordrules.go create mode 100644 vendor/golang.org/x/crypto/hkdf/hkdf.go diff --git a/cmd/gotosocial/action/server/server.go b/cmd/gotosocial/action/server/server.go index efedda9ec..7a374fbcd 100644 --- a/cmd/gotosocial/action/server/server.go +++ b/cmd/gotosocial/action/server/server.go @@ -36,37 +36,37 @@ "github.com/superseriousbusiness/gotosocial/internal/api" apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" "github.com/superseriousbusiness/gotosocial/internal/cleaner" - "github.com/superseriousbusiness/gotosocial/internal/filter/interaction" - "github.com/superseriousbusiness/gotosocial/internal/filter/spam" - "github.com/superseriousbusiness/gotosocial/internal/filter/visibility" - "github.com/superseriousbusiness/gotosocial/internal/gtserror" - "github.com/superseriousbusiness/gotosocial/internal/media/ffmpeg" - "github.com/superseriousbusiness/gotosocial/internal/messages" - "github.com/superseriousbusiness/gotosocial/internal/metrics" - "github.com/superseriousbusiness/gotosocial/internal/middleware" - tlprocessor "github.com/superseriousbusiness/gotosocial/internal/processing/timeline" - "github.com/superseriousbusiness/gotosocial/internal/subscriptions" - "github.com/superseriousbusiness/gotosocial/internal/timeline" - "github.com/superseriousbusiness/gotosocial/internal/tracing" - "go.uber.org/automaxprocs/maxprocs" - "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db/bundb" "github.com/superseriousbusiness/gotosocial/internal/email" "github.com/superseriousbusiness/gotosocial/internal/federation" "github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb" + "github.com/superseriousbusiness/gotosocial/internal/filter/interaction" + "github.com/superseriousbusiness/gotosocial/internal/filter/spam" + "github.com/superseriousbusiness/gotosocial/internal/filter/visibility" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/httpclient" "github.com/superseriousbusiness/gotosocial/internal/log" "github.com/superseriousbusiness/gotosocial/internal/media" + "github.com/superseriousbusiness/gotosocial/internal/media/ffmpeg" + "github.com/superseriousbusiness/gotosocial/internal/messages" + "github.com/superseriousbusiness/gotosocial/internal/metrics" + "github.com/superseriousbusiness/gotosocial/internal/middleware" "github.com/superseriousbusiness/gotosocial/internal/oauth" "github.com/superseriousbusiness/gotosocial/internal/oidc" "github.com/superseriousbusiness/gotosocial/internal/processing" + tlprocessor "github.com/superseriousbusiness/gotosocial/internal/processing/timeline" "github.com/superseriousbusiness/gotosocial/internal/router" "github.com/superseriousbusiness/gotosocial/internal/state" gtsstorage "github.com/superseriousbusiness/gotosocial/internal/storage" + "github.com/superseriousbusiness/gotosocial/internal/subscriptions" + "github.com/superseriousbusiness/gotosocial/internal/timeline" + "github.com/superseriousbusiness/gotosocial/internal/tracing" "github.com/superseriousbusiness/gotosocial/internal/transport" "github.com/superseriousbusiness/gotosocial/internal/typeutils" "github.com/superseriousbusiness/gotosocial/internal/web" + "github.com/superseriousbusiness/gotosocial/internal/webpush" + "go.uber.org/automaxprocs/maxprocs" ) // Start creates and starts a gotosocial server @@ -248,6 +248,14 @@ } } + // Get or create a VAPID key pair. + if _, err := dbService.GetVAPIDKeyPair(ctx); err != nil { + return gtserror.Newf("error getting or creating VAPID key pair: %w", err) + } + + // Create a Web Push notification sender. + webPushSender := webpush.NewSender(client, state, typeConverter) + // Initialize both home / list timelines. state.Timelines.Home = timeline.NewManager( tlprocessor.HomeTimelineGrab(state), @@ -307,6 +315,7 @@ func(context.Context, time.Time) { mediaManager, state, emailSender, + webPushSender, visFilter, intFilter, ) diff --git a/cmd/gotosocial/action/testrig/testrig.go b/cmd/gotosocial/action/testrig/testrig.go index 0036b7a7d..d91758767 100644 --- a/cmd/gotosocial/action/testrig/testrig.go +++ b/cmd/gotosocial/action/testrig/testrig.go @@ -164,6 +164,7 @@ federator := testrig.NewTestFederator(state, transportController, mediaManager) emailSender := testrig.NewEmailSender("./web/template/", nil) + webPushSender := testrig.NewWebPushMockSender() typeConverter := typeutils.NewConverter(state) filter := visibility.NewFilter(state) @@ -187,7 +188,7 @@ return fmt.Errorf("error starting list timeline: %s", err) } - processor := testrig.NewTestProcessor(state, federator, emailSender, mediaManager) + processor := testrig.NewTestProcessor(state, federator, emailSender, webPushSender, mediaManager) // Initialize workers. testrig.StartWorkers(state, processor.Workers()) diff --git a/docs/api/swagger.yaml b/docs/api/swagger.yaml index 322b79b16..5165f8c9e 100644 --- a/docs/api/swagger.yaml +++ b/docs/api/swagger.yaml @@ -186,6 +186,10 @@ definitions: title: TimelineMarker contains information about a user's progress through a specific timeline. type: object x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model + WebPushNotificationPolicy: + title: WebPushNotificationPolicy names sets of accounts that can generate notifications. + type: string + x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model account: description: The modelled account can be either a remote account, or one on this instance. properties: @@ -1946,6 +1950,8 @@ definitions: $ref: '#/definitions/instanceV2ConfigurationTranslation' urls: $ref: '#/definitions/instanceV2URLs' + vapid: + $ref: '#/definitions/instanceV2ConfigurationVAPID' title: Configured values and limits for this instance. type: object x-go-name: InstanceV2Configuration @@ -1962,6 +1968,16 @@ definitions: type: object x-go-name: InstanceV2ConfigurationTranslation x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model + instanceV2ConfigurationVAPID: + properties: + public_key: + description: The instance's VAPID public key, Base64-encoded. + type: string + x-go-name: PublicKey + title: InstanceV2ConfigurationVAPID holds the instance's VAPID configuration. + type: object + x-go-name: InstanceV2ConfigurationVAPID + x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model instanceV2Contact: properties: account: @@ -3381,6 +3397,139 @@ definitions: type: object x-go-name: User x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model + webPushNotification: + description: |- + It does not contain an entire Notification, just the NotificationID and some preview information. + It is not used in the client API directly, but is included in the API doc for decoding Web Push notifications. + properties: + access_token: + description: |- + AccessToken is the access token associated with the Web Push subscription. + I don't know why this is sent, given that the client should know that already, + but Feditext does use it. + type: string + x-go-name: AccessToken + body: + description: |- + Body is a preview of the notification body, + such as the first line of a status's CW or text, + or the first line of an account bio. + type: string + x-go-name: Body + icon: + description: |- + Icon is an image URL that can be displayed with the notification, + normally the account's avatar. + type: string + x-go-name: Icon + notification_id: + description: NotificationID is the Notification.ID of the referenced Notification. + type: string + x-go-name: NotificationID + notification_type: + description: NotificationType is the Notification.Type of the referenced Notification. + type: string + x-go-name: NotificationType + preferred_locale: + description: PreferredLocale is a BCP 47 language tag for the receiving user's locale. + type: string + x-go-name: PreferredLocale + title: + description: |- + Title is a title for the notification, + generally describing an action taken by a user. + type: string + x-go-name: Title + title: WebPushNotification represents a notification summary delivered to the client by the Web Push server. + type: object + x-go-name: WebPushNotification + x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model + webPushSubscription: + properties: + alerts: + $ref: '#/definitions/webPushSubscriptionAlerts' + endpoint: + description: Where push alerts will be sent to. + type: string + x-go-name: Endpoint + id: + description: The id of the push subscription in the database. + type: string + x-go-name: ID + policy: + $ref: '#/definitions/WebPushNotificationPolicy' + server_key: + description: The streaming server's VAPID public key. + type: string + x-go-name: ServerKey + standard: + description: |- + Whether the subscription uses RFC or pre-RFC Web Push standards. + For GotoSocial, this is always true. + type: boolean + x-go-name: Standard + title: WebPushSubscription represents a subscription to a Web Push server. + type: object + x-go-name: WebPushSubscription + x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model + webPushSubscriptionAlerts: + properties: + admin.report: + description: Receive a push notification when a new report has been filed? + type: boolean + x-go-name: AdminReport + admin.sign_up: + description: Receive a push notification when a new user has signed up? + type: boolean + x-go-name: AdminSignup + favourite: + description: Receive a push notification when a status you created has been favourited by someone else? + type: boolean + x-go-name: Favourite + follow: + description: Receive a push notification when someone has followed you? + type: boolean + x-go-name: Follow + follow_request: + description: Receive a push notification when someone has requested to follow you? + type: boolean + x-go-name: FollowRequest + mention: + description: Receive a push notification when someone else has mentioned you in a status? + type: boolean + x-go-name: Mention + pending.favourite: + description: Receive a push notification when a fave is pending? + type: boolean + x-go-name: PendingFavourite + pending.reblog: + description: Receive a push notification when a boost is pending? + type: boolean + x-go-name: PendingReblog + pending.reply: + description: Receive a push notification when a reply is pending? + type: boolean + x-go-name: PendingReply + poll: + description: Receive a push notification when a poll you voted in or created has ended? + type: boolean + x-go-name: Poll + reblog: + description: Receive a push notification when a status you created has been boosted by someone else? + type: boolean + x-go-name: Reblog + status: + description: Receive a push notification when a subscribed account posts a status? + type: boolean + x-go-name: Status + update: + description: Receive a push notification when a status you interacted with has been edited? + type: boolean + x-go-name: Update + title: WebPushSubscriptionAlerts represents the specific events that this Web Push subscription will receive. + type: object + x-go-name: WebPushSubscriptionAlerts + x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model wellKnownResponse: description: See https://webfinger.net/ properties: @@ -9642,6 +9791,259 @@ paths: summary: Delete the authenticated account's header. tags: - accounts + /api/v1/push/subscription: + delete: + description: If there is no subscription, returns successfully anyway. + operationId: pushSubscriptionDelete + responses: + "200": + description: Push subscription deleted, or did not exist. + "400": + description: bad request + "401": + description: unauthorized + "500": + description: internal server error + security: + - OAuth2 Bearer: + - push + summary: Delete the Web Push subscription associated with the current auth token. + tags: + - push + get: + operationId: pushSubscriptionGet + produces: + - application/json + responses: + "200": + description: Web Push subscription for current access token. + schema: + $ref: '#/definitions/webPushSubscription' + "400": + description: bad request + "401": + description: unauthorized + "404": + description: This access token doesn't have an associated subscription. + "500": + description: internal server error + security: + - OAuth2 Bearer: + - push + summary: Get the push subscription for the current access token. + tags: + - push + post: + consumes: + - application/json + - application/x-www-form-urlencoded + operationId: pushSubscriptionPost + parameters: + - description: The URL to which Web Push notifications will be sent. + in: formData + minLength: 1 + name: subscription[endpoint] + required: true + type: string + - description: The auth secret, a Base64 encoded string of 16 bytes of random data. + in: formData + minLength: 1 + name: subscription[keys][auth] + required: true + type: string + - description: The user agent public key, a Base64 encoded string of a public key from an ECDH keypair using the prime256v1 curve. + in: formData + minLength: 1 + name: subscription[keys][p256dh] + required: true + type: string + - default: false + description: Receive a push notification when someone has followed you? + in: formData + name: data[alerts][follow] + type: boolean + - default: false + description: Receive a push notification when someone has requested to follow you? + in: formData + name: data[alerts][follow_request] + type: boolean + - default: false + description: Receive a push notification when a status you created has been favourited by someone else? + in: formData + name: data[alerts][favourite] + type: boolean + - default: false + description: Receive a push notification when someone else has mentioned you in a status? + in: formData + name: data[alerts][mention] + type: boolean + - default: false + description: Receive a push notification when a status you created has been boosted by someone else? + in: formData + name: data[alerts][reblog] + type: boolean + - default: false + description: Receive a push notification when a poll you voted in or created has ended? + in: formData + name: data[alerts][poll] + type: boolean + - default: false + description: Receive a push notification when a subscribed account posts a status? + in: formData + name: data[alerts][status] + type: boolean + - default: false + description: Receive a push notification when a status you interacted with has been edited? + in: formData + name: data[alerts][update] + type: boolean + - default: false + description: Receive a push notification when a new user has signed up? + in: formData + name: data[alerts][admin.sign_up] + type: boolean + - default: false + description: Receive a push notification when a new report has been filed? + in: formData + name: data[alerts][admin.report] + type: boolean + - default: false + description: Receive a push notification when a fave is pending? + in: formData + name: data[alerts][pending.favourite] + type: boolean + - default: false + description: Receive a push notification when a reply is pending? + in: formData + name: data[alerts][pending.reply] + type: boolean + - default: false + description: Receive a push notification when a boost is pending? + in: formData + name: data[alerts][pending.reblog] + type: boolean + produces: + - application/json + responses: + "200": + description: Web Push subscription for current access token. + schema: + $ref: '#/definitions/webPushSubscription' + "400": + description: bad request + "401": + description: unauthorized + "403": + description: forbidden + "404": + description: not found + "406": + description: not acceptable + "500": + description: internal server error + security: + - OAuth2 Bearer: + - push + summary: Create a new Web Push subscription for the current access token, or replace the existing one. + tags: + - push + put: + consumes: + - application/json + - application/x-www-form-urlencoded + description: Only which notifications you receive can be updated. + operationId: pushSubscriptionPut + parameters: + - default: false + description: Receive a push notification when someone has followed you? + in: formData + name: data[alerts][follow] + type: boolean + - default: false + description: Receive a push notification when someone has requested to follow you? + in: formData + name: data[alerts][follow_request] + type: boolean + - default: false + description: Receive a push notification when a status you created has been favourited by someone else? + in: formData + name: data[alerts][favourite] + type: boolean + - default: false + description: Receive a push notification when someone else has mentioned you in a status? + in: formData + name: data[alerts][mention] + type: boolean + - default: false + description: Receive a push notification when a status you created has been boosted by someone else? + in: formData + name: data[alerts][reblog] + type: boolean + - default: false + description: Receive a push notification when a poll you voted in or created has ended? + in: formData + name: data[alerts][poll] + type: boolean + - default: false + description: Receive a push notification when a subscribed account posts a status? + in: formData + name: data[alerts][status] + type: boolean + - default: false + description: Receive a push notification when a status you interacted with has been edited? + in: formData + name: data[alerts][update] + type: boolean + - default: false + description: Receive a push notification when a new user has signed up? + in: formData + name: data[alerts][admin.sign_up] + type: boolean + - default: false + description: Receive a push notification when a new report has been filed? + in: formData + name: data[alerts][admin.report] + type: boolean + - default: false + description: Receive a push notification when a fave is pending? + in: formData + name: data[alerts][pending.favourite] + type: boolean + - default: false + description: Receive a push notification when a reply is pending? + in: formData + name: data[alerts][pending.reply] + type: boolean + - default: false + description: Receive a push notification when a boost is pending? + in: formData + name: data[alerts][pending.reblog] + type: boolean + produces: + - application/json + responses: + "200": + description: Web Push subscription for current access token. + schema: + $ref: '#/definitions/webPushSubscription' + "400": + description: bad request + "401": + description: unauthorized + "403": + description: forbidden + "404": + description: This access token doesn't have an associated subscription. + "406": + description: not acceptable + "500": + description: internal server error + security: + - OAuth2 Bearer: + - push + summary: Update the Web Push subscription for the current access token. + tags: + - push /api/v1/reports: get: description: |- diff --git a/go.mod b/go.mod index 4f4d7ad09..d9bf90289 100644 --- a/go.mod +++ b/go.mod @@ -44,6 +44,7 @@ require ( codeberg.org/superseriousbusiness/exif-terminator v0.9.1 github.com/DmitriyVTitov/size v1.5.0 github.com/KimMachineGun/automemlimit v0.6.1 + github.com/SherClockHolmes/webpush-go v1.3.0 github.com/buckket/go-blurhash v1.1.0 github.com/coreos/go-oidc/v3 v3.12.0 github.com/gin-contrib/cors v1.7.3 @@ -65,6 +66,7 @@ require ( github.com/ncruces/go-sqlite3 v0.22.0 github.com/oklog/ulid v1.3.1 github.com/prometheus/client_golang v1.20.5 + github.com/rivo/uniseg v0.4.7 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.10.0 diff --git a/go.sum b/go.sum index 73f00377e..a4b0e6cfa 100644 --- a/go.sum +++ b/go.sum @@ -88,6 +88,8 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/SherClockHolmes/webpush-go v1.3.0 h1:CAu3FvEE9QS4drc3iKNgpBWFfGqNthKlZhp5QpYnu6k= +github.com/SherClockHolmes/webpush-go v1.3.0/go.mod h1:AxRHmJuYwKGG1PVgYzToik1lphQvDnqFYDqimHvwhIw= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= @@ -474,6 +476,8 @@ github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b h1:aUNXCGgukb4gtY github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b/go.mod h1:wTPjTepVu7uJBYgZ0SdWHQlIas582j6cn2jgk4DDdlg= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM= @@ -666,6 +670,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -703,6 +708,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -737,6 +743,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -756,6 +764,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -796,12 +805,16 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -811,6 +824,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -858,6 +873,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/api/activitypub/emoji/emojiget_test.go b/internal/api/activitypub/emoji/emojiget_test.go index 0eb1f5931..7d3587fd8 100644 --- a/internal/api/activitypub/emoji/emojiget_test.go +++ b/internal/api/activitypub/emoji/emojiget_test.go @@ -88,7 +88,13 @@ func (suite *EmojiGetTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.emojiModule = emoji.New(suite.processor) testrig.StandardDBSetup(suite.db, suite.testAccounts) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/activitypub/users/user_test.go b/internal/api/activitypub/users/user_test.go index 10eb33937..d66fe8cf9 100644 --- a/internal/api/activitypub/users/user_test.go +++ b/internal/api/activitypub/users/user_test.go @@ -100,7 +100,13 @@ func (suite *UserStandardTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) testrig.StartWorkers(&suite.state, suite.processor.Workers()) suite.userModule = users.New(suite.processor) diff --git a/internal/api/auth/auth_test.go b/internal/api/auth/auth_test.go index c5ceba387..cfbdec7ec 100644 --- a/internal/api/auth/auth_test.go +++ b/internal/api/auth/auth_test.go @@ -91,7 +91,13 @@ func (suite *AuthStandardTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.authModule = auth.New(suite.db, suite.processor, suite.idp) testrig.StandardDBSetup(suite.db, suite.testAccounts) diff --git a/internal/api/client.go b/internal/api/client.go index 60daddf87..3112aeea5 100644 --- a/internal/api/client.go +++ b/internal/api/client.go @@ -47,6 +47,7 @@ "github.com/superseriousbusiness/gotosocial/internal/api/client/notifications" "github.com/superseriousbusiness/gotosocial/internal/api/client/polls" "github.com/superseriousbusiness/gotosocial/internal/api/client/preferences" + "github.com/superseriousbusiness/gotosocial/internal/api/client/push" "github.com/superseriousbusiness/gotosocial/internal/api/client/reports" "github.com/superseriousbusiness/gotosocial/internal/api/client/search" "github.com/superseriousbusiness/gotosocial/internal/api/client/statuses" @@ -91,6 +92,7 @@ type Client struct { notifications *notifications.Module // api/v1/notifications polls *polls.Module // api/v1/polls preferences *preferences.Module // api/v1/preferences + push *push.Module // api/v1/push reports *reports.Module // api/v1/reports search *search.Module // api/v1/search, api/v2/search statuses *statuses.Module // api/v1/statuses @@ -143,6 +145,7 @@ func (c *Client) Route(r *router.Router, m ...gin.HandlerFunc) { c.notifications.Route(h) c.polls.Route(h) c.preferences.Route(h) + c.push.Route(h) c.reports.Route(h) c.search.Route(h) c.statuses.Route(h) @@ -183,6 +186,7 @@ func NewClient(state *state.State, p *processing.Processor) *Client { notifications: notifications.New(p), polls: polls.New(p), preferences: preferences.New(p), + push: push.New(p), reports: reports.New(p), search: search.New(p), statuses: statuses.New(p), diff --git a/internal/api/client/accounts/account_test.go b/internal/api/client/accounts/account_test.go index db212af22..e700ade78 100644 --- a/internal/api/client/accounts/account_test.go +++ b/internal/api/client/accounts/account_test.go @@ -100,7 +100,13 @@ func (suite *AccountStandardTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.accountsModule = accounts.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/client/admin/admin_test.go b/internal/api/client/admin/admin_test.go index 479f16f45..f44d48d78 100644 --- a/internal/api/client/admin/admin_test.go +++ b/internal/api/client/admin/admin_test.go @@ -106,7 +106,13 @@ func (suite *AdminStandardTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.adminModule = admin.New(&suite.state, suite.processor) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/client/bookmarks/bookmarks_test.go b/internal/api/client/bookmarks/bookmarks_test.go index 43c1eeee4..a11597f7c 100644 --- a/internal/api/client/bookmarks/bookmarks_test.go +++ b/internal/api/client/bookmarks/bookmarks_test.go @@ -114,7 +114,13 @@ func (suite *BookmarkTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.statusModule = statuses.New(suite.processor) suite.bookmarkModule = bookmarks.New(suite.processor) } diff --git a/internal/api/client/exports/exports_test.go b/internal/api/client/exports/exports_test.go index 13f7bea05..55d873348 100644 --- a/internal/api/client/exports/exports_test.go +++ b/internal/api/client/exports/exports_test.go @@ -95,6 +95,7 @@ func (suite *ExportsTestSuite) SetupTest() { &suite.state, federator, testrig.NewEmailSender("../../../../web/template/", nil), + testrig.NewNoopWebPushSender(), mediaManager, ) diff --git a/internal/api/client/favourites/favourites_test.go b/internal/api/client/favourites/favourites_test.go index dcdc8fee2..7cfa205e3 100644 --- a/internal/api/client/favourites/favourites_test.go +++ b/internal/api/client/favourites/favourites_test.go @@ -98,7 +98,13 @@ func (suite *FavouritesStandardTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.favModule = favourites.New(suite.processor) } diff --git a/internal/api/client/filters/v1/filter_test.go b/internal/api/client/filters/v1/filter_test.go index 128426435..558f3d959 100644 --- a/internal/api/client/filters/v1/filter_test.go +++ b/internal/api/client/filters/v1/filter_test.go @@ -105,7 +105,13 @@ func (suite *FiltersTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.filtersModule = filtersV1.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) diff --git a/internal/api/client/filters/v2/filter_test.go b/internal/api/client/filters/v2/filter_test.go index 20411c090..8301c67ad 100644 --- a/internal/api/client/filters/v2/filter_test.go +++ b/internal/api/client/filters/v2/filter_test.go @@ -103,9 +103,14 @@ func (suite *FiltersTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../../testrig/media")), suite.mediaManager) - suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.filtersModule = filtersV2.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) diff --git a/internal/api/client/followedtags/followedtags_test.go b/internal/api/client/followedtags/followedtags_test.go index 89a61aca1..816e1d0cc 100644 --- a/internal/api/client/followedtags/followedtags_test.go +++ b/internal/api/client/followedtags/followedtags_test.go @@ -88,7 +88,13 @@ func (suite *FollowedTagsTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.followedTagsModule = followedtags.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) diff --git a/internal/api/client/followrequests/followrequest_test.go b/internal/api/client/followrequests/followrequest_test.go index 1faac2bbc..787d47c84 100644 --- a/internal/api/client/followrequests/followrequest_test.go +++ b/internal/api/client/followrequests/followrequest_test.go @@ -96,7 +96,13 @@ func (suite *FollowRequestStandardTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.followRequestModule = followrequests.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/client/import/import_test.go b/internal/api/client/import/import_test.go index 5129f862e..fba83e1a3 100644 --- a/internal/api/client/import/import_test.go +++ b/internal/api/client/import/import_test.go @@ -92,6 +92,7 @@ func (suite *ImportTestSuite) SetupTest() { &suite.state, federator, testrig.NewEmailSender("../../../../web/template/", nil), + testrig.NewNoopWebPushSender(), mediaManager, ) testrig.StartWorkers(&suite.state, processor.Workers()) diff --git a/internal/api/client/instance/instance_test.go b/internal/api/client/instance/instance_test.go index 293c96020..f0427369b 100644 --- a/internal/api/client/instance/instance_test.go +++ b/internal/api/client/instance/instance_test.go @@ -99,7 +99,13 @@ func (suite *InstanceStandardTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.instanceModule = instance.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/client/lists/lists_test.go b/internal/api/client/lists/lists_test.go index ea5adbb5c..5fd2304c7 100644 --- a/internal/api/client/lists/lists_test.go +++ b/internal/api/client/lists/lists_test.go @@ -99,7 +99,13 @@ func (suite *ListsStandardTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.listsModule = lists.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) diff --git a/internal/api/client/media/mediacreate_test.go b/internal/api/client/media/mediacreate_test.go index 2eec8341f..d26f2bb7a 100644 --- a/internal/api/client/media/mediacreate_test.go +++ b/internal/api/client/media/mediacreate_test.go @@ -104,7 +104,13 @@ func (suite *MediaCreateTestSuite) SetupTest() { suite.oauthServer = testrig.NewTestOauthServer(suite.db) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) // setup module being tested suite.mediaModule = mediamodule.New(suite.processor) diff --git a/internal/api/client/media/mediaupdate_test.go b/internal/api/client/media/mediaupdate_test.go index c3a1fb340..dd115f465 100644 --- a/internal/api/client/media/mediaupdate_test.go +++ b/internal/api/client/media/mediaupdate_test.go @@ -102,7 +102,13 @@ func (suite *MediaUpdateTestSuite) SetupTest() { suite.oauthServer = testrig.NewTestOauthServer(suite.db) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) // setup module being tested suite.mediaModule = mediamodule.New(suite.processor) diff --git a/internal/api/client/mutes/mutes_test.go b/internal/api/client/mutes/mutes_test.go index b721b080f..3f5686cfb 100644 --- a/internal/api/client/mutes/mutes_test.go +++ b/internal/api/client/mutes/mutes_test.go @@ -96,7 +96,13 @@ func (suite *MutesTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.mutesModule = mutes.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/client/notifications/notifications_test.go b/internal/api/client/notifications/notifications_test.go index 39fb66691..5794c0e12 100644 --- a/internal/api/client/notifications/notifications_test.go +++ b/internal/api/client/notifications/notifications_test.go @@ -100,7 +100,13 @@ func (suite *NotificationsTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.notificationsModule = notifications.New(suite.processor) } diff --git a/internal/api/client/polls/polls_test.go b/internal/api/client/polls/polls_test.go index b5552f39e..8c2bc8ba1 100644 --- a/internal/api/client/polls/polls_test.go +++ b/internal/api/client/polls/polls_test.go @@ -36,14 +36,15 @@ type PollsStandardTestSuite struct { suite.Suite - db db.DB - storage *storage.Driver - mediaManager *media.Manager - federator *federation.Federator - processor *processing.Processor - emailSender email.Sender - sentEmails map[string]string - state state.State + db db.DB + storage *storage.Driver + mediaManager *media.Manager + federator *federation.Federator + processor *processing.Processor + emailSender email.Sender + sentEmails map[string]string + webPushSender *testrig.WebPushMockSender + state state.State // standard suite models testTokens map[string]*gtsmodel.Token @@ -91,7 +92,13 @@ func (suite *PollsStandardTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.pollsModule = polls.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/client/push/push.go b/internal/api/client/push/push.go new file mode 100644 index 000000000..33b974efa --- /dev/null +++ b/internal/api/client/push/push.go @@ -0,0 +1,49 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/superseriousbusiness/gotosocial/internal/processing" +) + +const ( + // BasePath is the base path for serving the push API, minus the 'api' prefix. + BasePath = "/v1/push" + // SubscriptionPath is the path for serving requests for the current auth token's push subscription. + SubscriptionPath = BasePath + "/subscription" +) + +type Module struct { + processor *processing.Processor +} + +func New(processor *processing.Processor) *Module { + return &Module{ + processor: processor, + } +} + +func (m *Module) Route(attachHandler func(method string, path string, f ...gin.HandlerFunc) gin.IRoutes) { + attachHandler(http.MethodGet, SubscriptionPath, m.PushSubscriptionGETHandler) + attachHandler(http.MethodPost, SubscriptionPath, m.PushSubscriptionPOSTHandler) + attachHandler(http.MethodPut, SubscriptionPath, m.PushSubscriptionPUTHandler) + attachHandler(http.MethodDelete, SubscriptionPath, m.PushSubscriptionDELETEHandler) +} diff --git a/internal/api/client/push/push_test.go b/internal/api/client/push/push_test.go new file mode 100644 index 000000000..0d85192ff --- /dev/null +++ b/internal/api/client/push/push_test.go @@ -0,0 +1,110 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + "github.com/superseriousbusiness/gotosocial/internal/api/client/push" + "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/email" + "github.com/superseriousbusiness/gotosocial/internal/federation" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/media" + "github.com/superseriousbusiness/gotosocial/internal/processing" + "github.com/superseriousbusiness/gotosocial/internal/state" + "github.com/superseriousbusiness/gotosocial/internal/storage" + "github.com/superseriousbusiness/gotosocial/testrig" +) + +type PushTestSuite struct { + suite.Suite + db db.DB + storage *storage.Driver + mediaManager *media.Manager + federator *federation.Federator + processor *processing.Processor + emailSender email.Sender + sentEmails map[string]string + state state.State + + // standard suite models + testTokens map[string]*gtsmodel.Token + testClients map[string]*gtsmodel.Client + testApplications map[string]*gtsmodel.Application + testUsers map[string]*gtsmodel.User + testAccounts map[string]*gtsmodel.Account + testWebPushSubscriptions map[string]*gtsmodel.WebPushSubscription + + // module being tested + pushModule *push.Module +} + +func (suite *PushTestSuite) SetupSuite() { + suite.testTokens = testrig.NewTestTokens() + suite.testClients = testrig.NewTestClients() + suite.testApplications = testrig.NewTestApplications() + suite.testUsers = testrig.NewTestUsers() + suite.testAccounts = testrig.NewTestAccounts() + suite.testWebPushSubscriptions = testrig.NewTestWebPushSubscriptions() +} + +func (suite *PushTestSuite) SetupTest() { + suite.state.Caches.Init() + testrig.StartNoopWorkers(&suite.state) + + testrig.InitTestConfig() + config.Config(func(cfg *config.Configuration) { + cfg.WebAssetBaseDir = "../../../../web/assets/" + cfg.WebTemplateBaseDir = "../../../../web/templates/" + }) + testrig.InitTestLog() + + suite.db = testrig.NewTestDB(&suite.state) + suite.state.DB = suite.db + suite.storage = testrig.NewInMemoryStorage() + suite.state.Storage = suite.storage + + suite.mediaManager = testrig.NewTestMediaManager(&suite.state) + suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) + suite.sentEmails = make(map[string]string) + suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) + suite.pushModule = push.New(suite.processor) + + testrig.StandardDBSetup(suite.db, nil) + testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") +} + +func (suite *PushTestSuite) TearDownTest() { + testrig.StandardDBTeardown(suite.db) + testrig.StandardStorageTeardown(suite.storage) + testrig.StopWorkers(&suite.state) +} + +func TestPushTestSuite(t *testing.T) { + suite.Run(t, new(PushTestSuite)) +} diff --git a/internal/api/client/push/pushsubscriptiondelete.go b/internal/api/client/push/pushsubscriptiondelete.go new file mode 100644 index 000000000..2a5fd8e69 --- /dev/null +++ b/internal/api/client/push/pushsubscriptiondelete.go @@ -0,0 +1,64 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push + +import ( + "net/http" + + "github.com/gin-gonic/gin" + apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/oauth" +) + +// PushSubscriptionDELETEHandler swagger:operation DELETE /api/v1/push/subscription pushSubscriptionDelete +// +// Delete the Web Push subscription associated with the current auth token. +// If there is no subscription, returns successfully anyway. +// +// --- +// tags: +// - push +// +// security: +// - OAuth2 Bearer: +// - push +// +// responses: +// '200': +// description: Push subscription deleted, or did not exist. +// '400': +// description: bad request +// '401': +// description: unauthorized +// '500': +// description: internal server error +func (m *Module) PushSubscriptionDELETEHandler(c *gin.Context) { + authed, err := oauth.Authed(c, true, true, true, true) + if err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1) + return + } + + if errWithCode := m.processor.Push().Delete(c.Request.Context(), authed.Token.GetAccess()); errWithCode != nil { + apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) + return + } + + apiutil.Data(c, http.StatusOK, apiutil.AppJSON, apiutil.EmptyJSONObject) +} diff --git a/internal/api/client/push/pushsubscriptiondelete_test.go b/internal/api/client/push/pushsubscriptiondelete_test.go new file mode 100644 index 000000000..3e81ce2a1 --- /dev/null +++ b/internal/api/client/push/pushsubscriptiondelete_test.go @@ -0,0 +1,83 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push_test + +import ( + "fmt" + "net/http" + "net/http/httptest" + + "github.com/superseriousbusiness/gotosocial/internal/api/client/push" + "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/oauth" + "github.com/superseriousbusiness/gotosocial/testrig" +) + +// deleteSubscription deletes the push subscription for the named account and token. +func (suite *PushTestSuite) deleteSubscription( + accountFixtureName string, + tokenFixtureName string, + expectedHTTPStatus int, +) error { + // instantiate recorder + test context + recorder := httptest.NewRecorder() + ctx, _ := testrig.CreateGinTestContext(recorder, nil) + ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts[accountFixtureName]) + ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(suite.testTokens[tokenFixtureName])) + ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) + ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers[accountFixtureName]) + + // create the request + requestUrl := config.GetProtocol() + "://" + config.GetHost() + "/api" + push.SubscriptionPath + ctx.Request = httptest.NewRequest(http.MethodDelete, requestUrl, nil) + + // trigger the handler + suite.pushModule.PushSubscriptionDELETEHandler(ctx) + + // read the response + result := recorder.Result() + defer func() { + _ = result.Body.Close() + }() + + if resultCode := recorder.Code; expectedHTTPStatus != resultCode { + return fmt.Errorf("expected %d got %d", expectedHTTPStatus, resultCode) + } + + return nil +} + +// Delete a subscription that should exist. +func (suite *PushTestSuite) TestDeleteSubscription() { + accountFixtureName := "local_account_1" + // This token should have a subscription associated with it already. + tokenFixtureName := "local_account_1" + + err := suite.deleteSubscription(accountFixtureName, tokenFixtureName, 200) + suite.NoError(err) +} + +// Delete a subscription that should not exist, which should succeed anyway. +func (suite *PushTestSuite) TestDeleteMissingSubscription() { + accountFixtureName := "local_account_1" + // This token should not have a subscription. + tokenFixtureName := "local_account_1_user_authorization_token" + + err := suite.deleteSubscription(accountFixtureName, tokenFixtureName, 200) + suite.NoError(err) +} diff --git a/internal/api/client/push/pushsubscriptionget.go b/internal/api/client/push/pushsubscriptionget.go new file mode 100644 index 000000000..10774b862 --- /dev/null +++ b/internal/api/client/push/pushsubscriptionget.go @@ -0,0 +1,71 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push + +import ( + "net/http" + + "github.com/gin-gonic/gin" + apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/oauth" +) + +// PushSubscriptionGETHandler swagger:operation GET /api/v1/push/subscription pushSubscriptionGet +// +// Get the push subscription for the current access token. +// +// --- +// tags: +// - push +// +// produces: +// - application/json +// +// security: +// - OAuth2 Bearer: +// - push +// +// responses: +// '200': +// description: Web Push subscription for current access token. +// schema: +// "$ref": "#/definitions/webPushSubscription" +// '400': +// description: bad request +// '401': +// description: unauthorized +// '404': +// description: This access token doesn't have an associated subscription. +// '500': +// description: internal server error +func (m *Module) PushSubscriptionGETHandler(c *gin.Context) { + authed, err := oauth.Authed(c, true, true, true, true) + if err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1) + return + } + + apiSubscription, errWithCode := m.processor.Push().Get(c, authed.Token.GetAccess()) + if errWithCode != nil { + apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) + return + } + + apiutil.JSON(c, http.StatusOK, apiSubscription) +} diff --git a/internal/api/client/push/pushsubscriptionget_test.go b/internal/api/client/push/pushsubscriptionget_test.go new file mode 100644 index 000000000..23fb9e7f2 --- /dev/null +++ b/internal/api/client/push/pushsubscriptionget_test.go @@ -0,0 +1,102 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push_test + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + + "github.com/superseriousbusiness/gotosocial/internal/api/client/push" + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/oauth" + "github.com/superseriousbusiness/gotosocial/testrig" +) + +// getSubscription gets the push subscription for the named account and token. +func (suite *PushTestSuite) getSubscription( + accountFixtureName string, + tokenFixtureName string, + expectedHTTPStatus int, +) (*apimodel.WebPushSubscription, error) { + // instantiate recorder + test context + recorder := httptest.NewRecorder() + ctx, _ := testrig.CreateGinTestContext(recorder, nil) + ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts[accountFixtureName]) + ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(suite.testTokens[tokenFixtureName])) + ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) + ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers[accountFixtureName]) + + // create the request + requestUrl := config.GetProtocol() + "://" + config.GetHost() + "/api" + push.SubscriptionPath + ctx.Request = httptest.NewRequest(http.MethodGet, requestUrl, nil) + ctx.Request.Header.Set("accept", "application/json") + + // trigger the handler + suite.pushModule.PushSubscriptionGETHandler(ctx) + + // read the response + result := recorder.Result() + defer func() { + _ = result.Body.Close() + }() + + b, err := io.ReadAll(result.Body) + if err != nil { + return nil, err + } + + if resultCode := recorder.Code; expectedHTTPStatus != resultCode { + return nil, fmt.Errorf("expected %d got %d", expectedHTTPStatus, resultCode) + } + + resp := &apimodel.WebPushSubscription{} + if err := json.Unmarshal(b, resp); err != nil { + return nil, err + } + + return resp, nil +} + +// Get a subscription that should exist. +func (suite *PushTestSuite) TestGetSubscription() { + accountFixtureName := "local_account_1" + // This token should have a subscription associated with it already, with all event types turned on. + tokenFixtureName := "local_account_1" + + subscription, err := suite.getSubscription(accountFixtureName, tokenFixtureName, 200) + if suite.NoError(err) { + suite.NotEmpty(subscription.ID) + suite.NotEmpty(subscription.Endpoint) + suite.NotEmpty(subscription.ServerKey) + suite.True(subscription.Alerts.Mention) + } +} + +// Get a subscription that should not exist, which should fail. +func (suite *PushTestSuite) TestGetMissingSubscription() { + accountFixtureName := "local_account_1" + // This token should not have a subscription. + tokenFixtureName := "local_account_1_user_authorization_token" + + _, err := suite.getSubscription(accountFixtureName, tokenFixtureName, 404) + suite.NoError(err) +} diff --git a/internal/api/client/push/pushsubscriptionpost.go b/internal/api/client/push/pushsubscriptionpost.go new file mode 100644 index 000000000..a7e299894 --- /dev/null +++ b/internal/api/client/push/pushsubscriptionpost.go @@ -0,0 +1,284 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push + +import ( + "crypto/ecdh" + "encoding/base64" + "errors" + "fmt" + "net/http" + "net/url" + + "github.com/gin-gonic/gin" + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/oauth" +) + +// PushSubscriptionPOSTHandler swagger:operation POST /api/v1/push/subscription pushSubscriptionPost +// +// Create a new Web Push subscription for the current access token, or replace the existing one. +// +// --- +// tags: +// - push +// +// consumes: +// - application/json +// - application/x-www-form-urlencoded +// +// produces: +// - application/json +// +// parameters: +// - +// name: subscription[endpoint] +// in: formData +// type: string +// required: true +// minLength: 1 +// description: The URL to which Web Push notifications will be sent. +// - +// name: subscription[keys][auth] +// in: formData +// type: string +// required: true +// minLength: 1 +// description: The auth secret, a Base64 encoded string of 16 bytes of random data. +// - +// name: subscription[keys][p256dh] +// in: formData +// type: string +// required: true +// minLength: 1 +// description: The user agent public key, a Base64 encoded string of a public key from an ECDH keypair using the prime256v1 curve. +// - +// name: data[alerts][follow] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when someone has followed you? +// - +// name: data[alerts][follow_request] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when someone has requested to follow you? +// - +// name: data[alerts][favourite] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a status you created has been favourited by someone else? +// - +// name: data[alerts][mention] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when someone else has mentioned you in a status? +// - +// name: data[alerts][reblog] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a status you created has been boosted by someone else? +// - +// name: data[alerts][poll] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a poll you voted in or created has ended? +// - +// name: data[alerts][status] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a subscribed account posts a status? +// - +// name: data[alerts][update] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a status you interacted with has been edited? +// - +// name: data[alerts][admin.sign_up] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a new user has signed up? +// - +// name: data[alerts][admin.report] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a new report has been filed? +// - +// name: data[alerts][pending.favourite] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a fave is pending? +// - +// name: data[alerts][pending.reply] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a reply is pending? +// - +// name: data[alerts][pending.reblog] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a boost is pending? +// +// security: +// - OAuth2 Bearer: +// - push +// +// responses: +// '200': +// description: Web Push subscription for current access token. +// schema: +// "$ref": "#/definitions/webPushSubscription" +// '400': +// description: bad request +// '401': +// description: unauthorized +// '403': +// description: forbidden +// '404': +// description: not found +// '406': +// description: not acceptable +// '500': +// description: internal server error +func (m *Module) PushSubscriptionPOSTHandler(c *gin.Context) { + authed, err := oauth.Authed(c, true, true, true, true) + if err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1) + return + } + + if authed.Account.IsMoving() { + apiutil.ForbiddenAfterMove(c) + return + } + + if _, err := apiutil.NegotiateAccept(c, apiutil.JSONAcceptHeaders...); err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1) + return + } + + form := &apimodel.WebPushSubscriptionCreateRequest{} + if err := c.ShouldBind(form); err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) + return + } + + if err := validateNormalizeCreate(form); err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorUnprocessableEntity(err, err.Error()), m.processor.InstanceGetV1) + return + } + + apiSubscription, errWithCode := m.processor.Push().CreateOrReplace(c, authed.Account.ID, authed.Token.GetAccess(), form) + if errWithCode != nil { + apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) + return + } + + apiutil.JSON(c, http.StatusOK, apiSubscription) +} + +// validateNormalizeCreate checks subscription endpoint format and keys decodability, +// and copies form fields to their canonical JSON equivalents. +func validateNormalizeCreate(request *apimodel.WebPushSubscriptionCreateRequest) error { + if request.Subscription == nil { + request.Subscription = &apimodel.WebPushSubscriptionRequestSubscription{} + } + + // Normalize and validate endpoint URL. + if request.SubscriptionEndpoint != nil { + request.Subscription.Endpoint = *request.SubscriptionEndpoint + } + + if request.Subscription.Endpoint == "" { + return errors.New("endpoint is required") + } + endpointURL, err := url.Parse(request.Subscription.Endpoint) + if err != nil { + return errors.New("endpoint must be a valid URL") + } + if endpointURL.Scheme != "https" { + return errors.New("endpoint must be an https:// URL") + } + if endpointURL.Host == "" { + return errors.New("endpoint URL must have a host") + } + if endpointURL.Fragment != "" { + return errors.New("endpoint URL must not have a fragment") + } + + // Normalize and validate auth secret. + if request.SubscriptionKeysAuth != nil { + request.Subscription.Keys.Auth = *request.SubscriptionKeysAuth + } + + authBytes, err := base64DecodeAny("auth", request.Subscription.Keys.Auth) + if err != nil { + return err + } + if len(authBytes) != 16 { + return fmt.Errorf("auth must be 16 bytes long, got %d", len(authBytes)) + } + + // Normalize and validate public key. + if request.SubscriptionKeysP256dh != nil { + request.Subscription.Keys.P256dh = *request.SubscriptionKeysP256dh + } + + p256dhBytes, err := base64DecodeAny("p256dh", request.Subscription.Keys.P256dh) + if err != nil { + return err + } + _, err = ecdh.P256().NewPublicKey(p256dhBytes) + if err != nil { + return fmt.Errorf("p256dh must be a valid public key on the NIST P-256 curve: %w", err) + } + + return validateNormalizeUpdate(&request.WebPushSubscriptionUpdateRequest) +} + +// base64DecodeAny tries decoding a string with standard and URL alphabets of Base64, with and without padding. +func base64DecodeAny(name string, value string) ([]byte, error) { + encodings := []*base64.Encoding{ + base64.StdEncoding, + base64.URLEncoding, + base64.RawStdEncoding, + base64.RawURLEncoding, + } + + for _, encoding := range encodings { + if bytes, err := encoding.DecodeString(value); err == nil { + return bytes, nil + } + } + + return nil, fmt.Errorf("%s is not valid Base64 data", name) +} diff --git a/internal/api/client/push/pushsubscriptionpost_test.go b/internal/api/client/push/pushsubscriptionpost_test.go new file mode 100644 index 000000000..bdd22d729 --- /dev/null +++ b/internal/api/client/push/pushsubscriptionpost_test.go @@ -0,0 +1,346 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push_test + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "net/url" + "strconv" + "strings" + + "github.com/superseriousbusiness/gotosocial/internal/api/client/push" + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/oauth" + "github.com/superseriousbusiness/gotosocial/testrig" +) + +// postSubscription creates or replaces the push subscription for the named account and token. +// It only allows updating two event types if using the form API. Add more if you need them. +func (suite *PushTestSuite) postSubscription( + accountFixtureName string, + tokenFixtureName string, + endpoint *string, + auth *string, + p256dh *string, + alertsMention *bool, + alertsStatus *bool, + requestJson *string, + expectedHTTPStatus int, +) (*apimodel.WebPushSubscription, error) { + // instantiate recorder + test context + recorder := httptest.NewRecorder() + ctx, _ := testrig.CreateGinTestContext(recorder, nil) + ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts[accountFixtureName]) + ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(suite.testTokens[tokenFixtureName])) + ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) + ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers[accountFixtureName]) + + // create the request + requestUrl := config.GetProtocol() + "://" + config.GetHost() + "/api" + push.SubscriptionPath + ctx.Request = httptest.NewRequest(http.MethodPost, requestUrl, nil) + ctx.Request.Header.Set("accept", "application/json") + + if requestJson != nil { + ctx.Request.Header.Set("content-type", "application/json") + ctx.Request.Body = io.NopCloser(strings.NewReader(*requestJson)) + } else { + ctx.Request.Form = make(url.Values) + if endpoint != nil { + ctx.Request.Form["subscription[endpoint]"] = []string{*endpoint} + } + if auth != nil { + ctx.Request.Form["subscription[keys][auth]"] = []string{*auth} + } + if p256dh != nil { + ctx.Request.Form["subscription[keys][p256dh]"] = []string{*p256dh} + } + if alertsMention != nil { + ctx.Request.Form["data[alerts][mention]"] = []string{strconv.FormatBool(*alertsMention)} + } + if alertsStatus != nil { + ctx.Request.Form["data[alerts][status]"] = []string{strconv.FormatBool(*alertsStatus)} + } + } + + // trigger the handler + suite.pushModule.PushSubscriptionPOSTHandler(ctx) + + // read the response + result := recorder.Result() + defer func() { + _ = result.Body.Close() + }() + + b, err := io.ReadAll(result.Body) + if err != nil { + return nil, err + } + + if resultCode := recorder.Code; expectedHTTPStatus != resultCode { + return nil, fmt.Errorf("expected %d got %d", expectedHTTPStatus, resultCode) + } + + resp := &apimodel.WebPushSubscription{} + if err := json.Unmarshal(b, resp); err != nil { + return nil, err + } + + return resp, nil +} + +// Create a new subscription. +func (suite *PushTestSuite) TestPostSubscription() { + accountFixtureName := "local_account_1" + // This token should not have a subscription. + tokenFixtureName := "local_account_1_user_authorization_token" + + endpoint := "https://example.test/push" + auth := "cgna/fzrYLDQyPf5hD7IsA==" + p256dh := "BMYVItYVOX+AHBdtA62Q0i6c+F7MV2Gia3aoDr8mvHkuPBNIOuTLDfmFcnBqoZcQk6BtLcIONbxhHpy2R+mYIUY=" + alertsMention := true + alertsStatus := false + subscription, err := suite.postSubscription( + accountFixtureName, + tokenFixtureName, + &endpoint, + &auth, + &p256dh, + &alertsMention, + &alertsStatus, + nil, + 200, + ) + if suite.NoError(err) { + suite.NotEmpty(subscription.ID) + suite.NotEmpty(subscription.Endpoint) + suite.NotEmpty(subscription.ServerKey) + suite.True(subscription.Alerts.Mention) + suite.False(subscription.Alerts.Status) + // Omitted event types should default to off. + suite.False(subscription.Alerts.Favourite) + } +} + +// Create a new subscription with only required fields. +func (suite *PushTestSuite) TestPostSubscriptionMinimal() { + accountFixtureName := "local_account_1" + // This token should not have a subscription. + tokenFixtureName := "local_account_1_user_authorization_token" + + endpoint := "https://example.test/push" + auth := "cgna/fzrYLDQyPf5hD7IsA==" + p256dh := "BMYVItYVOX+AHBdtA62Q0i6c+F7MV2Gia3aoDr8mvHkuPBNIOuTLDfmFcnBqoZcQk6BtLcIONbxhHpy2R+mYIUY=" + subscription, err := suite.postSubscription( + accountFixtureName, + tokenFixtureName, + &endpoint, + &auth, + &p256dh, + nil, + nil, + nil, + 200, + ) + if suite.NoError(err) { + suite.NotEmpty(subscription.ID) + suite.NotEmpty(subscription.Endpoint) + suite.NotEmpty(subscription.ServerKey) + // All event types should default to off. + suite.False(subscription.Alerts.Mention) + suite.False(subscription.Alerts.Status) + suite.False(subscription.Alerts.Favourite) + } +} + +// Create a new subscription with a missing endpoint, which should fail. +func (suite *PushTestSuite) TestPostInvalidSubscription() { + accountFixtureName := "local_account_1" + // This token should not have a subscription. + tokenFixtureName := "local_account_1_user_authorization_token" + + // No endpoint. + auth := "cgna/fzrYLDQyPf5hD7IsA==" + p256dh := "BMYVItYVOX+AHBdtA62Q0i6c+F7MV2Gia3aoDr8mvHkuPBNIOuTLDfmFcnBqoZcQk6BtLcIONbxhHpy2R+mYIUY=" + alertsMention := true + alertsStatus := false + _, err := suite.postSubscription( + accountFixtureName, + tokenFixtureName, + nil, + &auth, + &p256dh, + &alertsMention, + &alertsStatus, + nil, + 422, + ) + suite.NoError(err) +} + +// Create a new subscription, using the JSON format. +func (suite *PushTestSuite) TestPostSubscriptionJSON() { + accountFixtureName := "local_account_1" + // This token should not have a subscription. + tokenFixtureName := "local_account_1_user_authorization_token" + + requestJson := `{ + "subscription": { + "endpoint": "https://example.test/push", + "keys": { + "auth": "cgna/fzrYLDQyPf5hD7IsA==", + "p256dh": "BMYVItYVOX+AHBdtA62Q0i6c+F7MV2Gia3aoDr8mvHkuPBNIOuTLDfmFcnBqoZcQk6BtLcIONbxhHpy2R+mYIUY=" + } + }, + "data": { + "alerts": { + "mention": true, + "status": false + } + } + }` + subscription, err := suite.postSubscription( + accountFixtureName, + tokenFixtureName, + nil, + nil, + nil, + nil, + nil, + &requestJson, + 200, + ) + if suite.NoError(err) { + suite.NotEmpty(subscription.ID) + suite.NotEmpty(subscription.Endpoint) + suite.NotEmpty(subscription.ServerKey) + suite.True(subscription.Alerts.Mention) + suite.False(subscription.Alerts.Status) + // Omitted event types should default to off. + suite.False(subscription.Alerts.Favourite) + } +} + +// Create a new subscription, using the JSON format and only required fields. +func (suite *PushTestSuite) TestPostSubscriptionJSONMinimal() { + accountFixtureName := "local_account_1" + // This token should not have a subscription. + tokenFixtureName := "local_account_1_user_authorization_token" + + requestJson := `{ + "subscription": { + "endpoint": "https://example.test/push", + "keys": { + "auth": "cgna/fzrYLDQyPf5hD7IsA==", + "p256dh": "BMYVItYVOX+AHBdtA62Q0i6c+F7MV2Gia3aoDr8mvHkuPBNIOuTLDfmFcnBqoZcQk6BtLcIONbxhHpy2R+mYIUY=" + } + } + }` + subscription, err := suite.postSubscription( + accountFixtureName, + tokenFixtureName, + nil, + nil, + nil, + nil, + nil, + &requestJson, + 200, + ) + if suite.NoError(err) { + suite.NotEmpty(subscription.ID) + suite.NotEmpty(subscription.Endpoint) + suite.NotEmpty(subscription.ServerKey) + // All event types should default to off. + suite.False(subscription.Alerts.Mention) + suite.False(subscription.Alerts.Status) + suite.False(subscription.Alerts.Favourite) + } +} + +// Create a new subscription with a missing endpoint, using the JSON format, which should fail. +func (suite *PushTestSuite) TestPostInvalidSubscriptionJSON() { + accountFixtureName := "local_account_1" + // This token should not have a subscription. + tokenFixtureName := "local_account_1_user_authorization_token" + + // No endpoint. + requestJson := `{ + "subscription": { + "keys": { + "auth": "cgna/fzrYLDQyPf5hD7IsA==", + "p256dh": "BMYVItYVOX+AHBdtA62Q0i6c+F7MV2Gia3aoDr8mvHkuPBNIOuTLDfmFcnBqoZcQk6BtLcIONbxhHpy2R+mYIUY=" + } + }, + "data": { + "alerts": { + "mention": true, + "status": false + } + } + }` + _, err := suite.postSubscription( + accountFixtureName, + tokenFixtureName, + nil, + nil, + nil, + nil, + nil, + &requestJson, + 422, + ) + suite.NoError(err) +} + +// Replace a subscription that already exists. +func (suite *PushTestSuite) TestPostExistingSubscription() { + accountFixtureName := "local_account_1" + // This token should have a subscription associated with it already, with all event types turned on. + tokenFixtureName := "local_account_1" + + endpoint := "https://example.test/push" + auth := "JMFtMRgZaeHpwsDjBnhcmQ==" + p256dh := "BMYVItYVOX+AHBdtA62Q0i6c+F7MV2Gia3aoDr8mvHkuPBNIOuTLDfmFcnBqoZcQk6BtLcIONbxhHpy2R+mYIUY=" + alertsMention := true + alertsStatus := false + subscription, err := suite.postSubscription( + accountFixtureName, + tokenFixtureName, + &endpoint, + &auth, + &p256dh, + &alertsMention, + &alertsStatus, + nil, + 200, + ) + if suite.NoError(err) { + suite.NotEqual(suite.testWebPushSubscriptions["local_account_1_token_1"].ID, subscription.ID) + suite.NotEmpty(subscription.Endpoint) + suite.NotEmpty(subscription.ServerKey) + suite.True(subscription.Alerts.Mention) + suite.False(subscription.Alerts.Status) + // Omitted event types should default to off. + suite.False(subscription.Alerts.Favourite) + } +} diff --git a/internal/api/client/push/pushsubscriptionput.go b/internal/api/client/push/pushsubscriptionput.go new file mode 100644 index 000000000..06575f4ee --- /dev/null +++ b/internal/api/client/push/pushsubscriptionput.go @@ -0,0 +1,232 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push + +import ( + "net/http" + + "github.com/gin-gonic/gin" + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/oauth" +) + +// PushSubscriptionPUTHandler swagger:operation PUT /api/v1/push/subscription pushSubscriptionPut +// +// Update the Web Push subscription for the current access token. +// Only which notifications you receive can be updated. +// +// --- +// tags: +// - push +// +// consumes: +// - application/json +// - application/x-www-form-urlencoded +// +// produces: +// - application/json +// +// parameters: +// - +// name: data[alerts][follow] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when someone has followed you? +// - +// name: data[alerts][follow_request] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when someone has requested to follow you? +// - +// name: data[alerts][favourite] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a status you created has been favourited by someone else? +// - +// name: data[alerts][mention] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when someone else has mentioned you in a status? +// - +// name: data[alerts][reblog] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a status you created has been boosted by someone else? +// - +// name: data[alerts][poll] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a poll you voted in or created has ended? +// - +// name: data[alerts][status] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a subscribed account posts a status? +// - +// name: data[alerts][update] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a status you interacted with has been edited? +// - +// name: data[alerts][admin.sign_up] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a new user has signed up? +// - +// name: data[alerts][admin.report] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a new report has been filed? +// - +// name: data[alerts][pending.favourite] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a fave is pending? +// - +// name: data[alerts][pending.reply] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a reply is pending? +// - +// name: data[alerts][pending.reblog] +// in: formData +// type: boolean +// default: false +// description: Receive a push notification when a boost is pending? +// +// security: +// - OAuth2 Bearer: +// - push +// +// responses: +// '200': +// description: Web Push subscription for current access token. +// schema: +// "$ref": "#/definitions/webPushSubscription" +// '400': +// description: bad request +// '401': +// description: unauthorized +// '403': +// description: forbidden +// '404': +// description: This access token doesn't have an associated subscription. +// '406': +// description: not acceptable +// '500': +// description: internal server error +func (m *Module) PushSubscriptionPUTHandler(c *gin.Context) { + authed, err := oauth.Authed(c, true, true, true, true) + if err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1) + return + } + + if authed.Account.IsMoving() { + apiutil.ForbiddenAfterMove(c) + return + } + + if _, err := apiutil.NegotiateAccept(c, apiutil.JSONAcceptHeaders...); err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1) + return + } + + form := &apimodel.WebPushSubscriptionUpdateRequest{} + if err := c.ShouldBind(form); err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) + return + } + + if err := validateNormalizeUpdate(form); err != nil { + apiutil.ErrorHandler(c, gtserror.NewErrorUnprocessableEntity(err, err.Error()), m.processor.InstanceGetV1) + return + } + + apiSubscription, errWithCode := m.processor.Push().Update(c, authed.Token.GetAccess(), form) + if errWithCode != nil { + apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) + return + } + + apiutil.JSON(c, http.StatusOK, apiSubscription) +} + +// validateNormalizeUpdate copies form fields to their canonical JSON equivalents. +func validateNormalizeUpdate(request *apimodel.WebPushSubscriptionUpdateRequest) error { + if request.Data == nil { + request.Data = &apimodel.WebPushSubscriptionRequestData{} + } + + if request.Data.Alerts == nil { + request.Data.Alerts = &apimodel.WebPushSubscriptionAlerts{} + } + + if request.DataAlertsFollow != nil { + request.Data.Alerts.Follow = *request.DataAlertsFollow + } + if request.DataAlertsFollowRequest != nil { + request.Data.Alerts.FollowRequest = *request.DataAlertsFollowRequest + } + if request.DataAlertsMention != nil { + request.Data.Alerts.Mention = *request.DataAlertsMention + } + if request.DataAlertsReblog != nil { + request.Data.Alerts.Reblog = *request.DataAlertsReblog + } + if request.DataAlertsPoll != nil { + request.Data.Alerts.Poll = *request.DataAlertsPoll + } + if request.DataAlertsStatus != nil { + request.Data.Alerts.Status = *request.DataAlertsStatus + } + if request.DataAlertsUpdate != nil { + request.Data.Alerts.Update = *request.DataAlertsUpdate + } + if request.DataAlertsAdminSignup != nil { + request.Data.Alerts.AdminSignup = *request.DataAlertsAdminSignup + } + if request.DataAlertsAdminReport != nil { + request.Data.Alerts.AdminReport = *request.DataAlertsAdminReport + } + if request.DataAlertsPendingFavourite != nil { + request.Data.Alerts.PendingFavourite = *request.DataAlertsPendingFavourite + } + if request.DataAlertsPendingReply != nil { + request.Data.Alerts.PendingReply = *request.DataAlertsPendingReply + } + if request.DataAlertsPendingReblog != nil { + request.Data.Alerts.Reblog = *request.DataAlertsPendingReblog + } + + return nil +} diff --git a/internal/api/client/push/pushsubscriptionput_test.go b/internal/api/client/push/pushsubscriptionput_test.go new file mode 100644 index 000000000..924e3d475 --- /dev/null +++ b/internal/api/client/push/pushsubscriptionput_test.go @@ -0,0 +1,176 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push_test + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "net/url" + "strconv" + "strings" + + "github.com/superseriousbusiness/gotosocial/internal/api/client/push" + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/oauth" + "github.com/superseriousbusiness/gotosocial/testrig" +) + +// putSubscription updates the push subscription for the named account and token. +// It only allows updating two event types if using the form API. Add more if you need them. +func (suite *PushTestSuite) putSubscription( + accountFixtureName string, + tokenFixtureName string, + alertsMention *bool, + alertsStatus *bool, + requestJson *string, + expectedHTTPStatus int, +) (*apimodel.WebPushSubscription, error) { + // instantiate recorder + test context + recorder := httptest.NewRecorder() + ctx, _ := testrig.CreateGinTestContext(recorder, nil) + ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts[accountFixtureName]) + ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(suite.testTokens[tokenFixtureName])) + ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) + ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers[accountFixtureName]) + + // create the request + requestUrl := config.GetProtocol() + "://" + config.GetHost() + "/api" + push.SubscriptionPath + ctx.Request = httptest.NewRequest(http.MethodPut, requestUrl, nil) + ctx.Request.Header.Set("accept", "application/json") + + if requestJson != nil { + ctx.Request.Header.Set("content-type", "application/json") + ctx.Request.Body = io.NopCloser(strings.NewReader(*requestJson)) + } else { + ctx.Request.Form = make(url.Values) + if alertsMention != nil { + ctx.Request.Form["data[alerts][mention]"] = []string{strconv.FormatBool(*alertsMention)} + } + if alertsStatus != nil { + ctx.Request.Form["data[alerts][status]"] = []string{strconv.FormatBool(*alertsStatus)} + } + } + + // trigger the handler + suite.pushModule.PushSubscriptionPUTHandler(ctx) + + // read the response + result := recorder.Result() + defer func() { + _ = result.Body.Close() + }() + + b, err := io.ReadAll(result.Body) + if err != nil { + return nil, err + } + + if resultCode := recorder.Code; expectedHTTPStatus != resultCode { + return nil, fmt.Errorf("expected %d got %d", expectedHTTPStatus, resultCode) + } + + resp := &apimodel.WebPushSubscription{} + if err := json.Unmarshal(b, resp); err != nil { + return nil, err + } + + return resp, nil +} + +// Update a subscription that already exists. +func (suite *PushTestSuite) TestPutSubscription() { + accountFixtureName := "local_account_1" + // This token should have a subscription associated with it already, with all event types turned on. + tokenFixtureName := "local_account_1" + + alertsMention := true + alertsStatus := false + subscription, err := suite.putSubscription( + accountFixtureName, + tokenFixtureName, + &alertsMention, + &alertsStatus, + nil, + 200, + ) + if suite.NoError(err) { + suite.NotEmpty(subscription.ID) + suite.NotEmpty(subscription.Endpoint) + suite.NotEmpty(subscription.ServerKey) + suite.True(subscription.Alerts.Mention) + suite.False(subscription.Alerts.Status) + // Omitted event types should default to off. + suite.False(subscription.Alerts.Favourite) + } +} + +// Update a subscription that already exists, using the JSON format. +func (suite *PushTestSuite) TestPutSubscriptionJSON() { + accountFixtureName := "local_account_1" + // This token should have a subscription associated with it already, with all event types turned on. + tokenFixtureName := "local_account_1" + + requestJson := `{ + "data": { + "alerts": { + "mention": true, + "status": false + } + } + }` + subscription, err := suite.putSubscription( + accountFixtureName, + tokenFixtureName, + nil, + nil, + &requestJson, + 200, + ) + if suite.NoError(err) { + suite.NotEmpty(subscription.ID) + suite.NotEmpty(subscription.Endpoint) + suite.NotEmpty(subscription.ServerKey) + suite.True(subscription.Alerts.Mention) + suite.False(subscription.Alerts.Status) + // Omitted event types should default to off. + suite.False(subscription.Alerts.Favourite) + } +} + +// Update a subscription that does not exist, which should fail. +func (suite *PushTestSuite) TestPutMissingSubscription() { + accountFixtureName := "local_account_1" + // This token should not have a subscription. + tokenFixtureName := "local_account_1_user_authorization_token" + + alertsMention := true + alertsStatus := false + _, err := suite.putSubscription( + accountFixtureName, + tokenFixtureName, + &alertsMention, + &alertsStatus, + nil, + 404, + ) + suite.NoError(err) +} diff --git a/internal/api/client/reports/reports_test.go b/internal/api/client/reports/reports_test.go index 031fd953a..89240a4b1 100644 --- a/internal/api/client/reports/reports_test.go +++ b/internal/api/client/reports/reports_test.go @@ -91,7 +91,13 @@ func (suite *ReportsStandardTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.reportsModule = reports.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/client/search/search_test.go b/internal/api/client/search/search_test.go index fecb30d38..219966c7c 100644 --- a/internal/api/client/search/search_test.go +++ b/internal/api/client/search/search_test.go @@ -95,7 +95,13 @@ func (suite *SearchStandardTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.searchModule = search.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/client/statuses/status_test.go b/internal/api/client/statuses/status_test.go index 5a4473344..c5f2838e8 100644 --- a/internal/api/client/statuses/status_test.go +++ b/internal/api/client/statuses/status_test.go @@ -211,7 +211,13 @@ func (suite *StatusStandardTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.statusModule = statuses.New(suite.processor) testrig.StartWorkers(&suite.state, suite.processor.Workers()) diff --git a/internal/api/client/streaming/streaming_test.go b/internal/api/client/streaming/streaming_test.go index 03cd6f434..00ad2de03 100644 --- a/internal/api/client/streaming/streaming_test.go +++ b/internal/api/client/streaming/streaming_test.go @@ -111,7 +111,13 @@ func (suite *StreamingTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.streamingModule = streaming.New(suite.processor, 1, 4096) } diff --git a/internal/api/client/tags/tags_test.go b/internal/api/client/tags/tags_test.go index 71a84435a..c24574d47 100644 --- a/internal/api/client/tags/tags_test.go +++ b/internal/api/client/tags/tags_test.go @@ -96,7 +96,13 @@ func (suite *TagsTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.tagsModule = tags.New(suite.processor) testrig.StandardDBSetup(suite.db, nil) diff --git a/internal/api/client/user/emailchange_test.go b/internal/api/client/user/emailchange_test.go index fce96c144..868ad766c 100644 --- a/internal/api/client/user/emailchange_test.go +++ b/internal/api/client/user/emailchange_test.go @@ -44,7 +44,8 @@ func (suite *EmailChangeTestSuite) TestEmailChangePOST() { storage := testrig.NewInMemoryStorage() sentEmails := make(map[string]string) emailSender := testrig.NewEmailSender("../../../../web/template/", sentEmails) - processor := testrig.NewTestProcessor(state, suite.federator, emailSender, suite.mediaManager) + webPushSender := testrig.NewNoopWebPushSender() + processor := testrig.NewTestProcessor(state, suite.federator, emailSender, webPushSender, suite.mediaManager) testrig.StartWorkers(state, processor.Workers()) userModule := user.New(processor) testrig.StandardDBSetup(state.DB, suite.testAccounts) diff --git a/internal/api/client/user/user_test.go b/internal/api/client/user/user_test.go index 320c743f8..8cf359cd8 100644 --- a/internal/api/client/user/user_test.go +++ b/internal/api/client/user/user_test.go @@ -86,8 +86,21 @@ func (suite *UserStandardTestSuite) SetupTest() { ) suite.mediaManager = testrig.NewTestMediaManager(&suite.state) - suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, testrig.NewEmailSender("../../../../web/template/", nil), suite.mediaManager) + suite.federator = testrig.NewTestFederator( + &suite.state, + testrig.NewTestTransportController( + &suite.state, + testrig.NewMockHTTPClient(nil, "../../../../testrig/media"), + ), + suite.mediaManager, + ) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + testrig.NewEmailSender("../../../../web/template/", nil), + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.userModule = user.New(suite.processor) testrig.StandardDBSetup(suite.db, suite.testAccounts) testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media") diff --git a/internal/api/fileserver/fileserver_test.go b/internal/api/fileserver/fileserver_test.go index af6f125dc..9b0580e92 100644 --- a/internal/api/fileserver/fileserver_test.go +++ b/internal/api/fileserver/fileserver_test.go @@ -75,8 +75,21 @@ func (suite *FileserverTestSuite) SetupSuite() { suite.state.Storage = suite.storage suite.mediaManager = testrig.NewTestMediaManager(&suite.state) - suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../testrig/media")), suite.mediaManager) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.federator = testrig.NewTestFederator( + &suite.state, + testrig.NewTestTransportController( + &suite.state, + testrig.NewMockHTTPClient(nil, "../../../testrig/media"), + ), + suite.mediaManager, + ) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.tc = typeutils.NewConverter(&suite.state) diff --git a/internal/api/model/instancev2.go b/internal/api/model/instancev2.go index 982ed0c63..b3d11dee2 100644 --- a/internal/api/model/instancev2.go +++ b/internal/api/model/instancev2.go @@ -174,6 +174,8 @@ type InstanceV2Configuration struct { Emojis InstanceConfigurationEmojis `json:"emojis"` // True if instance is running with OIDC as auth/identity backend, else omitted. OIDCEnabled bool `json:"oidc_enabled,omitempty"` + // Instance VAPID configuration. + VAPID InstanceV2ConfigurationVAPID `json:"vapid"` } // Information about registering for this instance. @@ -204,3 +206,11 @@ type InstanceV2Contact struct { // Key/value not present if no contact account set. Account *Account `json:"account,omitempty"` } + +// InstanceV2ConfigurationVAPID holds the instance's VAPID configuration. +// +// swagger:model instanceV2ConfigurationVAPID +type InstanceV2ConfigurationVAPID struct { + // The instance's VAPID public key, Base64-encoded. + PublicKey string `json:"public_key"` +} diff --git a/internal/api/model/pushsubscription.go b/internal/api/model/pushsubscription.go deleted file mode 100644 index 1e7708d94..000000000 --- a/internal/api/model/pushsubscription.go +++ /dev/null @@ -1,44 +0,0 @@ -// GoToSocial -// Copyright (C) GoToSocial Authors admin@gotosocial.org -// SPDX-License-Identifier: AGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package model - -// PushSubscription represents a subscription to the push streaming server. -type PushSubscription struct { - // The id of the push subscription in the database. - ID string `json:"id"` - // Where push alerts will be sent to. - Endpoint string `json:"endpoint"` - // The streaming server's VAPID key. - ServerKey string `json:"server_key"` - // Which alerts should be delivered to the endpoint. - Alerts *PushSubscriptionAlerts `json:"alerts"` -} - -// PushSubscriptionAlerts represents the specific alerts that this push subscription will give. -type PushSubscriptionAlerts struct { - // Receive a push notification when someone has followed you? - Follow bool `json:"follow"` - // Receive a push notification when a status you created has been favourited by someone else? - Favourite bool `json:"favourite"` - // Receive a push notification when someone else has mentioned you in a status? - Mention bool `json:"mention"` - // Receive a push notification when a status you created has been boosted by someone else? - Reblog bool `json:"reblog"` - // Receive a push notification when a poll you voted in or created has ended? - Poll bool `json:"poll"` -} diff --git a/internal/api/model/webpushnotification.go b/internal/api/model/webpushnotification.go new file mode 100644 index 000000000..5d7a593fc --- /dev/null +++ b/internal/api/model/webpushnotification.go @@ -0,0 +1,52 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package model + +// WebPushNotification represents a notification summary delivered to the client by the Web Push server. +// It does not contain an entire Notification, just the NotificationID and some preview information. +// It is not used in the client API directly, but is included in the API doc for decoding Web Push notifications. +// +// swagger:model webPushNotification +type WebPushNotification struct { + // NotificationID is the Notification.ID of the referenced Notification. + NotificationID string `json:"notification_id"` + + // NotificationType is the Notification.Type of the referenced Notification. + NotificationType string `json:"notification_type"` + + // Title is a title for the notification, + // generally describing an action taken by a user. + Title string `json:"title"` + + // Body is a preview of the notification body, + // such as the first line of a status's CW or text, + // or the first line of an account bio. + Body string `json:"body"` + + // Icon is an image URL that can be displayed with the notification, + // normally the account's avatar. + Icon string `json:"icon"` + + // PreferredLocale is a BCP 47 language tag for the receiving user's locale. + PreferredLocale string `json:"preferred_locale"` + + // AccessToken is the access token associated with the Web Push subscription. + // I don't know why this is sent, given that the client should know that already, + // but Feditext does use it. + AccessToken string `json:"access_token"` +} diff --git a/internal/api/model/webpushsubscription.go b/internal/api/model/webpushsubscription.go new file mode 100644 index 000000000..a28bb7294 --- /dev/null +++ b/internal/api/model/webpushsubscription.go @@ -0,0 +1,157 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package model + +// WebPushSubscription represents a subscription to a Web Push server. +// +// swagger:model webPushSubscription +type WebPushSubscription struct { + // The id of the push subscription in the database. + ID string `json:"id"` + + // Where push alerts will be sent to. + Endpoint string `json:"endpoint"` + + // The streaming server's VAPID public key. + ServerKey string `json:"server_key"` + + // Which alerts should be delivered to the endpoint. + Alerts WebPushSubscriptionAlerts `json:"alerts"` + + // Which accounts should generate notifications. + Policy WebPushNotificationPolicy `json:"policy"` + + // Whether the subscription uses RFC or pre-RFC Web Push standards. + // For GotoSocial, this is always true. + Standard bool `json:"standard"` +} + +// WebPushSubscriptionAlerts represents the specific events that this Web Push subscription will receive. +// +// swagger:model webPushSubscriptionAlerts +type WebPushSubscriptionAlerts struct { + // Receive a push notification when someone has followed you? + Follow bool `json:"follow"` + + // Receive a push notification when someone has requested to follow you? + FollowRequest bool `json:"follow_request"` + + // Receive a push notification when a status you created has been favourited by someone else? + Favourite bool `json:"favourite"` + + // Receive a push notification when someone else has mentioned you in a status? + Mention bool `json:"mention"` + + // Receive a push notification when a status you created has been boosted by someone else? + Reblog bool `json:"reblog"` + + // Receive a push notification when a poll you voted in or created has ended? + Poll bool `json:"poll"` + + // Receive a push notification when a subscribed account posts a status? + Status bool `json:"status"` + + // Receive a push notification when a status you interacted with has been edited? + Update bool `json:"update"` + + // Receive a push notification when a new user has signed up? + AdminSignup bool `json:"admin.sign_up"` + + // Receive a push notification when a new report has been filed? + AdminReport bool `json:"admin.report"` + + // Receive a push notification when a fave is pending? + PendingFavourite bool `json:"pending.favourite"` + + // Receive a push notification when a reply is pending? + PendingReply bool `json:"pending.reply"` + + // Receive a push notification when a boost is pending? + PendingReblog bool `json:"pending.reblog"` +} + +// WebPushSubscriptionCreateRequest captures params for creating or replacing a Web Push subscription. +// +// swagger:ignore +type WebPushSubscriptionCreateRequest struct { + Subscription *WebPushSubscriptionRequestSubscription `form:"-" json:"subscription"` + + SubscriptionEndpoint *string `form:"subscription[endpoint]" json:"-"` + SubscriptionKeysAuth *string `form:"subscription[keys][auth]" json:"-"` + SubscriptionKeysP256dh *string `form:"subscription[keys][p256dh]" json:"-"` + + WebPushSubscriptionUpdateRequest +} + +// WebPushSubscriptionRequestSubscription is the part of a Web Push subscription that is fixed at creation. +// +// swagger:ignore +type WebPushSubscriptionRequestSubscription struct { + // Endpoint is the URL to which Web Push notifications will be sent. + Endpoint string `json:"endpoint"` + + Keys WebPushSubscriptionRequestSubscriptionKeys `json:"keys"` +} + +// WebPushSubscriptionRequestSubscriptionKeys is the part of a Web Push subscription that contains auth secrets. +// +// swagger:ignore +type WebPushSubscriptionRequestSubscriptionKeys struct { + // Auth is the auth secret, a Base64 encoded string of 16 bytes of random data. + Auth string `json:"auth"` + + // P256dh is the user agent public key, a Base64 encoded string of a public key from an ECDH keypair using the prime256v1 curve. + P256dh string `json:"p256dh"` +} + +// WebPushSubscriptionUpdateRequest captures params for updating a Web Push subscription. +// +// swagger:ignore +type WebPushSubscriptionUpdateRequest struct { + Data *WebPushSubscriptionRequestData `form:"-" json:"data"` + + DataAlertsFollow *bool `form:"data[alerts][follow]" json:"-"` + DataAlertsFollowRequest *bool `form:"data[alerts][follow_request]" json:"-"` + DataAlertsFavourite *bool `form:"data[alerts][favourite]" json:"-"` + DataAlertsMention *bool `form:"data[alerts][mention]" json:"-"` + DataAlertsReblog *bool `form:"data[alerts][reblog]" json:"-"` + DataAlertsPoll *bool `form:"data[alerts][poll]" json:"-"` + DataAlertsStatus *bool `form:"data[alerts][status]" json:"-"` + DataAlertsUpdate *bool `form:"data[alerts][update]" json:"-"` + DataAlertsAdminSignup *bool `form:"data[alerts][admin.sign_up]" json:"-"` + DataAlertsAdminReport *bool `form:"data[alerts][admin.report]" json:"-"` + DataAlertsPendingFavourite *bool `form:"data[alerts][pending.favourite]" json:"-"` + DataAlertsPendingReply *bool `form:"data[alerts][pending.reply]" json:"-"` + DataAlertsPendingReblog *bool `form:"data[alerts][pending.reblog]" json:"-"` +} + +// WebPushSubscriptionRequestData is the part of a Web Push subscription that can be changed after creation. +// +// swagger:ignore +type WebPushSubscriptionRequestData struct { + // Alerts selects the specific events that this Web Push subscription will receive. + Alerts *WebPushSubscriptionAlerts `form:"-" json:"alerts"` +} + +// WebPushNotificationPolicy names sets of accounts that can generate notifications. +type WebPushNotificationPolicy string + +const ( + // WebPushNotificationPolicyAll allows all accounts to send notifications to the subscribing user. + WebPushNotificationPolicyAll WebPushNotificationPolicy = "all" +) diff --git a/internal/api/wellknown/webfinger/webfinger_test.go b/internal/api/wellknown/webfinger/webfinger_test.go index 76c1fb5bb..234c1ad16 100644 --- a/internal/api/wellknown/webfinger/webfinger_test.go +++ b/internal/api/wellknown/webfinger/webfinger_test.go @@ -94,7 +94,13 @@ func (suite *WebfingerStandardTestSuite) SetupTest() { suite.mediaManager = testrig.NewTestMediaManager(&suite.state) suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../../../testrig/media")), suite.mediaManager) suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) suite.webfingerModule = webfinger.New(suite.processor) suite.oauthServer = testrig.NewTestOauthServer(suite.db) testrig.StandardDBSetup(suite.db, suite.testAccounts) diff --git a/internal/api/wellknown/webfinger/webfingerget_test.go b/internal/api/wellknown/webfinger/webfingerget_test.go index b3aec57fe..4bb6f323d 100644 --- a/internal/api/wellknown/webfinger/webfingerget_test.go +++ b/internal/api/wellknown/webfinger/webfingerget_test.go @@ -98,6 +98,7 @@ func (suite *WebfingerGetTestSuite) funkifyAccountDomain(host string, accountDom testrig.NewTestMediaManager(&suite.state), &suite.state, suite.emailSender, + testrig.NewNoopWebPushSender(), visibility.NewFilter(&suite.state), interaction.NewFilter(&suite.state), ) diff --git a/internal/cache/cache.go b/internal/cache/cache.go index 6f925e24f..5771b4e95 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -117,6 +117,8 @@ func (c *Caches) Init() { c.initUserMute() c.initUserMuteIDs() c.initWebfinger() + c.initWebPushSubscription() + c.initWebPushSubscriptionIDs() c.initVisibility() c.initStatusesFilterableFields() } diff --git a/internal/cache/db.go b/internal/cache/db.go index 1052446c4..180d81907 100644 --- a/internal/cache/db.go +++ b/internal/cache/db.go @@ -258,6 +258,15 @@ type DBCaches struct { // UserMuteIDs provides access to the user mute IDs database cache. UserMuteIDs SliceCache[string] + + // VAPIDKeyPair caches the server's VAPID key pair. + VAPIDKeyPair atomic.Pointer[gtsmodel.VAPIDKeyPair] + + // WebPushSubscription provides access to the gtsmodel WebPushSubscription database cache. + WebPushSubscription StructCache[*gtsmodel.WebPushSubscription] + + // WebPushSubscriptionIDs provides access to the Web Push subscription IDs database cache. + WebPushSubscriptionIDs SliceCache[string] } // NOTE: @@ -1579,9 +1588,10 @@ func (c *Caches) initToken() { {Fields: "Refresh"}, {Fields: "ClientID", Multiple: true}, }, - MaxSize: cap, - IgnoreErr: ignoreErrors, - Copy: copyF, + MaxSize: cap, + IgnoreErr: ignoreErrors, + Copy: copyF, + Invalidate: c.OnInvalidateToken, }) } @@ -1691,3 +1701,40 @@ func (c *Caches) initUserMuteIDs() { c.DB.UserMuteIDs.Init(0, cap) } + +func (c *Caches) initWebPushSubscription() { + cap := calculateResultCacheMax( + sizeofWebPushSubscription(), // model in-mem size. + config.GetCacheWebPushSubscriptionMemRatio(), + ) + + log.Infof(nil, "cache size = %d", cap) + + copyF := func(s1 *gtsmodel.WebPushSubscription) *gtsmodel.WebPushSubscription { + s2 := new(gtsmodel.WebPushSubscription) + *s2 = *s1 + return s2 + } + + c.DB.WebPushSubscription.Init(structr.CacheConfig[*gtsmodel.WebPushSubscription]{ + Indices: []structr.IndexConfig{ + {Fields: "ID"}, + {Fields: "TokenID"}, + {Fields: "AccountID", Multiple: true}, + }, + MaxSize: cap, + IgnoreErr: ignoreErrors, + Invalidate: c.OnInvalidateWebPushSubscription, + Copy: copyF, + }) +} + +func (c *Caches) initWebPushSubscriptionIDs() { + cap := calculateSliceCacheMax( + config.GetCacheWebPushSubscriptionIDsMemRatio(), + ) + + log.Infof(nil, "cache size = %d", cap) + + c.DB.WebPushSubscriptionIDs.Init(0, cap) +} diff --git a/internal/cache/invalidate.go b/internal/cache/invalidate.go index 42d7b7399..555c73cd7 100644 --- a/internal/cache/invalidate.go +++ b/internal/cache/invalidate.go @@ -283,6 +283,11 @@ func (c *Caches) OnInvalidateStatusFave(fave *gtsmodel.StatusFave) { c.DB.StatusFaveIDs.Invalidate(fave.StatusID) } +func (c *Caches) OnInvalidateToken(token *gtsmodel.Token) { + // Invalidate token's push subscription. + c.DB.WebPushSubscription.Invalidate("ID", token.ID) +} + func (c *Caches) OnInvalidateUser(user *gtsmodel.User) { // Invalidate local account ID cached visibility. c.Visibility.Invalidate("ItemID", user.AccountID) @@ -296,3 +301,8 @@ func (c *Caches) OnInvalidateUserMute(mute *gtsmodel.UserMute) { // Invalidate source account's user mute lists. c.DB.UserMuteIDs.Invalidate(mute.AccountID) } + +func (c *Caches) OnInvalidateWebPushSubscription(subscription *gtsmodel.WebPushSubscription) { + // Invalidate source account's Web Push subscription list. + c.DB.WebPushSubscriptionIDs.Invalidate(subscription.AccountID) +} diff --git a/internal/cache/size.go b/internal/cache/size.go index 24101683a..c96a3cd2e 100644 --- a/internal/cache/size.go +++ b/internal/cache/size.go @@ -66,6 +66,14 @@ // be a serialized string of almost any type, so we pick a // nice serialized key size on the upper end of normal. sizeofResultKey = 2 * sizeofIDStr + + // exampleWebPushAuth is a Base64-encoded 16-byte random auth secret. + // This secret is consumed as Base64 by webpush-go. + exampleWebPushAuth = "ZVxqlt5fzVgmSz2aqiA2XQ==" + + // exampleWebPushP256dh is a Base64-encoded DH P-256 public key. + // This secret is consumed as Base64 by webpush-go. + exampleWebPushP256dh = "OrpejO16gV97uBXew/T0I7YoUv/CX8fz0z4g8RrQ+edXJqQPjX3XVSo2P0HhcCpCOR1+Dzj5LFcK9jYNqX7SBg==" ) var ( @@ -576,7 +584,7 @@ func sizeofMove() uintptr { func sizeofNotification() uintptr { return uintptr(size.Of(>smodel.Notification{ ID: exampleID, - NotificationType: gtsmodel.NotificationFave, + NotificationType: gtsmodel.NotificationFavourite, CreatedAt: exampleTime, TargetAccountID: exampleID, OriginAccountID: exampleID, @@ -821,3 +829,11 @@ func sizeofUserMute() uintptr { Notifications: util.Ptr(false), })) } + +func sizeofWebPushSubscription() uintptr { + return uintptr(size.Of(>smodel.WebPushSubscription{ + TokenID: exampleID, + Auth: exampleWebPushAuth, + P256dh: exampleWebPushP256dh, + })) +} diff --git a/internal/config/config.go b/internal/config/config.go index 72154b3f2..f77c86c50 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -252,6 +252,8 @@ type CacheConfiguration struct { UserMuteMemRatio float64 `name:"user-mute-mem-ratio"` UserMuteIDsMemRatio float64 `name:"user-mute-ids-mem-ratio"` WebfingerMemRatio float64 `name:"webfinger-mem-ratio"` + WebPushSubscriptionMemRatio float64 `name:"web-push-subscription-mem-ratio"` + WebPushSubscriptionIDsMemRatio float64 `name:"web-push-subscription-ids-mem-ratio"` VisibilityMemRatio float64 `name:"visibility-mem-ratio"` } diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 8c2ae90de..157dfde0a 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -213,6 +213,8 @@ UserMuteMemRatio: 2, UserMuteIDsMemRatio: 3, WebfingerMemRatio: 0.1, + WebPushSubscriptionMemRatio: 1, + WebPushSubscriptionIDsMemRatio: 1, VisibilityMemRatio: 2, }, diff --git a/internal/config/helpers.gen.go b/internal/config/helpers.gen.go index e1c41638c..fd1b86898 100644 --- a/internal/config/helpers.gen.go +++ b/internal/config/helpers.gen.go @@ -4274,6 +4274,64 @@ func GetCacheWebfingerMemRatio() float64 { return global.GetCacheWebfingerMemRat // SetCacheWebfingerMemRatio safely sets the value for global configuration 'Cache.WebfingerMemRatio' field func SetCacheWebfingerMemRatio(v float64) { global.SetCacheWebfingerMemRatio(v) } +// GetCacheWebPushSubscriptionMemRatio safely fetches the Configuration value for state's 'Cache.WebPushSubscriptionMemRatio' field +func (st *ConfigState) GetCacheWebPushSubscriptionMemRatio() (v float64) { + st.mutex.RLock() + v = st.config.Cache.WebPushSubscriptionMemRatio + st.mutex.RUnlock() + return +} + +// SetCacheWebPushSubscriptionMemRatio safely sets the Configuration value for state's 'Cache.WebPushSubscriptionMemRatio' field +func (st *ConfigState) SetCacheWebPushSubscriptionMemRatio(v float64) { + st.mutex.Lock() + defer st.mutex.Unlock() + st.config.Cache.WebPushSubscriptionMemRatio = v + st.reloadToViper() +} + +// CacheWebPushSubscriptionMemRatioFlag returns the flag name for the 'Cache.WebPushSubscriptionMemRatio' field +func CacheWebPushSubscriptionMemRatioFlag() string { return "cache-web-push-subscription-mem-ratio" } + +// GetCacheWebPushSubscriptionMemRatio safely fetches the value for global configuration 'Cache.WebPushSubscriptionMemRatio' field +func GetCacheWebPushSubscriptionMemRatio() float64 { + return global.GetCacheWebPushSubscriptionMemRatio() +} + +// SetCacheWebPushSubscriptionMemRatio safely sets the value for global configuration 'Cache.WebPushSubscriptionMemRatio' field +func SetCacheWebPushSubscriptionMemRatio(v float64) { global.SetCacheWebPushSubscriptionMemRatio(v) } + +// GetCacheWebPushSubscriptionIDsMemRatio safely fetches the Configuration value for state's 'Cache.WebPushSubscriptionIDsMemRatio' field +func (st *ConfigState) GetCacheWebPushSubscriptionIDsMemRatio() (v float64) { + st.mutex.RLock() + v = st.config.Cache.WebPushSubscriptionIDsMemRatio + st.mutex.RUnlock() + return +} + +// SetCacheWebPushSubscriptionIDsMemRatio safely sets the Configuration value for state's 'Cache.WebPushSubscriptionIDsMemRatio' field +func (st *ConfigState) SetCacheWebPushSubscriptionIDsMemRatio(v float64) { + st.mutex.Lock() + defer st.mutex.Unlock() + st.config.Cache.WebPushSubscriptionIDsMemRatio = v + st.reloadToViper() +} + +// CacheWebPushSubscriptionIDsMemRatioFlag returns the flag name for the 'Cache.WebPushSubscriptionIDsMemRatio' field +func CacheWebPushSubscriptionIDsMemRatioFlag() string { + return "cache-web-push-subscription-ids-mem-ratio" +} + +// GetCacheWebPushSubscriptionIDsMemRatio safely fetches the value for global configuration 'Cache.WebPushSubscriptionIDsMemRatio' field +func GetCacheWebPushSubscriptionIDsMemRatio() float64 { + return global.GetCacheWebPushSubscriptionIDsMemRatio() +} + +// SetCacheWebPushSubscriptionIDsMemRatio safely sets the value for global configuration 'Cache.WebPushSubscriptionIDsMemRatio' field +func SetCacheWebPushSubscriptionIDsMemRatio(v float64) { + global.SetCacheWebPushSubscriptionIDsMemRatio(v) +} + // GetCacheVisibilityMemRatio safely fetches the Configuration value for state's 'Cache.VisibilityMemRatio' field func (st *ConfigState) GetCacheVisibilityMemRatio() (v float64) { st.mutex.RLock() diff --git a/internal/db/application.go b/internal/db/application.go index b71e593c2..5a4068431 100644 --- a/internal/db/application.go +++ b/internal/db/application.go @@ -48,6 +48,9 @@ type Application interface { // GetAllTokens ... GetAllTokens(ctx context.Context) ([]*gtsmodel.Token, error) + // GetTokenByID ... + GetTokenByID(ctx context.Context, id string) (*gtsmodel.Token, error) + // GetTokenByCode ... GetTokenByCode(ctx context.Context, code string) (*gtsmodel.Token, error) diff --git a/internal/db/bundb/application.go b/internal/db/bundb/application.go index cbba499b0..92fc5ea2b 100644 --- a/internal/db/bundb/application.go +++ b/internal/db/bundb/application.go @@ -174,6 +174,16 @@ func(uncached []string) ([]*gtsmodel.Token, error) { return tokens, nil } +func (a *applicationDB) GetTokenByID(ctx context.Context, code string) (*gtsmodel.Token, error) { + return a.getTokenBy( + "ID", + func(t *gtsmodel.Token) error { + return a.db.NewSelect().Model(t).Where("? = ?", bun.Ident("id"), code).Scan(ctx) + }, + code, + ) +} + func (a *applicationDB) GetTokenByCode(ctx context.Context, code string) (*gtsmodel.Token, error) { return a.getTokenBy( "Code", diff --git a/internal/db/bundb/bundb.go b/internal/db/bundb/bundb.go index cf612fd2e..c9dd7866d 100644 --- a/internal/db/bundb/bundb.go +++ b/internal/db/bundb/bundb.go @@ -88,6 +88,7 @@ type DBService struct { db.Timeline db.User db.Tombstone + db.WebPush db.WorkerTask db *bun.DB } @@ -301,6 +302,10 @@ func NewBunDBService(ctx context.Context, state *state.State) (db.DB, error) { db: db, state: state, }, + WebPush: &webPushDB{ + db: db, + state: state, + }, WorkerTask: &workerTaskDB{ db: db, }, diff --git a/internal/db/bundb/migrations/20241121121623_enum_strings_to_ints.go b/internal/db/bundb/migrations/20241121121623_enum_strings_to_ints.go index 6767c6809..5f3eb1409 100644 --- a/internal/db/bundb/migrations/20241121121623_enum_strings_to_ints.go +++ b/internal/db/bundb/migrations/20241121121623_enum_strings_to_ints.go @@ -149,10 +149,10 @@ func notificationEnumMapping[T ~string]() map[T]new_gtsmodel.NotificationType { T(old_gtsmodel.NotificationFollowRequest): new_gtsmodel.NotificationFollowRequest, T(old_gtsmodel.NotificationMention): new_gtsmodel.NotificationMention, T(old_gtsmodel.NotificationReblog): new_gtsmodel.NotificationReblog, - T(old_gtsmodel.NotificationFave): new_gtsmodel.NotificationFave, + T(old_gtsmodel.NotificationFave): new_gtsmodel.NotificationFavourite, T(old_gtsmodel.NotificationPoll): new_gtsmodel.NotificationPoll, T(old_gtsmodel.NotificationStatus): new_gtsmodel.NotificationStatus, - T(old_gtsmodel.NotificationSignup): new_gtsmodel.NotificationSignup, + T(old_gtsmodel.NotificationSignup): new_gtsmodel.NotificationAdminSignup, T(old_gtsmodel.NotificationPendingFave): new_gtsmodel.NotificationPendingFave, T(old_gtsmodel.NotificationPendingReply): new_gtsmodel.NotificationPendingReply, T(old_gtsmodel.NotificationPendingReblog): new_gtsmodel.NotificationPendingReblog, diff --git a/internal/db/bundb/migrations/20241124012635_add_vapid_key_pairs.go b/internal/db/bundb/migrations/20241124012635_add_vapid_key_pairs.go new file mode 100644 index 000000000..c1a32f6be --- /dev/null +++ b/internal/db/bundb/migrations/20241124012635_add_vapid_key_pairs.go @@ -0,0 +1,51 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package migrations + +import ( + "context" + + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/uptrace/bun" +) + +func init() { + up := func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + if _, err := tx. + NewCreateTable(). + Model(>smodel.VAPIDKeyPair{}). + IfNotExists(). + Exec(ctx); err != nil { + return err + } + + return nil + }) + } + + down := func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + return nil + }) + } + + if err := Migrations.Register(up, down); err != nil { + panic(err) + } +} diff --git a/internal/db/bundb/migrations/20241124012636_add_web_push_subscriptions.go b/internal/db/bundb/migrations/20241124012636_add_web_push_subscriptions.go new file mode 100644 index 000000000..87d966903 --- /dev/null +++ b/internal/db/bundb/migrations/20241124012636_add_web_push_subscriptions.go @@ -0,0 +1,61 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package migrations + +import ( + "context" + + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/uptrace/bun" +) + +func init() { + up := func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + if _, err := tx. + NewCreateTable(). + Model(>smodel.WebPushSubscription{}). + IfNotExists(). + Exec(ctx); err != nil { + return err + } + + if _, err := tx. + NewCreateIndex(). + Model(>smodel.WebPushSubscription{}). + Index("web_push_subscriptions_account_id_idx"). + Column("account_id"). + IfNotExists(). + Exec(ctx); err != nil { + return err + } + + return nil + }) + } + + down := func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + return nil + }) + } + + if err := Migrations.Register(up, down); err != nil { + panic(err) + } +} diff --git a/internal/db/bundb/notification_test.go b/internal/db/bundb/notification_test.go index 8e2fb8031..8cc778071 100644 --- a/internal/db/bundb/notification_test.go +++ b/internal/db/bundb/notification_test.go @@ -66,7 +66,7 @@ func (suite *NotificationTestSuite) spamNotifs() { notif := >smodel.Notification{ ID: notifID, - NotificationType: gtsmodel.NotificationFave, + NotificationType: gtsmodel.NotificationFavourite, CreatedAt: time.Now(), TargetAccountID: targetAccountID, OriginAccountID: originAccountID, diff --git a/internal/db/bundb/webpush.go b/internal/db/bundb/webpush.go new file mode 100644 index 000000000..c61209573 --- /dev/null +++ b/internal/db/bundb/webpush.go @@ -0,0 +1,270 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package bundb + +import ( + "context" + "errors" + + webpushgo "github.com/SherClockHolmes/webpush-go" + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/state" + "github.com/superseriousbusiness/gotosocial/internal/util/xslices" + "github.com/uptrace/bun" +) + +type webPushDB struct { + db *bun.DB + state *state.State +} + +func (w *webPushDB) GetVAPIDKeyPair(ctx context.Context) (*gtsmodel.VAPIDKeyPair, error) { + var err error + + vapidKeyPair, err := w.getVAPIDKeyPair(ctx) + if err != nil { + return nil, err + } + if vapidKeyPair != nil { + return vapidKeyPair, nil + } + + // If there aren't any, generate new ones. + vapidKeyPair = >smodel.VAPIDKeyPair{} + if vapidKeyPair.Private, vapidKeyPair.Public, err = webpushgo.GenerateVAPIDKeys(); err != nil { + return nil, gtserror.Newf("error generating VAPID key pair: %w", err) + } + + // Store the keys in the database. + if _, err = w.db.NewInsert(). + Model(vapidKeyPair). + Exec(ctx); // nocollapse + err != nil { + if errors.Is(err, db.ErrAlreadyExists) { + // Multiple concurrent attempts to generate new keys, and this one didn't win. + // Get the results of the one that did. + return w.getVAPIDKeyPair(ctx) + } + return nil, err + } + + // Cache the keys. + w.state.Caches.DB.VAPIDKeyPair.Store(vapidKeyPair) + + return vapidKeyPair, nil +} + +// getVAPIDKeyPair gets an existing VAPID key pair from cache or DB. +// If there is no existing VAPID key pair, it returns nil, with no error. +func (w *webPushDB) getVAPIDKeyPair(ctx context.Context) (*gtsmodel.VAPIDKeyPair, error) { + // Look for cached keys. + vapidKeyPair := w.state.Caches.DB.VAPIDKeyPair.Load() + if vapidKeyPair != nil { + return vapidKeyPair, nil + } + + // Look for previously generated keys in the database. + vapidKeyPair = >smodel.VAPIDKeyPair{} + if err := w.db.NewSelect(). + Model(vapidKeyPair). + Limit(1). + Scan(ctx); // nocollapse + err != nil { + if errors.Is(err, db.ErrNoEntries) { + return nil, nil + } + return nil, err + } + + return vapidKeyPair, nil +} + +func (w *webPushDB) DeleteVAPIDKeyPair(ctx context.Context) error { + // Delete any existing keys. + if _, err := w.db.NewTruncateTable(). + Model((*gtsmodel.VAPIDKeyPair)(nil)). + Exec(ctx); // nocollapse + err != nil { + return err + } + + // Clear the key cache. + w.state.Caches.DB.VAPIDKeyPair.Store(nil) + + return nil +} + +func (w *webPushDB) GetWebPushSubscriptionByTokenID(ctx context.Context, tokenID string) (*gtsmodel.WebPushSubscription, error) { + subscription, err := w.state.Caches.DB.WebPushSubscription.LoadOne( + "TokenID", + func() (*gtsmodel.WebPushSubscription, error) { + var subscription gtsmodel.WebPushSubscription + err := w.db. + NewSelect(). + Model(&subscription). + Where("? = ?", bun.Ident("token_id"), tokenID). + Scan(ctx) + return &subscription, err + }, + tokenID, + ) + if err != nil { + return nil, err + } + return subscription, nil +} + +func (w *webPushDB) PutWebPushSubscription(ctx context.Context, subscription *gtsmodel.WebPushSubscription) error { + return w.state.Caches.DB.WebPushSubscription.Store(subscription, func() error { + _, err := w.db.NewInsert(). + Model(subscription). + Exec(ctx) + return err + }) +} + +func (w *webPushDB) UpdateWebPushSubscription(ctx context.Context, subscription *gtsmodel.WebPushSubscription, columns ...string) error { + // Update database. + result, err := w.db. + NewUpdate(). + Model(subscription). + Column(columns...). + Where("? = ?", bun.Ident("id"), subscription.ID). + Exec(ctx) + if err != nil { + return err + } + rowsAffected, err := result.RowsAffected() + if err != nil { + return gtserror.Newf("error getting updated row count: %w", err) + } + if rowsAffected == 0 { + return db.ErrNoEntries + } + + // Update cache. + w.state.Caches.DB.WebPushSubscription.Put(subscription) + + return nil +} + +func (w *webPushDB) DeleteWebPushSubscriptionByTokenID(ctx context.Context, tokenID string) error { + // Deleted partial model for cache invalidation. + var deleted gtsmodel.WebPushSubscription + + // Delete subscription, returning subset of columns used by invalidation hook. + if _, err := w.db.NewDelete(). + Model(&deleted). + Where("? = ?", bun.Ident("token_id"), tokenID). + Returning("?", bun.Ident("account_id")). + Exec(ctx); // nocollapse + err != nil && !errors.Is(err, db.ErrNoEntries) { + return err + } + + // Invalidate cached subscription by token ID. + w.state.Caches.DB.WebPushSubscription.Invalidate("TokenID", tokenID) + + // Call invalidate hook directly. + w.state.Caches.OnInvalidateWebPushSubscription(&deleted) + + return nil +} + +func (w *webPushDB) GetWebPushSubscriptionsByAccountID(ctx context.Context, accountID string) ([]*gtsmodel.WebPushSubscription, error) { + // Fetch IDs of all subscriptions created by this account. + subscriptionIDs, err := loadPagedIDs(&w.state.Caches.DB.WebPushSubscriptionIDs, accountID, nil, func() ([]string, error) { + // Subscription IDs not in cache. Perform DB query. + var subscriptionIDs []string + if _, err := w.db. + NewSelect(). + Model((*gtsmodel.WebPushSubscription)(nil)). + Column("id"). + Where("? = ?", bun.Ident("account_id"), accountID). + Order("id DESC"). + Exec(ctx, &subscriptionIDs); // nocollapse + err != nil && !errors.Is(err, db.ErrNoEntries) { + return nil, err + } + return subscriptionIDs, nil + }) + if err != nil { + return nil, err + } + if len(subscriptionIDs) == 0 { + return nil, nil + } + + // Get each subscription by ID from the cache or DB. + subscriptions, err := w.state.Caches.DB.WebPushSubscription.LoadIDs("ID", + subscriptionIDs, + func(uncached []string) ([]*gtsmodel.WebPushSubscription, error) { + subscriptions := make([]*gtsmodel.WebPushSubscription, 0, len(uncached)) + if err := w.db. + NewSelect(). + Model(&subscriptions). + Where("? IN (?)", bun.Ident("id"), bun.In(uncached)). + Scan(ctx); // nocollapse + err != nil { + return nil, err + } + return subscriptions, nil + }, + ) + if err != nil { + return nil, err + } + + // Put the subscription structs in the same order as the filter IDs. + xslices.OrderBy( + subscriptions, + subscriptionIDs, + func(subscription *gtsmodel.WebPushSubscription) string { + return subscription.ID + }, + ) + + return subscriptions, nil +} + +func (w *webPushDB) DeleteWebPushSubscriptionsByAccountID(ctx context.Context, accountID string) error { + // Deleted partial models for cache invalidation. + var deleted []*gtsmodel.WebPushSubscription + + // Delete subscriptions, returning subset of columns. + if _, err := w.db.NewDelete(). + Model(&deleted). + Where("? = ?", bun.Ident("account_id"), accountID). + Returning("?", bun.Ident("account_id")). + Exec(ctx); // nocollapse + err != nil && !errors.Is(err, db.ErrNoEntries) { + return err + } + + // Invalidate cached subscriptions by account ID. + w.state.Caches.DB.WebPushSubscription.Invalidate("AccountID", accountID) + + // Call invalidate hooks directly in case those entries weren't cached. + for _, subscription := range deleted { + w.state.Caches.OnInvalidateWebPushSubscription(subscription) + } + + return nil +} diff --git a/internal/db/bundb/webpush_test.go b/internal/db/bundb/webpush_test.go new file mode 100644 index 000000000..8ca83955a --- /dev/null +++ b/internal/db/bundb/webpush_test.go @@ -0,0 +1,81 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package bundb_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/suite" +) + +type WebPushTestSuite struct { + BunDBStandardTestSuite +} + +// Get the text fixture VAPID key pair. +func (suite *WebPushTestSuite) TestGetVAPIDKeyPair() { + ctx := context.Background() + + vapidKeyPair, err := suite.db.GetVAPIDKeyPair(ctx) + suite.NoError(err) + if !suite.NotNil(vapidKeyPair) { + suite.FailNow("Got a nil VAPID key pair, can't continue") + } + suite.NotEmpty(vapidKeyPair.Private) + suite.NotEmpty(vapidKeyPair.Public) + + // Get it again. It should be the same one. + vapidKeyPair2, err := suite.db.GetVAPIDKeyPair(ctx) + suite.NoError(err) + if suite.NotNil(vapidKeyPair2) { + suite.Equal(vapidKeyPair.Private, vapidKeyPair2.Private) + suite.Equal(vapidKeyPair.Public, vapidKeyPair2.Public) + } +} + +// Generate a VAPID key pair when there isn't one. +func (suite *WebPushTestSuite) TestGenerateVAPIDKeyPair() { + ctx := context.Background() + + // Delete the text fixture VAPID key pair. + if err := suite.db.DeleteVAPIDKeyPair(ctx); !suite.NoError(err) { + suite.FailNow("Test setup failed: DB error deleting fixture VAPID key pair: %v", err) + } + + // Get a new one. + vapidKeyPair, err := suite.db.GetVAPIDKeyPair(ctx) + suite.NoError(err) + if !suite.NotNil(vapidKeyPair) { + suite.FailNow("Got a nil VAPID key pair, can't continue") + } + suite.NotEmpty(vapidKeyPair.Private) + suite.NotEmpty(vapidKeyPair.Public) + + // Get it again. It should be the same one. + vapidKeyPair2, err := suite.db.GetVAPIDKeyPair(ctx) + suite.NoError(err) + if suite.NotNil(vapidKeyPair2) { + suite.Equal(vapidKeyPair.Private, vapidKeyPair2.Private) + suite.Equal(vapidKeyPair.Public, vapidKeyPair2.Public) + } +} + +func TestWebPushTestSuite(t *testing.T) { + suite.Run(t, new(WebPushTestSuite)) +} diff --git a/internal/db/db.go b/internal/db/db.go index 11dd2e507..16796ae49 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -58,5 +58,6 @@ type DB interface { Timeline User Tombstone + WebPush WorkerTask } diff --git a/internal/db/webpush.go b/internal/db/webpush.go new file mode 100644 index 000000000..22bf449de --- /dev/null +++ b/internal/db/webpush.go @@ -0,0 +1,54 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package db + +import ( + "context" + + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" +) + +// WebPush contains functions related to Web Push notifications. +type WebPush interface { + // GetVAPIDKeyPair retrieves the server's existing VAPID key pair, if there is one. + // If there isn't one, it generates a new one, stores it, and returns that. + GetVAPIDKeyPair(ctx context.Context) (*gtsmodel.VAPIDKeyPair, error) + + // DeleteVAPIDKeyPair deletes the server's VAPID key pair. + DeleteVAPIDKeyPair(ctx context.Context) error + + // GetWebPushSubscriptionByTokenID retrieves an access token's Web Push subscription. + // There may not be one, in which case an error will be returned. + GetWebPushSubscriptionByTokenID(ctx context.Context, tokenID string) (*gtsmodel.WebPushSubscription, error) + + // PutWebPushSubscription creates an access token's Web Push subscription. + PutWebPushSubscription(ctx context.Context, subscription *gtsmodel.WebPushSubscription) error + + // UpdateWebPushSubscription updates an access token's Web Push subscription. + // There may not be one, in which case an error will be returned. + UpdateWebPushSubscription(ctx context.Context, subscription *gtsmodel.WebPushSubscription, columns ...string) error + + // DeleteWebPushSubscriptionByTokenID deletes an access token's Web Push subscription, if there is one. + DeleteWebPushSubscriptionByTokenID(ctx context.Context, tokenID string) error + + // GetWebPushSubscriptionsByAccountID retrieves an account's list of Web Push subscriptions. + GetWebPushSubscriptionsByAccountID(ctx context.Context, accountID string) ([]*gtsmodel.WebPushSubscription, error) + + // DeleteWebPushSubscriptionsByAccountID deletes an account's list of Web Push subscriptions. + DeleteWebPushSubscriptionsByAccountID(ctx context.Context, accountID string) error +} diff --git a/internal/gtsmodel/notification.go b/internal/gtsmodel/notification.go index 1ef805081..d160e0883 100644 --- a/internal/gtsmodel/notification.go +++ b/internal/gtsmodel/notification.go @@ -48,13 +48,16 @@ type Notification struct { NotificationFollowRequest NotificationType = 2 // NotificationFollowRequest -- someone requested to follow you NotificationMention NotificationType = 3 // NotificationMention -- someone mentioned you in their status NotificationReblog NotificationType = 4 // NotificationReblog -- someone boosted one of your statuses - NotificationFave NotificationType = 5 // NotificationFave -- someone faved/liked one of your statuses + NotificationFavourite NotificationType = 5 // NotificationFavourite -- someone faved/liked one of your statuses NotificationPoll NotificationType = 6 // NotificationPoll -- a poll you voted in or created has ended NotificationStatus NotificationType = 7 // NotificationStatus -- someone you enabled notifications for has posted a status. - NotificationSignup NotificationType = 8 // NotificationSignup -- someone has submitted a new account sign-up to the instance. - NotificationPendingFave NotificationType = 9 // Someone has faved a status of yours, which requires approval by you. - NotificationPendingReply NotificationType = 10 // Someone has replied to a status of yours, which requires approval by you. - NotificationPendingReblog NotificationType = 11 // Someone has boosted a status of yours, which requires approval by you. + NotificationAdminSignup NotificationType = 8 // NotificationAdminSignup -- someone has submitted a new account sign-up to the instance. + NotificationPendingFave NotificationType = 9 // NotificationPendingFave -- Someone has faved a status of yours, which requires approval by you. + NotificationPendingReply NotificationType = 10 // NotificationPendingReply -- Someone has replied to a status of yours, which requires approval by you. + NotificationPendingReblog NotificationType = 11 // NotificationPendingReblog -- Someone has boosted a status of yours, which requires approval by you. + NotificationAdminReport NotificationType = 12 // NotificationAdminReport -- someone has submitted a new report to the instance. + NotificationUpdate NotificationType = 13 // NotificationUpdate -- someone has edited their status. + NotificationTypeNumValues NotificationType = 14 // NotificationTypeNumValues -- 1 + number of max notification type ) // String returns a stringified, frontend API compatible form of NotificationType. @@ -68,13 +71,13 @@ func (t NotificationType) String() string { return "mention" case NotificationReblog: return "reblog" - case NotificationFave: + case NotificationFavourite: return "favourite" case NotificationPoll: return "poll" case NotificationStatus: return "status" - case NotificationSignup: + case NotificationAdminSignup: return "admin.sign_up" case NotificationPendingFave: return "pending.favourite" @@ -82,6 +85,10 @@ func (t NotificationType) String() string { return "pending.reply" case NotificationPendingReblog: return "pending.reblog" + case NotificationAdminReport: + return "admin.report" + case NotificationUpdate: + return "update" default: panic("invalid notification type") } @@ -99,19 +106,23 @@ func ParseNotificationType(in string) NotificationType { case "reblog": return NotificationReblog case "favourite": - return NotificationFave + return NotificationFavourite case "poll": return NotificationPoll case "status": return NotificationStatus case "admin.sign_up": - return NotificationSignup + return NotificationAdminSignup case "pending.favourite": return NotificationPendingFave case "pending.reply": return NotificationPendingReply case "pending.reblog": return NotificationPendingReblog + case "admin.report": + return NotificationAdminReport + case "update": + return NotificationUpdate default: return NotificationUnknown } diff --git a/internal/gtsmodel/vapidkeypair.go b/internal/gtsmodel/vapidkeypair.go new file mode 100644 index 000000000..56b7edda8 --- /dev/null +++ b/internal/gtsmodel/vapidkeypair.go @@ -0,0 +1,28 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package gtsmodel + +// VAPIDKeyPair represents the instance's VAPID keys (stored as Base64 strings). +// This table should only ever have one entry, with a known ID of 0. +// +// See: https://datatracker.ietf.org/doc/html/rfc8292 +type VAPIDKeyPair struct { + ID int `bun:",pk,notnull"` + Public string `bun:",notnull,nullzero"` + Private string `bun:",notnull,nullzero"` +} diff --git a/internal/gtsmodel/webpushsubscription.go b/internal/gtsmodel/webpushsubscription.go new file mode 100644 index 000000000..4aeef654a --- /dev/null +++ b/internal/gtsmodel/webpushsubscription.go @@ -0,0 +1,82 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package gtsmodel + +// WebPushSubscription represents an access token's Web Push subscription. +// There can be at most one per access token. +type WebPushSubscription struct { + // ID of this subscription in the database. + ID string `bun:"type:CHAR(26),pk,nullzero"` + + // AccountID of the local account that created this subscription. + AccountID string `bun:"type:CHAR(26),nullzero,notnull"` + + // TokenID is the ID of the associated access token. + // There can be at most one subscription for any given access token, + TokenID string `bun:"type:CHAR(26),nullzero,notnull,unique"` + + // Endpoint is the URL receiving Web Push notifications for this subscription. + Endpoint string `bun:",nullzero,notnull"` + + // Auth is a Base64-encoded authentication secret. + Auth string `bun:",nullzero,notnull"` + + // P256dh is a Base64-encoded Diffie-Hellman public key on the P-256 elliptic curve. + P256dh string `bun:",nullzero,notnull"` + + // NotificationFlags controls which notifications are delivered to a given subscription. + // Corresponds to model.PushSubscriptionAlerts. + NotificationFlags WebPushSubscriptionNotificationFlags `bun:",notnull"` +} + +// WebPushSubscriptionNotificationFlags is a bitfield representation of a set of NotificationType. +type WebPushSubscriptionNotificationFlags int64 + +// WebPushSubscriptionNotificationFlagsFromSlice packs a slice of NotificationType into a WebPushSubscriptionNotificationFlags. +func WebPushSubscriptionNotificationFlagsFromSlice(notificationTypes []NotificationType) WebPushSubscriptionNotificationFlags { + var n WebPushSubscriptionNotificationFlags + for _, notificationType := range notificationTypes { + n.Set(notificationType, true) + } + return n +} + +// ToSlice unpacks a WebPushSubscriptionNotificationFlags into a slice of NotificationType. +func (n *WebPushSubscriptionNotificationFlags) ToSlice() []NotificationType { + notificationTypes := make([]NotificationType, 0, NotificationTypeNumValues) + for notificationType := NotificationUnknown; notificationType < NotificationTypeNumValues; notificationType++ { + if n.Get(notificationType) { + notificationTypes = append(notificationTypes, notificationType) + } + } + return notificationTypes +} + +// Get tests to see if a given NotificationType is included in this set of flags. +func (n *WebPushSubscriptionNotificationFlags) Get(notificationType NotificationType) bool { + return *n&(1<. + +package push + +import ( + "context" + + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/id" +) + +// CreateOrReplace creates a Web Push subscription for the given access token, +// or entirely replaces the previously existing subscription for that token. +func (p *Processor) CreateOrReplace( + ctx context.Context, + accountID string, + accessToken string, + request *apimodel.WebPushSubscriptionCreateRequest, +) (*apimodel.WebPushSubscription, gtserror.WithCode) { + tokenID, errWithCode := p.getTokenID(ctx, accessToken) + if errWithCode != nil { + return nil, errWithCode + } + + // Clear any previous subscription. + if err := p.state.DB.DeleteWebPushSubscriptionByTokenID(ctx, tokenID); err != nil { + err := gtserror.Newf("couldn't delete Web Push subscription for token ID %s: %w", tokenID, err) + return nil, gtserror.NewErrorInternalError(err) + } + + // Insert a new one. + subscription := >smodel.WebPushSubscription{ + ID: id.NewULID(), + AccountID: accountID, + TokenID: tokenID, + Endpoint: request.Subscription.Endpoint, + Auth: request.Subscription.Keys.Auth, + P256dh: request.Subscription.Keys.P256dh, + NotificationFlags: alertsToNotificationFlags(request.Data.Alerts), + } + + if err := p.state.DB.PutWebPushSubscription(ctx, subscription); err != nil { + err := gtserror.Newf("couldn't create Web Push subscription for token ID %s: %w", tokenID, err) + return nil, gtserror.NewErrorInternalError(err) + } + + return p.apiSubscription(ctx, subscription) +} diff --git a/internal/processing/push/delete.go b/internal/processing/push/delete.go new file mode 100644 index 000000000..6f5c61444 --- /dev/null +++ b/internal/processing/push/delete.go @@ -0,0 +1,39 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push + +import ( + "context" + + "github.com/superseriousbusiness/gotosocial/internal/gtserror" +) + +// Delete deletes the Web Push subscription for the given access token, if there is one. +func (p *Processor) Delete(ctx context.Context, accessToken string) gtserror.WithCode { + tokenID, errWithCode := p.getTokenID(ctx, accessToken) + if errWithCode != nil { + return errWithCode + } + + if err := p.state.DB.DeleteWebPushSubscriptionByTokenID(ctx, tokenID); err != nil { + err := gtserror.Newf("couldn't delete Web Push subscription for token ID %s: %w", tokenID, err) + return gtserror.NewErrorInternalError(err) + } + + return nil +} diff --git a/internal/processing/push/get.go b/internal/processing/push/get.go new file mode 100644 index 000000000..542f08862 --- /dev/null +++ b/internal/processing/push/get.go @@ -0,0 +1,47 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push + +import ( + "context" + "errors" + + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" +) + +// Get returns the Web Push subscription for the given access token. +func (p *Processor) Get(ctx context.Context, accessToken string) (*apimodel.WebPushSubscription, gtserror.WithCode) { + tokenID, errWithCode := p.getTokenID(ctx, accessToken) + if errWithCode != nil { + return nil, errWithCode + } + + subscription, err := p.state.DB.GetWebPushSubscriptionByTokenID(ctx, tokenID) + if err != nil && !errors.Is(err, db.ErrNoEntries) { + err := gtserror.Newf("couldn't get Web Push subscription for token ID %s: %w", tokenID, err) + return nil, gtserror.NewErrorInternalError(err) + } + if subscription == nil { + err := errors.New("no Web Push subscription exists for this access token") + return nil, gtserror.NewErrorNotFound(err) + } + + return p.apiSubscription(ctx, subscription) +} diff --git a/internal/processing/push/push.go b/internal/processing/push/push.go new file mode 100644 index 000000000..f46280386 --- /dev/null +++ b/internal/processing/push/push.go @@ -0,0 +1,85 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push + +import ( + "context" + + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/state" + "github.com/superseriousbusiness/gotosocial/internal/typeutils" +) + +type Processor struct { + state *state.State + converter *typeutils.Converter +} + +func New(state *state.State, converter *typeutils.Converter) Processor { + return Processor{ + state: state, + converter: converter, + } +} + +// getTokenID returns the token ID for a given access token. +// Since all push API calls require authentication, this should always be available. +func (p *Processor) getTokenID(ctx context.Context, accessToken string) (string, gtserror.WithCode) { + token, err := p.state.DB.GetTokenByAccess(ctx, accessToken) + if err != nil { + err := gtserror.Newf("couldn't find token ID for access token: %w", err) + return "", gtserror.NewErrorInternalError(err) + } + + return token.ID, nil +} + +// apiSubscription is a shortcut to return the API version of the given Web Push subscription, +// or return an appropriate error if conversion fails. +func (p *Processor) apiSubscription(ctx context.Context, subscription *gtsmodel.WebPushSubscription) (*apimodel.WebPushSubscription, gtserror.WithCode) { + apiSubscription, err := p.converter.WebPushSubscriptionToAPIWebPushSubscription(ctx, subscription) + if err != nil { + err := gtserror.Newf("error converting Web Push subscription %s to API representation: %w", subscription.ID, err) + return nil, gtserror.NewErrorInternalError(err) + } + + return apiSubscription, nil +} + +// alertsToNotificationFlags turns the alerts section of a push subscription API request into a packed bitfield. +func alertsToNotificationFlags(alerts *apimodel.WebPushSubscriptionAlerts) gtsmodel.WebPushSubscriptionNotificationFlags { + var n gtsmodel.WebPushSubscriptionNotificationFlags + + n.Set(gtsmodel.NotificationFollow, alerts.Follow) + n.Set(gtsmodel.NotificationFollowRequest, alerts.FollowRequest) + n.Set(gtsmodel.NotificationFavourite, alerts.Favourite) + n.Set(gtsmodel.NotificationMention, alerts.Mention) + n.Set(gtsmodel.NotificationReblog, alerts.Reblog) + n.Set(gtsmodel.NotificationPoll, alerts.Poll) + n.Set(gtsmodel.NotificationStatus, alerts.Status) + n.Set(gtsmodel.NotificationUpdate, alerts.Update) + n.Set(gtsmodel.NotificationAdminSignup, alerts.AdminSignup) + n.Set(gtsmodel.NotificationAdminReport, alerts.AdminReport) + n.Set(gtsmodel.NotificationPendingFave, alerts.PendingFavourite) + n.Set(gtsmodel.NotificationPendingReply, alerts.PendingReply) + n.Set(gtsmodel.NotificationPendingReblog, alerts.PendingReblog) + + return n +} diff --git a/internal/processing/push/update.go b/internal/processing/push/update.go new file mode 100644 index 000000000..370536f9b --- /dev/null +++ b/internal/processing/push/update.go @@ -0,0 +1,63 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package push + +import ( + "context" + "errors" + + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" +) + +// Update updates the Web Push subscription for the given access token. +func (p *Processor) Update( + ctx context.Context, + accessToken string, + request *apimodel.WebPushSubscriptionUpdateRequest, +) (*apimodel.WebPushSubscription, gtserror.WithCode) { + tokenID, errWithCode := p.getTokenID(ctx, accessToken) + if errWithCode != nil { + return nil, errWithCode + } + + // Get existing subscription. + subscription, err := p.state.DB.GetWebPushSubscriptionByTokenID(ctx, tokenID) + if err != nil && !errors.Is(err, db.ErrNoEntries) { + err := gtserror.Newf("couldn't get Web Push subscription for token ID %s: %w", tokenID, err) + return nil, gtserror.NewErrorInternalError(err) + } + if subscription == nil { + err := errors.New("no Web Push subscription exists for this access token") + return nil, gtserror.NewErrorNotFound(err) + } + + // Update it. + subscription.NotificationFlags = alertsToNotificationFlags(request.Data.Alerts) + if err = p.state.DB.UpdateWebPushSubscription( + ctx, + subscription, + "notification_flags", + ); err != nil { + err := gtserror.Newf("couldn't update Web Push subscription for token ID %s: %w", tokenID, err) + return nil, gtserror.NewErrorInternalError(err) + } + + return p.apiSubscription(ctx, subscription) +} diff --git a/internal/processing/timeline/notification.go b/internal/processing/timeline/notification.go index a242c7b74..09636e7eb 100644 --- a/internal/processing/timeline/notification.go +++ b/internal/processing/timeline/notification.go @@ -184,7 +184,7 @@ func (p *Processor) notifVisible( // If this is a new local account sign-up, // skip normal visibility checking because // origin account won't be confirmed yet. - if n.NotificationType == gtsmodel.NotificationSignup { + if n.NotificationType == gtsmodel.NotificationAdminSignup { return true, nil } diff --git a/internal/processing/workers/fromclientapi_test.go b/internal/processing/workers/fromclientapi_test.go index d955f0529..acb25673d 100644 --- a/internal/processing/workers/fromclientapi_test.go +++ b/internal/processing/workers/fromclientapi_test.go @@ -179,6 +179,28 @@ func (suite *FromClientAPITestSuite) checkStreamed( } } +// checkWebPushed asserts that the target account got a single Web Push notification with a given type. +func (suite *FromClientAPITestSuite) checkWebPushed( + sender *testrig.WebPushMockSender, + accountID string, + notificationType gtsmodel.NotificationType, +) { + pushedNotifications := sender.Sent[accountID] + if suite.Len(pushedNotifications, 1) { + pushedNotification := pushedNotifications[0] + suite.Equal(notificationType, pushedNotification.NotificationType) + } +} + +// checkNotWebPushed asserts that the target account got no Web Push notifications. +func (suite *FromClientAPITestSuite) checkNotWebPushed( + sender *testrig.WebPushMockSender, + accountID string, +) { + pushedNotifications := sender.Sent[accountID] + suite.Len(pushedNotifications, 0) +} + func (suite *FromClientAPITestSuite) statusJSON( ctx context.Context, typeConverter *typeutils.Converter, @@ -341,6 +363,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWithNotification() { string(notifJSON), stream.EventTypeNotification, ) + + // Check for a Web Push status notification. + suite.checkWebPushed(testStructs.WebPushSender, receivingAccount.ID, gtsmodel.NotificationStatus) } func (suite *FromClientAPITestSuite) TestProcessCreateStatusReply() { @@ -409,6 +434,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusReply() { statusJSON, stream.EventTypeUpdate, ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } func (suite *FromClientAPITestSuite) TestProcessCreateStatusReplyMuted() { @@ -470,6 +498,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusReplyMuted() { suite.ErrorIs(err, db.ErrNoEntries) suite.Nil(notif) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } func (suite *FromClientAPITestSuite) TestProcessCreateStatusBoostMuted() { @@ -531,6 +562,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusBoostMuted() { suite.ErrorIs(err, db.ErrNoEntries) suite.Nil(notif) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } func (suite *FromClientAPITestSuite) TestProcessCreateStatusListRepliesPolicyListOnlyOK() { @@ -607,6 +641,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusListRepliesPolicyLis statusJSON, stream.EventTypeUpdate, ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } func (suite *FromClientAPITestSuite) TestProcessCreateStatusListRepliesPolicyListOnlyNo() { @@ -689,6 +726,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusListRepliesPolicyLis "", "", ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } func (suite *FromClientAPITestSuite) TestProcessCreateStatusReplyListRepliesPolicyNone() { @@ -765,6 +805,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusReplyListRepliesPoli "", "", ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } func (suite *FromClientAPITestSuite) TestProcessCreateStatusBoost() { @@ -829,6 +872,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusBoost() { statusJSON, stream.EventTypeUpdate, ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } func (suite *FromClientAPITestSuite) TestProcessCreateStatusBoostNoReblogs() { @@ -981,6 +1027,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWhichBeginsConversat conversationJSON, stream.EventTypeConversation, ) + + // Check for a Web Push mention notification. + suite.checkWebPushed(testStructs.WebPushSender, receivingAccount.ID, gtsmodel.NotificationMention) } // A public message to a local user should not result in a conversation notification. @@ -1050,6 +1099,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWhichShouldNotCreate "", "", ) + + // Check for a Web Push mention notification. + suite.checkWebPushed(testStructs.WebPushSender, receivingAccount.ID, gtsmodel.NotificationMention) } // A public status with a hashtag followed by a local user who does not otherwise follow the author @@ -1123,6 +1175,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWithFollowedHashtag( "", stream.EventTypeUpdate, ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } // A public status with a hashtag followed by a local user who does not otherwise follow the author @@ -1204,6 +1259,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWithFollowedHashtagA "", "", ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } // A boost of a public status with a hashtag followed by a local user @@ -1306,6 +1364,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateBoostWithFollowedHashtag() "", stream.EventTypeUpdate, ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } // A boost of a public status with a hashtag followed by a local user @@ -1416,6 +1477,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateBoostWithFollowedHashtagAn "", "", ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } // A boost of a public status with a hashtag followed by a local user @@ -1526,6 +1590,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateBoostWithFollowedHashtagAn "", "", ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } // A public status with a hashtag followed by a local user who follows the author and has them on an exclusive list @@ -1598,6 +1665,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWithAuthorOnExclusiv "", "", ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } // A public status with a hashtag followed by a local user who follows the author and has them on an exclusive list @@ -1712,6 +1782,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWithAuthorOnExclusiv "", "", ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } // A public status with a hashtag followed by a local user who follows the author and has them on an exclusive list @@ -1837,6 +1910,9 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusWithAuthorOnExclusiv "", "", ) + + // Check for a Web Push status notification. + suite.checkWebPushed(testStructs.WebPushSender, receivingAccount.ID, gtsmodel.NotificationStatus) } // Updating a public status with a hashtag followed by a local user who does not otherwise follow the author @@ -1910,6 +1986,9 @@ func (suite *FromClientAPITestSuite) TestProcessUpdateStatusWithFollowedHashtag( "", stream.EventTypeStatusUpdate, ) + + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) } func (suite *FromClientAPITestSuite) TestProcessStatusDelete() { @@ -1963,6 +2042,9 @@ func (suite *FromClientAPITestSuite) TestProcessStatusDelete() { stream.EventTypeDelete, ) + // Check for absence of Web Push notifications. + suite.checkNotWebPushed(testStructs.WebPushSender, receivingAccount.ID) + // Boost should no longer be in the database. if !testrig.WaitFor(func() bool { _, err := testStructs.State.DB.GetStatusByID(ctx, boostOfDeletedStatus.ID) diff --git a/internal/processing/workers/fromfediapi_test.go b/internal/processing/workers/fromfediapi_test.go index 88d0e6071..70886d698 100644 --- a/internal/processing/workers/fromfediapi_test.go +++ b/internal/processing/workers/fromfediapi_test.go @@ -240,7 +240,7 @@ func (suite *FromFediAPITestSuite) TestProcessFave() { notif := >smodel.Notification{} err = testStructs.State.DB.GetWhere(context.Background(), where, notif) suite.NoError(err) - suite.Equal(gtsmodel.NotificationFave, notif.NotificationType) + suite.Equal(gtsmodel.NotificationFavourite, notif.NotificationType) suite.Equal(fave.TargetAccountID, notif.TargetAccountID) suite.Equal(fave.AccountID, notif.OriginAccountID) suite.Equal(fave.StatusID, notif.StatusID) @@ -313,7 +313,7 @@ func (suite *FromFediAPITestSuite) TestProcessFaveWithDifferentReceivingAccount( notif := >smodel.Notification{} err = testStructs.State.DB.GetWhere(context.Background(), where, notif) suite.NoError(err) - suite.Equal(gtsmodel.NotificationFave, notif.NotificationType) + suite.Equal(gtsmodel.NotificationFavourite, notif.NotificationType) suite.Equal(fave.TargetAccountID, notif.TargetAccountID) suite.Equal(fave.AccountID, notif.OriginAccountID) suite.Equal(fave.StatusID, notif.StatusID) diff --git a/internal/processing/workers/surface.go b/internal/processing/workers/surface.go index 4f6597b9a..4dc58c433 100644 --- a/internal/processing/workers/surface.go +++ b/internal/processing/workers/surface.go @@ -24,6 +24,7 @@ "github.com/superseriousbusiness/gotosocial/internal/processing/stream" "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/superseriousbusiness/gotosocial/internal/typeutils" + "github.com/superseriousbusiness/gotosocial/internal/webpush" ) // Surface wraps functions for 'surfacing' the result @@ -38,5 +39,6 @@ type Surface struct { Stream *stream.Processor VisFilter *visibility.Filter EmailSender email.Sender + WebPushSender webpush.Sender Conversations *conversations.Processor } diff --git a/internal/processing/workers/surfacenotify.go b/internal/processing/workers/surfacenotify.go index 1520d2ec0..fdbd5e3c1 100644 --- a/internal/processing/workers/surfacenotify.go +++ b/internal/processing/workers/surfacenotify.go @@ -250,7 +250,7 @@ func (s *Surface) notifyFave( // notify status author // of fave by account. if err := s.Notify(ctx, - gtsmodel.NotificationFave, + gtsmodel.NotificationFavourite, fave.TargetAccount, fave.Account, fave.StatusID, @@ -521,7 +521,7 @@ func (s *Surface) notifySignup(ctx context.Context, newUser *gtsmodel.User) erro var errs gtserror.MultiError for _, mod := range modAccounts { if err := s.Notify(ctx, - gtsmodel.NotificationSignup, + gtsmodel.NotificationAdminSignup, mod, newUser.Account, "", @@ -647,5 +647,10 @@ func (s *Surface) Notify( } s.Stream.Notify(ctx, targetAccount, apiNotif) + // Send Web Push notification to the user. + if err = s.WebPushSender.Send(ctx, notif, filters, compiledMutes); err != nil { + return gtserror.Newf("error sending Web Push notifications: %w", err) + } + return nil } diff --git a/internal/processing/workers/surfacenotify_test.go b/internal/processing/workers/surfacenotify_test.go index 52ee89e8b..6444314e2 100644 --- a/internal/processing/workers/surfacenotify_test.go +++ b/internal/processing/workers/surfacenotify_test.go @@ -45,6 +45,7 @@ func (suite *SurfaceNotifyTestSuite) TestSpamNotifs() { Stream: testStructs.Processor.Stream(), VisFilter: visibility.NewFilter(testStructs.State), EmailSender: testStructs.EmailSender, + WebPushSender: testStructs.WebPushSender, Conversations: testStructs.Processor.Conversations(), } diff --git a/internal/processing/workers/workers.go b/internal/processing/workers/workers.go index ad673481b..9f37f554e 100644 --- a/internal/processing/workers/workers.go +++ b/internal/processing/workers/workers.go @@ -28,6 +28,7 @@ "github.com/superseriousbusiness/gotosocial/internal/processing/stream" "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/superseriousbusiness/gotosocial/internal/typeutils" + "github.com/superseriousbusiness/gotosocial/internal/webpush" "github.com/superseriousbusiness/gotosocial/internal/workers" ) @@ -44,6 +45,7 @@ func New( converter *typeutils.Converter, visFilter *visibility.Filter, emailSender email.Sender, + webPushSender webpush.Sender, account *account.Processor, media *media.Processor, stream *stream.Processor, @@ -65,6 +67,7 @@ func New( Stream: stream, VisFilter: visFilter, EmailSender: emailSender, + WebPushSender: webPushSender, Conversations: conversations, } diff --git a/internal/text/substring.go b/internal/text/substring.go new file mode 100644 index 000000000..659b4ab50 --- /dev/null +++ b/internal/text/substring.go @@ -0,0 +1,45 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package text + +import ( + "github.com/rivo/uniseg" +) + +// FirstNBytesByWords produces a prefix substring of up to n bytes from a given string, respecting Unicode grapheme and +// word boundaries. The substring may be empty, and may include leading or trailing whitespace. +func FirstNBytesByWords(s string, n int) string { + substringEnd := 0 + + graphemes := uniseg.NewGraphemes(s) + for graphemes.Next() { + + if !graphemes.IsWordBoundary() { + continue + } + + _, end := graphemes.Positions() + if end > n { + break + } + + substringEnd = end + } + + return s[0:substringEnd] +} diff --git a/internal/text/substring_test.go b/internal/text/substring_test.go new file mode 100644 index 000000000..f85688218 --- /dev/null +++ b/internal/text/substring_test.go @@ -0,0 +1,47 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package text_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + "github.com/superseriousbusiness/gotosocial/internal/text" +) + +type SubstringTestSuite struct { + suite.Suite +} + +func (suite *SubstringTestSuite) TestText() { + suite.Equal( + "Sphinx of black quartz, ", + text.FirstNBytesByWords("Sphinx of black quartz, judge my vow!", 25), + ) +} + +func (suite *SubstringTestSuite) TestEmoji() { + suite.Equal( + "🏳️‍⚧️ ", + text.FirstNBytesByWords("🏳️‍⚧️ 🙈", 20), + ) +} + +func TestSubstringTestSuite(t *testing.T) { + suite.Run(t, new(SubstringTestSuite)) +} diff --git a/internal/transport/transport_test.go b/internal/transport/transport_test.go index c51c0755f..61df16e52 100644 --- a/internal/transport/transport_test.go +++ b/internal/transport/transport_test.go @@ -89,7 +89,13 @@ func (suite *TransportTestSuite) SetupTest() { suite.federator = testrig.NewTestFederator(&suite.state, testrig.NewTestTransportController(&suite.state, testrig.NewMockHTTPClient(nil, "../../testrig/media")), suite.mediaManager) suite.sentEmails = make(map[string]string) suite.emailSender = testrig.NewEmailSender("../../web/template/", suite.sentEmails) - suite.processor = testrig.NewTestProcessor(&suite.state, suite.federator, suite.emailSender, suite.mediaManager) + suite.processor = testrig.NewTestProcessor( + &suite.state, + suite.federator, + suite.emailSender, + testrig.NewNoopWebPushSender(), + suite.mediaManager, + ) testrig.StandardDBSetup(suite.db, nil) testrig.StandardStorageSetup(suite.storage, "../../testrig/media") diff --git a/internal/typeutils/converter_test.go b/internal/typeutils/converter_test.go index a5fe5201b..3ed2828f2 100644 --- a/internal/typeutils/converter_test.go +++ b/internal/typeutils/converter_test.go @@ -540,8 +540,9 @@ func (suite *TypeUtilsTestSuite) GetProcessor() *processing.Processor { mediaManager := testrig.NewTestMediaManager(&suite.state) federator := testrig.NewTestFederator(&suite.state, transportController, mediaManager) emailSender := testrig.NewEmailSender("../../web/template/", nil) + webPushSender := testrig.NewNoopWebPushSender() - processor := testrig.NewTestProcessor(&suite.state, federator, emailSender, mediaManager) + processor := testrig.NewTestProcessor(&suite.state, federator, emailSender, webPushSender, mediaManager) testrig.StartWorkers(&suite.state, processor.Workers()) return processor diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go index cdc250f98..6739d0540 100644 --- a/internal/typeutils/internaltofrontend.go +++ b/internal/typeutils/internaltofrontend.go @@ -616,6 +616,11 @@ func (c *Converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Ac } func (c *Converter) AppToAPIAppSensitive(ctx context.Context, a *gtsmodel.Application) (*apimodel.Application, error) { + vapidKeyPair, err := c.state.DB.GetVAPIDKeyPair(ctx) + if err != nil { + return nil, gtserror.Newf("error getting VAPID public key: %w", err) + } + return &apimodel.Application{ ID: a.ID, Name: a.Name, @@ -623,6 +628,7 @@ func (c *Converter) AppToAPIAppSensitive(ctx context.Context, a *gtsmodel.Applic RedirectURI: a.RedirectURI, ClientID: a.ClientID, ClientSecret: a.ClientSecret, + VapidKey: vapidKeyPair.Public, }, nil } @@ -1878,6 +1884,12 @@ func (c *Converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins instance.Configuration.Emojis.EmojiSizeLimit = int(config.GetMediaEmojiLocalMaxSize()) // #nosec G115 -- Already validated. instance.Configuration.OIDCEnabled = config.GetOIDCEnabled() + vapidKeyPair, err := c.state.DB.GetVAPIDKeyPair(ctx) + if err != nil { + return nil, gtserror.Newf("error getting VAPID public key: %w", err) + } + instance.Configuration.VAPID.PublicKey = vapidKeyPair.Public + // registrations instance.Registrations.Enabled = config.GetAccountsRegistrationOpen() instance.Registrations.ApprovalRequired = true // always required @@ -2985,3 +2997,36 @@ func (c *Converter) InteractionReqToAPIInteractionReq( URI: req.URI, }, nil } + +func (c *Converter) WebPushSubscriptionToAPIWebPushSubscription( + ctx context.Context, + subscription *gtsmodel.WebPushSubscription, +) (*apimodel.WebPushSubscription, error) { + vapidKeyPair, err := c.state.DB.GetVAPIDKeyPair(ctx) + if err != nil { + return nil, gtserror.Newf("error getting VAPID key pair: %w", err) + } + + return &apimodel.WebPushSubscription{ + ID: subscription.ID, + Endpoint: subscription.Endpoint, + ServerKey: vapidKeyPair.Public, + Alerts: apimodel.WebPushSubscriptionAlerts{ + Follow: subscription.NotificationFlags.Get(gtsmodel.NotificationFollow), + FollowRequest: subscription.NotificationFlags.Get(gtsmodel.NotificationFollowRequest), + Favourite: subscription.NotificationFlags.Get(gtsmodel.NotificationFavourite), + Mention: subscription.NotificationFlags.Get(gtsmodel.NotificationMention), + Reblog: subscription.NotificationFlags.Get(gtsmodel.NotificationReblog), + Poll: subscription.NotificationFlags.Get(gtsmodel.NotificationPoll), + Status: subscription.NotificationFlags.Get(gtsmodel.NotificationStatus), + Update: subscription.NotificationFlags.Get(gtsmodel.NotificationUpdate), + AdminSignup: subscription.NotificationFlags.Get(gtsmodel.NotificationAdminSignup), + AdminReport: subscription.NotificationFlags.Get(gtsmodel.NotificationAdminReport), + PendingFavourite: subscription.NotificationFlags.Get(gtsmodel.NotificationPendingFave), + PendingReply: subscription.NotificationFlags.Get(gtsmodel.NotificationPendingReply), + PendingReblog: subscription.NotificationFlags.Get(gtsmodel.NotificationPendingReblog), + }, + Policy: apimodel.WebPushNotificationPolicyAll, + Standard: true, + }, nil +} diff --git a/internal/typeutils/internaltofrontend_test.go b/internal/typeutils/internaltofrontend_test.go index 005abf4eb..1ca0840a5 100644 --- a/internal/typeutils/internaltofrontend_test.go +++ b/internal/typeutils/internaltofrontend_test.go @@ -21,6 +21,7 @@ "bytes" "context" "encoding/json" + "strings" "testing" "github.com/stretchr/testify/suite" @@ -2061,6 +2062,13 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV2ToFrontend() { b, err := json.MarshalIndent(instance, "", " ") suite.NoError(err) + // The VAPID public key changes from run to run. + vapidKeyPair, err := suite.db.GetVAPIDKeyPair(ctx) + if err != nil { + suite.FailNow(err.Error()) + } + s := strings.Replace(string(b), vapidKeyPair.Public, "VAPID_PUBLIC_KEY_PLACEHOLDER", 1) + suite.Equal(`{ "domain": "localhost:8080", "account_domain": "localhost:8080", @@ -2140,6 +2148,9 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV2ToFrontend() { }, "emojis": { "emoji_size_limit": 51200 + }, + "vapid": { + "public_key": "VAPID_PUBLIC_KEY_PLACEHOLDER" } }, "registrations": { @@ -2184,7 +2195,7 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV2ToFrontend() { "rules": [], "terms": "\u003cp\u003eThis is where a list of terms and conditions might go.\u003c/p\u003e\u003cp\u003eFor example:\u003c/p\u003e\u003cp\u003eIf you want to sign up on this instance, you oughta know that we:\u003c/p\u003e\u003col\u003e\u003cli\u003eWill sell your data to whoever offers.\u003c/li\u003e\u003cli\u003eSecure the server with password \u003ccode\u003epassword\u003c/code\u003e wherever possible.\u003c/li\u003e\u003c/ol\u003e", "terms_text": "This is where a list of terms and conditions might go.\n\nFor example:\n\nIf you want to sign up on this instance, you oughta know that we:\n\n1. Will sell your data to whoever offers.\n2. Secure the server with password `+"`"+`password`+"`"+` wherever possible." -}`, string(b)) +}`, s) } func (suite *InternalToFrontendTestSuite) TestEmojiToFrontend() { diff --git a/internal/webpush/realsender.go b/internal/webpush/realsender.go new file mode 100644 index 000000000..8b3a1bd66 --- /dev/null +++ b/internal/webpush/realsender.go @@ -0,0 +1,341 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package webpush + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "slices" + "strings" + "time" + + webpushgo "github.com/SherClockHolmes/webpush-go" + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/filter/usermute" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/httpclient" + "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" + "github.com/superseriousbusiness/gotosocial/internal/text" + "github.com/superseriousbusiness/gotosocial/internal/typeutils" +) + +// realSender is the production Web Push sender, backed by an HTTP client, DB, and worker pool. +type realSender struct { + httpClient *http.Client + state *state.State + converter *typeutils.Converter +} + +// NewRealSender creates a Sender from an http.Client instead of an httpclient.Client. +// This should only be used by NewSender and in tests. +func NewRealSender(httpClient *http.Client, state *state.State, converter *typeutils.Converter) Sender { + return &realSender{ + httpClient: httpClient, + state: state, + converter: converter, + } +} + +func (r *realSender) Send( + ctx context.Context, + notification *gtsmodel.Notification, + filters []*gtsmodel.Filter, + mutes *usermute.CompiledUserMuteList, +) error { + // Load subscriptions. + subscriptions, err := r.state.DB.GetWebPushSubscriptionsByAccountID(ctx, notification.TargetAccountID) + if err != nil { + return gtserror.Newf( + "error getting Web Push subscriptions for account %s: %w", + notification.TargetAccountID, + err, + ) + } + + // Subscriptions we're actually going to send to. + relevantSubscriptions := slices.DeleteFunc( + subscriptions, + func(subscription *gtsmodel.WebPushSubscription) bool { + // Remove subscriptions that don't want this type of notification. + return !subscription.NotificationFlags.Get(notification.NotificationType) + }, + ) + if len(relevantSubscriptions) == 0 { + return nil + } + + // Get VAPID keys. + vapidKeyPair, err := r.state.DB.GetVAPIDKeyPair(ctx) + if err != nil { + return gtserror.Newf("error getting VAPID key pair: %w", err) + } + + // Get contact email for this instance, if available. + domain := config.GetHost() + instance, err := r.state.DB.GetInstance(ctx, domain) + if err != nil { + return gtserror.Newf("error getting current instance: %w", err) + } + vapidSubjectEmail := instance.ContactEmail + if vapidSubjectEmail == "" { + // Instance contact email not configured. Use a dummy address. + vapidSubjectEmail = "admin@" + domain + } + + // Get target account settings. + targetAccountSettings, err := r.state.DB.GetAccountSettings(ctx, notification.TargetAccountID) + if err != nil { + return gtserror.Newf("error getting settings for account %s: %w", notification.TargetAccountID, err) + } + + // Get API representations of notification and accounts involved. + apiNotification, err := r.converter.NotificationToAPINotification(ctx, notification, filters, mutes) + if err != nil { + return gtserror.Newf("error converting notification %s to API representation: %w", notification.ID, err) + } + + // Queue up a .Send() call for each relevant subscription. + for _, subscription := range relevantSubscriptions { + r.state.Workers.WebPush.Queue.Push(func(ctx context.Context) { + if err := r.sendToSubscription( + ctx, + vapidKeyPair, + vapidSubjectEmail, + targetAccountSettings, + subscription, + notification, + apiNotification, + ); err != nil { + log.Errorf( + ctx, + "error sending Web Push notification for subscription with token ID %s: %v", + subscription.TokenID, + err, + ) + } + }) + } + + return nil +} + +// sendToSubscription sends a notification to a single Web Push subscription. +func (r *realSender) sendToSubscription( + ctx context.Context, + vapidKeyPair *gtsmodel.VAPIDKeyPair, + vapidSubjectEmail string, + targetAccountSettings *gtsmodel.AccountSettings, + subscription *gtsmodel.WebPushSubscription, + notification *gtsmodel.Notification, + apiNotification *apimodel.Notification, +) error { + const ( + // TTL is an arbitrary time to ask the Web Push server to store notifications + // while waiting for the client to retrieve them. + TTL = 48 * time.Hour + + // responseBodyMaxLen limits how much of the Web Push server response we read for error messages. + responseBodyMaxLen = 1024 + ) + + // Get the associated access token. + token, err := r.state.DB.GetTokenByID(ctx, subscription.TokenID) + if err != nil { + return gtserror.Newf("error getting token %s: %w", subscription.TokenID, err) + } + + // Create push notification payload struct. + pushNotification := &apimodel.WebPushNotification{ + NotificationID: apiNotification.ID, + NotificationType: apiNotification.Type, + Title: formatNotificationTitle(ctx, subscription, notification, apiNotification), + Body: formatNotificationBody(apiNotification), + Icon: apiNotification.Account.Avatar, + PreferredLocale: targetAccountSettings.Language, + AccessToken: token.Access, + } + + // Encode the push notification as JSON. + pushNotificationBytes, err := json.Marshal(pushNotification) + if err != nil { + return gtserror.Newf("error encoding Web Push notification: %w", err) + } + + // Send push notification. + resp, err := webpushgo.SendNotificationWithContext( + ctx, + pushNotificationBytes, + &webpushgo.Subscription{ + Endpoint: subscription.Endpoint, + Keys: webpushgo.Keys{ + Auth: subscription.Auth, + P256dh: subscription.P256dh, + }, + }, + &webpushgo.Options{ + HTTPClient: r.httpClient, + Subscriber: vapidSubjectEmail, + VAPIDPublicKey: vapidKeyPair.Public, + VAPIDPrivateKey: vapidKeyPair.Private, + TTL: int(TTL.Seconds()), + }, + ) + if err != nil { + return gtserror.Newf("error sending Web Push notification: %w", err) + } + defer resp.Body.Close() + + switch { + // All good, delivered. + case resp.StatusCode >= 200 && resp.StatusCode <= 299: + return nil + + // Temporary outage or some other delivery issue. + case resp.StatusCode == http.StatusRequestTimeout || + resp.StatusCode == http.StatusRequestEntityTooLarge || + resp.StatusCode == http.StatusTooManyRequests || + (resp.StatusCode >= 500 && resp.StatusCode <= 599): + + // Try to get the response body. + bodyBytes, err := io.ReadAll(io.LimitReader(resp.Body, responseBodyMaxLen)) + if err != nil { + return gtserror.Newf("error reading Web Push server response: %w", err) + } + + // Return the error with its response body. + return gtserror.Newf( + "unexpected HTTP status %s received when sending Web Push notification: %s", + resp.Status, + string(bodyBytes), + ) + + // Some serious error that indicates auth problems, not a Web Push server, etc. + // We should not send any more notifications to this subscription. Try to delete it. + default: + err := r.state.DB.DeleteWebPushSubscriptionByTokenID(ctx, subscription.TokenID) + if err != nil { + return gtserror.Newf( + "received HTTP status %s but failed to delete subscription: %s", + resp.Status, + err, + ) + } + + log.Infof( + ctx, + "Deleted Web Push subscription with token ID %s because push server sent HTTP status %s", + subscription.TokenID, resp.Status, + ) + return nil + } +} + +// formatNotificationTitle creates a title for a Web Push notification from the notification type and account's name. +func formatNotificationTitle( + ctx context.Context, + subscription *gtsmodel.WebPushSubscription, + notification *gtsmodel.Notification, + apiNotification *apimodel.Notification, +) string { + displayNameOrAcct := apiNotification.Account.DisplayName + if displayNameOrAcct == "" { + displayNameOrAcct = apiNotification.Account.Acct + } + + switch notification.NotificationType { + case gtsmodel.NotificationFollow: + return fmt.Sprintf("%s followed you", displayNameOrAcct) + case gtsmodel.NotificationFollowRequest: + return fmt.Sprintf("%s requested to follow you", displayNameOrAcct) + case gtsmodel.NotificationMention: + return fmt.Sprintf("%s mentioned you", displayNameOrAcct) + case gtsmodel.NotificationReblog: + return fmt.Sprintf("%s boosted your post", displayNameOrAcct) + case gtsmodel.NotificationFavourite: + return fmt.Sprintf("%s faved your post", displayNameOrAcct) + case gtsmodel.NotificationPoll: + if subscription.AccountID == notification.TargetAccountID { + return "Your poll has ended" + } else { + return fmt.Sprintf("%s's poll has ended", displayNameOrAcct) + } + case gtsmodel.NotificationStatus: + return fmt.Sprintf("%s posted", displayNameOrAcct) + case gtsmodel.NotificationAdminSignup: + return fmt.Sprintf("%s requested to sign up", displayNameOrAcct) + case gtsmodel.NotificationPendingFave: + return fmt.Sprintf("%s faved your post, which requires your approval", displayNameOrAcct) + case gtsmodel.NotificationPendingReply: + return fmt.Sprintf("%s mentioned you, which requires your approval", displayNameOrAcct) + case gtsmodel.NotificationPendingReblog: + return fmt.Sprintf("%s boosted your post, which requires your approval", displayNameOrAcct) + case gtsmodel.NotificationAdminReport: + return fmt.Sprintf("%s submitted a report", displayNameOrAcct) + case gtsmodel.NotificationUpdate: + return fmt.Sprintf("%s updated their post", displayNameOrAcct) + default: + log.Warnf(ctx, "Unknown notification type: %d", notification.NotificationType) + return fmt.Sprintf( + "%s did something (unknown notification type %d)", + displayNameOrAcct, + notification.NotificationType, + ) + } +} + +// formatNotificationBody creates a body for a Web Push notification, +// from the CW or beginning of the body text of the status, if there is one, +// or the beginning of the bio text of the related account. +func formatNotificationBody(apiNotification *apimodel.Notification) string { + // bodyMaxLen is a polite maximum length for a Web Push notification's body text, in bytes. Note that this isn't + // limited per se, but Web Push servers may reject anything with a total request body size over 4k. + const bodyMaxLen = 3000 + + var body string + if apiNotification.Status != nil { + if apiNotification.Status.SpoilerText != "" { + body = apiNotification.Status.SpoilerText + } else { + body = text.SanitizeToPlaintext(apiNotification.Status.Content) + } + } else { + body = text.SanitizeToPlaintext(apiNotification.Account.Note) + } + return firstNBytesTrimSpace(body, bodyMaxLen) +} + +// firstNBytesTrimSpace returns the first N bytes of a string, trimming leading and trailing whitespace. +func firstNBytesTrimSpace(s string, n int) string { + return strings.TrimSpace(text.FirstNBytesByWords(strings.TrimSpace(s), n)) +} + +// gtsHTTPClientRoundTripper helps wrap a GtS HTTP client back into a regular HTTP client, +// so that webpush-go can use our IP filters, bad hosts list, and retries. +type gtsHTTPClientRoundTripper struct { + httpClient *httpclient.Client +} + +func (r *gtsHTTPClientRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) { + return r.httpClient.Do(request) +} diff --git a/internal/webpush/realsender_test.go b/internal/webpush/realsender_test.go new file mode 100644 index 000000000..c94bbbb8e --- /dev/null +++ b/internal/webpush/realsender_test.go @@ -0,0 +1,263 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package webpush_test + +import ( + "context" + "io" + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/suite" + "github.com/superseriousbusiness/gotosocial/internal/cleaner" + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/email" + "github.com/superseriousbusiness/gotosocial/internal/federation" + "github.com/superseriousbusiness/gotosocial/internal/filter/interaction" + "github.com/superseriousbusiness/gotosocial/internal/filter/visibility" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/media" + "github.com/superseriousbusiness/gotosocial/internal/oauth" + "github.com/superseriousbusiness/gotosocial/internal/processing" + "github.com/superseriousbusiness/gotosocial/internal/state" + "github.com/superseriousbusiness/gotosocial/internal/storage" + "github.com/superseriousbusiness/gotosocial/internal/subscriptions" + "github.com/superseriousbusiness/gotosocial/internal/transport" + "github.com/superseriousbusiness/gotosocial/internal/typeutils" + "github.com/superseriousbusiness/gotosocial/internal/webpush" + "github.com/superseriousbusiness/gotosocial/testrig" +) + +type RealSenderStandardTestSuite struct { + suite.Suite + db db.DB + storage *storage.Driver + state state.State + mediaManager *media.Manager + typeconverter *typeutils.Converter + httpClient *testrig.MockHTTPClient + transportController transport.Controller + federator *federation.Federator + oauthServer oauth.Server + emailSender email.Sender + webPushSender webpush.Sender + + // standard suite models + testTokens map[string]*gtsmodel.Token + testClients map[string]*gtsmodel.Client + testApplications map[string]*gtsmodel.Application + testUsers map[string]*gtsmodel.User + testAccounts map[string]*gtsmodel.Account + testAttachments map[string]*gtsmodel.MediaAttachment + testStatuses map[string]*gtsmodel.Status + testTags map[string]*gtsmodel.Tag + testMentions map[string]*gtsmodel.Mention + testEmojis map[string]*gtsmodel.Emoji + testNotifications map[string]*gtsmodel.Notification + testWebPushSubscriptions map[string]*gtsmodel.WebPushSubscription + + processor *processing.Processor + + webPushHttpClientDo func(request *http.Request) (*http.Response, error) +} + +func (suite *RealSenderStandardTestSuite) SetupSuite() { + suite.testTokens = testrig.NewTestTokens() + suite.testClients = testrig.NewTestClients() + suite.testApplications = testrig.NewTestApplications() + suite.testUsers = testrig.NewTestUsers() + suite.testAccounts = testrig.NewTestAccounts() + suite.testAttachments = testrig.NewTestAttachments() + suite.testStatuses = testrig.NewTestStatuses() + suite.testTags = testrig.NewTestTags() + suite.testMentions = testrig.NewTestMentions() + suite.testEmojis = testrig.NewTestEmojis() + suite.testNotifications = testrig.NewTestNotifications() + suite.testWebPushSubscriptions = testrig.NewTestWebPushSubscriptions() +} + +func (suite *RealSenderStandardTestSuite) SetupTest() { + suite.state.Caches.Init() + + testrig.InitTestConfig() + testrig.InitTestLog() + + suite.db = testrig.NewTestDB(&suite.state) + suite.state.DB = suite.db + suite.storage = testrig.NewInMemoryStorage() + suite.state.Storage = suite.storage + suite.typeconverter = typeutils.NewConverter(&suite.state) + + testrig.StartTimelines( + &suite.state, + visibility.NewFilter(&suite.state), + suite.typeconverter, + ) + + suite.httpClient = testrig.NewMockHTTPClient(nil, "../../testrig/media") + suite.httpClient.TestRemotePeople = testrig.NewTestFediPeople() + suite.httpClient.TestRemoteStatuses = testrig.NewTestFediStatuses() + + suite.transportController = testrig.NewTestTransportController(&suite.state, suite.httpClient) + suite.mediaManager = testrig.NewTestMediaManager(&suite.state) + suite.federator = testrig.NewTestFederator(&suite.state, suite.transportController, suite.mediaManager) + suite.oauthServer = testrig.NewTestOauthServer(suite.db) + suite.emailSender = testrig.NewEmailSender("../../web/template/", nil) + + suite.webPushSender = webpush.NewRealSender( + &http.Client{ + Transport: suite, + }, + &suite.state, + suite.typeconverter, + ) + + suite.processor = processing.NewProcessor( + cleaner.New(&suite.state), + subscriptions.New( + &suite.state, + suite.transportController, + suite.typeconverter, + ), + suite.typeconverter, + suite.federator, + suite.oauthServer, + suite.mediaManager, + &suite.state, + suite.emailSender, + suite.webPushSender, + visibility.NewFilter(&suite.state), + interaction.NewFilter(&suite.state), + ) + testrig.StartWorkers(&suite.state, suite.processor.Workers()) + + testrig.StandardDBSetup(suite.db, suite.testAccounts) + testrig.StandardStorageSetup(suite.storage, "../../testrig/media") +} + +func (suite *RealSenderStandardTestSuite) TearDownTest() { + testrig.StandardDBTeardown(suite.db) + testrig.StandardStorageTeardown(suite.storage) + testrig.StopWorkers(&suite.state) + suite.webPushHttpClientDo = nil +} + +// RoundTrip implements http.RoundTripper with a closure stored in the test suite. +func (suite *RealSenderStandardTestSuite) RoundTrip(request *http.Request) (*http.Response, error) { + return suite.webPushHttpClientDo(request) +} + +// notifyingReadCloser is a zero-length io.ReadCloser that can tell us when it's been closed, +// indicating the simulated Web Push server response has been sent, received, read, and closed. +type notifyingReadCloser struct { + bodyClosed chan struct{} +} + +func (rc *notifyingReadCloser) Read(_ []byte) (n int, err error) { + return 0, io.EOF +} + +func (rc *notifyingReadCloser) Close() error { + rc.bodyClosed <- struct{}{} + close(rc.bodyClosed) + return nil +} + +// Simulate sending a push notification with the suite's fake web client. +func (suite *RealSenderStandardTestSuite) simulatePushNotification( + statusCode int, + expectDeletedSubscription bool, +) error { + // Don't let the test run forever if the push notification was not sent for some reason. + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + notification, err := suite.state.DB.GetNotificationByID(ctx, suite.testNotifications["local_account_1_like"].ID) + if !suite.NoError(err) { + suite.FailNow("Couldn't fetch notification to send") + } + + rc := ¬ifyingReadCloser{ + bodyClosed: make(chan struct{}, 1), + } + + // Simulate a response from the Web Push server. + suite.webPushHttpClientDo = func(request *http.Request) (*http.Response, error) { + return &http.Response{ + Status: http.StatusText(statusCode), + StatusCode: statusCode, + Body: rc, + }, nil + } + + // Send the push notification. + sendError := suite.webPushSender.Send(ctx, notification, nil, nil) + + // Wait for it to be sent or for the context to time out. + bodyClosed := false + contextExpired := false + select { + case <-rc.bodyClosed: + bodyClosed = true + case <-ctx.Done(): + contextExpired = true + } + suite.True(bodyClosed) + suite.False(contextExpired) + + // Look for the associated Web Push subscription. Some server responses should delete it. + subscription, err := suite.state.DB.GetWebPushSubscriptionByTokenID( + ctx, + suite.testWebPushSubscriptions["local_account_1_token_1"].TokenID, + ) + if expectDeletedSubscription { + suite.ErrorIs(err, db.ErrNoEntries) + } else { + suite.NotNil(subscription) + } + + return sendError +} + +// Test a successful response to sending a push notification. +func (suite *RealSenderStandardTestSuite) TestSendSuccess() { + suite.NoError(suite.simulatePushNotification(http.StatusOK, false)) +} + +// Test a rate-limiting response to sending a push notification. +// This should not delete the subscription. +func (suite *RealSenderStandardTestSuite) TestRateLimited() { + suite.NoError(suite.simulatePushNotification(http.StatusTooManyRequests, false)) +} + +// Test a non-special-cased client error response to sending a push notification. +// This should delete the subscription. +func (suite *RealSenderStandardTestSuite) TestClientError() { + suite.NoError(suite.simulatePushNotification(http.StatusBadRequest, true)) +} + +// Test a server error response to sending a push notification. +// This should not delete the subscription. +func (suite *RealSenderStandardTestSuite) TestServerError() { + suite.NoError(suite.simulatePushNotification(http.StatusInternalServerError, false)) +} + +func TestRealSenderStandardTestSuite(t *testing.T) { + suite.Run(t, &RealSenderStandardTestSuite{}) +} diff --git a/internal/webpush/sender.go b/internal/webpush/sender.go new file mode 100644 index 000000000..5331f049a --- /dev/null +++ b/internal/webpush/sender.go @@ -0,0 +1,54 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package webpush + +import ( + "context" + "net/http" + + "github.com/superseriousbusiness/gotosocial/internal/filter/usermute" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/httpclient" + "github.com/superseriousbusiness/gotosocial/internal/state" + "github.com/superseriousbusiness/gotosocial/internal/typeutils" +) + +// Sender can send Web Push notifications. +type Sender interface { + // Send queues up a notification for delivery to all of an account's Web Push subscriptions. + Send( + ctx context.Context, + notification *gtsmodel.Notification, + filters []*gtsmodel.Filter, + mutes *usermute.CompiledUserMuteList, + ) error +} + +// NewSender creates a new sender from an HTTP client, DB, and worker pool. +func NewSender(httpClient *httpclient.Client, state *state.State, converter *typeutils.Converter) Sender { + return NewRealSender( + &http.Client{ + Transport: >sHTTPClientRoundTripper{ + httpClient: httpClient, + }, + // Other fields are already set on the http.Client inside the httpclient.Client. + }, + state, + converter, + ) +} diff --git a/internal/workers/workers.go b/internal/workers/workers.go index 4cf549041..50ad3cce5 100644 --- a/internal/workers/workers.go +++ b/internal/workers/workers.go @@ -54,6 +54,10 @@ type Workers struct { // eg., import tasks, admin tasks. Processing FnWorkerPool + // WebPush provides a worker pool for + // delivering Web Push notifications. + WebPush FnWorkerPool + // prevent pass-by-value. _ nocopy } @@ -90,6 +94,10 @@ func (w *Workers) Start() { n = maxprocs w.Processing.Start(n) log.Infof(nil, "started %d processing workers", n) + + n = maxprocs + w.WebPush.Start(n) + log.Infof(nil, "started %d Web Push workers", n) } // Stop will stop all of the contained @@ -113,6 +121,9 @@ func (w *Workers) Stop() { w.Processing.Stop() log.Info(nil, "stopped processing workers") + + w.WebPush.Stop() + log.Info(nil, "stopped WebPush workers") } // nocopy when embedded will signal linter to diff --git a/test/envparsing.sh b/test/envparsing.sh index 94d0855ca..1cef22c5b 100755 --- a/test/envparsing.sh +++ b/test/envparsing.sh @@ -77,6 +77,8 @@ EXPECT=$(cat << "EOF" "user-mute-ids-mem-ratio": 3, "user-mute-mem-ratio": 2, "visibility-mem-ratio": 2, + "web-push-subscription-ids-mem-ratio": 1, + "web-push-subscription-mem-ratio": 1, "webfinger-mem-ratio": 0.1 }, "config-path": "internal/config/testdata/test.yaml", diff --git a/testrig/db.go b/testrig/db.go index e53e9c9f0..d33a63f12 100644 --- a/testrig/db.go +++ b/testrig/db.go @@ -61,6 +61,8 @@ >smodel.ThreadToStatus{}, >smodel.User{}, >smodel.UserMute{}, + >smodel.VAPIDKeyPair{}, + >smodel.WebPushSubscription{}, >smodel.Emoji{}, >smodel.Instance{}, >smodel.Notification{}, @@ -348,6 +350,12 @@ func StandardDBSetup(db db.DB, accounts map[string]*gtsmodel.Account) { } } + for _, v := range NewTestWebPushSubscriptions() { + if err := db.Put(ctx, v); err != nil { + log.Panic(nil, err) + } + } + for _, v := range NewTestInteractionRequests() { if err := db.Put(ctx, v); err != nil { log.Panic(ctx, err) @@ -368,6 +376,11 @@ func StandardDBSetup(db db.DB, accounts map[string]*gtsmodel.Account) { log.Panic(ctx, err) } + // Generates and stores a VAPID key pair as a side effect. + if _, err := db.GetVAPIDKeyPair(ctx); err != nil { + log.Panic(nil, err) + } + log.Debug(ctx, "testing db setup complete") } diff --git a/testrig/processor.go b/testrig/processor.go index bbb8d9d1d..478e2124c 100644 --- a/testrig/processor.go +++ b/testrig/processor.go @@ -28,6 +28,7 @@ "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/superseriousbusiness/gotosocial/internal/subscriptions" "github.com/superseriousbusiness/gotosocial/internal/typeutils" + "github.com/superseriousbusiness/gotosocial/internal/webpush" ) // NewTestProcessor returns a Processor suitable for testing purposes. @@ -37,6 +38,7 @@ func NewTestProcessor( state *state.State, federator *federation.Federator, emailSender email.Sender, + webPushSender webpush.Sender, mediaManager *media.Manager, ) *processing.Processor { @@ -53,6 +55,7 @@ func NewTestProcessor( mediaManager, state, emailSender, + webPushSender, visibility.NewFilter(state), interaction.NewFilter(state), ) diff --git a/testrig/testmodels.go b/testrig/testmodels.go index da4202eed..9a54aba70 100644 --- a/testrig/testmodels.go +++ b/testrig/testmodels.go @@ -2585,7 +2585,7 @@ func NewTestNotifications() map[string]*gtsmodel.Notification { return map[string]*gtsmodel.Notification{ "local_account_1_like": { ID: "01F8Q0ANPTWW10DAKTX7BRPBJP", - NotificationType: gtsmodel.NotificationFave, + NotificationType: gtsmodel.NotificationFavourite, CreatedAt: TimeMustParse("2022-05-14T13:21:09+02:00"), TargetAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF", OriginAccountID: "01F8MH17FWEB39HZJ76B6VXSKF", @@ -2594,7 +2594,7 @@ func NewTestNotifications() map[string]*gtsmodel.Notification { }, "local_account_2_like": { ID: "01GTS6PRPXJYZBPFFQ56PP0XR8", - NotificationType: gtsmodel.NotificationFave, + NotificationType: gtsmodel.NotificationFavourite, CreatedAt: TimeMustParse("2022-01-13T12:45:01+02:00"), TargetAccountID: "01F8MH17FWEB39HZJ76B6VXSKF", OriginAccountID: "01F8MH5NBDF2MV7CTC4Q5128HF", @@ -2603,7 +2603,7 @@ func NewTestNotifications() map[string]*gtsmodel.Notification { }, "new_signup": { ID: "01HTM9TETMB3YQCBKZ7KD4KV02", - NotificationType: gtsmodel.NotificationSignup, + NotificationType: gtsmodel.NotificationAdminSignup, CreatedAt: TimeMustParse("2022-06-04T13:12:00Z"), TargetAccountID: "01F8MH17FWEB39HZJ76B6VXSKF", OriginAccountID: "01F8MH0BBE4FHXPH513MBVFHB0", @@ -3586,6 +3586,34 @@ func NewTestUserMutes() map[string]*gtsmodel.UserMute { return map[string]*gtsmodel.UserMute{} } +func NewTestWebPushSubscriptions() map[string]*gtsmodel.WebPushSubscription { + return map[string]*gtsmodel.WebPushSubscription{ + "local_account_1_token_1": { + ID: "01G65Z755AFWAKHE12NY0CQ9FH", + AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF", + TokenID: "01F8MGTQW4DKTDF8SW5CT9HYGA", + Endpoint: "https://example.test/push", + Auth: "cgna/fzrYLDQyPf5hD7IsA==", + P256dh: "BMYVItYVOX+AHBdtA62Q0i6c+F7MV2Gia3aoDr8mvHkuPBNIOuTLDfmFcnBqoZcQk6BtLcIONbxhHpy2R+mYIUY=", + NotificationFlags: gtsmodel.WebPushSubscriptionNotificationFlagsFromSlice([]gtsmodel.NotificationType{ + gtsmodel.NotificationFollow, + gtsmodel.NotificationFollowRequest, + gtsmodel.NotificationFavourite, + gtsmodel.NotificationMention, + gtsmodel.NotificationReblog, + gtsmodel.NotificationPoll, + gtsmodel.NotificationStatus, + gtsmodel.NotificationUpdate, + gtsmodel.NotificationAdminSignup, + gtsmodel.NotificationAdminReport, + gtsmodel.NotificationPendingFave, + gtsmodel.NotificationPendingReply, + gtsmodel.NotificationPendingReblog, + }), + }, + } +} + func NewTestInteractionRequests() map[string]*gtsmodel.InteractionRequest { return map[string]*gtsmodel.InteractionRequest{ "admin_account_reply_turtle": { diff --git a/testrig/teststructs.go b/testrig/teststructs.go index 58986bffa..7d5c3caab 100644 --- a/testrig/teststructs.go +++ b/testrig/teststructs.go @@ -47,6 +47,7 @@ type TestStructs struct { HTTPClient *MockHTTPClient TypeConverter *typeutils.Converter EmailSender email.Sender + WebPushSender *WebPushMockSender TransportController transport.Controller } @@ -83,6 +84,7 @@ func SetupTestStructs( federator := NewTestFederator(&state, transportController, mediaManager) oauthServer := NewTestOauthServer(db) emailSender := NewEmailSender(rTemplatePath, nil) + webPushSender := NewWebPushMockSender() common := common.New( &state, @@ -101,6 +103,7 @@ func SetupTestStructs( mediaManager, &state, emailSender, + webPushSender, visFilter, intFilter, ) @@ -117,6 +120,7 @@ func SetupTestStructs( HTTPClient: httpClient, TypeConverter: typeconverter, EmailSender: emailSender, + WebPushSender: webPushSender, TransportController: transportController, } } diff --git a/testrig/util.go b/testrig/util.go index 957553d79..a4bf1bea4 100644 --- a/testrig/util.go +++ b/testrig/util.go @@ -84,6 +84,7 @@ func StartWorkers(state *state.State, processor *workers.Processor) { state.Workers.Federator.Start(1) state.Workers.Dereference.Start(1) state.Workers.Processing.Start(1) + state.Workers.WebPush.Start(1) } func StopWorkers(state *state.State) { @@ -92,6 +93,7 @@ func StopWorkers(state *state.State) { state.Workers.Federator.Stop() state.Workers.Dereference.Stop() state.Workers.Processing.Stop() + state.Workers.WebPush.Stop() } func StartTimelines(state *state.State, visFilter *visibility.Filter, converter *typeutils.Converter) { diff --git a/testrig/webpush.go b/testrig/webpush.go new file mode 100644 index 000000000..4cd5d7a81 --- /dev/null +++ b/testrig/webpush.go @@ -0,0 +1,65 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package testrig + +import ( + "context" + + "github.com/superseriousbusiness/gotosocial/internal/filter/usermute" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/webpush" +) + +// WebPushMockSender collects a map of notifications sent to each account ID. +type WebPushMockSender struct { + Sent map[string][]*gtsmodel.Notification +} + +// NewWebPushMockSender creates a mock sender that can record sent Web Push notifications for test expectations. +func NewWebPushMockSender() *WebPushMockSender { + return &WebPushMockSender{ + Sent: map[string][]*gtsmodel.Notification{}, + } +} + +func (m *WebPushMockSender) Send( + ctx context.Context, + notification *gtsmodel.Notification, + filters []*gtsmodel.Filter, + mutes *usermute.CompiledUserMuteList, +) error { + m.Sent[notification.TargetAccountID] = append(m.Sent[notification.TargetAccountID], notification) + return nil +} + +// noopSender drops anything sent to it. +type noopWebPushSender struct{} + +// NewNoopWebPushSender creates a no-op sender that does nothing. +func NewNoopWebPushSender() webpush.Sender { + return &noopWebPushSender{} +} + +func (n *noopWebPushSender) Send( + ctx context.Context, + notification *gtsmodel.Notification, + filters []*gtsmodel.Filter, + mutes *usermute.CompiledUserMuteList, +) error { + return nil +} diff --git a/vendor/github.com/SherClockHolmes/webpush-go/.gitignore b/vendor/github.com/SherClockHolmes/webpush-go/.gitignore new file mode 100644 index 000000000..13b7c32ac --- /dev/null +++ b/vendor/github.com/SherClockHolmes/webpush-go/.gitignore @@ -0,0 +1,4 @@ +vendor/** + +.DS_Store +*.out diff --git a/vendor/github.com/SherClockHolmes/webpush-go/LICENSE b/vendor/github.com/SherClockHolmes/webpush-go/LICENSE new file mode 100644 index 000000000..161eac777 --- /dev/null +++ b/vendor/github.com/SherClockHolmes/webpush-go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Ethan Holmes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/SherClockHolmes/webpush-go/README.md b/vendor/github.com/SherClockHolmes/webpush-go/README.md new file mode 100644 index 000000000..c313fc6b1 --- /dev/null +++ b/vendor/github.com/SherClockHolmes/webpush-go/README.md @@ -0,0 +1,63 @@ +# webpush-go + +[![Go Report Card](https://goreportcard.com/badge/github.com/SherClockHolmes/webpush-go)](https://goreportcard.com/report/github.com/SherClockHolmes/webpush-go) +[![GoDoc](https://godoc.org/github.com/SherClockHolmes/webpush-go?status.svg)](https://godoc.org/github.com/SherClockHolmes/webpush-go) + +Web Push API Encryption with VAPID support. + +```bash +go get -u github.com/SherClockHolmes/webpush-go +``` + +## Example + +For a full example, refer to the code in the [example](example/) directory. + +```go +package main + +import ( + "encoding/json" + + webpush "github.com/SherClockHolmes/webpush-go" +) + +func main() { + // Decode subscription + s := &webpush.Subscription{} + json.Unmarshal([]byte(""), s) + + // Send Notification + resp, err := webpush.SendNotification([]byte("Test"), s, &webpush.Options{ + Subscriber: "example@example.com", + VAPIDPublicKey: "", + VAPIDPrivateKey: "", + TTL: 30, + }) + if err != nil { + // TODO: Handle error + } + defer resp.Body.Close() +} +``` + +### Generating VAPID Keys + +Use the helper method `GenerateVAPIDKeys` to generate the VAPID key pair. + +```golang +privateKey, publicKey, err := webpush.GenerateVAPIDKeys() +if err != nil { + // TODO: Handle error +} +``` + +## Development + +1. Install [Go 1.11+](https://golang.org/) +2. `go mod vendor` +3. `go test` + +#### For other language implementations visit: + +[WebPush Libs](https://github.com/web-push-libs) diff --git a/vendor/github.com/SherClockHolmes/webpush-go/urgency.go b/vendor/github.com/SherClockHolmes/webpush-go/urgency.go new file mode 100644 index 000000000..97c4a32b4 --- /dev/null +++ b/vendor/github.com/SherClockHolmes/webpush-go/urgency.go @@ -0,0 +1,26 @@ +package webpush + +// Urgency indicates to the push service how important a message is to the user. +// This can be used by the push service to help conserve the battery life of a user's device +// by only waking up for important messages when battery is low. +type Urgency string + +const ( + // UrgencyVeryLow requires device state: on power and Wi-Fi + UrgencyVeryLow Urgency = "very-low" + // UrgencyLow requires device state: on either power or Wi-Fi + UrgencyLow Urgency = "low" + // UrgencyNormal excludes device state: low battery + UrgencyNormal Urgency = "normal" + // UrgencyHigh admits device state: low battery + UrgencyHigh Urgency = "high" +) + +// Checking allowable values for the urgency header +func isValidUrgency(urgency Urgency) bool { + switch urgency { + case UrgencyVeryLow, UrgencyLow, UrgencyNormal, UrgencyHigh: + return true + } + return false +} diff --git a/vendor/github.com/SherClockHolmes/webpush-go/vapid.go b/vendor/github.com/SherClockHolmes/webpush-go/vapid.go new file mode 100644 index 000000000..fe2c580a6 --- /dev/null +++ b/vendor/github.com/SherClockHolmes/webpush-go/vapid.go @@ -0,0 +1,117 @@ +package webpush + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "encoding/base64" + "fmt" + "math/big" + "net/url" + "time" + + "github.com/golang-jwt/jwt" +) + +// GenerateVAPIDKeys will create a private and public VAPID key pair +func GenerateVAPIDKeys() (privateKey, publicKey string, err error) { + // Get the private key from the P256 curve + curve := elliptic.P256() + + private, x, y, err := elliptic.GenerateKey(curve, rand.Reader) + if err != nil { + return + } + + public := elliptic.Marshal(curve, x, y) + + // Convert to base64 + publicKey = base64.RawURLEncoding.EncodeToString(public) + privateKey = base64.RawURLEncoding.EncodeToString(private) + + return +} + +// Generates the ECDSA public and private keys for the JWT encryption +func generateVAPIDHeaderKeys(privateKey []byte) *ecdsa.PrivateKey { + // Public key + curve := elliptic.P256() + px, py := curve.ScalarMult( + curve.Params().Gx, + curve.Params().Gy, + privateKey, + ) + + pubKey := ecdsa.PublicKey{ + Curve: curve, + X: px, + Y: py, + } + + // Private key + d := &big.Int{} + d.SetBytes(privateKey) + + return &ecdsa.PrivateKey{ + PublicKey: pubKey, + D: d, + } +} + +// getVAPIDAuthorizationHeader +func getVAPIDAuthorizationHeader( + endpoint, + subscriber, + vapidPublicKey, + vapidPrivateKey string, + expiration time.Time, +) (string, error) { + // Create the JWT token + subURL, err := url.Parse(endpoint) + if err != nil { + return "", err + } + + token := jwt.NewWithClaims(jwt.SigningMethodES256, jwt.MapClaims{ + "aud": fmt.Sprintf("%s://%s", subURL.Scheme, subURL.Host), + "exp": expiration.Unix(), + "sub": fmt.Sprintf("mailto:%s", subscriber), + }) + + // Decode the VAPID private key + decodedVapidPrivateKey, err := decodeVapidKey(vapidPrivateKey) + if err != nil { + return "", err + } + + privKey := generateVAPIDHeaderKeys(decodedVapidPrivateKey) + + // Sign token with private key + jwtString, err := token.SignedString(privKey) + if err != nil { + return "", err + } + + // Decode the VAPID public key + pubKey, err := decodeVapidKey(vapidPublicKey) + if err != nil { + return "", err + } + + return fmt.Sprintf( + "vapid t=%s, k=%s", + jwtString, + base64.RawURLEncoding.EncodeToString(pubKey), + ), nil +} + +// Need to decode the vapid private key in multiple base64 formats +// Solution from: https://github.com/SherClockHolmes/webpush-go/issues/29 +func decodeVapidKey(key string) ([]byte, error) { + bytes, err := base64.URLEncoding.DecodeString(key) + if err == nil { + return bytes, nil + } + + return base64.RawURLEncoding.DecodeString(key) +} diff --git a/vendor/github.com/SherClockHolmes/webpush-go/webpush.go b/vendor/github.com/SherClockHolmes/webpush-go/webpush.go new file mode 100644 index 000000000..4c85ad638 --- /dev/null +++ b/vendor/github.com/SherClockHolmes/webpush-go/webpush.go @@ -0,0 +1,287 @@ +package webpush + +import ( + "bytes" + "context" + "crypto/aes" + "crypto/cipher" + "crypto/elliptic" + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "encoding/binary" + "errors" + "io" + "net/http" + "strconv" + "strings" + "time" + + "golang.org/x/crypto/hkdf" +) + +const MaxRecordSize uint32 = 4096 + +var ErrMaxPadExceeded = errors.New("payload has exceeded the maximum length") + +// saltFunc generates a salt of 16 bytes +var saltFunc = func() ([]byte, error) { + salt := make([]byte, 16) + _, err := io.ReadFull(rand.Reader, salt) + if err != nil { + return salt, err + } + + return salt, nil +} + +// HTTPClient is an interface for sending the notification HTTP request / testing +type HTTPClient interface { + Do(*http.Request) (*http.Response, error) +} + +// Options are config and extra params needed to send a notification +type Options struct { + HTTPClient HTTPClient // Will replace with *http.Client by default if not included + RecordSize uint32 // Limit the record size + Subscriber string // Sub in VAPID JWT token + Topic string // Set the Topic header to collapse a pending messages (Optional) + TTL int // Set the TTL on the endpoint POST request + Urgency Urgency // Set the Urgency header to change a message priority (Optional) + VAPIDPublicKey string // VAPID public key, passed in VAPID Authorization header + VAPIDPrivateKey string // VAPID private key, used to sign VAPID JWT token + VapidExpiration time.Time // optional expiration for VAPID JWT token (defaults to now + 12 hours) +} + +// Keys are the base64 encoded values from PushSubscription.getKey() +type Keys struct { + Auth string `json:"auth"` + P256dh string `json:"p256dh"` +} + +// Subscription represents a PushSubscription object from the Push API +type Subscription struct { + Endpoint string `json:"endpoint"` + Keys Keys `json:"keys"` +} + +// SendNotification calls SendNotificationWithContext with default context for backwards-compatibility +func SendNotification(message []byte, s *Subscription, options *Options) (*http.Response, error) { + return SendNotificationWithContext(context.Background(), message, s, options) +} + +// SendNotificationWithContext sends a push notification to a subscription's endpoint +// Message Encryption for Web Push, and VAPID protocols. +// FOR MORE INFORMATION SEE RFC8291: https://datatracker.ietf.org/doc/rfc8291 +func SendNotificationWithContext(ctx context.Context, message []byte, s *Subscription, options *Options) (*http.Response, error) { + // Authentication secret (auth_secret) + authSecret, err := decodeSubscriptionKey(s.Keys.Auth) + if err != nil { + return nil, err + } + + // dh (Diffie Hellman) + dh, err := decodeSubscriptionKey(s.Keys.P256dh) + if err != nil { + return nil, err + } + + // Generate 16 byte salt + salt, err := saltFunc() + if err != nil { + return nil, err + } + + // Create the ecdh_secret shared key pair + curve := elliptic.P256() + + // Application server key pairs (single use) + localPrivateKey, x, y, err := elliptic.GenerateKey(curve, rand.Reader) + if err != nil { + return nil, err + } + + localPublicKey := elliptic.Marshal(curve, x, y) + + // Combine application keys with receiver's EC public key + sharedX, sharedY := elliptic.Unmarshal(curve, dh) + if sharedX == nil { + return nil, errors.New("Unmarshal Error: Public key is not a valid point on the curve") + } + + // Derive ECDH shared secret + sx, sy := curve.ScalarMult(sharedX, sharedY, localPrivateKey) + if !curve.IsOnCurve(sx, sy) { + return nil, errors.New("Encryption error: ECDH shared secret isn't on curve") + } + mlen := curve.Params().BitSize / 8 + sharedECDHSecret := make([]byte, mlen) + sx.FillBytes(sharedECDHSecret) + + hash := sha256.New + + // ikm + prkInfoBuf := bytes.NewBuffer([]byte("WebPush: info\x00")) + prkInfoBuf.Write(dh) + prkInfoBuf.Write(localPublicKey) + + prkHKDF := hkdf.New(hash, sharedECDHSecret, authSecret, prkInfoBuf.Bytes()) + ikm, err := getHKDFKey(prkHKDF, 32) + if err != nil { + return nil, err + } + + // Derive Content Encryption Key + contentEncryptionKeyInfo := []byte("Content-Encoding: aes128gcm\x00") + contentHKDF := hkdf.New(hash, ikm, salt, contentEncryptionKeyInfo) + contentEncryptionKey, err := getHKDFKey(contentHKDF, 16) + if err != nil { + return nil, err + } + + // Derive the Nonce + nonceInfo := []byte("Content-Encoding: nonce\x00") + nonceHKDF := hkdf.New(hash, ikm, salt, nonceInfo) + nonce, err := getHKDFKey(nonceHKDF, 12) + if err != nil { + return nil, err + } + + // Cipher + c, err := aes.NewCipher(contentEncryptionKey) + if err != nil { + return nil, err + } + + gcm, err := cipher.NewGCM(c) + if err != nil { + return nil, err + } + + // Get the record size + recordSize := options.RecordSize + if recordSize == 0 { + recordSize = MaxRecordSize + } + + recordLength := int(recordSize) - 16 + + // Encryption Content-Coding Header + recordBuf := bytes.NewBuffer(salt) + + rs := make([]byte, 4) + binary.BigEndian.PutUint32(rs, recordSize) + + recordBuf.Write(rs) + recordBuf.Write([]byte{byte(len(localPublicKey))}) + recordBuf.Write(localPublicKey) + + // Data + dataBuf := bytes.NewBuffer(message) + + // Pad content to max record size - 16 - header + // Padding ending delimeter + dataBuf.Write([]byte("\x02")) + if err := pad(dataBuf, recordLength-recordBuf.Len()); err != nil { + return nil, err + } + + // Compose the ciphertext + ciphertext := gcm.Seal([]byte{}, nonce, dataBuf.Bytes(), nil) + recordBuf.Write(ciphertext) + + // POST request + req, err := http.NewRequest("POST", s.Endpoint, recordBuf) + if err != nil { + return nil, err + } + + if ctx != nil { + req = req.WithContext(ctx) + } + + req.Header.Set("Content-Encoding", "aes128gcm") + req.Header.Set("Content-Length", strconv.Itoa(len(ciphertext))) + req.Header.Set("Content-Type", "application/octet-stream") + req.Header.Set("TTL", strconv.Itoa(options.TTL)) + + // Сheck the optional headers + if len(options.Topic) > 0 { + req.Header.Set("Topic", options.Topic) + } + + if isValidUrgency(options.Urgency) { + req.Header.Set("Urgency", string(options.Urgency)) + } + + expiration := options.VapidExpiration + if expiration.IsZero() { + expiration = time.Now().Add(time.Hour * 12) + } + + // Get VAPID Authorization header + vapidAuthHeader, err := getVAPIDAuthorizationHeader( + s.Endpoint, + options.Subscriber, + options.VAPIDPublicKey, + options.VAPIDPrivateKey, + expiration, + ) + if err != nil { + return nil, err + } + + req.Header.Set("Authorization", vapidAuthHeader) + + // Send the request + var client HTTPClient + if options.HTTPClient != nil { + client = options.HTTPClient + } else { + client = &http.Client{} + } + + return client.Do(req) +} + +// decodeSubscriptionKey decodes a base64 subscription key. +// if necessary, add "=" padding to the key for URL decode +func decodeSubscriptionKey(key string) ([]byte, error) { + // "=" padding + buf := bytes.NewBufferString(key) + if rem := len(key) % 4; rem != 0 { + buf.WriteString(strings.Repeat("=", 4-rem)) + } + + bytes, err := base64.StdEncoding.DecodeString(buf.String()) + if err == nil { + return bytes, nil + } + + return base64.URLEncoding.DecodeString(buf.String()) +} + +// Returns a key of length "length" given an hkdf function +func getHKDFKey(hkdf io.Reader, length int) ([]byte, error) { + key := make([]byte, length) + n, err := io.ReadFull(hkdf, key) + if n != len(key) || err != nil { + return key, err + } + + return key, nil +} + +func pad(payload *bytes.Buffer, maxPadLen int) error { + payloadLen := payload.Len() + if payloadLen > maxPadLen { + return ErrMaxPadExceeded + } + + padLen := maxPadLen - payloadLen + + padding := make([]byte, padLen) + payload.Write(padding) + + return nil +} diff --git a/vendor/github.com/rivo/uniseg/LICENSE.txt b/vendor/github.com/rivo/uniseg/LICENSE.txt new file mode 100644 index 000000000..5040f1ef8 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Oliver Kuederle + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/rivo/uniseg/README.md b/vendor/github.com/rivo/uniseg/README.md new file mode 100644 index 000000000..a8191b815 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/README.md @@ -0,0 +1,137 @@ +# Unicode Text Segmentation for Go + +[![Go Reference](https://pkg.go.dev/badge/github.com/rivo/uniseg.svg)](https://pkg.go.dev/github.com/rivo/uniseg) +[![Go Report](https://img.shields.io/badge/go%20report-A%2B-brightgreen.svg)](https://goreportcard.com/report/github.com/rivo/uniseg) + +This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](https://unicode.org/reports/tr29/), Unicode Line Breaking according to [Unicode Standard Annex #14](https://unicode.org/reports/tr14/) (Unicode version 15.0.0), and monospace font string width calculation similar to [wcwidth](https://man7.org/linux/man-pages/man3/wcwidth.3.html). + +## Background + +### Grapheme Clusters + +In Go, [strings are read-only slices of bytes](https://go.dev/blog/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples: + +|String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters| +|-|-|-|-| +|Käse|6 bytes: `4b 61 cc 88 73 65`|5 code points: `4b 61 308 73 65`|4 clusters: `[4b],[61 308],[73],[65]`| +|🏳️‍🌈|14 bytes: `f0 9f 8f b3 ef b8 8f e2 80 8d f0 9f 8c 88`|4 code points: `1f3f3 fe0f 200d 1f308`|1 cluster: `[1f3f3 fe0f 200d 1f308]`| +|🇩🇪|8 bytes: `f0 9f 87 a9 f0 9f 87 aa`|2 code points: `1f1e9 1f1ea`|1 cluster: `[1f1e9 1f1ea]`| + +This package provides tools to iterate over these grapheme clusters. This may be used to determine the number of user-perceived characters, to split strings in their intended places, or to extract individual characters which form a unit. + +### Word Boundaries + +Word boundaries are used in a number of different contexts. The most familiar ones are selection (double-click mouse selection), cursor movement ("move to next word" control-arrow keys), and the dialog option "Whole Word Search" for search and replace. They are also used in database queries, to determine whether elements are within a certain number of words of one another. Searching may also use word boundaries in determining matching items. This package provides tools to determine word boundaries within strings. + +### Sentence Boundaries + +Sentence boundaries are often used for triple-click or some other method of selecting or iterating through blocks of text that are larger than single words. They are also used to determine whether words occur within the same sentence in database queries. This package provides tools to determine sentence boundaries within strings. + +### Line Breaking + +Line breaking, also known as word wrapping, is the process of breaking a section of text into lines such that it will fit in the available width of a page, window or other display area. This package provides tools to determine where a string may or may not be broken and where it must be broken (for example after newline characters). + +### Monospace Width + +Most terminals or text displays / text editors using a monospace font (for example source code editors) use a fixed width for each character. Some characters such as emojis or characters found in Asian and other languages may take up more than one character cell. This package provides tools to determine the number of cells a string will take up when displayed in a monospace font. See [here](https://pkg.go.dev/github.com/rivo/uniseg#hdr-Monospace_Width) for more information. + +## Installation + +```bash +go get github.com/rivo/uniseg +``` + +## Examples + +### Counting Characters in a String + +```go +n := uniseg.GraphemeClusterCount("🇩🇪🏳️‍🌈") +fmt.Println(n) +// 2 +``` + +### Calculating the Monospace String Width + +```go +width := uniseg.StringWidth("🇩🇪🏳️‍🌈!") +fmt.Println(width) +// 5 +``` + +### Using the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) Class + +This is the most convenient method of iterating over grapheme clusters: + +```go +gr := uniseg.NewGraphemes("👍🏼!") +for gr.Next() { + fmt.Printf("%x ", gr.Runes()) +} +// [1f44d 1f3fc] [21] +``` + +### Using the [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) Function + +This avoids allocating a new `Graphemes` object but it requires the handling of states and boundaries: + +```go +str := "🇩🇪🏳️‍🌈" +state := -1 +var c string +for len(str) > 0 { + c, str, _, state = uniseg.StepString(str, state) + fmt.Printf("%x ", []rune(c)) +} +// [1f1e9 1f1ea] [1f3f3 fe0f 200d 1f308] +``` + +### Advanced Examples + +The [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class offers the most convenient way to access all functionality of this package. But in some cases, it may be better to use the specialized functions directly. For example, if you're only interested in word segmentation, use [`FirstWord`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWord) or [`FirstWordInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWordInString): + +```go +str := "Hello, world!" +state := -1 +var c string +for len(str) > 0 { + c, str, state = uniseg.FirstWordInString(str, state) + fmt.Printf("(%s)\n", c) +} +// (Hello) +// (,) +// ( ) +// (world) +// (!) +``` + +Similarly, use + +- [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString) for grapheme cluster determination only, +- [`FirstSentence`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentence) or [`FirstSentenceInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentenceInString) for sentence segmentation only, and +- [`FirstLineSegment`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegment) or [`FirstLineSegmentInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegmentInString) for line breaking / word wrapping (although using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) is preferred as it will observe grapheme cluster boundaries). + +If you're only interested in the width of characters, use [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString). It is much faster than using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step), [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString), or the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class because it does not include the logic for word / sentence / line boundaries. + +Finally, if you need to reverse a string while preserving grapheme clusters, use [`ReverseString`](https://pkg.go.dev/github.com/rivo/uniseg#ReverseString): + +```go +fmt.Println(uniseg.ReverseString("🇩🇪🏳️‍🌈")) +// 🏳️‍🌈🇩🇪 +``` + +## Documentation + +Refer to https://pkg.go.dev/github.com/rivo/uniseg for the package's documentation. + +## Dependencies + +This package does not depend on any packages outside the standard library. + +## Sponsor this Project + +[Become a Sponsor on GitHub](https://github.com/sponsors/rivo?metadata_source=uniseg_readme) to support this project! + +## Your Feedback + +Add your issue here on GitHub, preferably before submitting any PR's. Feel free to get in touch if you have any questions. \ No newline at end of file diff --git a/vendor/github.com/rivo/uniseg/doc.go b/vendor/github.com/rivo/uniseg/doc.go new file mode 100644 index 000000000..11224ae22 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/doc.go @@ -0,0 +1,108 @@ +/* +Package uniseg implements Unicode Text Segmentation, Unicode Line Breaking, and +string width calculation for monospace fonts. Unicode Text Segmentation conforms +to Unicode Standard Annex #29 (https://unicode.org/reports/tr29/) and Unicode +Line Breaking conforms to Unicode Standard Annex #14 +(https://unicode.org/reports/tr14/). + +In short, using this package, you can split a string into grapheme clusters +(what people would usually refer to as a "character"), into words, and into +sentences. Or, in its simplest case, this package allows you to count the number +of characters in a string, especially when it contains complex characters such +as emojis, combining characters, or characters from Asian, Arabic, Hebrew, or +other languages. Additionally, you can use it to implement line breaking (or +"word wrapping"), that is, to determine where text can be broken over to the +next line when the width of the line is not big enough to fit the entire text. +Finally, you can use it to calculate the display width of a string for monospace +fonts. + +# Getting Started + +If you just want to count the number of characters in a string, you can use +[GraphemeClusterCount]. If you want to determine the display width of a string, +you can use [StringWidth]. If you want to iterate over a string, you can use +[Step], [StepString], or the [Graphemes] class (more convenient but less +performant). This will provide you with all information: grapheme clusters, +word boundaries, sentence boundaries, line breaks, and monospace character +widths. The specialized functions [FirstGraphemeCluster], +[FirstGraphemeClusterInString], [FirstWord], [FirstWordInString], +[FirstSentence], and [FirstSentenceInString] can be used if only one type of +information is needed. + +# Grapheme Clusters + +Consider the rainbow flag emoji: 🏳️‍🌈. On most modern systems, it appears as one +character. But its string representation actually has 14 bytes, so counting +bytes (or using len("🏳️‍🌈")) will not work as expected. Counting runes won't, +either: The flag has 4 Unicode code points, thus 4 runes. The stdlib function +utf8.RuneCountInString("🏳️‍🌈") and len([]rune("🏳️‍🌈")) will both return 4. + +The [GraphemeClusterCount] function will return 1 for the rainbow flag emoji. +The Graphemes class and a variety of functions in this package will allow you to +split strings into its grapheme clusters. + +# Word Boundaries + +Word boundaries are used in a number of different contexts. The most familiar +ones are selection (double-click mouse selection), cursor movement ("move to +next word" control-arrow keys), and the dialog option "Whole Word Search" for +search and replace. This package provides methods for determining word +boundaries. + +# Sentence Boundaries + +Sentence boundaries are often used for triple-click or some other method of +selecting or iterating through blocks of text that are larger than single words. +They are also used to determine whether words occur within the same sentence in +database queries. This package provides methods for determining sentence +boundaries. + +# Line Breaking + +Line breaking, also known as word wrapping, is the process of breaking a section +of text into lines such that it will fit in the available width of a page, +window or other display area. This package provides methods to determine the +positions in a string where a line must be broken, may be broken, or must not be +broken. + +# Monospace Width + +Monospace width, as referred to in this package, is the width of a string in a +monospace font. This is commonly used in terminal user interfaces or text +displays or editors that don't support proportional fonts. A width of 1 +corresponds to a single character cell. The C function [wcswidth()] and its +implementation in other programming languages is in widespread use for the same +purpose. However, there is no standard for the calculation of such widths, and +this package differs from wcswidth() in a number of ways, presumably to generate +more visually pleasing results. + +To start, we assume that every code point has a width of 1, with the following +exceptions: + + - Code points with grapheme cluster break properties Control, CR, LF, Extend, + and ZWJ have a width of 0. + - U+2E3A, Two-Em Dash, has a width of 3. + - U+2E3B, Three-Em Dash, has a width of 4. + - Characters with the East-Asian Width properties "Fullwidth" (F) and "Wide" + (W) have a width of 2. (Properties "Ambiguous" (A) and "Neutral" (N) both + have a width of 1.) + - Code points with grapheme cluster break property Regional Indicator have a + width of 2. + - Code points with grapheme cluster break property Extended Pictographic have + a width of 2, unless their Emoji Presentation flag is "No", in which case + the width is 1. + +For Hangul grapheme clusters composed of conjoining Jamo and for Regional +Indicators (flags), all code points except the first one have a width of 0. For +grapheme clusters starting with an Extended Pictographic, any additional code +point will force a total width of 2, except if the Variation Selector-15 +(U+FE0E) is included, in which case the total width is always 1. Grapheme +clusters ending with Variation Selector-16 (U+FE0F) have a width of 2. + +Note that whether these widths appear correct depends on your application's +render engine, to which extent it conforms to the Unicode Standard, and its +choice of font. + +[wcswidth()]: https://man7.org/linux/man-pages/man3/wcswidth.3.html +*/ +package uniseg diff --git a/vendor/github.com/rivo/uniseg/eastasianwidth.go b/vendor/github.com/rivo/uniseg/eastasianwidth.go new file mode 100644 index 000000000..5fc54d991 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/eastasianwidth.go @@ -0,0 +1,2588 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// eastAsianWidth are taken from +// https://www.unicode.org/Public/15.0.0/ucd/EastAsianWidth.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var eastAsianWidth = [][3]int{ + {0x0000, 0x001F, prN}, // Cc [32] .. + {0x0020, 0x0020, prNa}, // Zs SPACE + {0x0021, 0x0023, prNa}, // Po [3] EXCLAMATION MARK..NUMBER SIGN + {0x0024, 0x0024, prNa}, // Sc DOLLAR SIGN + {0x0025, 0x0027, prNa}, // Po [3] PERCENT SIGN..APOSTROPHE + {0x0028, 0x0028, prNa}, // Ps LEFT PARENTHESIS + {0x0029, 0x0029, prNa}, // Pe RIGHT PARENTHESIS + {0x002A, 0x002A, prNa}, // Po ASTERISK + {0x002B, 0x002B, prNa}, // Sm PLUS SIGN + {0x002C, 0x002C, prNa}, // Po COMMA + {0x002D, 0x002D, prNa}, // Pd HYPHEN-MINUS + {0x002E, 0x002F, prNa}, // Po [2] FULL STOP..SOLIDUS + {0x0030, 0x0039, prNa}, // Nd [10] DIGIT ZERO..DIGIT NINE + {0x003A, 0x003B, prNa}, // Po [2] COLON..SEMICOLON + {0x003C, 0x003E, prNa}, // Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN + {0x003F, 0x0040, prNa}, // Po [2] QUESTION MARK..COMMERCIAL AT + {0x0041, 0x005A, prNa}, // Lu [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z + {0x005B, 0x005B, prNa}, // Ps LEFT SQUARE BRACKET + {0x005C, 0x005C, prNa}, // Po REVERSE SOLIDUS + {0x005D, 0x005D, prNa}, // Pe RIGHT SQUARE BRACKET + {0x005E, 0x005E, prNa}, // Sk CIRCUMFLEX ACCENT + {0x005F, 0x005F, prNa}, // Pc LOW LINE + {0x0060, 0x0060, prNa}, // Sk GRAVE ACCENT + {0x0061, 0x007A, prNa}, // Ll [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z + {0x007B, 0x007B, prNa}, // Ps LEFT CURLY BRACKET + {0x007C, 0x007C, prNa}, // Sm VERTICAL LINE + {0x007D, 0x007D, prNa}, // Pe RIGHT CURLY BRACKET + {0x007E, 0x007E, prNa}, // Sm TILDE + {0x007F, 0x007F, prN}, // Cc + {0x0080, 0x009F, prN}, // Cc [32] .. + {0x00A0, 0x00A0, prN}, // Zs NO-BREAK SPACE + {0x00A1, 0x00A1, prA}, // Po INVERTED EXCLAMATION MARK + {0x00A2, 0x00A3, prNa}, // Sc [2] CENT SIGN..POUND SIGN + {0x00A4, 0x00A4, prA}, // Sc CURRENCY SIGN + {0x00A5, 0x00A5, prNa}, // Sc YEN SIGN + {0x00A6, 0x00A6, prNa}, // So BROKEN BAR + {0x00A7, 0x00A7, prA}, // Po SECTION SIGN + {0x00A8, 0x00A8, prA}, // Sk DIAERESIS + {0x00A9, 0x00A9, prN}, // So COPYRIGHT SIGN + {0x00AA, 0x00AA, prA}, // Lo FEMININE ORDINAL INDICATOR + {0x00AB, 0x00AB, prN}, // Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00AC, 0x00AC, prNa}, // Sm NOT SIGN + {0x00AD, 0x00AD, prA}, // Cf SOFT HYPHEN + {0x00AE, 0x00AE, prA}, // So REGISTERED SIGN + {0x00AF, 0x00AF, prNa}, // Sk MACRON + {0x00B0, 0x00B0, prA}, // So DEGREE SIGN + {0x00B1, 0x00B1, prA}, // Sm PLUS-MINUS SIGN + {0x00B2, 0x00B3, prA}, // No [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE + {0x00B4, 0x00B4, prA}, // Sk ACUTE ACCENT + {0x00B5, 0x00B5, prN}, // Ll MICRO SIGN + {0x00B6, 0x00B7, prA}, // Po [2] PILCROW SIGN..MIDDLE DOT + {0x00B8, 0x00B8, prA}, // Sk CEDILLA + {0x00B9, 0x00B9, prA}, // No SUPERSCRIPT ONE + {0x00BA, 0x00BA, prA}, // Lo MASCULINE ORDINAL INDICATOR + {0x00BB, 0x00BB, prN}, // Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00BC, 0x00BE, prA}, // No [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS + {0x00BF, 0x00BF, prA}, // Po INVERTED QUESTION MARK + {0x00C0, 0x00C5, prN}, // Lu [6] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER A WITH RING ABOVE + {0x00C6, 0x00C6, prA}, // Lu LATIN CAPITAL LETTER AE + {0x00C7, 0x00CF, prN}, // Lu [9] LATIN CAPITAL LETTER C WITH CEDILLA..LATIN CAPITAL LETTER I WITH DIAERESIS + {0x00D0, 0x00D0, prA}, // Lu LATIN CAPITAL LETTER ETH + {0x00D1, 0x00D6, prN}, // Lu [6] LATIN CAPITAL LETTER N WITH TILDE..LATIN CAPITAL LETTER O WITH DIAERESIS + {0x00D7, 0x00D7, prA}, // Sm MULTIPLICATION SIGN + {0x00D8, 0x00D8, prA}, // Lu LATIN CAPITAL LETTER O WITH STROKE + {0x00D9, 0x00DD, prN}, // Lu [5] LATIN CAPITAL LETTER U WITH GRAVE..LATIN CAPITAL LETTER Y WITH ACUTE + {0x00DE, 0x00E1, prA}, // L& [4] LATIN CAPITAL LETTER THORN..LATIN SMALL LETTER A WITH ACUTE + {0x00E2, 0x00E5, prN}, // Ll [4] LATIN SMALL LETTER A WITH CIRCUMFLEX..LATIN SMALL LETTER A WITH RING ABOVE + {0x00E6, 0x00E6, prA}, // Ll LATIN SMALL LETTER AE + {0x00E7, 0x00E7, prN}, // Ll LATIN SMALL LETTER C WITH CEDILLA + {0x00E8, 0x00EA, prA}, // Ll [3] LATIN SMALL LETTER E WITH GRAVE..LATIN SMALL LETTER E WITH CIRCUMFLEX + {0x00EB, 0x00EB, prN}, // Ll LATIN SMALL LETTER E WITH DIAERESIS + {0x00EC, 0x00ED, prA}, // Ll [2] LATIN SMALL LETTER I WITH GRAVE..LATIN SMALL LETTER I WITH ACUTE + {0x00EE, 0x00EF, prN}, // Ll [2] LATIN SMALL LETTER I WITH CIRCUMFLEX..LATIN SMALL LETTER I WITH DIAERESIS + {0x00F0, 0x00F0, prA}, // Ll LATIN SMALL LETTER ETH + {0x00F1, 0x00F1, prN}, // Ll LATIN SMALL LETTER N WITH TILDE + {0x00F2, 0x00F3, prA}, // Ll [2] LATIN SMALL LETTER O WITH GRAVE..LATIN SMALL LETTER O WITH ACUTE + {0x00F4, 0x00F6, prN}, // Ll [3] LATIN SMALL LETTER O WITH CIRCUMFLEX..LATIN SMALL LETTER O WITH DIAERESIS + {0x00F7, 0x00F7, prA}, // Sm DIVISION SIGN + {0x00F8, 0x00FA, prA}, // Ll [3] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER U WITH ACUTE + {0x00FB, 0x00FB, prN}, // Ll LATIN SMALL LETTER U WITH CIRCUMFLEX + {0x00FC, 0x00FC, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS + {0x00FD, 0x00FD, prN}, // Ll LATIN SMALL LETTER Y WITH ACUTE + {0x00FE, 0x00FE, prA}, // Ll LATIN SMALL LETTER THORN + {0x00FF, 0x00FF, prN}, // Ll LATIN SMALL LETTER Y WITH DIAERESIS + {0x0100, 0x0100, prN}, // Lu LATIN CAPITAL LETTER A WITH MACRON + {0x0101, 0x0101, prA}, // Ll LATIN SMALL LETTER A WITH MACRON + {0x0102, 0x0110, prN}, // L& [15] LATIN CAPITAL LETTER A WITH BREVE..LATIN CAPITAL LETTER D WITH STROKE + {0x0111, 0x0111, prA}, // Ll LATIN SMALL LETTER D WITH STROKE + {0x0112, 0x0112, prN}, // Lu LATIN CAPITAL LETTER E WITH MACRON + {0x0113, 0x0113, prA}, // Ll LATIN SMALL LETTER E WITH MACRON + {0x0114, 0x011A, prN}, // L& [7] LATIN CAPITAL LETTER E WITH BREVE..LATIN CAPITAL LETTER E WITH CARON + {0x011B, 0x011B, prA}, // Ll LATIN SMALL LETTER E WITH CARON + {0x011C, 0x0125, prN}, // L& [10] LATIN CAPITAL LETTER G WITH CIRCUMFLEX..LATIN SMALL LETTER H WITH CIRCUMFLEX + {0x0126, 0x0127, prA}, // L& [2] LATIN CAPITAL LETTER H WITH STROKE..LATIN SMALL LETTER H WITH STROKE + {0x0128, 0x012A, prN}, // L& [3] LATIN CAPITAL LETTER I WITH TILDE..LATIN CAPITAL LETTER I WITH MACRON + {0x012B, 0x012B, prA}, // Ll LATIN SMALL LETTER I WITH MACRON + {0x012C, 0x0130, prN}, // L& [5] LATIN CAPITAL LETTER I WITH BREVE..LATIN CAPITAL LETTER I WITH DOT ABOVE + {0x0131, 0x0133, prA}, // L& [3] LATIN SMALL LETTER DOTLESS I..LATIN SMALL LIGATURE IJ + {0x0134, 0x0137, prN}, // L& [4] LATIN CAPITAL LETTER J WITH CIRCUMFLEX..LATIN SMALL LETTER K WITH CEDILLA + {0x0138, 0x0138, prA}, // Ll LATIN SMALL LETTER KRA + {0x0139, 0x013E, prN}, // L& [6] LATIN CAPITAL LETTER L WITH ACUTE..LATIN SMALL LETTER L WITH CARON + {0x013F, 0x0142, prA}, // L& [4] LATIN CAPITAL LETTER L WITH MIDDLE DOT..LATIN SMALL LETTER L WITH STROKE + {0x0143, 0x0143, prN}, // Lu LATIN CAPITAL LETTER N WITH ACUTE + {0x0144, 0x0144, prA}, // Ll LATIN SMALL LETTER N WITH ACUTE + {0x0145, 0x0147, prN}, // L& [3] LATIN CAPITAL LETTER N WITH CEDILLA..LATIN CAPITAL LETTER N WITH CARON + {0x0148, 0x014B, prA}, // L& [4] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER ENG + {0x014C, 0x014C, prN}, // Lu LATIN CAPITAL LETTER O WITH MACRON + {0x014D, 0x014D, prA}, // Ll LATIN SMALL LETTER O WITH MACRON + {0x014E, 0x0151, prN}, // L& [4] LATIN CAPITAL LETTER O WITH BREVE..LATIN SMALL LETTER O WITH DOUBLE ACUTE + {0x0152, 0x0153, prA}, // L& [2] LATIN CAPITAL LIGATURE OE..LATIN SMALL LIGATURE OE + {0x0154, 0x0165, prN}, // L& [18] LATIN CAPITAL LETTER R WITH ACUTE..LATIN SMALL LETTER T WITH CARON + {0x0166, 0x0167, prA}, // L& [2] LATIN CAPITAL LETTER T WITH STROKE..LATIN SMALL LETTER T WITH STROKE + {0x0168, 0x016A, prN}, // L& [3] LATIN CAPITAL LETTER U WITH TILDE..LATIN CAPITAL LETTER U WITH MACRON + {0x016B, 0x016B, prA}, // Ll LATIN SMALL LETTER U WITH MACRON + {0x016C, 0x017F, prN}, // L& [20] LATIN CAPITAL LETTER U WITH BREVE..LATIN SMALL LETTER LONG S + {0x0180, 0x01BA, prN}, // L& [59] LATIN SMALL LETTER B WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL + {0x01BB, 0x01BB, prN}, // Lo LATIN LETTER TWO WITH STROKE + {0x01BC, 0x01BF, prN}, // L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN + {0x01C0, 0x01C3, prN}, // Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK + {0x01C4, 0x01CD, prN}, // L& [10] LATIN CAPITAL LETTER DZ WITH CARON..LATIN CAPITAL LETTER A WITH CARON + {0x01CE, 0x01CE, prA}, // Ll LATIN SMALL LETTER A WITH CARON + {0x01CF, 0x01CF, prN}, // Lu LATIN CAPITAL LETTER I WITH CARON + {0x01D0, 0x01D0, prA}, // Ll LATIN SMALL LETTER I WITH CARON + {0x01D1, 0x01D1, prN}, // Lu LATIN CAPITAL LETTER O WITH CARON + {0x01D2, 0x01D2, prA}, // Ll LATIN SMALL LETTER O WITH CARON + {0x01D3, 0x01D3, prN}, // Lu LATIN CAPITAL LETTER U WITH CARON + {0x01D4, 0x01D4, prA}, // Ll LATIN SMALL LETTER U WITH CARON + {0x01D5, 0x01D5, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON + {0x01D6, 0x01D6, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND MACRON + {0x01D7, 0x01D7, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE + {0x01D8, 0x01D8, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE + {0x01D9, 0x01D9, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON + {0x01DA, 0x01DA, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND CARON + {0x01DB, 0x01DB, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE + {0x01DC, 0x01DC, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE + {0x01DD, 0x024F, prN}, // L& [115] LATIN SMALL LETTER TURNED E..LATIN SMALL LETTER Y WITH STROKE + {0x0250, 0x0250, prN}, // Ll LATIN SMALL LETTER TURNED A + {0x0251, 0x0251, prA}, // Ll LATIN SMALL LETTER ALPHA + {0x0252, 0x0260, prN}, // Ll [15] LATIN SMALL LETTER TURNED ALPHA..LATIN SMALL LETTER G WITH HOOK + {0x0261, 0x0261, prA}, // Ll LATIN SMALL LETTER SCRIPT G + {0x0262, 0x0293, prN}, // Ll [50] LATIN LETTER SMALL CAPITAL G..LATIN SMALL LETTER EZH WITH CURL + {0x0294, 0x0294, prN}, // Lo LATIN LETTER GLOTTAL STOP + {0x0295, 0x02AF, prN}, // Ll [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL + {0x02B0, 0x02C1, prN}, // Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP + {0x02C2, 0x02C3, prN}, // Sk [2] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER RIGHT ARROWHEAD + {0x02C4, 0x02C4, prA}, // Sk MODIFIER LETTER UP ARROWHEAD + {0x02C5, 0x02C5, prN}, // Sk MODIFIER LETTER DOWN ARROWHEAD + {0x02C6, 0x02C6, prN}, // Lm MODIFIER LETTER CIRCUMFLEX ACCENT + {0x02C7, 0x02C7, prA}, // Lm CARON + {0x02C8, 0x02C8, prN}, // Lm MODIFIER LETTER VERTICAL LINE + {0x02C9, 0x02CB, prA}, // Lm [3] MODIFIER LETTER MACRON..MODIFIER LETTER GRAVE ACCENT + {0x02CC, 0x02CC, prN}, // Lm MODIFIER LETTER LOW VERTICAL LINE + {0x02CD, 0x02CD, prA}, // Lm MODIFIER LETTER LOW MACRON + {0x02CE, 0x02CF, prN}, // Lm [2] MODIFIER LETTER LOW GRAVE ACCENT..MODIFIER LETTER LOW ACUTE ACCENT + {0x02D0, 0x02D0, prA}, // Lm MODIFIER LETTER TRIANGULAR COLON + {0x02D1, 0x02D1, prN}, // Lm MODIFIER LETTER HALF TRIANGULAR COLON + {0x02D2, 0x02D7, prN}, // Sk [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN + {0x02D8, 0x02DB, prA}, // Sk [4] BREVE..OGONEK + {0x02DC, 0x02DC, prN}, // Sk SMALL TILDE + {0x02DD, 0x02DD, prA}, // Sk DOUBLE ACUTE ACCENT + {0x02DE, 0x02DE, prN}, // Sk MODIFIER LETTER RHOTIC HOOK + {0x02DF, 0x02DF, prA}, // Sk MODIFIER LETTER CROSS ACCENT + {0x02E0, 0x02E4, prN}, // Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP + {0x02E5, 0x02EB, prN}, // Sk [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK + {0x02EC, 0x02EC, prN}, // Lm MODIFIER LETTER VOICING + {0x02ED, 0x02ED, prN}, // Sk MODIFIER LETTER UNASPIRATED + {0x02EE, 0x02EE, prN}, // Lm MODIFIER LETTER DOUBLE APOSTROPHE + {0x02EF, 0x02FF, prN}, // Sk [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW + {0x0300, 0x036F, prA}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X + {0x0370, 0x0373, prN}, // L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI + {0x0374, 0x0374, prN}, // Lm GREEK NUMERAL SIGN + {0x0375, 0x0375, prN}, // Sk GREEK LOWER NUMERAL SIGN + {0x0376, 0x0377, prN}, // L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA + {0x037A, 0x037A, prN}, // Lm GREEK YPOGEGRAMMENI + {0x037B, 0x037D, prN}, // Ll [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x037E, 0x037E, prN}, // Po GREEK QUESTION MARK + {0x037F, 0x037F, prN}, // Lu GREEK CAPITAL LETTER YOT + {0x0384, 0x0385, prN}, // Sk [2] GREEK TONOS..GREEK DIALYTIKA TONOS + {0x0386, 0x0386, prN}, // Lu GREEK CAPITAL LETTER ALPHA WITH TONOS + {0x0387, 0x0387, prN}, // Po GREEK ANO TELEIA + {0x0388, 0x038A, prN}, // Lu [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS + {0x038C, 0x038C, prN}, // Lu GREEK CAPITAL LETTER OMICRON WITH TONOS + {0x038E, 0x0390, prN}, // L& [3] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + {0x0391, 0x03A1, prA}, // Lu [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO + {0x03A3, 0x03A9, prA}, // Lu [7] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER OMEGA + {0x03AA, 0x03B0, prN}, // L& [7] GREEK CAPITAL LETTER IOTA WITH DIALYTIKA..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + {0x03B1, 0x03C1, prA}, // Ll [17] GREEK SMALL LETTER ALPHA..GREEK SMALL LETTER RHO + {0x03C2, 0x03C2, prN}, // Ll GREEK SMALL LETTER FINAL SIGMA + {0x03C3, 0x03C9, prA}, // Ll [7] GREEK SMALL LETTER SIGMA..GREEK SMALL LETTER OMEGA + {0x03CA, 0x03F5, prN}, // L& [44] GREEK SMALL LETTER IOTA WITH DIALYTIKA..GREEK LUNATE EPSILON SYMBOL + {0x03F6, 0x03F6, prN}, // Sm GREEK REVERSED LUNATE EPSILON SYMBOL + {0x03F7, 0x03FF, prN}, // L& [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x0400, 0x0400, prN}, // Lu CYRILLIC CAPITAL LETTER IE WITH GRAVE + {0x0401, 0x0401, prA}, // Lu CYRILLIC CAPITAL LETTER IO + {0x0402, 0x040F, prN}, // Lu [14] CYRILLIC CAPITAL LETTER DJE..CYRILLIC CAPITAL LETTER DZHE + {0x0410, 0x044F, prA}, // L& [64] CYRILLIC CAPITAL LETTER A..CYRILLIC SMALL LETTER YA + {0x0450, 0x0450, prN}, // Ll CYRILLIC SMALL LETTER IE WITH GRAVE + {0x0451, 0x0451, prA}, // Ll CYRILLIC SMALL LETTER IO + {0x0452, 0x0481, prN}, // L& [48] CYRILLIC SMALL LETTER DJE..CYRILLIC SMALL LETTER KOPPA + {0x0482, 0x0482, prN}, // So CYRILLIC THOUSANDS SIGN + {0x0483, 0x0487, prN}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prN}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x048A, 0x04FF, prN}, // L& [118] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER HA WITH STROKE + {0x0500, 0x052F, prN}, // L& [48] CYRILLIC CAPITAL LETTER KOMI DE..CYRILLIC SMALL LETTER EL WITH DESCENDER + {0x0531, 0x0556, prN}, // Lu [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH + {0x0559, 0x0559, prN}, // Lm ARMENIAN MODIFIER LETTER LEFT HALF RING + {0x055A, 0x055F, prN}, // Po [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK + {0x0560, 0x0588, prN}, // Ll [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE + {0x0589, 0x0589, prN}, // Po ARMENIAN FULL STOP + {0x058A, 0x058A, prN}, // Pd ARMENIAN HYPHEN + {0x058D, 0x058E, prN}, // So [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN + {0x058F, 0x058F, prN}, // Sc ARMENIAN DRAM SIGN + {0x0591, 0x05BD, prN}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BE, 0x05BE, prN}, // Pd HEBREW PUNCTUATION MAQAF + {0x05BF, 0x05BF, prN}, // Mn HEBREW POINT RAFE + {0x05C0, 0x05C0, prN}, // Po HEBREW PUNCTUATION PASEQ + {0x05C1, 0x05C2, prN}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C3, 0x05C3, prN}, // Po HEBREW PUNCTUATION SOF PASUQ + {0x05C4, 0x05C5, prN}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C6, 0x05C6, prN}, // Po HEBREW PUNCTUATION NUN HAFUKHA + {0x05C7, 0x05C7, prN}, // Mn HEBREW POINT QAMATS QATAN + {0x05D0, 0x05EA, prN}, // Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV + {0x05EF, 0x05F2, prN}, // Lo [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD + {0x05F3, 0x05F4, prN}, // Po [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM + {0x0600, 0x0605, prN}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x0606, 0x0608, prN}, // Sm [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY + {0x0609, 0x060A, prN}, // Po [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN + {0x060B, 0x060B, prN}, // Sc AFGHANI SIGN + {0x060C, 0x060D, prN}, // Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR + {0x060E, 0x060F, prN}, // So [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA + {0x0610, 0x061A, prN}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061B, 0x061B, prN}, // Po ARABIC SEMICOLON + {0x061C, 0x061C, prN}, // Cf ARABIC LETTER MARK + {0x061D, 0x061F, prN}, // Po [3] ARABIC END OF TEXT MARK..ARABIC QUESTION MARK + {0x0620, 0x063F, prN}, // Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE + {0x0640, 0x0640, prN}, // Lm ARABIC TATWEEL + {0x0641, 0x064A, prN}, // Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH + {0x064B, 0x065F, prN}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0660, 0x0669, prN}, // Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE + {0x066A, 0x066D, prN}, // Po [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR + {0x066E, 0x066F, prN}, // Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF + {0x0670, 0x0670, prN}, // Mn ARABIC LETTER SUPERSCRIPT ALEF + {0x0671, 0x06D3, prN}, // Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE + {0x06D4, 0x06D4, prN}, // Po ARABIC FULL STOP + {0x06D5, 0x06D5, prN}, // Lo ARABIC LETTER AE + {0x06D6, 0x06DC, prN}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prN}, // Cf ARABIC END OF AYAH + {0x06DE, 0x06DE, prN}, // So ARABIC START OF RUB EL HIZB + {0x06DF, 0x06E4, prN}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E5, 0x06E6, prN}, // Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH + {0x06E7, 0x06E8, prN}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06E9, 0x06E9, prN}, // So ARABIC PLACE OF SAJDAH + {0x06EA, 0x06ED, prN}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x06EE, 0x06EF, prN}, // Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V + {0x06F0, 0x06F9, prN}, // Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE + {0x06FA, 0x06FC, prN}, // Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW + {0x06FD, 0x06FE, prN}, // So [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN + {0x06FF, 0x06FF, prN}, // Lo ARABIC LETTER HEH WITH INVERTED V + {0x0700, 0x070D, prN}, // Po [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS + {0x070F, 0x070F, prN}, // Cf SYRIAC ABBREVIATION MARK + {0x0710, 0x0710, prN}, // Lo SYRIAC LETTER ALAPH + {0x0711, 0x0711, prN}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0712, 0x072F, prN}, // Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH + {0x0730, 0x074A, prN}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x074D, 0x074F, prN}, // Lo [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE + {0x0750, 0x077F, prN}, // Lo [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE + {0x0780, 0x07A5, prN}, // Lo [38] THAANA LETTER HAA..THAANA LETTER WAAVU + {0x07A6, 0x07B0, prN}, // Mn [11] THAANA ABAFILI..THAANA SUKUN + {0x07B1, 0x07B1, prN}, // Lo THAANA LETTER NAA + {0x07C0, 0x07C9, prN}, // Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE + {0x07CA, 0x07EA, prN}, // Lo [33] NKO LETTER A..NKO LETTER JONA RA + {0x07EB, 0x07F3, prN}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07F4, 0x07F5, prN}, // Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE + {0x07F6, 0x07F6, prN}, // So NKO SYMBOL OO DENNEN + {0x07F7, 0x07F9, prN}, // Po [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK + {0x07FA, 0x07FA, prN}, // Lm NKO LAJANYALAN + {0x07FD, 0x07FD, prN}, // Mn NKO DANTAYALAN + {0x07FE, 0x07FF, prN}, // Sc [2] NKO DOROME SIGN..NKO TAMAN SIGN + {0x0800, 0x0815, prN}, // Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF + {0x0816, 0x0819, prN}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081A, 0x081A, prN}, // Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT + {0x081B, 0x0823, prN}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0824, 0x0824, prN}, // Lm SAMARITAN MODIFIER LETTER SHORT A + {0x0825, 0x0827, prN}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0828, 0x0828, prN}, // Lm SAMARITAN MODIFIER LETTER I + {0x0829, 0x082D, prN}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0830, 0x083E, prN}, // Po [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU + {0x0840, 0x0858, prN}, // Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN + {0x0859, 0x085B, prN}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x085E, 0x085E, prN}, // Po MANDAIC PUNCTUATION + {0x0860, 0x086A, prN}, // Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA + {0x0870, 0x0887, prN}, // Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT + {0x0888, 0x0888, prN}, // Sk ARABIC RAISED ROUND DOT + {0x0889, 0x088E, prN}, // Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL + {0x0890, 0x0891, prN}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prN}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08A0, 0x08C8, prN}, // Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF + {0x08C9, 0x08C9, prN}, // Lm ARABIC SMALL FARSI YEH + {0x08CA, 0x08E1, prN}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prN}, // Cf ARABIC DISPUTED END OF AYAH + {0x08E3, 0x08FF, prN}, // Mn [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA + {0x0900, 0x0902, prN}, // Mn [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prN}, // Mc DEVANAGARI SIGN VISARGA + {0x0904, 0x0939, prN}, // Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA + {0x093A, 0x093A, prN}, // Mn DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prN}, // Mc DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prN}, // Mn DEVANAGARI SIGN NUKTA + {0x093D, 0x093D, prN}, // Lo DEVANAGARI SIGN AVAGRAHA + {0x093E, 0x0940, prN}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prN}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prN}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prN}, // Mn DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prN}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0950, 0x0950, prN}, // Lo DEVANAGARI OM + {0x0951, 0x0957, prN}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0958, 0x0961, prN}, // Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL + {0x0962, 0x0963, prN}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0964, 0x0965, prN}, // Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA + {0x0966, 0x096F, prN}, // Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE + {0x0970, 0x0970, prN}, // Po DEVANAGARI ABBREVIATION SIGN + {0x0971, 0x0971, prN}, // Lm DEVANAGARI SIGN HIGH SPACING DOT + {0x0972, 0x097F, prN}, // Lo [14] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER BBA + {0x0980, 0x0980, prN}, // Lo BENGALI ANJI + {0x0981, 0x0981, prN}, // Mn BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prN}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x0985, 0x098C, prN}, // Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L + {0x098F, 0x0990, prN}, // Lo [2] BENGALI LETTER E..BENGALI LETTER AI + {0x0993, 0x09A8, prN}, // Lo [22] BENGALI LETTER O..BENGALI LETTER NA + {0x09AA, 0x09B0, prN}, // Lo [7] BENGALI LETTER PA..BENGALI LETTER RA + {0x09B2, 0x09B2, prN}, // Lo BENGALI LETTER LA + {0x09B6, 0x09B9, prN}, // Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA + {0x09BC, 0x09BC, prN}, // Mn BENGALI SIGN NUKTA + {0x09BD, 0x09BD, prN}, // Lo BENGALI SIGN AVAGRAHA + {0x09BE, 0x09C0, prN}, // Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prN}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prN}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prN}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prN}, // Mn BENGALI SIGN VIRAMA + {0x09CE, 0x09CE, prN}, // Lo BENGALI LETTER KHANDA TA + {0x09D7, 0x09D7, prN}, // Mc BENGALI AU LENGTH MARK + {0x09DC, 0x09DD, prN}, // Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA + {0x09DF, 0x09E1, prN}, // Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL + {0x09E2, 0x09E3, prN}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09E6, 0x09EF, prN}, // Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE + {0x09F0, 0x09F1, prN}, // Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL + {0x09F2, 0x09F3, prN}, // Sc [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN + {0x09F4, 0x09F9, prN}, // No [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN + {0x09FA, 0x09FA, prN}, // So BENGALI ISSHAR + {0x09FB, 0x09FB, prN}, // Sc BENGALI GANDA MARK + {0x09FC, 0x09FC, prN}, // Lo BENGALI LETTER VEDIC ANUSVARA + {0x09FD, 0x09FD, prN}, // Po BENGALI ABBREVIATION SIGN + {0x09FE, 0x09FE, prN}, // Mn BENGALI SANDHI MARK + {0x0A01, 0x0A02, prN}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prN}, // Mc GURMUKHI SIGN VISARGA + {0x0A05, 0x0A0A, prN}, // Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU + {0x0A0F, 0x0A10, prN}, // Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI + {0x0A13, 0x0A28, prN}, // Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA + {0x0A2A, 0x0A30, prN}, // Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA + {0x0A32, 0x0A33, prN}, // Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA + {0x0A35, 0x0A36, prN}, // Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA + {0x0A38, 0x0A39, prN}, // Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA + {0x0A3C, 0x0A3C, prN}, // Mn GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prN}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prN}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prN}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prN}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prN}, // Mn GURMUKHI SIGN UDAAT + {0x0A59, 0x0A5C, prN}, // Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA + {0x0A5E, 0x0A5E, prN}, // Lo GURMUKHI LETTER FA + {0x0A66, 0x0A6F, prN}, // Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE + {0x0A70, 0x0A71, prN}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A72, 0x0A74, prN}, // Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR + {0x0A75, 0x0A75, prN}, // Mn GURMUKHI SIGN YAKASH + {0x0A76, 0x0A76, prN}, // Po GURMUKHI ABBREVIATION SIGN + {0x0A81, 0x0A82, prN}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prN}, // Mc GUJARATI SIGN VISARGA + {0x0A85, 0x0A8D, prN}, // Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E + {0x0A8F, 0x0A91, prN}, // Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O + {0x0A93, 0x0AA8, prN}, // Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA + {0x0AAA, 0x0AB0, prN}, // Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA + {0x0AB2, 0x0AB3, prN}, // Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA + {0x0AB5, 0x0AB9, prN}, // Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA + {0x0ABC, 0x0ABC, prN}, // Mn GUJARATI SIGN NUKTA + {0x0ABD, 0x0ABD, prN}, // Lo GUJARATI SIGN AVAGRAHA + {0x0ABE, 0x0AC0, prN}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prN}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prN}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prN}, // Mc GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prN}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prN}, // Mn GUJARATI SIGN VIRAMA + {0x0AD0, 0x0AD0, prN}, // Lo GUJARATI OM + {0x0AE0, 0x0AE1, prN}, // Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL + {0x0AE2, 0x0AE3, prN}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AE6, 0x0AEF, prN}, // Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE + {0x0AF0, 0x0AF0, prN}, // Po GUJARATI ABBREVIATION SIGN + {0x0AF1, 0x0AF1, prN}, // Sc GUJARATI RUPEE SIGN + {0x0AF9, 0x0AF9, prN}, // Lo GUJARATI LETTER ZHA + {0x0AFA, 0x0AFF, prN}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prN}, // Mn ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prN}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B05, 0x0B0C, prN}, // Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L + {0x0B0F, 0x0B10, prN}, // Lo [2] ORIYA LETTER E..ORIYA LETTER AI + {0x0B13, 0x0B28, prN}, // Lo [22] ORIYA LETTER O..ORIYA LETTER NA + {0x0B2A, 0x0B30, prN}, // Lo [7] ORIYA LETTER PA..ORIYA LETTER RA + {0x0B32, 0x0B33, prN}, // Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA + {0x0B35, 0x0B39, prN}, // Lo [5] ORIYA LETTER VA..ORIYA LETTER HA + {0x0B3C, 0x0B3C, prN}, // Mn ORIYA SIGN NUKTA + {0x0B3D, 0x0B3D, prN}, // Lo ORIYA SIGN AVAGRAHA + {0x0B3E, 0x0B3E, prN}, // Mc ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prN}, // Mn ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prN}, // Mc ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prN}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prN}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prN}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prN}, // Mn ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prN}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prN}, // Mc ORIYA AU LENGTH MARK + {0x0B5C, 0x0B5D, prN}, // Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA + {0x0B5F, 0x0B61, prN}, // Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL + {0x0B62, 0x0B63, prN}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B66, 0x0B6F, prN}, // Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE + {0x0B70, 0x0B70, prN}, // So ORIYA ISSHAR + {0x0B71, 0x0B71, prN}, // Lo ORIYA LETTER WA + {0x0B72, 0x0B77, prN}, // No [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS + {0x0B82, 0x0B82, prN}, // Mn TAMIL SIGN ANUSVARA + {0x0B83, 0x0B83, prN}, // Lo TAMIL SIGN VISARGA + {0x0B85, 0x0B8A, prN}, // Lo [6] TAMIL LETTER A..TAMIL LETTER UU + {0x0B8E, 0x0B90, prN}, // Lo [3] TAMIL LETTER E..TAMIL LETTER AI + {0x0B92, 0x0B95, prN}, // Lo [4] TAMIL LETTER O..TAMIL LETTER KA + {0x0B99, 0x0B9A, prN}, // Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA + {0x0B9C, 0x0B9C, prN}, // Lo TAMIL LETTER JA + {0x0B9E, 0x0B9F, prN}, // Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA + {0x0BA3, 0x0BA4, prN}, // Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA + {0x0BA8, 0x0BAA, prN}, // Lo [3] TAMIL LETTER NA..TAMIL LETTER PA + {0x0BAE, 0x0BB9, prN}, // Lo [12] TAMIL LETTER MA..TAMIL LETTER HA + {0x0BBE, 0x0BBF, prN}, // Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prN}, // Mn TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prN}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prN}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prN}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prN}, // Mn TAMIL SIGN VIRAMA + {0x0BD0, 0x0BD0, prN}, // Lo TAMIL OM + {0x0BD7, 0x0BD7, prN}, // Mc TAMIL AU LENGTH MARK + {0x0BE6, 0x0BEF, prN}, // Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE + {0x0BF0, 0x0BF2, prN}, // No [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND + {0x0BF3, 0x0BF8, prN}, // So [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN + {0x0BF9, 0x0BF9, prN}, // Sc TAMIL RUPEE SIGN + {0x0BFA, 0x0BFA, prN}, // So TAMIL NUMBER SIGN + {0x0C00, 0x0C00, prN}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prN}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prN}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C05, 0x0C0C, prN}, // Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L + {0x0C0E, 0x0C10, prN}, // Lo [3] TELUGU LETTER E..TELUGU LETTER AI + {0x0C12, 0x0C28, prN}, // Lo [23] TELUGU LETTER O..TELUGU LETTER NA + {0x0C2A, 0x0C39, prN}, // Lo [16] TELUGU LETTER PA..TELUGU LETTER HA + {0x0C3C, 0x0C3C, prN}, // Mn TELUGU SIGN NUKTA + {0x0C3D, 0x0C3D, prN}, // Lo TELUGU SIGN AVAGRAHA + {0x0C3E, 0x0C40, prN}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prN}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prN}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prN}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prN}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C58, 0x0C5A, prN}, // Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA + {0x0C5D, 0x0C5D, prN}, // Lo TELUGU LETTER NAKAARA POLLU + {0x0C60, 0x0C61, prN}, // Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL + {0x0C62, 0x0C63, prN}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C66, 0x0C6F, prN}, // Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE + {0x0C77, 0x0C77, prN}, // Po TELUGU SIGN SIDDHAM + {0x0C78, 0x0C7E, prN}, // No [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR + {0x0C7F, 0x0C7F, prN}, // So TELUGU SIGN TUUMU + {0x0C80, 0x0C80, prN}, // Lo KANNADA SIGN SPACING CANDRABINDU + {0x0C81, 0x0C81, prN}, // Mn KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prN}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0C84, 0x0C84, prN}, // Po KANNADA SIGN SIDDHAM + {0x0C85, 0x0C8C, prN}, // Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L + {0x0C8E, 0x0C90, prN}, // Lo [3] KANNADA LETTER E..KANNADA LETTER AI + {0x0C92, 0x0CA8, prN}, // Lo [23] KANNADA LETTER O..KANNADA LETTER NA + {0x0CAA, 0x0CB3, prN}, // Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA + {0x0CB5, 0x0CB9, prN}, // Lo [5] KANNADA LETTER VA..KANNADA LETTER HA + {0x0CBC, 0x0CBC, prN}, // Mn KANNADA SIGN NUKTA + {0x0CBD, 0x0CBD, prN}, // Lo KANNADA SIGN AVAGRAHA + {0x0CBE, 0x0CBE, prN}, // Mc KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prN}, // Mn KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC4, prN}, // Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prN}, // Mn KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prN}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prN}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prN}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prN}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CDD, 0x0CDE, prN}, // Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA + {0x0CE0, 0x0CE1, prN}, // Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL + {0x0CE2, 0x0CE3, prN}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CE6, 0x0CEF, prN}, // Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE + {0x0CF1, 0x0CF2, prN}, // Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA + {0x0CF3, 0x0CF3, prN}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prN}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prN}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D04, 0x0D0C, prN}, // Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L + {0x0D0E, 0x0D10, prN}, // Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI + {0x0D12, 0x0D3A, prN}, // Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA + {0x0D3B, 0x0D3C, prN}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3D, 0x0D3D, prN}, // Lo MALAYALAM SIGN AVAGRAHA + {0x0D3E, 0x0D40, prN}, // Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prN}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prN}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prN}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prN}, // Mn MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prN}, // Lo MALAYALAM LETTER DOT REPH + {0x0D4F, 0x0D4F, prN}, // So MALAYALAM SIGN PARA + {0x0D54, 0x0D56, prN}, // Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL + {0x0D57, 0x0D57, prN}, // Mc MALAYALAM AU LENGTH MARK + {0x0D58, 0x0D5E, prN}, // No [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH + {0x0D5F, 0x0D61, prN}, // Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL + {0x0D62, 0x0D63, prN}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D66, 0x0D6F, prN}, // Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE + {0x0D70, 0x0D78, prN}, // No [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS + {0x0D79, 0x0D79, prN}, // So MALAYALAM DATE MARK + {0x0D7A, 0x0D7F, prN}, // Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K + {0x0D81, 0x0D81, prN}, // Mn SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prN}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0D85, 0x0D96, prN}, // Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA + {0x0D9A, 0x0DB1, prN}, // Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA + {0x0DB3, 0x0DBB, prN}, // Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA + {0x0DBD, 0x0DBD, prN}, // Lo SINHALA LETTER DANTAJA LAYANNA + {0x0DC0, 0x0DC6, prN}, // Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA + {0x0DCA, 0x0DCA, prN}, // Mn SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DD1, prN}, // Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prN}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prN}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDF, prN}, // Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA + {0x0DE6, 0x0DEF, prN}, // Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE + {0x0DF2, 0x0DF3, prN}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0DF4, 0x0DF4, prN}, // Po SINHALA PUNCTUATION KUNDDALIYA + {0x0E01, 0x0E30, prN}, // Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A + {0x0E31, 0x0E31, prN}, // Mn THAI CHARACTER MAI HAN-AKAT + {0x0E32, 0x0E33, prN}, // Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM + {0x0E34, 0x0E3A, prN}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E3F, 0x0E3F, prN}, // Sc THAI CURRENCY SYMBOL BAHT + {0x0E40, 0x0E45, prN}, // Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO + {0x0E46, 0x0E46, prN}, // Lm THAI CHARACTER MAIYAMOK + {0x0E47, 0x0E4E, prN}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0E4F, 0x0E4F, prN}, // Po THAI CHARACTER FONGMAN + {0x0E50, 0x0E59, prN}, // Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE + {0x0E5A, 0x0E5B, prN}, // Po [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT + {0x0E81, 0x0E82, prN}, // Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG + {0x0E84, 0x0E84, prN}, // Lo LAO LETTER KHO TAM + {0x0E86, 0x0E8A, prN}, // Lo [5] LAO LETTER PALI GHA..LAO LETTER SO TAM + {0x0E8C, 0x0EA3, prN}, // Lo [24] LAO LETTER PALI JHA..LAO LETTER LO LING + {0x0EA5, 0x0EA5, prN}, // Lo LAO LETTER LO LOOT + {0x0EA7, 0x0EB0, prN}, // Lo [10] LAO LETTER WO..LAO VOWEL SIGN A + {0x0EB1, 0x0EB1, prN}, // Mn LAO VOWEL SIGN MAI KAN + {0x0EB2, 0x0EB3, prN}, // Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM + {0x0EB4, 0x0EBC, prN}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EBD, 0x0EBD, prN}, // Lo LAO SEMIVOWEL SIGN NYO + {0x0EC0, 0x0EC4, prN}, // Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI + {0x0EC6, 0x0EC6, prN}, // Lm LAO KO LA + {0x0EC8, 0x0ECE, prN}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0ED0, 0x0ED9, prN}, // Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE + {0x0EDC, 0x0EDF, prN}, // Lo [4] LAO HO NO..LAO LETTER KHMU NYO + {0x0F00, 0x0F00, prN}, // Lo TIBETAN SYLLABLE OM + {0x0F01, 0x0F03, prN}, // So [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA + {0x0F04, 0x0F12, prN}, // Po [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD + {0x0F13, 0x0F13, prN}, // So TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN + {0x0F14, 0x0F14, prN}, // Po TIBETAN MARK GTER TSHEG + {0x0F15, 0x0F17, prN}, // So [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS + {0x0F18, 0x0F19, prN}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F1A, 0x0F1F, prN}, // So [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG + {0x0F20, 0x0F29, prN}, // Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE + {0x0F2A, 0x0F33, prN}, // No [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO + {0x0F34, 0x0F34, prN}, // So TIBETAN MARK BSDUS RTAGS + {0x0F35, 0x0F35, prN}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F36, 0x0F36, prN}, // So TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN + {0x0F37, 0x0F37, prN}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F38, 0x0F38, prN}, // So TIBETAN MARK CHE MGO + {0x0F39, 0x0F39, prN}, // Mn TIBETAN MARK TSA -PHRU + {0x0F3A, 0x0F3A, prN}, // Ps TIBETAN MARK GUG RTAGS GYON + {0x0F3B, 0x0F3B, prN}, // Pe TIBETAN MARK GUG RTAGS GYAS + {0x0F3C, 0x0F3C, prN}, // Ps TIBETAN MARK ANG KHANG GYON + {0x0F3D, 0x0F3D, prN}, // Pe TIBETAN MARK ANG KHANG GYAS + {0x0F3E, 0x0F3F, prN}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F40, 0x0F47, prN}, // Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA + {0x0F49, 0x0F6C, prN}, // Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA + {0x0F71, 0x0F7E, prN}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prN}, // Mc TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prN}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F85, 0x0F85, prN}, // Po TIBETAN MARK PALUTA + {0x0F86, 0x0F87, prN}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F88, 0x0F8C, prN}, // Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN + {0x0F8D, 0x0F97, prN}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prN}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FBE, 0x0FC5, prN}, // So [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE + {0x0FC6, 0x0FC6, prN}, // Mn TIBETAN SYMBOL PADMA GDAN + {0x0FC7, 0x0FCC, prN}, // So [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL + {0x0FCE, 0x0FCF, prN}, // So [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM + {0x0FD0, 0x0FD4, prN}, // Po [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA + {0x0FD5, 0x0FD8, prN}, // So [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS + {0x0FD9, 0x0FDA, prN}, // Po [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS + {0x1000, 0x102A, prN}, // Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU + {0x102B, 0x102C, prN}, // Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA + {0x102D, 0x1030, prN}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prN}, // Mc MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prN}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1038, 0x1038, prN}, // Mc MYANMAR SIGN VISARGA + {0x1039, 0x103A, prN}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prN}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prN}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x103F, 0x103F, prN}, // Lo MYANMAR LETTER GREAT SA + {0x1040, 0x1049, prN}, // Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE + {0x104A, 0x104F, prN}, // Po [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE + {0x1050, 0x1055, prN}, // Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL + {0x1056, 0x1057, prN}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prN}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105A, 0x105D, prN}, // Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE + {0x105E, 0x1060, prN}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1061, 0x1061, prN}, // Lo MYANMAR LETTER SGAW KAREN SHA + {0x1062, 0x1064, prN}, // Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO + {0x1065, 0x1066, prN}, // Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA + {0x1067, 0x106D, prN}, // Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 + {0x106E, 0x1070, prN}, // Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA + {0x1071, 0x1074, prN}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1075, 0x1081, prN}, // Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA + {0x1082, 0x1082, prN}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1083, 0x1084, prN}, // Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prN}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x1087, 0x108C, prN}, // Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 + {0x108D, 0x108D, prN}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x108E, 0x108E, prN}, // Lo MYANMAR LETTER RUMAI PALAUNG FA + {0x108F, 0x108F, prN}, // Mc MYANMAR SIGN RUMAI PALAUNG TONE-5 + {0x1090, 0x1099, prN}, // Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE + {0x109A, 0x109C, prN}, // Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A + {0x109D, 0x109D, prN}, // Mn MYANMAR VOWEL SIGN AITON AI + {0x109E, 0x109F, prN}, // So [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION + {0x10A0, 0x10C5, prN}, // Lu [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE + {0x10C7, 0x10C7, prN}, // Lu GEORGIAN CAPITAL LETTER YN + {0x10CD, 0x10CD, prN}, // Lu GEORGIAN CAPITAL LETTER AEN + {0x10D0, 0x10FA, prN}, // Ll [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN + {0x10FB, 0x10FB, prN}, // Po GEORGIAN PARAGRAPH SEPARATOR + {0x10FC, 0x10FC, prN}, // Lm MODIFIER LETTER GEORGIAN NAR + {0x10FD, 0x10FF, prN}, // Ll [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN + {0x1100, 0x115F, prW}, // Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER + {0x1160, 0x11FF, prN}, // Lo [160] HANGUL JUNGSEONG FILLER..HANGUL JONGSEONG SSANGNIEUN + {0x1200, 0x1248, prN}, // Lo [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA + {0x124A, 0x124D, prN}, // Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE + {0x1250, 0x1256, prN}, // Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO + {0x1258, 0x1258, prN}, // Lo ETHIOPIC SYLLABLE QHWA + {0x125A, 0x125D, prN}, // Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE + {0x1260, 0x1288, prN}, // Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA + {0x128A, 0x128D, prN}, // Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE + {0x1290, 0x12B0, prN}, // Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA + {0x12B2, 0x12B5, prN}, // Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE + {0x12B8, 0x12BE, prN}, // Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO + {0x12C0, 0x12C0, prN}, // Lo ETHIOPIC SYLLABLE KXWA + {0x12C2, 0x12C5, prN}, // Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE + {0x12C8, 0x12D6, prN}, // Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O + {0x12D8, 0x1310, prN}, // Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA + {0x1312, 0x1315, prN}, // Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE + {0x1318, 0x135A, prN}, // Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA + {0x135D, 0x135F, prN}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1360, 0x1368, prN}, // Po [9] ETHIOPIC SECTION MARK..ETHIOPIC PARAGRAPH SEPARATOR + {0x1369, 0x137C, prN}, // No [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND + {0x1380, 0x138F, prN}, // Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE + {0x1390, 0x1399, prN}, // So [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT + {0x13A0, 0x13F5, prN}, // Lu [86] CHEROKEE LETTER A..CHEROKEE LETTER MV + {0x13F8, 0x13FD, prN}, // Ll [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV + {0x1400, 0x1400, prN}, // Pd CANADIAN SYLLABICS HYPHEN + {0x1401, 0x166C, prN}, // Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA + {0x166D, 0x166D, prN}, // So CANADIAN SYLLABICS CHI SIGN + {0x166E, 0x166E, prN}, // Po CANADIAN SYLLABICS FULL STOP + {0x166F, 0x167F, prN}, // Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W + {0x1680, 0x1680, prN}, // Zs OGHAM SPACE MARK + {0x1681, 0x169A, prN}, // Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH + {0x169B, 0x169B, prN}, // Ps OGHAM FEATHER MARK + {0x169C, 0x169C, prN}, // Pe OGHAM REVERSED FEATHER MARK + {0x16A0, 0x16EA, prN}, // Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X + {0x16EB, 0x16ED, prN}, // Po [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION + {0x16EE, 0x16F0, prN}, // Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL + {0x16F1, 0x16F8, prN}, // Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC + {0x1700, 0x1711, prN}, // Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA + {0x1712, 0x1714, prN}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prN}, // Mc TAGALOG SIGN PAMUDPOD + {0x171F, 0x171F, prN}, // Lo TAGALOG LETTER ARCHAIC RA + {0x1720, 0x1731, prN}, // Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA + {0x1732, 0x1733, prN}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prN}, // Mc HANUNOO SIGN PAMUDPOD + {0x1735, 0x1736, prN}, // Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION + {0x1740, 0x1751, prN}, // Lo [18] BUHID LETTER A..BUHID LETTER HA + {0x1752, 0x1753, prN}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1760, 0x176C, prN}, // Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA + {0x176E, 0x1770, prN}, // Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA + {0x1772, 0x1773, prN}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x1780, 0x17B3, prN}, // Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU + {0x17B4, 0x17B5, prN}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prN}, // Mc KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prN}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prN}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prN}, // Mn KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prN}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prN}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17D4, 0x17D6, prN}, // Po [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH + {0x17D7, 0x17D7, prN}, // Lm KHMER SIGN LEK TOO + {0x17D8, 0x17DA, prN}, // Po [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT + {0x17DB, 0x17DB, prN}, // Sc KHMER CURRENCY SYMBOL RIEL + {0x17DC, 0x17DC, prN}, // Lo KHMER SIGN AVAKRAHASANYA + {0x17DD, 0x17DD, prN}, // Mn KHMER SIGN ATTHACAN + {0x17E0, 0x17E9, prN}, // Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE + {0x17F0, 0x17F9, prN}, // No [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON + {0x1800, 0x1805, prN}, // Po [6] MONGOLIAN BIRGA..MONGOLIAN FOUR DOTS + {0x1806, 0x1806, prN}, // Pd MONGOLIAN TODO SOFT HYPHEN + {0x1807, 0x180A, prN}, // Po [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU + {0x180B, 0x180D, prN}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prN}, // Cf MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prN}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1810, 0x1819, prN}, // Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE + {0x1820, 0x1842, prN}, // Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI + {0x1843, 0x1843, prN}, // Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN + {0x1844, 0x1878, prN}, // Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS + {0x1880, 0x1884, prN}, // Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA + {0x1885, 0x1886, prN}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x1887, 0x18A8, prN}, // Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA + {0x18A9, 0x18A9, prN}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA + {0x18AA, 0x18AA, prN}, // Lo MONGOLIAN LETTER MANCHU ALI GALI LHA + {0x18B0, 0x18F5, prN}, // Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S + {0x1900, 0x191E, prN}, // Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA + {0x1920, 0x1922, prN}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prN}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prN}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prN}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prN}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prN}, // Mn LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prN}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prN}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1940, 0x1940, prN}, // So LIMBU SIGN LOO + {0x1944, 0x1945, prN}, // Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK + {0x1946, 0x194F, prN}, // Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE + {0x1950, 0x196D, prN}, // Lo [30] TAI LE LETTER KA..TAI LE LETTER AI + {0x1970, 0x1974, prN}, // Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 + {0x1980, 0x19AB, prN}, // Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA + {0x19B0, 0x19C9, prN}, // Lo [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2 + {0x19D0, 0x19D9, prN}, // Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE + {0x19DA, 0x19DA, prN}, // No NEW TAI LUE THAM DIGIT ONE + {0x19DE, 0x19DF, prN}, // So [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV + {0x19E0, 0x19FF, prN}, // So [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC + {0x1A00, 0x1A16, prN}, // Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA + {0x1A17, 0x1A18, prN}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prN}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prN}, // Mn BUGINESE VOWEL SIGN AE + {0x1A1E, 0x1A1F, prN}, // Po [2] BUGINESE PALLAWA..BUGINESE END OF SECTION + {0x1A20, 0x1A54, prN}, // Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA + {0x1A55, 0x1A55, prN}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prN}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prN}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prN}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prN}, // Mn TAI THAM SIGN SAKOT + {0x1A61, 0x1A61, prN}, // Mc TAI THAM VOWEL SIGN A + {0x1A62, 0x1A62, prN}, // Mn TAI THAM VOWEL SIGN MAI SAT + {0x1A63, 0x1A64, prN}, // Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA + {0x1A65, 0x1A6C, prN}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prN}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prN}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prN}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1A80, 0x1A89, prN}, // Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE + {0x1A90, 0x1A99, prN}, // Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE + {0x1AA0, 0x1AA6, prN}, // Po [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA + {0x1AA7, 0x1AA7, prN}, // Lm TAI THAM SIGN MAI YAMOK + {0x1AA8, 0x1AAD, prN}, // Po [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG + {0x1AB0, 0x1ABD, prN}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prN}, // Me COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prN}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prN}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prN}, // Mc BALINESE SIGN BISAH + {0x1B05, 0x1B33, prN}, // Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA + {0x1B34, 0x1B34, prN}, // Mn BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prN}, // Mc BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prN}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prN}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prN}, // Mn BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prN}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prN}, // Mn BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prN}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B45, 0x1B4C, prN}, // Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA + {0x1B50, 0x1B59, prN}, // Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE + {0x1B5A, 0x1B60, prN}, // Po [7] BALINESE PANTI..BALINESE PAMENENG + {0x1B61, 0x1B6A, prN}, // So [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE + {0x1B6B, 0x1B73, prN}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B74, 0x1B7C, prN}, // So [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING + {0x1B7D, 0x1B7E, prN}, // Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG + {0x1B80, 0x1B81, prN}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prN}, // Mc SUNDANESE SIGN PANGWISAD + {0x1B83, 0x1BA0, prN}, // Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA + {0x1BA1, 0x1BA1, prN}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prN}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prN}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prN}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prN}, // Mc SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prN}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BAE, 0x1BAF, prN}, // Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA + {0x1BB0, 0x1BB9, prN}, // Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE + {0x1BBA, 0x1BBF, prN}, // Lo [6] SUNDANESE AVAGRAHA..SUNDANESE LETTER FINAL M + {0x1BC0, 0x1BE5, prN}, // Lo [38] BATAK LETTER A..BATAK LETTER U + {0x1BE6, 0x1BE6, prN}, // Mn BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prN}, // Mc BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prN}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prN}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prN}, // Mn BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prN}, // Mc BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prN}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prN}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1BFC, 0x1BFF, prN}, // Po [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT + {0x1C00, 0x1C23, prN}, // Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A + {0x1C24, 0x1C2B, prN}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prN}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prN}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prN}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1C3B, 0x1C3F, prN}, // Po [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK + {0x1C40, 0x1C49, prN}, // Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE + {0x1C4D, 0x1C4F, prN}, // Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA + {0x1C50, 0x1C59, prN}, // Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE + {0x1C5A, 0x1C77, prN}, // Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH + {0x1C78, 0x1C7D, prN}, // Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD + {0x1C7E, 0x1C7F, prN}, // Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD + {0x1C80, 0x1C88, prN}, // Ll [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK + {0x1C90, 0x1CBA, prN}, // Lu [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN + {0x1CBD, 0x1CBF, prN}, // Lu [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN + {0x1CC0, 0x1CC7, prN}, // Po [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA + {0x1CD0, 0x1CD2, prN}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD3, 0x1CD3, prN}, // Po VEDIC SIGN NIHSHVASA + {0x1CD4, 0x1CE0, prN}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prN}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prN}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CE9, 0x1CEC, prN}, // Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL + {0x1CED, 0x1CED, prN}, // Mn VEDIC SIGN TIRYAK + {0x1CEE, 0x1CF3, prN}, // Lo [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA + {0x1CF4, 0x1CF4, prN}, // Mn VEDIC TONE CANDRA ABOVE + {0x1CF5, 0x1CF6, prN}, // Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA + {0x1CF7, 0x1CF7, prN}, // Mc VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prN}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1CFA, 0x1CFA, prN}, // Lo VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA + {0x1D00, 0x1D2B, prN}, // Ll [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL + {0x1D2C, 0x1D6A, prN}, // Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI + {0x1D6B, 0x1D77, prN}, // Ll [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G + {0x1D78, 0x1D78, prN}, // Lm MODIFIER LETTER CYRILLIC EN + {0x1D79, 0x1D7F, prN}, // Ll [7] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER UPSILON WITH STROKE + {0x1D80, 0x1D9A, prN}, // Ll [27] LATIN SMALL LETTER B WITH PALATAL HOOK..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK + {0x1D9B, 0x1DBF, prN}, // Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA + {0x1DC0, 0x1DFF, prN}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x1E00, 0x1EFF, prN}, // L& [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP + {0x1F00, 0x1F15, prN}, // L& [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA + {0x1F18, 0x1F1D, prN}, // Lu [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA + {0x1F20, 0x1F45, prN}, // L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA + {0x1F48, 0x1F4D, prN}, // Lu [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA + {0x1F50, 0x1F57, prN}, // Ll [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F59, 0x1F59, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA + {0x1F5B, 0x1F5B, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA + {0x1F5D, 0x1F5D, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA + {0x1F5F, 0x1F7D, prN}, // L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA + {0x1F80, 0x1FB4, prN}, // L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI + {0x1FB6, 0x1FBC, prN}, // L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI + {0x1FBD, 0x1FBD, prN}, // Sk GREEK KORONIS + {0x1FBE, 0x1FBE, prN}, // Ll GREEK PROSGEGRAMMENI + {0x1FBF, 0x1FC1, prN}, // Sk [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI + {0x1FC2, 0x1FC4, prN}, // Ll [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI + {0x1FC6, 0x1FCC, prN}, // L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI + {0x1FCD, 0x1FCF, prN}, // Sk [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI + {0x1FD0, 0x1FD3, prN}, // Ll [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + {0x1FD6, 0x1FDB, prN}, // L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA + {0x1FDD, 0x1FDF, prN}, // Sk [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI + {0x1FE0, 0x1FEC, prN}, // L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA + {0x1FED, 0x1FEF, prN}, // Sk [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA + {0x1FF2, 0x1FF4, prN}, // Ll [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI + {0x1FF6, 0x1FFC, prN}, // L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + {0x1FFD, 0x1FFE, prN}, // Sk [2] GREEK OXIA..GREEK DASIA + {0x2000, 0x200A, prN}, // Zs [11] EN QUAD..HAIR SPACE + {0x200B, 0x200F, prN}, // Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK + {0x2010, 0x2010, prA}, // Pd HYPHEN + {0x2011, 0x2012, prN}, // Pd [2] NON-BREAKING HYPHEN..FIGURE DASH + {0x2013, 0x2015, prA}, // Pd [3] EN DASH..HORIZONTAL BAR + {0x2016, 0x2016, prA}, // Po DOUBLE VERTICAL LINE + {0x2017, 0x2017, prN}, // Po DOUBLE LOW LINE + {0x2018, 0x2018, prA}, // Pi LEFT SINGLE QUOTATION MARK + {0x2019, 0x2019, prA}, // Pf RIGHT SINGLE QUOTATION MARK + {0x201A, 0x201A, prN}, // Ps SINGLE LOW-9 QUOTATION MARK + {0x201B, 0x201B, prN}, // Pi SINGLE HIGH-REVERSED-9 QUOTATION MARK + {0x201C, 0x201C, prA}, // Pi LEFT DOUBLE QUOTATION MARK + {0x201D, 0x201D, prA}, // Pf RIGHT DOUBLE QUOTATION MARK + {0x201E, 0x201E, prN}, // Ps DOUBLE LOW-9 QUOTATION MARK + {0x201F, 0x201F, prN}, // Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK + {0x2020, 0x2022, prA}, // Po [3] DAGGER..BULLET + {0x2023, 0x2023, prN}, // Po TRIANGULAR BULLET + {0x2024, 0x2027, prA}, // Po [4] ONE DOT LEADER..HYPHENATION POINT + {0x2028, 0x2028, prN}, // Zl LINE SEPARATOR + {0x2029, 0x2029, prN}, // Zp PARAGRAPH SEPARATOR + {0x202A, 0x202E, prN}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x202F, 0x202F, prN}, // Zs NARROW NO-BREAK SPACE + {0x2030, 0x2030, prA}, // Po PER MILLE SIGN + {0x2031, 0x2031, prN}, // Po PER TEN THOUSAND SIGN + {0x2032, 0x2033, prA}, // Po [2] PRIME..DOUBLE PRIME + {0x2034, 0x2034, prN}, // Po TRIPLE PRIME + {0x2035, 0x2035, prA}, // Po REVERSED PRIME + {0x2036, 0x2038, prN}, // Po [3] REVERSED DOUBLE PRIME..CARET + {0x2039, 0x2039, prN}, // Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK + {0x203A, 0x203A, prN}, // Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + {0x203B, 0x203B, prA}, // Po REFERENCE MARK + {0x203C, 0x203D, prN}, // Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG + {0x203E, 0x203E, prA}, // Po OVERLINE + {0x203F, 0x2040, prN}, // Pc [2] UNDERTIE..CHARACTER TIE + {0x2041, 0x2043, prN}, // Po [3] CARET INSERTION POINT..HYPHEN BULLET + {0x2044, 0x2044, prN}, // Sm FRACTION SLASH + {0x2045, 0x2045, prN}, // Ps LEFT SQUARE BRACKET WITH QUILL + {0x2046, 0x2046, prN}, // Pe RIGHT SQUARE BRACKET WITH QUILL + {0x2047, 0x2051, prN}, // Po [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY + {0x2052, 0x2052, prN}, // Sm COMMERCIAL MINUS SIGN + {0x2053, 0x2053, prN}, // Po SWUNG DASH + {0x2054, 0x2054, prN}, // Pc INVERTED UNDERTIE + {0x2055, 0x205E, prN}, // Po [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS + {0x205F, 0x205F, prN}, // Zs MEDIUM MATHEMATICAL SPACE + {0x2060, 0x2064, prN}, // Cf [5] WORD JOINER..INVISIBLE PLUS + {0x2066, 0x206F, prN}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x2070, 0x2070, prN}, // No SUPERSCRIPT ZERO + {0x2071, 0x2071, prN}, // Lm SUPERSCRIPT LATIN SMALL LETTER I + {0x2074, 0x2074, prA}, // No SUPERSCRIPT FOUR + {0x2075, 0x2079, prN}, // No [5] SUPERSCRIPT FIVE..SUPERSCRIPT NINE + {0x207A, 0x207C, prN}, // Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN + {0x207D, 0x207D, prN}, // Ps SUPERSCRIPT LEFT PARENTHESIS + {0x207E, 0x207E, prN}, // Pe SUPERSCRIPT RIGHT PARENTHESIS + {0x207F, 0x207F, prA}, // Lm SUPERSCRIPT LATIN SMALL LETTER N + {0x2080, 0x2080, prN}, // No SUBSCRIPT ZERO + {0x2081, 0x2084, prA}, // No [4] SUBSCRIPT ONE..SUBSCRIPT FOUR + {0x2085, 0x2089, prN}, // No [5] SUBSCRIPT FIVE..SUBSCRIPT NINE + {0x208A, 0x208C, prN}, // Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN + {0x208D, 0x208D, prN}, // Ps SUBSCRIPT LEFT PARENTHESIS + {0x208E, 0x208E, prN}, // Pe SUBSCRIPT RIGHT PARENTHESIS + {0x2090, 0x209C, prN}, // Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T + {0x20A0, 0x20A8, prN}, // Sc [9] EURO-CURRENCY SIGN..RUPEE SIGN + {0x20A9, 0x20A9, prH}, // Sc WON SIGN + {0x20AA, 0x20AB, prN}, // Sc [2] NEW SHEQEL SIGN..DONG SIGN + {0x20AC, 0x20AC, prA}, // Sc EURO SIGN + {0x20AD, 0x20C0, prN}, // Sc [20] KIP SIGN..SOM SIGN + {0x20D0, 0x20DC, prN}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prN}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prN}, // Mn COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prN}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prN}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2100, 0x2101, prN}, // So [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT + {0x2102, 0x2102, prN}, // Lu DOUBLE-STRUCK CAPITAL C + {0x2103, 0x2103, prA}, // So DEGREE CELSIUS + {0x2104, 0x2104, prN}, // So CENTRE LINE SYMBOL + {0x2105, 0x2105, prA}, // So CARE OF + {0x2106, 0x2106, prN}, // So CADA UNA + {0x2107, 0x2107, prN}, // Lu EULER CONSTANT + {0x2108, 0x2108, prN}, // So SCRUPLE + {0x2109, 0x2109, prA}, // So DEGREE FAHRENHEIT + {0x210A, 0x2112, prN}, // L& [9] SCRIPT SMALL G..SCRIPT CAPITAL L + {0x2113, 0x2113, prA}, // Ll SCRIPT SMALL L + {0x2114, 0x2114, prN}, // So L B BAR SYMBOL + {0x2115, 0x2115, prN}, // Lu DOUBLE-STRUCK CAPITAL N + {0x2116, 0x2116, prA}, // So NUMERO SIGN + {0x2117, 0x2117, prN}, // So SOUND RECORDING COPYRIGHT + {0x2118, 0x2118, prN}, // Sm SCRIPT CAPITAL P + {0x2119, 0x211D, prN}, // Lu [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R + {0x211E, 0x2120, prN}, // So [3] PRESCRIPTION TAKE..SERVICE MARK + {0x2121, 0x2122, prA}, // So [2] TELEPHONE SIGN..TRADE MARK SIGN + {0x2123, 0x2123, prN}, // So VERSICLE + {0x2124, 0x2124, prN}, // Lu DOUBLE-STRUCK CAPITAL Z + {0x2125, 0x2125, prN}, // So OUNCE SIGN + {0x2126, 0x2126, prA}, // Lu OHM SIGN + {0x2127, 0x2127, prN}, // So INVERTED OHM SIGN + {0x2128, 0x2128, prN}, // Lu BLACK-LETTER CAPITAL Z + {0x2129, 0x2129, prN}, // So TURNED GREEK SMALL LETTER IOTA + {0x212A, 0x212A, prN}, // Lu KELVIN SIGN + {0x212B, 0x212B, prA}, // Lu ANGSTROM SIGN + {0x212C, 0x212D, prN}, // Lu [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C + {0x212E, 0x212E, prN}, // So ESTIMATED SYMBOL + {0x212F, 0x2134, prN}, // L& [6] SCRIPT SMALL E..SCRIPT SMALL O + {0x2135, 0x2138, prN}, // Lo [4] ALEF SYMBOL..DALET SYMBOL + {0x2139, 0x2139, prN}, // Ll INFORMATION SOURCE + {0x213A, 0x213B, prN}, // So [2] ROTATED CAPITAL Q..FACSIMILE SIGN + {0x213C, 0x213F, prN}, // L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI + {0x2140, 0x2144, prN}, // Sm [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y + {0x2145, 0x2149, prN}, // L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J + {0x214A, 0x214A, prN}, // So PROPERTY LINE + {0x214B, 0x214B, prN}, // Sm TURNED AMPERSAND + {0x214C, 0x214D, prN}, // So [2] PER SIGN..AKTIESELSKAB + {0x214E, 0x214E, prN}, // Ll TURNED SMALL F + {0x214F, 0x214F, prN}, // So SYMBOL FOR SAMARITAN SOURCE + {0x2150, 0x2152, prN}, // No [3] VULGAR FRACTION ONE SEVENTH..VULGAR FRACTION ONE TENTH + {0x2153, 0x2154, prA}, // No [2] VULGAR FRACTION ONE THIRD..VULGAR FRACTION TWO THIRDS + {0x2155, 0x215A, prN}, // No [6] VULGAR FRACTION ONE FIFTH..VULGAR FRACTION FIVE SIXTHS + {0x215B, 0x215E, prA}, // No [4] VULGAR FRACTION ONE EIGHTH..VULGAR FRACTION SEVEN EIGHTHS + {0x215F, 0x215F, prN}, // No FRACTION NUMERATOR ONE + {0x2160, 0x216B, prA}, // Nl [12] ROMAN NUMERAL ONE..ROMAN NUMERAL TWELVE + {0x216C, 0x216F, prN}, // Nl [4] ROMAN NUMERAL FIFTY..ROMAN NUMERAL ONE THOUSAND + {0x2170, 0x2179, prA}, // Nl [10] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL TEN + {0x217A, 0x2182, prN}, // Nl [9] SMALL ROMAN NUMERAL ELEVEN..ROMAN NUMERAL TEN THOUSAND + {0x2183, 0x2184, prN}, // L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C + {0x2185, 0x2188, prN}, // Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND + {0x2189, 0x2189, prA}, // No VULGAR FRACTION ZERO THIRDS + {0x218A, 0x218B, prN}, // So [2] TURNED DIGIT TWO..TURNED DIGIT THREE + {0x2190, 0x2194, prA}, // Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW + {0x2195, 0x2199, prA}, // So [5] UP DOWN ARROW..SOUTH WEST ARROW + {0x219A, 0x219B, prN}, // Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE + {0x219C, 0x219F, prN}, // So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW + {0x21A0, 0x21A0, prN}, // Sm RIGHTWARDS TWO HEADED ARROW + {0x21A1, 0x21A2, prN}, // So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL + {0x21A3, 0x21A3, prN}, // Sm RIGHTWARDS ARROW WITH TAIL + {0x21A4, 0x21A5, prN}, // So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR + {0x21A6, 0x21A6, prN}, // Sm RIGHTWARDS ARROW FROM BAR + {0x21A7, 0x21AD, prN}, // So [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW + {0x21AE, 0x21AE, prN}, // Sm LEFT RIGHT ARROW WITH STROKE + {0x21AF, 0x21B7, prN}, // So [9] DOWNWARDS ZIGZAG ARROW..CLOCKWISE TOP SEMICIRCLE ARROW + {0x21B8, 0x21B9, prA}, // So [2] NORTH WEST ARROW TO LONG BAR..LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR + {0x21BA, 0x21CD, prN}, // So [20] ANTICLOCKWISE OPEN CIRCLE ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE + {0x21CE, 0x21CF, prN}, // Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE + {0x21D0, 0x21D1, prN}, // So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW + {0x21D2, 0x21D2, prA}, // Sm RIGHTWARDS DOUBLE ARROW + {0x21D3, 0x21D3, prN}, // So DOWNWARDS DOUBLE ARROW + {0x21D4, 0x21D4, prA}, // Sm LEFT RIGHT DOUBLE ARROW + {0x21D5, 0x21E6, prN}, // So [18] UP DOWN DOUBLE ARROW..LEFTWARDS WHITE ARROW + {0x21E7, 0x21E7, prA}, // So UPWARDS WHITE ARROW + {0x21E8, 0x21F3, prN}, // So [12] RIGHTWARDS WHITE ARROW..UP DOWN WHITE ARROW + {0x21F4, 0x21FF, prN}, // Sm [12] RIGHT ARROW WITH SMALL CIRCLE..LEFT RIGHT OPEN-HEADED ARROW + {0x2200, 0x2200, prA}, // Sm FOR ALL + {0x2201, 0x2201, prN}, // Sm COMPLEMENT + {0x2202, 0x2203, prA}, // Sm [2] PARTIAL DIFFERENTIAL..THERE EXISTS + {0x2204, 0x2206, prN}, // Sm [3] THERE DOES NOT EXIST..INCREMENT + {0x2207, 0x2208, prA}, // Sm [2] NABLA..ELEMENT OF + {0x2209, 0x220A, prN}, // Sm [2] NOT AN ELEMENT OF..SMALL ELEMENT OF + {0x220B, 0x220B, prA}, // Sm CONTAINS AS MEMBER + {0x220C, 0x220E, prN}, // Sm [3] DOES NOT CONTAIN AS MEMBER..END OF PROOF + {0x220F, 0x220F, prA}, // Sm N-ARY PRODUCT + {0x2210, 0x2210, prN}, // Sm N-ARY COPRODUCT + {0x2211, 0x2211, prA}, // Sm N-ARY SUMMATION + {0x2212, 0x2214, prN}, // Sm [3] MINUS SIGN..DOT PLUS + {0x2215, 0x2215, prA}, // Sm DIVISION SLASH + {0x2216, 0x2219, prN}, // Sm [4] SET MINUS..BULLET OPERATOR + {0x221A, 0x221A, prA}, // Sm SQUARE ROOT + {0x221B, 0x221C, prN}, // Sm [2] CUBE ROOT..FOURTH ROOT + {0x221D, 0x2220, prA}, // Sm [4] PROPORTIONAL TO..ANGLE + {0x2221, 0x2222, prN}, // Sm [2] MEASURED ANGLE..SPHERICAL ANGLE + {0x2223, 0x2223, prA}, // Sm DIVIDES + {0x2224, 0x2224, prN}, // Sm DOES NOT DIVIDE + {0x2225, 0x2225, prA}, // Sm PARALLEL TO + {0x2226, 0x2226, prN}, // Sm NOT PARALLEL TO + {0x2227, 0x222C, prA}, // Sm [6] LOGICAL AND..DOUBLE INTEGRAL + {0x222D, 0x222D, prN}, // Sm TRIPLE INTEGRAL + {0x222E, 0x222E, prA}, // Sm CONTOUR INTEGRAL + {0x222F, 0x2233, prN}, // Sm [5] SURFACE INTEGRAL..ANTICLOCKWISE CONTOUR INTEGRAL + {0x2234, 0x2237, prA}, // Sm [4] THEREFORE..PROPORTION + {0x2238, 0x223B, prN}, // Sm [4] DOT MINUS..HOMOTHETIC + {0x223C, 0x223D, prA}, // Sm [2] TILDE OPERATOR..REVERSED TILDE + {0x223E, 0x2247, prN}, // Sm [10] INVERTED LAZY S..NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + {0x2248, 0x2248, prA}, // Sm ALMOST EQUAL TO + {0x2249, 0x224B, prN}, // Sm [3] NOT ALMOST EQUAL TO..TRIPLE TILDE + {0x224C, 0x224C, prA}, // Sm ALL EQUAL TO + {0x224D, 0x2251, prN}, // Sm [5] EQUIVALENT TO..GEOMETRICALLY EQUAL TO + {0x2252, 0x2252, prA}, // Sm APPROXIMATELY EQUAL TO OR THE IMAGE OF + {0x2253, 0x225F, prN}, // Sm [13] IMAGE OF OR APPROXIMATELY EQUAL TO..QUESTIONED EQUAL TO + {0x2260, 0x2261, prA}, // Sm [2] NOT EQUAL TO..IDENTICAL TO + {0x2262, 0x2263, prN}, // Sm [2] NOT IDENTICAL TO..STRICTLY EQUIVALENT TO + {0x2264, 0x2267, prA}, // Sm [4] LESS-THAN OR EQUAL TO..GREATER-THAN OVER EQUAL TO + {0x2268, 0x2269, prN}, // Sm [2] LESS-THAN BUT NOT EQUAL TO..GREATER-THAN BUT NOT EQUAL TO + {0x226A, 0x226B, prA}, // Sm [2] MUCH LESS-THAN..MUCH GREATER-THAN + {0x226C, 0x226D, prN}, // Sm [2] BETWEEN..NOT EQUIVALENT TO + {0x226E, 0x226F, prA}, // Sm [2] NOT LESS-THAN..NOT GREATER-THAN + {0x2270, 0x2281, prN}, // Sm [18] NEITHER LESS-THAN NOR EQUAL TO..DOES NOT SUCCEED + {0x2282, 0x2283, prA}, // Sm [2] SUBSET OF..SUPERSET OF + {0x2284, 0x2285, prN}, // Sm [2] NOT A SUBSET OF..NOT A SUPERSET OF + {0x2286, 0x2287, prA}, // Sm [2] SUBSET OF OR EQUAL TO..SUPERSET OF OR EQUAL TO + {0x2288, 0x2294, prN}, // Sm [13] NEITHER A SUBSET OF NOR EQUAL TO..SQUARE CUP + {0x2295, 0x2295, prA}, // Sm CIRCLED PLUS + {0x2296, 0x2298, prN}, // Sm [3] CIRCLED MINUS..CIRCLED DIVISION SLASH + {0x2299, 0x2299, prA}, // Sm CIRCLED DOT OPERATOR + {0x229A, 0x22A4, prN}, // Sm [11] CIRCLED RING OPERATOR..DOWN TACK + {0x22A5, 0x22A5, prA}, // Sm UP TACK + {0x22A6, 0x22BE, prN}, // Sm [25] ASSERTION..RIGHT ANGLE WITH ARC + {0x22BF, 0x22BF, prA}, // Sm RIGHT TRIANGLE + {0x22C0, 0x22FF, prN}, // Sm [64] N-ARY LOGICAL AND..Z NOTATION BAG MEMBERSHIP + {0x2300, 0x2307, prN}, // So [8] DIAMETER SIGN..WAVY LINE + {0x2308, 0x2308, prN}, // Ps LEFT CEILING + {0x2309, 0x2309, prN}, // Pe RIGHT CEILING + {0x230A, 0x230A, prN}, // Ps LEFT FLOOR + {0x230B, 0x230B, prN}, // Pe RIGHT FLOOR + {0x230C, 0x2311, prN}, // So [6] BOTTOM RIGHT CROP..SQUARE LOZENGE + {0x2312, 0x2312, prA}, // So ARC + {0x2313, 0x2319, prN}, // So [7] SEGMENT..TURNED NOT SIGN + {0x231A, 0x231B, prW}, // So [2] WATCH..HOURGLASS + {0x231C, 0x231F, prN}, // So [4] TOP LEFT CORNER..BOTTOM RIGHT CORNER + {0x2320, 0x2321, prN}, // Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL + {0x2322, 0x2328, prN}, // So [7] FROWN..KEYBOARD + {0x2329, 0x2329, prW}, // Ps LEFT-POINTING ANGLE BRACKET + {0x232A, 0x232A, prW}, // Pe RIGHT-POINTING ANGLE BRACKET + {0x232B, 0x237B, prN}, // So [81] ERASE TO THE LEFT..NOT CHECK MARK + {0x237C, 0x237C, prN}, // Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW + {0x237D, 0x239A, prN}, // So [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL + {0x239B, 0x23B3, prN}, // Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM + {0x23B4, 0x23DB, prN}, // So [40] TOP SQUARE BRACKET..FUSE + {0x23DC, 0x23E1, prN}, // Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET + {0x23E2, 0x23E8, prN}, // So [7] WHITE TRAPEZIUM..DECIMAL EXPONENT SYMBOL + {0x23E9, 0x23EC, prW}, // So [4] BLACK RIGHT-POINTING DOUBLE TRIANGLE..BLACK DOWN-POINTING DOUBLE TRIANGLE + {0x23ED, 0x23EF, prN}, // So [3] BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR..BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR + {0x23F0, 0x23F0, prW}, // So ALARM CLOCK + {0x23F1, 0x23F2, prN}, // So [2] STOPWATCH..TIMER CLOCK + {0x23F3, 0x23F3, prW}, // So HOURGLASS WITH FLOWING SAND + {0x23F4, 0x23FF, prN}, // So [12] BLACK MEDIUM LEFT-POINTING TRIANGLE..OBSERVER EYE SYMBOL + {0x2400, 0x2426, prN}, // So [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO + {0x2440, 0x244A, prN}, // So [11] OCR HOOK..OCR DOUBLE BACKSLASH + {0x2460, 0x249B, prA}, // No [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP + {0x249C, 0x24E9, prA}, // So [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z + {0x24EA, 0x24EA, prN}, // No CIRCLED DIGIT ZERO + {0x24EB, 0x24FF, prA}, // No [21] NEGATIVE CIRCLED NUMBER ELEVEN..NEGATIVE CIRCLED DIGIT ZERO + {0x2500, 0x254B, prA}, // So [76] BOX DRAWINGS LIGHT HORIZONTAL..BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + {0x254C, 0x254F, prN}, // So [4] BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL..BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL + {0x2550, 0x2573, prA}, // So [36] BOX DRAWINGS DOUBLE HORIZONTAL..BOX DRAWINGS LIGHT DIAGONAL CROSS + {0x2574, 0x257F, prN}, // So [12] BOX DRAWINGS LIGHT LEFT..BOX DRAWINGS HEAVY UP AND LIGHT DOWN + {0x2580, 0x258F, prA}, // So [16] UPPER HALF BLOCK..LEFT ONE EIGHTH BLOCK + {0x2590, 0x2591, prN}, // So [2] RIGHT HALF BLOCK..LIGHT SHADE + {0x2592, 0x2595, prA}, // So [4] MEDIUM SHADE..RIGHT ONE EIGHTH BLOCK + {0x2596, 0x259F, prN}, // So [10] QUADRANT LOWER LEFT..QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT + {0x25A0, 0x25A1, prA}, // So [2] BLACK SQUARE..WHITE SQUARE + {0x25A2, 0x25A2, prN}, // So WHITE SQUARE WITH ROUNDED CORNERS + {0x25A3, 0x25A9, prA}, // So [7] WHITE SQUARE CONTAINING BLACK SMALL SQUARE..SQUARE WITH DIAGONAL CROSSHATCH FILL + {0x25AA, 0x25B1, prN}, // So [8] BLACK SMALL SQUARE..WHITE PARALLELOGRAM + {0x25B2, 0x25B3, prA}, // So [2] BLACK UP-POINTING TRIANGLE..WHITE UP-POINTING TRIANGLE + {0x25B4, 0x25B5, prN}, // So [2] BLACK UP-POINTING SMALL TRIANGLE..WHITE UP-POINTING SMALL TRIANGLE + {0x25B6, 0x25B6, prA}, // So BLACK RIGHT-POINTING TRIANGLE + {0x25B7, 0x25B7, prA}, // Sm WHITE RIGHT-POINTING TRIANGLE + {0x25B8, 0x25BB, prN}, // So [4] BLACK RIGHT-POINTING SMALL TRIANGLE..WHITE RIGHT-POINTING POINTER + {0x25BC, 0x25BD, prA}, // So [2] BLACK DOWN-POINTING TRIANGLE..WHITE DOWN-POINTING TRIANGLE + {0x25BE, 0x25BF, prN}, // So [2] BLACK DOWN-POINTING SMALL TRIANGLE..WHITE DOWN-POINTING SMALL TRIANGLE + {0x25C0, 0x25C0, prA}, // So BLACK LEFT-POINTING TRIANGLE + {0x25C1, 0x25C1, prA}, // Sm WHITE LEFT-POINTING TRIANGLE + {0x25C2, 0x25C5, prN}, // So [4] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE LEFT-POINTING POINTER + {0x25C6, 0x25C8, prA}, // So [3] BLACK DIAMOND..WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND + {0x25C9, 0x25CA, prN}, // So [2] FISHEYE..LOZENGE + {0x25CB, 0x25CB, prA}, // So WHITE CIRCLE + {0x25CC, 0x25CD, prN}, // So [2] DOTTED CIRCLE..CIRCLE WITH VERTICAL FILL + {0x25CE, 0x25D1, prA}, // So [4] BULLSEYE..CIRCLE WITH RIGHT HALF BLACK + {0x25D2, 0x25E1, prN}, // So [16] CIRCLE WITH LOWER HALF BLACK..LOWER HALF CIRCLE + {0x25E2, 0x25E5, prA}, // So [4] BLACK LOWER RIGHT TRIANGLE..BLACK UPPER RIGHT TRIANGLE + {0x25E6, 0x25EE, prN}, // So [9] WHITE BULLET..UP-POINTING TRIANGLE WITH RIGHT HALF BLACK + {0x25EF, 0x25EF, prA}, // So LARGE CIRCLE + {0x25F0, 0x25F7, prN}, // So [8] WHITE SQUARE WITH UPPER LEFT QUADRANT..WHITE CIRCLE WITH UPPER RIGHT QUADRANT + {0x25F8, 0x25FC, prN}, // Sm [5] UPPER LEFT TRIANGLE..BLACK MEDIUM SQUARE + {0x25FD, 0x25FE, prW}, // Sm [2] WHITE MEDIUM SMALL SQUARE..BLACK MEDIUM SMALL SQUARE + {0x25FF, 0x25FF, prN}, // Sm LOWER RIGHT TRIANGLE + {0x2600, 0x2604, prN}, // So [5] BLACK SUN WITH RAYS..COMET + {0x2605, 0x2606, prA}, // So [2] BLACK STAR..WHITE STAR + {0x2607, 0x2608, prN}, // So [2] LIGHTNING..THUNDERSTORM + {0x2609, 0x2609, prA}, // So SUN + {0x260A, 0x260D, prN}, // So [4] ASCENDING NODE..OPPOSITION + {0x260E, 0x260F, prA}, // So [2] BLACK TELEPHONE..WHITE TELEPHONE + {0x2610, 0x2613, prN}, // So [4] BALLOT BOX..SALTIRE + {0x2614, 0x2615, prW}, // So [2] UMBRELLA WITH RAIN DROPS..HOT BEVERAGE + {0x2616, 0x261B, prN}, // So [6] WHITE SHOGI PIECE..BLACK RIGHT POINTING INDEX + {0x261C, 0x261C, prA}, // So WHITE LEFT POINTING INDEX + {0x261D, 0x261D, prN}, // So WHITE UP POINTING INDEX + {0x261E, 0x261E, prA}, // So WHITE RIGHT POINTING INDEX + {0x261F, 0x263F, prN}, // So [33] WHITE DOWN POINTING INDEX..MERCURY + {0x2640, 0x2640, prA}, // So FEMALE SIGN + {0x2641, 0x2641, prN}, // So EARTH + {0x2642, 0x2642, prA}, // So MALE SIGN + {0x2643, 0x2647, prN}, // So [5] JUPITER..PLUTO + {0x2648, 0x2653, prW}, // So [12] ARIES..PISCES + {0x2654, 0x265F, prN}, // So [12] WHITE CHESS KING..BLACK CHESS PAWN + {0x2660, 0x2661, prA}, // So [2] BLACK SPADE SUIT..WHITE HEART SUIT + {0x2662, 0x2662, prN}, // So WHITE DIAMOND SUIT + {0x2663, 0x2665, prA}, // So [3] BLACK CLUB SUIT..BLACK HEART SUIT + {0x2666, 0x2666, prN}, // So BLACK DIAMOND SUIT + {0x2667, 0x266A, prA}, // So [4] WHITE CLUB SUIT..EIGHTH NOTE + {0x266B, 0x266B, prN}, // So BEAMED EIGHTH NOTES + {0x266C, 0x266D, prA}, // So [2] BEAMED SIXTEENTH NOTES..MUSIC FLAT SIGN + {0x266E, 0x266E, prN}, // So MUSIC NATURAL SIGN + {0x266F, 0x266F, prA}, // Sm MUSIC SHARP SIGN + {0x2670, 0x267E, prN}, // So [15] WEST SYRIAC CROSS..PERMANENT PAPER SIGN + {0x267F, 0x267F, prW}, // So WHEELCHAIR SYMBOL + {0x2680, 0x2692, prN}, // So [19] DIE FACE-1..HAMMER AND PICK + {0x2693, 0x2693, prW}, // So ANCHOR + {0x2694, 0x269D, prN}, // So [10] CROSSED SWORDS..OUTLINED WHITE STAR + {0x269E, 0x269F, prA}, // So [2] THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT + {0x26A0, 0x26A0, prN}, // So WARNING SIGN + {0x26A1, 0x26A1, prW}, // So HIGH VOLTAGE SIGN + {0x26A2, 0x26A9, prN}, // So [8] DOUBLED FEMALE SIGN..HORIZONTAL MALE WITH STROKE SIGN + {0x26AA, 0x26AB, prW}, // So [2] MEDIUM WHITE CIRCLE..MEDIUM BLACK CIRCLE + {0x26AC, 0x26BC, prN}, // So [17] MEDIUM SMALL WHITE CIRCLE..SESQUIQUADRATE + {0x26BD, 0x26BE, prW}, // So [2] SOCCER BALL..BASEBALL + {0x26BF, 0x26BF, prA}, // So SQUARED KEY + {0x26C0, 0x26C3, prN}, // So [4] WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING + {0x26C4, 0x26C5, prW}, // So [2] SNOWMAN WITHOUT SNOW..SUN BEHIND CLOUD + {0x26C6, 0x26CD, prA}, // So [8] RAIN..DISABLED CAR + {0x26CE, 0x26CE, prW}, // So OPHIUCHUS + {0x26CF, 0x26D3, prA}, // So [5] PICK..CHAINS + {0x26D4, 0x26D4, prW}, // So NO ENTRY + {0x26D5, 0x26E1, prA}, // So [13] ALTERNATE ONE-WAY LEFT WAY TRAFFIC..RESTRICTED LEFT ENTRY-2 + {0x26E2, 0x26E2, prN}, // So ASTRONOMICAL SYMBOL FOR URANUS + {0x26E3, 0x26E3, prA}, // So HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE + {0x26E4, 0x26E7, prN}, // So [4] PENTAGRAM..INVERTED PENTAGRAM + {0x26E8, 0x26E9, prA}, // So [2] BLACK CROSS ON SHIELD..SHINTO SHRINE + {0x26EA, 0x26EA, prW}, // So CHURCH + {0x26EB, 0x26F1, prA}, // So [7] CASTLE..UMBRELLA ON GROUND + {0x26F2, 0x26F3, prW}, // So [2] FOUNTAIN..FLAG IN HOLE + {0x26F4, 0x26F4, prA}, // So FERRY + {0x26F5, 0x26F5, prW}, // So SAILBOAT + {0x26F6, 0x26F9, prA}, // So [4] SQUARE FOUR CORNERS..PERSON WITH BALL + {0x26FA, 0x26FA, prW}, // So TENT + {0x26FB, 0x26FC, prA}, // So [2] JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL + {0x26FD, 0x26FD, prW}, // So FUEL PUMP + {0x26FE, 0x26FF, prA}, // So [2] CUP ON BLACK SQUARE..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE + {0x2700, 0x2704, prN}, // So [5] BLACK SAFETY SCISSORS..WHITE SCISSORS + {0x2705, 0x2705, prW}, // So WHITE HEAVY CHECK MARK + {0x2706, 0x2709, prN}, // So [4] TELEPHONE LOCATION SIGN..ENVELOPE + {0x270A, 0x270B, prW}, // So [2] RAISED FIST..RAISED HAND + {0x270C, 0x2727, prN}, // So [28] VICTORY HAND..WHITE FOUR POINTED STAR + {0x2728, 0x2728, prW}, // So SPARKLES + {0x2729, 0x273C, prN}, // So [20] STRESS OUTLINED WHITE STAR..OPEN CENTRE TEARDROP-SPOKED ASTERISK + {0x273D, 0x273D, prA}, // So HEAVY TEARDROP-SPOKED ASTERISK + {0x273E, 0x274B, prN}, // So [14] SIX PETALLED BLACK AND WHITE FLORETTE..HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK + {0x274C, 0x274C, prW}, // So CROSS MARK + {0x274D, 0x274D, prN}, // So SHADOWED WHITE CIRCLE + {0x274E, 0x274E, prW}, // So NEGATIVE SQUARED CROSS MARK + {0x274F, 0x2752, prN}, // So [4] LOWER RIGHT DROP-SHADOWED WHITE SQUARE..UPPER RIGHT SHADOWED WHITE SQUARE + {0x2753, 0x2755, prW}, // So [3] BLACK QUESTION MARK ORNAMENT..WHITE EXCLAMATION MARK ORNAMENT + {0x2756, 0x2756, prN}, // So BLACK DIAMOND MINUS WHITE X + {0x2757, 0x2757, prW}, // So HEAVY EXCLAMATION MARK SYMBOL + {0x2758, 0x2767, prN}, // So [16] LIGHT VERTICAL BAR..ROTATED FLORAL HEART BULLET + {0x2768, 0x2768, prN}, // Ps MEDIUM LEFT PARENTHESIS ORNAMENT + {0x2769, 0x2769, prN}, // Pe MEDIUM RIGHT PARENTHESIS ORNAMENT + {0x276A, 0x276A, prN}, // Ps MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT + {0x276B, 0x276B, prN}, // Pe MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT + {0x276C, 0x276C, prN}, // Ps MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x276D, 0x276D, prN}, // Pe MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x276E, 0x276E, prN}, // Ps HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x276F, 0x276F, prN}, // Pe HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x2770, 0x2770, prN}, // Ps HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x2771, 0x2771, prN}, // Pe HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x2772, 0x2772, prN}, // Ps LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + {0x2773, 0x2773, prN}, // Pe LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + {0x2774, 0x2774, prN}, // Ps MEDIUM LEFT CURLY BRACKET ORNAMENT + {0x2775, 0x2775, prN}, // Pe MEDIUM RIGHT CURLY BRACKET ORNAMENT + {0x2776, 0x277F, prA}, // No [10] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED NUMBER TEN + {0x2780, 0x2793, prN}, // No [20] DINGBAT CIRCLED SANS-SERIF DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN + {0x2794, 0x2794, prN}, // So HEAVY WIDE-HEADED RIGHTWARDS ARROW + {0x2795, 0x2797, prW}, // So [3] HEAVY PLUS SIGN..HEAVY DIVISION SIGN + {0x2798, 0x27AF, prN}, // So [24] HEAVY SOUTH EAST ARROW..NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + {0x27B0, 0x27B0, prW}, // So CURLY LOOP + {0x27B1, 0x27BE, prN}, // So [14] NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW..OPEN-OUTLINED RIGHTWARDS ARROW + {0x27BF, 0x27BF, prW}, // So DOUBLE CURLY LOOP + {0x27C0, 0x27C4, prN}, // Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET + {0x27C5, 0x27C5, prN}, // Ps LEFT S-SHAPED BAG DELIMITER + {0x27C6, 0x27C6, prN}, // Pe RIGHT S-SHAPED BAG DELIMITER + {0x27C7, 0x27E5, prN}, // Sm [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK + {0x27E6, 0x27E6, prNa}, // Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET + {0x27E7, 0x27E7, prNa}, // Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET + {0x27E8, 0x27E8, prNa}, // Ps MATHEMATICAL LEFT ANGLE BRACKET + {0x27E9, 0x27E9, prNa}, // Pe MATHEMATICAL RIGHT ANGLE BRACKET + {0x27EA, 0x27EA, prNa}, // Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + {0x27EB, 0x27EB, prNa}, // Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + {0x27EC, 0x27EC, prNa}, // Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + {0x27ED, 0x27ED, prNa}, // Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + {0x27EE, 0x27EE, prN}, // Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS + {0x27EF, 0x27EF, prN}, // Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS + {0x27F0, 0x27FF, prN}, // Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW + {0x2800, 0x28FF, prN}, // So [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678 + {0x2900, 0x297F, prN}, // Sm [128] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..DOWN FISH TAIL + {0x2980, 0x2982, prN}, // Sm [3] TRIPLE VERTICAL BAR DELIMITER..Z NOTATION TYPE COLON + {0x2983, 0x2983, prN}, // Ps LEFT WHITE CURLY BRACKET + {0x2984, 0x2984, prN}, // Pe RIGHT WHITE CURLY BRACKET + {0x2985, 0x2985, prNa}, // Ps LEFT WHITE PARENTHESIS + {0x2986, 0x2986, prNa}, // Pe RIGHT WHITE PARENTHESIS + {0x2987, 0x2987, prN}, // Ps Z NOTATION LEFT IMAGE BRACKET + {0x2988, 0x2988, prN}, // Pe Z NOTATION RIGHT IMAGE BRACKET + {0x2989, 0x2989, prN}, // Ps Z NOTATION LEFT BINDING BRACKET + {0x298A, 0x298A, prN}, // Pe Z NOTATION RIGHT BINDING BRACKET + {0x298B, 0x298B, prN}, // Ps LEFT SQUARE BRACKET WITH UNDERBAR + {0x298C, 0x298C, prN}, // Pe RIGHT SQUARE BRACKET WITH UNDERBAR + {0x298D, 0x298D, prN}, // Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x298E, 0x298E, prN}, // Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x298F, 0x298F, prN}, // Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x2990, 0x2990, prN}, // Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x2991, 0x2991, prN}, // Ps LEFT ANGLE BRACKET WITH DOT + {0x2992, 0x2992, prN}, // Pe RIGHT ANGLE BRACKET WITH DOT + {0x2993, 0x2993, prN}, // Ps LEFT ARC LESS-THAN BRACKET + {0x2994, 0x2994, prN}, // Pe RIGHT ARC GREATER-THAN BRACKET + {0x2995, 0x2995, prN}, // Ps DOUBLE LEFT ARC GREATER-THAN BRACKET + {0x2996, 0x2996, prN}, // Pe DOUBLE RIGHT ARC LESS-THAN BRACKET + {0x2997, 0x2997, prN}, // Ps LEFT BLACK TORTOISE SHELL BRACKET + {0x2998, 0x2998, prN}, // Pe RIGHT BLACK TORTOISE SHELL BRACKET + {0x2999, 0x29D7, prN}, // Sm [63] DOTTED FENCE..BLACK HOURGLASS + {0x29D8, 0x29D8, prN}, // Ps LEFT WIGGLY FENCE + {0x29D9, 0x29D9, prN}, // Pe RIGHT WIGGLY FENCE + {0x29DA, 0x29DA, prN}, // Ps LEFT DOUBLE WIGGLY FENCE + {0x29DB, 0x29DB, prN}, // Pe RIGHT DOUBLE WIGGLY FENCE + {0x29DC, 0x29FB, prN}, // Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS + {0x29FC, 0x29FC, prN}, // Ps LEFT-POINTING CURVED ANGLE BRACKET + {0x29FD, 0x29FD, prN}, // Pe RIGHT-POINTING CURVED ANGLE BRACKET + {0x29FE, 0x29FF, prN}, // Sm [2] TINY..MINY + {0x2A00, 0x2AFF, prN}, // Sm [256] N-ARY CIRCLED DOT OPERATOR..N-ARY WHITE VERTICAL BAR + {0x2B00, 0x2B1A, prN}, // So [27] NORTH EAST WHITE ARROW..DOTTED SQUARE + {0x2B1B, 0x2B1C, prW}, // So [2] BLACK LARGE SQUARE..WHITE LARGE SQUARE + {0x2B1D, 0x2B2F, prN}, // So [19] BLACK VERY SMALL SQUARE..WHITE VERTICAL ELLIPSE + {0x2B30, 0x2B44, prN}, // Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET + {0x2B45, 0x2B46, prN}, // So [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW + {0x2B47, 0x2B4C, prN}, // Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR + {0x2B4D, 0x2B4F, prN}, // So [3] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..SHORT BACKSLANTED SOUTH ARROW + {0x2B50, 0x2B50, prW}, // So WHITE MEDIUM STAR + {0x2B51, 0x2B54, prN}, // So [4] BLACK SMALL STAR..WHITE RIGHT-POINTING PENTAGON + {0x2B55, 0x2B55, prW}, // So HEAVY LARGE CIRCLE + {0x2B56, 0x2B59, prA}, // So [4] HEAVY OVAL WITH OVAL INSIDE..HEAVY CIRCLED SALTIRE + {0x2B5A, 0x2B73, prN}, // So [26] SLANTED NORTH ARROW WITH HOOKED HEAD..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR + {0x2B76, 0x2B95, prN}, // So [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW + {0x2B97, 0x2BFF, prN}, // So [105] SYMBOL FOR TYPE A ELECTRONICS..HELLSCHREIBER PAUSE SYMBOL + {0x2C00, 0x2C5F, prN}, // L& [96] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI + {0x2C60, 0x2C7B, prN}, // L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E + {0x2C7C, 0x2C7D, prN}, // Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V + {0x2C7E, 0x2C7F, prN}, // Lu [2] LATIN CAPITAL LETTER S WITH SWASH TAIL..LATIN CAPITAL LETTER Z WITH SWASH TAIL + {0x2C80, 0x2CE4, prN}, // L& [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI + {0x2CE5, 0x2CEA, prN}, // So [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA + {0x2CEB, 0x2CEE, prN}, // L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEF, 0x2CF1, prN}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2CF2, 0x2CF3, prN}, // L& [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI + {0x2CF9, 0x2CFC, prN}, // Po [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER + {0x2CFD, 0x2CFD, prN}, // No COPTIC FRACTION ONE HALF + {0x2CFE, 0x2CFF, prN}, // Po [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER + {0x2D00, 0x2D25, prN}, // Ll [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE + {0x2D27, 0x2D27, prN}, // Ll GEORGIAN SMALL LETTER YN + {0x2D2D, 0x2D2D, prN}, // Ll GEORGIAN SMALL LETTER AEN + {0x2D30, 0x2D67, prN}, // Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO + {0x2D6F, 0x2D6F, prN}, // Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK + {0x2D70, 0x2D70, prN}, // Po TIFINAGH SEPARATOR MARK + {0x2D7F, 0x2D7F, prN}, // Mn TIFINAGH CONSONANT JOINER + {0x2D80, 0x2D96, prN}, // Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE + {0x2DA0, 0x2DA6, prN}, // Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO + {0x2DA8, 0x2DAE, prN}, // Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO + {0x2DB0, 0x2DB6, prN}, // Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO + {0x2DB8, 0x2DBE, prN}, // Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO + {0x2DC0, 0x2DC6, prN}, // Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO + {0x2DC8, 0x2DCE, prN}, // Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO + {0x2DD0, 0x2DD6, prN}, // Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO + {0x2DD8, 0x2DDE, prN}, // Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO + {0x2DE0, 0x2DFF, prN}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x2E00, 0x2E01, prN}, // Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER + {0x2E02, 0x2E02, prN}, // Pi LEFT SUBSTITUTION BRACKET + {0x2E03, 0x2E03, prN}, // Pf RIGHT SUBSTITUTION BRACKET + {0x2E04, 0x2E04, prN}, // Pi LEFT DOTTED SUBSTITUTION BRACKET + {0x2E05, 0x2E05, prN}, // Pf RIGHT DOTTED SUBSTITUTION BRACKET + {0x2E06, 0x2E08, prN}, // Po [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER + {0x2E09, 0x2E09, prN}, // Pi LEFT TRANSPOSITION BRACKET + {0x2E0A, 0x2E0A, prN}, // Pf RIGHT TRANSPOSITION BRACKET + {0x2E0B, 0x2E0B, prN}, // Po RAISED SQUARE + {0x2E0C, 0x2E0C, prN}, // Pi LEFT RAISED OMISSION BRACKET + {0x2E0D, 0x2E0D, prN}, // Pf RIGHT RAISED OMISSION BRACKET + {0x2E0E, 0x2E16, prN}, // Po [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE + {0x2E17, 0x2E17, prN}, // Pd DOUBLE OBLIQUE HYPHEN + {0x2E18, 0x2E19, prN}, // Po [2] INVERTED INTERROBANG..PALM BRANCH + {0x2E1A, 0x2E1A, prN}, // Pd HYPHEN WITH DIAERESIS + {0x2E1B, 0x2E1B, prN}, // Po TILDE WITH RING ABOVE + {0x2E1C, 0x2E1C, prN}, // Pi LEFT LOW PARAPHRASE BRACKET + {0x2E1D, 0x2E1D, prN}, // Pf RIGHT LOW PARAPHRASE BRACKET + {0x2E1E, 0x2E1F, prN}, // Po [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW + {0x2E20, 0x2E20, prN}, // Pi LEFT VERTICAL BAR WITH QUILL + {0x2E21, 0x2E21, prN}, // Pf RIGHT VERTICAL BAR WITH QUILL + {0x2E22, 0x2E22, prN}, // Ps TOP LEFT HALF BRACKET + {0x2E23, 0x2E23, prN}, // Pe TOP RIGHT HALF BRACKET + {0x2E24, 0x2E24, prN}, // Ps BOTTOM LEFT HALF BRACKET + {0x2E25, 0x2E25, prN}, // Pe BOTTOM RIGHT HALF BRACKET + {0x2E26, 0x2E26, prN}, // Ps LEFT SIDEWAYS U BRACKET + {0x2E27, 0x2E27, prN}, // Pe RIGHT SIDEWAYS U BRACKET + {0x2E28, 0x2E28, prN}, // Ps LEFT DOUBLE PARENTHESIS + {0x2E29, 0x2E29, prN}, // Pe RIGHT DOUBLE PARENTHESIS + {0x2E2A, 0x2E2E, prN}, // Po [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK + {0x2E2F, 0x2E2F, prN}, // Lm VERTICAL TILDE + {0x2E30, 0x2E39, prN}, // Po [10] RING POINT..TOP HALF SECTION SIGN + {0x2E3A, 0x2E3B, prN}, // Pd [2] TWO-EM DASH..THREE-EM DASH + {0x2E3C, 0x2E3F, prN}, // Po [4] STENOGRAPHIC FULL STOP..CAPITULUM + {0x2E40, 0x2E40, prN}, // Pd DOUBLE HYPHEN + {0x2E41, 0x2E41, prN}, // Po REVERSED COMMA + {0x2E42, 0x2E42, prN}, // Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK + {0x2E43, 0x2E4F, prN}, // Po [13] DASH WITH LEFT UPTURN..CORNISH VERSE DIVIDER + {0x2E50, 0x2E51, prN}, // So [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR + {0x2E52, 0x2E54, prN}, // Po [3] TIRONIAN SIGN CAPITAL ET..MEDIEVAL QUESTION MARK + {0x2E55, 0x2E55, prN}, // Ps LEFT SQUARE BRACKET WITH STROKE + {0x2E56, 0x2E56, prN}, // Pe RIGHT SQUARE BRACKET WITH STROKE + {0x2E57, 0x2E57, prN}, // Ps LEFT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E58, 0x2E58, prN}, // Pe RIGHT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E59, 0x2E59, prN}, // Ps TOP HALF LEFT PARENTHESIS + {0x2E5A, 0x2E5A, prN}, // Pe TOP HALF RIGHT PARENTHESIS + {0x2E5B, 0x2E5B, prN}, // Ps BOTTOM HALF LEFT PARENTHESIS + {0x2E5C, 0x2E5C, prN}, // Pe BOTTOM HALF RIGHT PARENTHESIS + {0x2E5D, 0x2E5D, prN}, // Pd OBLIQUE HYPHEN + {0x2E80, 0x2E99, prW}, // So [26] CJK RADICAL REPEAT..CJK RADICAL RAP + {0x2E9B, 0x2EF3, prW}, // So [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE + {0x2F00, 0x2FD5, prW}, // So [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE + {0x2FF0, 0x2FFB, prW}, // So [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID + {0x3000, 0x3000, prF}, // Zs IDEOGRAPHIC SPACE + {0x3001, 0x3003, prW}, // Po [3] IDEOGRAPHIC COMMA..DITTO MARK + {0x3004, 0x3004, prW}, // So JAPANESE INDUSTRIAL STANDARD SYMBOL + {0x3005, 0x3005, prW}, // Lm IDEOGRAPHIC ITERATION MARK + {0x3006, 0x3006, prW}, // Lo IDEOGRAPHIC CLOSING MARK + {0x3007, 0x3007, prW}, // Nl IDEOGRAPHIC NUMBER ZERO + {0x3008, 0x3008, prW}, // Ps LEFT ANGLE BRACKET + {0x3009, 0x3009, prW}, // Pe RIGHT ANGLE BRACKET + {0x300A, 0x300A, prW}, // Ps LEFT DOUBLE ANGLE BRACKET + {0x300B, 0x300B, prW}, // Pe RIGHT DOUBLE ANGLE BRACKET + {0x300C, 0x300C, prW}, // Ps LEFT CORNER BRACKET + {0x300D, 0x300D, prW}, // Pe RIGHT CORNER BRACKET + {0x300E, 0x300E, prW}, // Ps LEFT WHITE CORNER BRACKET + {0x300F, 0x300F, prW}, // Pe RIGHT WHITE CORNER BRACKET + {0x3010, 0x3010, prW}, // Ps LEFT BLACK LENTICULAR BRACKET + {0x3011, 0x3011, prW}, // Pe RIGHT BLACK LENTICULAR BRACKET + {0x3012, 0x3013, prW}, // So [2] POSTAL MARK..GETA MARK + {0x3014, 0x3014, prW}, // Ps LEFT TORTOISE SHELL BRACKET + {0x3015, 0x3015, prW}, // Pe RIGHT TORTOISE SHELL BRACKET + {0x3016, 0x3016, prW}, // Ps LEFT WHITE LENTICULAR BRACKET + {0x3017, 0x3017, prW}, // Pe RIGHT WHITE LENTICULAR BRACKET + {0x3018, 0x3018, prW}, // Ps LEFT WHITE TORTOISE SHELL BRACKET + {0x3019, 0x3019, prW}, // Pe RIGHT WHITE TORTOISE SHELL BRACKET + {0x301A, 0x301A, prW}, // Ps LEFT WHITE SQUARE BRACKET + {0x301B, 0x301B, prW}, // Pe RIGHT WHITE SQUARE BRACKET + {0x301C, 0x301C, prW}, // Pd WAVE DASH + {0x301D, 0x301D, prW}, // Ps REVERSED DOUBLE PRIME QUOTATION MARK + {0x301E, 0x301F, prW}, // Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK + {0x3020, 0x3020, prW}, // So POSTAL MARK FACE + {0x3021, 0x3029, prW}, // Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE + {0x302A, 0x302D, prW}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prW}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3030, 0x3030, prW}, // Pd WAVY DASH + {0x3031, 0x3035, prW}, // Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF + {0x3036, 0x3037, prW}, // So [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL + {0x3038, 0x303A, prW}, // Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY + {0x303B, 0x303B, prW}, // Lm VERTICAL IDEOGRAPHIC ITERATION MARK + {0x303C, 0x303C, prW}, // Lo MASU MARK + {0x303D, 0x303D, prW}, // Po PART ALTERNATION MARK + {0x303E, 0x303E, prW}, // So IDEOGRAPHIC VARIATION INDICATOR + {0x303F, 0x303F, prN}, // So IDEOGRAPHIC HALF FILL SPACE + {0x3041, 0x3096, prW}, // Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE + {0x3099, 0x309A, prW}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309B, 0x309C, prW}, // Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309D, 0x309E, prW}, // Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK + {0x309F, 0x309F, prW}, // Lo HIRAGANA DIGRAPH YORI + {0x30A0, 0x30A0, prW}, // Pd KATAKANA-HIRAGANA DOUBLE HYPHEN + {0x30A1, 0x30FA, prW}, // Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO + {0x30FB, 0x30FB, prW}, // Po KATAKANA MIDDLE DOT + {0x30FC, 0x30FE, prW}, // Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK + {0x30FF, 0x30FF, prW}, // Lo KATAKANA DIGRAPH KOTO + {0x3105, 0x312F, prW}, // Lo [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN + {0x3131, 0x318E, prW}, // Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE + {0x3190, 0x3191, prW}, // So [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK + {0x3192, 0x3195, prW}, // No [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK + {0x3196, 0x319F, prW}, // So [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK + {0x31A0, 0x31BF, prW}, // Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH + {0x31C0, 0x31E3, prW}, // So [36] CJK STROKE T..CJK STROKE Q + {0x31F0, 0x31FF, prW}, // Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO + {0x3200, 0x321E, prW}, // So [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU + {0x3220, 0x3229, prW}, // No [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN + {0x322A, 0x3247, prW}, // So [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO + {0x3248, 0x324F, prA}, // No [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE + {0x3250, 0x3250, prW}, // So PARTNERSHIP SIGN + {0x3251, 0x325F, prW}, // No [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE + {0x3260, 0x327F, prW}, // So [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL + {0x3280, 0x3289, prW}, // No [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN + {0x328A, 0x32B0, prW}, // So [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT + {0x32B1, 0x32BF, prW}, // No [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY + {0x32C0, 0x32FF, prW}, // So [64] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..SQUARE ERA NAME REIWA + {0x3300, 0x33FF, prW}, // So [256] SQUARE APAATO..SQUARE GAL + {0x3400, 0x4DBF, prW}, // Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF + {0x4DC0, 0x4DFF, prN}, // So [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION + {0x4E00, 0x9FFF, prW}, // Lo [20992] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFF + {0xA000, 0xA014, prW}, // Lo [21] YI SYLLABLE IT..YI SYLLABLE E + {0xA015, 0xA015, prW}, // Lm YI SYLLABLE WU + {0xA016, 0xA48C, prW}, // Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR + {0xA490, 0xA4C6, prW}, // So [55] YI RADICAL QOT..YI RADICAL KE + {0xA4D0, 0xA4F7, prN}, // Lo [40] LISU LETTER BA..LISU LETTER OE + {0xA4F8, 0xA4FD, prN}, // Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU + {0xA4FE, 0xA4FF, prN}, // Po [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP + {0xA500, 0xA60B, prN}, // Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG + {0xA60C, 0xA60C, prN}, // Lm VAI SYLLABLE LENGTHENER + {0xA60D, 0xA60F, prN}, // Po [3] VAI COMMA..VAI QUESTION MARK + {0xA610, 0xA61F, prN}, // Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG + {0xA620, 0xA629, prN}, // Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE + {0xA62A, 0xA62B, prN}, // Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO + {0xA640, 0xA66D, prN}, // L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O + {0xA66E, 0xA66E, prN}, // Lo CYRILLIC LETTER MULTIOCULAR O + {0xA66F, 0xA66F, prN}, // Mn COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prN}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA673, 0xA673, prN}, // Po SLAVONIC ASTERISK + {0xA674, 0xA67D, prN}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA67E, 0xA67E, prN}, // Po CYRILLIC KAVYKA + {0xA67F, 0xA67F, prN}, // Lm CYRILLIC PAYEROK + {0xA680, 0xA69B, prN}, // L& [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O + {0xA69C, 0xA69D, prN}, // Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN + {0xA69E, 0xA69F, prN}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6A0, 0xA6E5, prN}, // Lo [70] BAMUM LETTER A..BAMUM LETTER KI + {0xA6E6, 0xA6EF, prN}, // Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM + {0xA6F0, 0xA6F1, prN}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA6F2, 0xA6F7, prN}, // Po [6] BAMUM NJAEMLI..BAMUM QUESTION MARK + {0xA700, 0xA716, prN}, // Sk [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR + {0xA717, 0xA71F, prN}, // Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK + {0xA720, 0xA721, prN}, // Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE + {0xA722, 0xA76F, prN}, // L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON + {0xA770, 0xA770, prN}, // Lm MODIFIER LETTER US + {0xA771, 0xA787, prN}, // L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T + {0xA788, 0xA788, prN}, // Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT + {0xA789, 0xA78A, prN}, // Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN + {0xA78B, 0xA78E, prN}, // L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT + {0xA78F, 0xA78F, prN}, // Lo LATIN LETTER SINOLOGICAL DOT + {0xA790, 0xA7CA, prN}, // L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY + {0xA7D0, 0xA7D1, prN}, // L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G + {0xA7D3, 0xA7D3, prN}, // Ll LATIN SMALL LETTER DOUBLE THORN + {0xA7D5, 0xA7D9, prN}, // L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S + {0xA7F2, 0xA7F4, prN}, // Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q + {0xA7F5, 0xA7F6, prN}, // L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H + {0xA7F7, 0xA7F7, prN}, // Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I + {0xA7F8, 0xA7F9, prN}, // Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE + {0xA7FA, 0xA7FA, prN}, // Ll LATIN LETTER SMALL CAPITAL TURNED M + {0xA7FB, 0xA7FF, prN}, // Lo [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M + {0xA800, 0xA801, prN}, // Lo [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I + {0xA802, 0xA802, prN}, // Mn SYLOTI NAGRI SIGN DVISVARA + {0xA803, 0xA805, prN}, // Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O + {0xA806, 0xA806, prN}, // Mn SYLOTI NAGRI SIGN HASANTA + {0xA807, 0xA80A, prN}, // Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO + {0xA80B, 0xA80B, prN}, // Mn SYLOTI NAGRI SIGN ANUSVARA + {0xA80C, 0xA822, prN}, // Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO + {0xA823, 0xA824, prN}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prN}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prN}, // Mc SYLOTI NAGRI VOWEL SIGN OO + {0xA828, 0xA82B, prN}, // So [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4 + {0xA82C, 0xA82C, prN}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA830, 0xA835, prN}, // No [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS + {0xA836, 0xA837, prN}, // So [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK + {0xA838, 0xA838, prN}, // Sc NORTH INDIC RUPEE MARK + {0xA839, 0xA839, prN}, // So NORTH INDIC QUANTITY MARK + {0xA840, 0xA873, prN}, // Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU + {0xA874, 0xA877, prN}, // Po [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD + {0xA880, 0xA881, prN}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA882, 0xA8B3, prN}, // Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA + {0xA8B4, 0xA8C3, prN}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prN}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8CE, 0xA8CF, prN}, // Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA + {0xA8D0, 0xA8D9, prN}, // Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE + {0xA8E0, 0xA8F1, prN}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8F2, 0xA8F7, prN}, // Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA + {0xA8F8, 0xA8FA, prN}, // Po [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET + {0xA8FB, 0xA8FB, prN}, // Lo DEVANAGARI HEADSTROKE + {0xA8FC, 0xA8FC, prN}, // Po DEVANAGARI SIGN SIDDHAM + {0xA8FD, 0xA8FE, prN}, // Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY + {0xA8FF, 0xA8FF, prN}, // Mn DEVANAGARI VOWEL SIGN AY + {0xA900, 0xA909, prN}, // Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE + {0xA90A, 0xA925, prN}, // Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO + {0xA926, 0xA92D, prN}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA92E, 0xA92F, prN}, // Po [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA + {0xA930, 0xA946, prN}, // Lo [23] REJANG LETTER KA..REJANG LETTER A + {0xA947, 0xA951, prN}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prN}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA95F, 0xA95F, prN}, // Po REJANG SECTION MARK + {0xA960, 0xA97C, prW}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prN}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prN}, // Mc JAVANESE SIGN WIGNYAN + {0xA984, 0xA9B2, prN}, // Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA + {0xA9B3, 0xA9B3, prN}, // Mn JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prN}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prN}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prN}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prN}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prN}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9C1, 0xA9CD, prN}, // Po [13] JAVANESE LEFT RERENGGAN..JAVANESE TURNED PADA PISELEH + {0xA9CF, 0xA9CF, prN}, // Lm JAVANESE PANGRANGKEP + {0xA9D0, 0xA9D9, prN}, // Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE + {0xA9DE, 0xA9DF, prN}, // Po [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN + {0xA9E0, 0xA9E4, prN}, // Lo [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA + {0xA9E5, 0xA9E5, prN}, // Mn MYANMAR SIGN SHAN SAW + {0xA9E6, 0xA9E6, prN}, // Lm MYANMAR MODIFIER LETTER SHAN REDUPLICATION + {0xA9E7, 0xA9EF, prN}, // Lo [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA + {0xA9F0, 0xA9F9, prN}, // Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE + {0xA9FA, 0xA9FE, prN}, // Lo [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA + {0xAA00, 0xAA28, prN}, // Lo [41] CHAM LETTER A..CHAM LETTER HA + {0xAA29, 0xAA2E, prN}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prN}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prN}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prN}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prN}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA40, 0xAA42, prN}, // Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG + {0xAA43, 0xAA43, prN}, // Mn CHAM CONSONANT SIGN FINAL NG + {0xAA44, 0xAA4B, prN}, // Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS + {0xAA4C, 0xAA4C, prN}, // Mn CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prN}, // Mc CHAM CONSONANT SIGN FINAL H + {0xAA50, 0xAA59, prN}, // Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE + {0xAA5C, 0xAA5F, prN}, // Po [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA + {0xAA60, 0xAA6F, prN}, // Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA + {0xAA70, 0xAA70, prN}, // Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION + {0xAA71, 0xAA76, prN}, // Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM + {0xAA77, 0xAA79, prN}, // So [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO + {0xAA7A, 0xAA7A, prN}, // Lo MYANMAR LETTER AITON RA + {0xAA7B, 0xAA7B, prN}, // Mc MYANMAR SIGN PAO KAREN TONE + {0xAA7C, 0xAA7C, prN}, // Mn MYANMAR SIGN TAI LAING TONE-2 + {0xAA7D, 0xAA7D, prN}, // Mc MYANMAR SIGN TAI LAING TONE-5 + {0xAA7E, 0xAA7F, prN}, // Lo [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA + {0xAA80, 0xAAAF, prN}, // Lo [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O + {0xAAB0, 0xAAB0, prN}, // Mn TAI VIET MAI KANG + {0xAAB1, 0xAAB1, prN}, // Lo TAI VIET VOWEL AA + {0xAAB2, 0xAAB4, prN}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB5, 0xAAB6, prN}, // Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O + {0xAAB7, 0xAAB8, prN}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAAB9, 0xAABD, prN}, // Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN + {0xAABE, 0xAABF, prN}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC0, 0xAAC0, prN}, // Lo TAI VIET TONE MAI NUENG + {0xAAC1, 0xAAC1, prN}, // Mn TAI VIET TONE MAI THO + {0xAAC2, 0xAAC2, prN}, // Lo TAI VIET TONE MAI SONG + {0xAADB, 0xAADC, prN}, // Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG + {0xAADD, 0xAADD, prN}, // Lm TAI VIET SYMBOL SAM + {0xAADE, 0xAADF, prN}, // Po [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI + {0xAAE0, 0xAAEA, prN}, // Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA + {0xAAEB, 0xAAEB, prN}, // Mc MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prN}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF0, 0xAAF1, prN}, // Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM + {0xAAF2, 0xAAF2, prN}, // Lo MEETEI MAYEK ANJI + {0xAAF3, 0xAAF4, prN}, // Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK + {0xAAF5, 0xAAF5, prN}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prN}, // Mn MEETEI MAYEK VIRAMA + {0xAB01, 0xAB06, prN}, // Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO + {0xAB09, 0xAB0E, prN}, // Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO + {0xAB11, 0xAB16, prN}, // Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO + {0xAB20, 0xAB26, prN}, // Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO + {0xAB28, 0xAB2E, prN}, // Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO + {0xAB30, 0xAB5A, prN}, // Ll [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG + {0xAB5B, 0xAB5B, prN}, // Sk MODIFIER BREVE WITH INVERTED BREVE + {0xAB5C, 0xAB5F, prN}, // Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK + {0xAB60, 0xAB68, prN}, // Ll [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE + {0xAB69, 0xAB69, prN}, // Lm MODIFIER LETTER SMALL TURNED W + {0xAB6A, 0xAB6B, prN}, // Sk [2] MODIFIER LETTER LEFT TACK..MODIFIER LETTER RIGHT TACK + {0xAB70, 0xABBF, prN}, // Ll [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA + {0xABC0, 0xABE2, prN}, // Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM + {0xABE3, 0xABE4, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prN}, // Mn MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prN}, // Mn MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEB, 0xABEB, prN}, // Po MEETEI MAYEK CHEIKHEI + {0xABEC, 0xABEC, prN}, // Mc MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prN}, // Mn MEETEI MAYEK APUN IYEK + {0xABF0, 0xABF9, prN}, // Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE + {0xAC00, 0xD7A3, prW}, // Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prN}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prN}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xD800, 0xDB7F, prN}, // Cs [896] .. + {0xDB80, 0xDBFF, prN}, // Cs [128] .. + {0xDC00, 0xDFFF, prN}, // Cs [1024] .. + {0xE000, 0xF8FF, prA}, // Co [6400] .. + {0xF900, 0xFA6D, prW}, // Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D + {0xFA6E, 0xFA6F, prW}, // Cn [2] .. + {0xFA70, 0xFAD9, prW}, // Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 + {0xFADA, 0xFAFF, prW}, // Cn [38] .. + {0xFB00, 0xFB06, prN}, // Ll [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST + {0xFB13, 0xFB17, prN}, // Ll [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH + {0xFB1D, 0xFB1D, prN}, // Lo HEBREW LETTER YOD WITH HIRIQ + {0xFB1E, 0xFB1E, prN}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA + {0xFB1F, 0xFB28, prN}, // Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV + {0xFB29, 0xFB29, prN}, // Sm HEBREW LETTER ALTERNATIVE PLUS SIGN + {0xFB2A, 0xFB36, prN}, // Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH + {0xFB38, 0xFB3C, prN}, // Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH + {0xFB3E, 0xFB3E, prN}, // Lo HEBREW LETTER MEM WITH DAGESH + {0xFB40, 0xFB41, prN}, // Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH + {0xFB43, 0xFB44, prN}, // Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH + {0xFB46, 0xFB4F, prN}, // Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED + {0xFB50, 0xFBB1, prN}, // Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM + {0xFBB2, 0xFBC2, prN}, // Sk [17] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL WASLA ABOVE + {0xFBD3, 0xFD3D, prN}, // Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM + {0xFD3E, 0xFD3E, prN}, // Pe ORNATE LEFT PARENTHESIS + {0xFD3F, 0xFD3F, prN}, // Ps ORNATE RIGHT PARENTHESIS + {0xFD40, 0xFD4F, prN}, // So [16] ARABIC LIGATURE RAHIMAHU ALLAAH..ARABIC LIGATURE RAHIMAHUM ALLAAH + {0xFD50, 0xFD8F, prN}, // Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM + {0xFD92, 0xFDC7, prN}, // Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM + {0xFDCF, 0xFDCF, prN}, // So ARABIC LIGATURE SALAAMUHU ALAYNAA + {0xFDF0, 0xFDFB, prN}, // Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU + {0xFDFC, 0xFDFC, prN}, // Sc RIAL SIGN + {0xFDFD, 0xFDFF, prN}, // So [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM..ARABIC LIGATURE AZZA WA JALL + {0xFE00, 0xFE0F, prA}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE10, 0xFE16, prW}, // Po [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK + {0xFE17, 0xFE17, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET + {0xFE18, 0xFE18, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET + {0xFE19, 0xFE19, prW}, // Po PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS + {0xFE20, 0xFE2F, prN}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFE30, 0xFE30, prW}, // Po PRESENTATION FORM FOR VERTICAL TWO DOT LEADER + {0xFE31, 0xFE32, prW}, // Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH + {0xFE33, 0xFE34, prW}, // Pc [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE + {0xFE35, 0xFE35, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS + {0xFE36, 0xFE36, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS + {0xFE37, 0xFE37, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET + {0xFE38, 0xFE38, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET + {0xFE39, 0xFE39, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET + {0xFE3A, 0xFE3A, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET + {0xFE3B, 0xFE3B, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET + {0xFE3C, 0xFE3C, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET + {0xFE3D, 0xFE3D, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET + {0xFE3E, 0xFE3E, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET + {0xFE3F, 0xFE3F, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET + {0xFE40, 0xFE40, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET + {0xFE41, 0xFE41, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET + {0xFE42, 0xFE42, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET + {0xFE43, 0xFE43, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET + {0xFE44, 0xFE44, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET + {0xFE45, 0xFE46, prW}, // Po [2] SESAME DOT..WHITE SESAME DOT + {0xFE47, 0xFE47, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET + {0xFE48, 0xFE48, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET + {0xFE49, 0xFE4C, prW}, // Po [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE + {0xFE4D, 0xFE4F, prW}, // Pc [3] DASHED LOW LINE..WAVY LOW LINE + {0xFE50, 0xFE52, prW}, // Po [3] SMALL COMMA..SMALL FULL STOP + {0xFE54, 0xFE57, prW}, // Po [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK + {0xFE58, 0xFE58, prW}, // Pd SMALL EM DASH + {0xFE59, 0xFE59, prW}, // Ps SMALL LEFT PARENTHESIS + {0xFE5A, 0xFE5A, prW}, // Pe SMALL RIGHT PARENTHESIS + {0xFE5B, 0xFE5B, prW}, // Ps SMALL LEFT CURLY BRACKET + {0xFE5C, 0xFE5C, prW}, // Pe SMALL RIGHT CURLY BRACKET + {0xFE5D, 0xFE5D, prW}, // Ps SMALL LEFT TORTOISE SHELL BRACKET + {0xFE5E, 0xFE5E, prW}, // Pe SMALL RIGHT TORTOISE SHELL BRACKET + {0xFE5F, 0xFE61, prW}, // Po [3] SMALL NUMBER SIGN..SMALL ASTERISK + {0xFE62, 0xFE62, prW}, // Sm SMALL PLUS SIGN + {0xFE63, 0xFE63, prW}, // Pd SMALL HYPHEN-MINUS + {0xFE64, 0xFE66, prW}, // Sm [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN + {0xFE68, 0xFE68, prW}, // Po SMALL REVERSE SOLIDUS + {0xFE69, 0xFE69, prW}, // Sc SMALL DOLLAR SIGN + {0xFE6A, 0xFE6B, prW}, // Po [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT + {0xFE70, 0xFE74, prN}, // Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM + {0xFE76, 0xFEFC, prN}, // Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM + {0xFEFF, 0xFEFF, prN}, // Cf ZERO WIDTH NO-BREAK SPACE + {0xFF01, 0xFF03, prF}, // Po [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN + {0xFF04, 0xFF04, prF}, // Sc FULLWIDTH DOLLAR SIGN + {0xFF05, 0xFF07, prF}, // Po [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE + {0xFF08, 0xFF08, prF}, // Ps FULLWIDTH LEFT PARENTHESIS + {0xFF09, 0xFF09, prF}, // Pe FULLWIDTH RIGHT PARENTHESIS + {0xFF0A, 0xFF0A, prF}, // Po FULLWIDTH ASTERISK + {0xFF0B, 0xFF0B, prF}, // Sm FULLWIDTH PLUS SIGN + {0xFF0C, 0xFF0C, prF}, // Po FULLWIDTH COMMA + {0xFF0D, 0xFF0D, prF}, // Pd FULLWIDTH HYPHEN-MINUS + {0xFF0E, 0xFF0F, prF}, // Po [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS + {0xFF10, 0xFF19, prF}, // Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE + {0xFF1A, 0xFF1B, prF}, // Po [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON + {0xFF1C, 0xFF1E, prF}, // Sm [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN + {0xFF1F, 0xFF20, prF}, // Po [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT + {0xFF21, 0xFF3A, prF}, // Lu [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z + {0xFF3B, 0xFF3B, prF}, // Ps FULLWIDTH LEFT SQUARE BRACKET + {0xFF3C, 0xFF3C, prF}, // Po FULLWIDTH REVERSE SOLIDUS + {0xFF3D, 0xFF3D, prF}, // Pe FULLWIDTH RIGHT SQUARE BRACKET + {0xFF3E, 0xFF3E, prF}, // Sk FULLWIDTH CIRCUMFLEX ACCENT + {0xFF3F, 0xFF3F, prF}, // Pc FULLWIDTH LOW LINE + {0xFF40, 0xFF40, prF}, // Sk FULLWIDTH GRAVE ACCENT + {0xFF41, 0xFF5A, prF}, // Ll [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z + {0xFF5B, 0xFF5B, prF}, // Ps FULLWIDTH LEFT CURLY BRACKET + {0xFF5C, 0xFF5C, prF}, // Sm FULLWIDTH VERTICAL LINE + {0xFF5D, 0xFF5D, prF}, // Pe FULLWIDTH RIGHT CURLY BRACKET + {0xFF5E, 0xFF5E, prF}, // Sm FULLWIDTH TILDE + {0xFF5F, 0xFF5F, prF}, // Ps FULLWIDTH LEFT WHITE PARENTHESIS + {0xFF60, 0xFF60, prF}, // Pe FULLWIDTH RIGHT WHITE PARENTHESIS + {0xFF61, 0xFF61, prH}, // Po HALFWIDTH IDEOGRAPHIC FULL STOP + {0xFF62, 0xFF62, prH}, // Ps HALFWIDTH LEFT CORNER BRACKET + {0xFF63, 0xFF63, prH}, // Pe HALFWIDTH RIGHT CORNER BRACKET + {0xFF64, 0xFF65, prH}, // Po [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT + {0xFF66, 0xFF6F, prH}, // Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU + {0xFF70, 0xFF70, prH}, // Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0xFF71, 0xFF9D, prH}, // Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N + {0xFF9E, 0xFF9F, prH}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFA0, 0xFFBE, prH}, // Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH + {0xFFC2, 0xFFC7, prH}, // Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E + {0xFFCA, 0xFFCF, prH}, // Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE + {0xFFD2, 0xFFD7, prH}, // Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU + {0xFFDA, 0xFFDC, prH}, // Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I + {0xFFE0, 0xFFE1, prF}, // Sc [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN + {0xFFE2, 0xFFE2, prF}, // Sm FULLWIDTH NOT SIGN + {0xFFE3, 0xFFE3, prF}, // Sk FULLWIDTH MACRON + {0xFFE4, 0xFFE4, prF}, // So FULLWIDTH BROKEN BAR + {0xFFE5, 0xFFE6, prF}, // Sc [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN + {0xFFE8, 0xFFE8, prH}, // So HALFWIDTH FORMS LIGHT VERTICAL + {0xFFE9, 0xFFEC, prH}, // Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW + {0xFFED, 0xFFEE, prH}, // So [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE + {0xFFF9, 0xFFFB, prN}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0xFFFC, 0xFFFC, prN}, // So OBJECT REPLACEMENT CHARACTER + {0xFFFD, 0xFFFD, prA}, // So REPLACEMENT CHARACTER + {0x10000, 0x1000B, prN}, // Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE + {0x1000D, 0x10026, prN}, // Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO + {0x10028, 0x1003A, prN}, // Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO + {0x1003C, 0x1003D, prN}, // Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE + {0x1003F, 0x1004D, prN}, // Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO + {0x10050, 0x1005D, prN}, // Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 + {0x10080, 0x100FA, prN}, // Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 + {0x10100, 0x10102, prN}, // Po [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK + {0x10107, 0x10133, prN}, // No [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND + {0x10137, 0x1013F, prN}, // So [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT + {0x10140, 0x10174, prN}, // Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS + {0x10175, 0x10178, prN}, // No [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN + {0x10179, 0x10189, prN}, // So [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN + {0x1018A, 0x1018B, prN}, // No [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN + {0x1018C, 0x1018E, prN}, // So [3] GREEK SINUSOID SIGN..NOMISMA SIGN + {0x10190, 0x1019C, prN}, // So [13] ROMAN SEXTANS SIGN..ASCIA SYMBOL + {0x101A0, 0x101A0, prN}, // So GREEK SYMBOL TAU RHO + {0x101D0, 0x101FC, prN}, // So [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND + {0x101FD, 0x101FD, prN}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x10280, 0x1029C, prN}, // Lo [29] LYCIAN LETTER A..LYCIAN LETTER X + {0x102A0, 0x102D0, prN}, // Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3 + {0x102E0, 0x102E0, prN}, // Mn COPTIC EPACT THOUSANDS MARK + {0x102E1, 0x102FB, prN}, // No [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED + {0x10300, 0x1031F, prN}, // Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS + {0x10320, 0x10323, prN}, // No [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY + {0x1032D, 0x1032F, prN}, // Lo [3] OLD ITALIC LETTER YE..OLD ITALIC LETTER SOUTHERN TSE + {0x10330, 0x10340, prN}, // Lo [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA + {0x10341, 0x10341, prN}, // Nl GOTHIC LETTER NINETY + {0x10342, 0x10349, prN}, // Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL + {0x1034A, 0x1034A, prN}, // Nl GOTHIC LETTER NINE HUNDRED + {0x10350, 0x10375, prN}, // Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA + {0x10376, 0x1037A, prN}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10380, 0x1039D, prN}, // Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU + {0x1039F, 0x1039F, prN}, // Po UGARITIC WORD DIVIDER + {0x103A0, 0x103C3, prN}, // Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA + {0x103C8, 0x103CF, prN}, // Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH + {0x103D0, 0x103D0, prN}, // Po OLD PERSIAN WORD DIVIDER + {0x103D1, 0x103D5, prN}, // Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED + {0x10400, 0x1044F, prN}, // L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW + {0x10450, 0x1047F, prN}, // Lo [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW + {0x10480, 0x1049D, prN}, // Lo [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO + {0x104A0, 0x104A9, prN}, // Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE + {0x104B0, 0x104D3, prN}, // Lu [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA + {0x104D8, 0x104FB, prN}, // Ll [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA + {0x10500, 0x10527, prN}, // Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE + {0x10530, 0x10563, prN}, // Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW + {0x1056F, 0x1056F, prN}, // Po CAUCASIAN ALBANIAN CITATION MARK + {0x10570, 0x1057A, prN}, // Lu [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA + {0x1057C, 0x1058A, prN}, // Lu [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE + {0x1058C, 0x10592, prN}, // Lu [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE + {0x10594, 0x10595, prN}, // Lu [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE + {0x10597, 0x105A1, prN}, // Ll [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA + {0x105A3, 0x105B1, prN}, // Ll [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE + {0x105B3, 0x105B9, prN}, // Ll [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE + {0x105BB, 0x105BC, prN}, // Ll [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE + {0x10600, 0x10736, prN}, // Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 + {0x10740, 0x10755, prN}, // Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE + {0x10760, 0x10767, prN}, // Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 + {0x10780, 0x10785, prN}, // Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK + {0x10787, 0x107B0, prN}, // Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK + {0x107B2, 0x107BA, prN}, // Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL + {0x10800, 0x10805, prN}, // Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA + {0x10808, 0x10808, prN}, // Lo CYPRIOT SYLLABLE JO + {0x1080A, 0x10835, prN}, // Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO + {0x10837, 0x10838, prN}, // Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE + {0x1083C, 0x1083C, prN}, // Lo CYPRIOT SYLLABLE ZA + {0x1083F, 0x1083F, prN}, // Lo CYPRIOT SYLLABLE ZO + {0x10840, 0x10855, prN}, // Lo [22] IMPERIAL ARAMAIC LETTER ALEPH..IMPERIAL ARAMAIC LETTER TAW + {0x10857, 0x10857, prN}, // Po IMPERIAL ARAMAIC SECTION SIGN + {0x10858, 0x1085F, prN}, // No [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND + {0x10860, 0x10876, prN}, // Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW + {0x10877, 0x10878, prN}, // So [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON + {0x10879, 0x1087F, prN}, // No [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY + {0x10880, 0x1089E, prN}, // Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW + {0x108A7, 0x108AF, prN}, // No [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED + {0x108E0, 0x108F2, prN}, // Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH + {0x108F4, 0x108F5, prN}, // Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW + {0x108FB, 0x108FF, prN}, // No [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED + {0x10900, 0x10915, prN}, // Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU + {0x10916, 0x1091B, prN}, // No [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE + {0x1091F, 0x1091F, prN}, // Po PHOENICIAN WORD SEPARATOR + {0x10920, 0x10939, prN}, // Lo [26] LYDIAN LETTER A..LYDIAN LETTER C + {0x1093F, 0x1093F, prN}, // Po LYDIAN TRIANGULAR MARK + {0x10980, 0x1099F, prN}, // Lo [32] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2 + {0x109A0, 0x109B7, prN}, // Lo [24] MEROITIC CURSIVE LETTER A..MEROITIC CURSIVE LETTER DA + {0x109BC, 0x109BD, prN}, // No [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF + {0x109BE, 0x109BF, prN}, // Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN + {0x109C0, 0x109CF, prN}, // No [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY + {0x109D2, 0x109FF, prN}, // No [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS + {0x10A00, 0x10A00, prN}, // Lo KHAROSHTHI LETTER A + {0x10A01, 0x10A03, prN}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prN}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prN}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A10, 0x10A13, prN}, // Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA + {0x10A15, 0x10A17, prN}, // Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA + {0x10A19, 0x10A35, prN}, // Lo [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA + {0x10A38, 0x10A3A, prN}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prN}, // Mn KHAROSHTHI VIRAMA + {0x10A40, 0x10A48, prN}, // No [9] KHAROSHTHI DIGIT ONE..KHAROSHTHI FRACTION ONE HALF + {0x10A50, 0x10A58, prN}, // Po [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES + {0x10A60, 0x10A7C, prN}, // Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH + {0x10A7D, 0x10A7E, prN}, // No [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY + {0x10A7F, 0x10A7F, prN}, // Po OLD SOUTH ARABIAN NUMERIC INDICATOR + {0x10A80, 0x10A9C, prN}, // Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH + {0x10A9D, 0x10A9F, prN}, // No [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY + {0x10AC0, 0x10AC7, prN}, // Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW + {0x10AC8, 0x10AC8, prN}, // So MANICHAEAN SIGN UD + {0x10AC9, 0x10AE4, prN}, // Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW + {0x10AE5, 0x10AE6, prN}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10AEB, 0x10AEF, prN}, // No [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED + {0x10AF0, 0x10AF6, prN}, // Po [7] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION LINE FILLER + {0x10B00, 0x10B35, prN}, // Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE + {0x10B39, 0x10B3F, prN}, // Po [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION + {0x10B40, 0x10B55, prN}, // Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW + {0x10B58, 0x10B5F, prN}, // No [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND + {0x10B60, 0x10B72, prN}, // Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW + {0x10B78, 0x10B7F, prN}, // No [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND + {0x10B80, 0x10B91, prN}, // Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW + {0x10B99, 0x10B9C, prN}, // Po [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT + {0x10BA9, 0x10BAF, prN}, // No [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED + {0x10C00, 0x10C48, prN}, // Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH + {0x10C80, 0x10CB2, prN}, // Lu [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US + {0x10CC0, 0x10CF2, prN}, // Ll [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US + {0x10CFA, 0x10CFF, prN}, // No [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND + {0x10D00, 0x10D23, prN}, // Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA + {0x10D24, 0x10D27, prN}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10D30, 0x10D39, prN}, // Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE + {0x10E60, 0x10E7E, prN}, // No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS + {0x10E80, 0x10EA9, prN}, // Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET + {0x10EAB, 0x10EAC, prN}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EAD, 0x10EAD, prN}, // Pd YEZIDI HYPHENATION MARK + {0x10EB0, 0x10EB1, prN}, // Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE + {0x10EFD, 0x10EFF, prN}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F00, 0x10F1C, prN}, // Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL + {0x10F1D, 0x10F26, prN}, // No [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF + {0x10F27, 0x10F27, prN}, // Lo OLD SOGDIAN LIGATURE AYIN-DALETH + {0x10F30, 0x10F45, prN}, // Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN + {0x10F46, 0x10F50, prN}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F51, 0x10F54, prN}, // No [4] SOGDIAN NUMBER ONE..SOGDIAN NUMBER ONE HUNDRED + {0x10F55, 0x10F59, prN}, // Po [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT + {0x10F70, 0x10F81, prN}, // Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH + {0x10F82, 0x10F85, prN}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x10F86, 0x10F89, prN}, // Po [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS + {0x10FB0, 0x10FC4, prN}, // Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW + {0x10FC5, 0x10FCB, prN}, // No [7] CHORASMIAN NUMBER ONE..CHORASMIAN NUMBER ONE HUNDRED + {0x10FE0, 0x10FF6, prN}, // Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH + {0x11000, 0x11000, prN}, // Mc BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prN}, // Mn BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prN}, // Mc BRAHMI SIGN VISARGA + {0x11003, 0x11037, prN}, // Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA + {0x11038, 0x11046, prN}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11047, 0x1104D, prN}, // Po [7] BRAHMI DANDA..BRAHMI PUNCTUATION LOTUS + {0x11052, 0x11065, prN}, // No [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND + {0x11066, 0x1106F, prN}, // Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE + {0x11070, 0x11070, prN}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA + {0x11071, 0x11072, prN}, // Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O + {0x11073, 0x11074, prN}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x11075, 0x11075, prN}, // Lo BRAHMI LETTER OLD TAMIL LLA + {0x1107F, 0x1107F, prN}, // Mn BRAHMI NUMBER JOINER + {0x11080, 0x11081, prN}, // Mn [2] KAITHI SIGN CANDRABINDU..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prN}, // Mc KAITHI SIGN VISARGA + {0x11083, 0x110AF, prN}, // Lo [45] KAITHI LETTER A..KAITHI LETTER HA + {0x110B0, 0x110B2, prN}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prN}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prN}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prN}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BB, 0x110BC, prN}, // Po [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN + {0x110BD, 0x110BD, prN}, // Cf KAITHI NUMBER SIGN + {0x110BE, 0x110C1, prN}, // Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA + {0x110C2, 0x110C2, prN}, // Mn KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prN}, // Cf KAITHI NUMBER SIGN ABOVE + {0x110D0, 0x110E8, prN}, // Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE + {0x110F0, 0x110F9, prN}, // Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE + {0x11100, 0x11102, prN}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11103, 0x11126, prN}, // Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA + {0x11127, 0x1112B, prN}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prN}, // Mc CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prN}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11136, 0x1113F, prN}, // Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE + {0x11140, 0x11143, prN}, // Po [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK + {0x11144, 0x11144, prN}, // Lo CHAKMA LETTER LHAA + {0x11145, 0x11146, prN}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11147, 0x11147, prN}, // Lo CHAKMA LETTER VAA + {0x11150, 0x11172, prN}, // Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA + {0x11173, 0x11173, prN}, // Mn MAHAJANI SIGN NUKTA + {0x11174, 0x11175, prN}, // Po [2] MAHAJANI ABBREVIATION SIGN..MAHAJANI SECTION MARK + {0x11176, 0x11176, prN}, // Lo MAHAJANI LIGATURE SHRI + {0x11180, 0x11181, prN}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prN}, // Mc SHARADA SIGN VISARGA + {0x11183, 0x111B2, prN}, // Lo [48] SHARADA LETTER A..SHARADA LETTER HA + {0x111B3, 0x111B5, prN}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prN}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prN}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C1, 0x111C4, prN}, // Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM + {0x111C5, 0x111C8, prN}, // Po [4] SHARADA DANDA..SHARADA SEPARATOR + {0x111C9, 0x111CC, prN}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CD, 0x111CD, prN}, // Po SHARADA SUTRA MARK + {0x111CE, 0x111CE, prN}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prN}, // Mn SHARADA SIGN INVERTED CANDRABINDU + {0x111D0, 0x111D9, prN}, // Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE + {0x111DA, 0x111DA, prN}, // Lo SHARADA EKAM + {0x111DB, 0x111DB, prN}, // Po SHARADA SIGN SIDDHAM + {0x111DC, 0x111DC, prN}, // Lo SHARADA HEADSTROKE + {0x111DD, 0x111DF, prN}, // Po [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2 + {0x111E1, 0x111F4, prN}, // No [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND + {0x11200, 0x11211, prN}, // Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA + {0x11213, 0x1122B, prN}, // Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA + {0x1122C, 0x1122E, prN}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prN}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prN}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prN}, // Mn KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prN}, // Mc KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prN}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x11238, 0x1123D, prN}, // Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN + {0x1123E, 0x1123E, prN}, // Mn KHOJKI SIGN SUKUN + {0x1123F, 0x11240, prN}, // Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I + {0x11241, 0x11241, prN}, // Mn KHOJKI VOWEL SIGN VOCALIC R + {0x11280, 0x11286, prN}, // Lo [7] MULTANI LETTER A..MULTANI LETTER GA + {0x11288, 0x11288, prN}, // Lo MULTANI LETTER GHA + {0x1128A, 0x1128D, prN}, // Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA + {0x1128F, 0x1129D, prN}, // Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA + {0x1129F, 0x112A8, prN}, // Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA + {0x112A9, 0x112A9, prN}, // Po MULTANI SECTION MARK + {0x112B0, 0x112DE, prN}, // Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA + {0x112DF, 0x112DF, prN}, // Mn KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prN}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prN}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x112F0, 0x112F9, prN}, // Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE + {0x11300, 0x11301, prN}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prN}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x11305, 0x1130C, prN}, // Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L + {0x1130F, 0x11310, prN}, // Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI + {0x11313, 0x11328, prN}, // Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA + {0x1132A, 0x11330, prN}, // Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA + {0x11332, 0x11333, prN}, // Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA + {0x11335, 0x11339, prN}, // Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA + {0x1133B, 0x1133C, prN}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133D, 0x1133D, prN}, // Lo GRANTHA SIGN AVAGRAHA + {0x1133E, 0x1133F, prN}, // Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prN}, // Mn GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prN}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prN}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prN}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11350, 0x11350, prN}, // Lo GRANTHA OM + {0x11357, 0x11357, prN}, // Mc GRANTHA AU LENGTH MARK + {0x1135D, 0x11361, prN}, // Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL + {0x11362, 0x11363, prN}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prN}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prN}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11400, 0x11434, prN}, // Lo [53] NEWA LETTER A..NEWA LETTER HA + {0x11435, 0x11437, prN}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prN}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prN}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prN}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prN}, // Mc NEWA SIGN VISARGA + {0x11446, 0x11446, prN}, // Mn NEWA SIGN NUKTA + {0x11447, 0x1144A, prN}, // Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI + {0x1144B, 0x1144F, prN}, // Po [5] NEWA DANDA..NEWA ABBREVIATION SIGN + {0x11450, 0x11459, prN}, // Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE + {0x1145A, 0x1145B, prN}, // Po [2] NEWA DOUBLE COMMA..NEWA PLACEHOLDER MARK + {0x1145D, 0x1145D, prN}, // Po NEWA INSERTION SIGN + {0x1145E, 0x1145E, prN}, // Mn NEWA SANDHI MARK + {0x1145F, 0x11461, prN}, // Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA + {0x11480, 0x114AF, prN}, // Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA + {0x114B0, 0x114B2, prN}, // Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prN}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prN}, // Mc TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prN}, // Mn TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BE, prN}, // Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prN}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prN}, // Mc TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prN}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x114C4, 0x114C5, prN}, // Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG + {0x114C6, 0x114C6, prN}, // Po TIRHUTA ABBREVIATION SIGN + {0x114C7, 0x114C7, prN}, // Lo TIRHUTA OM + {0x114D0, 0x114D9, prN}, // Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE + {0x11580, 0x115AE, prN}, // Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA + {0x115AF, 0x115B1, prN}, // Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prN}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prN}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prN}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prN}, // Mc SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prN}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115C1, 0x115D7, prN}, // Po [23] SIDDHAM SIGN SIDDHAM..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES + {0x115D8, 0x115DB, prN}, // Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U + {0x115DC, 0x115DD, prN}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11600, 0x1162F, prN}, // Lo [48] MODI LETTER A..MODI LETTER LLA + {0x11630, 0x11632, prN}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prN}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prN}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prN}, // Mn MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prN}, // Mc MODI SIGN VISARGA + {0x1163F, 0x11640, prN}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x11641, 0x11643, prN}, // Po [3] MODI DANDA..MODI ABBREVIATION SIGN + {0x11644, 0x11644, prN}, // Lo MODI SIGN HUVA + {0x11650, 0x11659, prN}, // Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE + {0x11660, 0x1166C, prN}, // Po [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT + {0x11680, 0x116AA, prN}, // Lo [43] TAKRI LETTER A..TAKRI LETTER RRA + {0x116AB, 0x116AB, prN}, // Mn TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prN}, // Mc TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prN}, // Mn TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prN}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prN}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prN}, // Mc TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prN}, // Mn TAKRI SIGN NUKTA + {0x116B8, 0x116B8, prN}, // Lo TAKRI LETTER ARCHAIC KHA + {0x116B9, 0x116B9, prN}, // Po TAKRI ABBREVIATION SIGN + {0x116C0, 0x116C9, prN}, // Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE + {0x11700, 0x1171A, prN}, // Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA + {0x1171D, 0x1171F, prN}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11720, 0x11721, prN}, // Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA + {0x11722, 0x11725, prN}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prN}, // Mc AHOM VOWEL SIGN E + {0x11727, 0x1172B, prN}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x11730, 0x11739, prN}, // Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE + {0x1173A, 0x1173B, prN}, // No [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY + {0x1173C, 0x1173E, prN}, // Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI + {0x1173F, 0x1173F, prN}, // So AHOM SYMBOL VI + {0x11740, 0x11746, prN}, // Lo [7] AHOM LETTER CA..AHOM LETTER LLA + {0x11800, 0x1182B, prN}, // Lo [44] DOGRA LETTER A..DOGRA LETTER RRA + {0x1182C, 0x1182E, prN}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prN}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prN}, // Mc DOGRA SIGN VISARGA + {0x11839, 0x1183A, prN}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x1183B, 0x1183B, prN}, // Po DOGRA ABBREVIATION SIGN + {0x118A0, 0x118DF, prN}, // L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO + {0x118E0, 0x118E9, prN}, // Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE + {0x118EA, 0x118F2, prN}, // No [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY + {0x118FF, 0x118FF, prN}, // Lo WARANG CITI OM + {0x11900, 0x11906, prN}, // Lo [7] DIVES AKURU LETTER A..DIVES AKURU LETTER E + {0x11909, 0x11909, prN}, // Lo DIVES AKURU LETTER O + {0x1190C, 0x11913, prN}, // Lo [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA + {0x11915, 0x11916, prN}, // Lo [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA + {0x11918, 0x1192F, prN}, // Lo [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA + {0x11930, 0x11935, prN}, // Mc [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prN}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prN}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prN}, // Mc DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prN}, // Mn DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prN}, // Lo DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prN}, // Mc DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prN}, // Lo DIVES AKURU INITIAL RA + {0x11942, 0x11942, prN}, // Mc DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prN}, // Mn DIVES AKURU SIGN NUKTA + {0x11944, 0x11946, prN}, // Po [3] DIVES AKURU DOUBLE DANDA..DIVES AKURU END OF TEXT MARK + {0x11950, 0x11959, prN}, // Nd [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE + {0x119A0, 0x119A7, prN}, // Lo [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR + {0x119AA, 0x119D0, prN}, // Lo [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA + {0x119D1, 0x119D3, prN}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prN}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prN}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prN}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prN}, // Mn NANDINAGARI SIGN VIRAMA + {0x119E1, 0x119E1, prN}, // Lo NANDINAGARI SIGN AVAGRAHA + {0x119E2, 0x119E2, prN}, // Po NANDINAGARI SIGN SIDDHAM + {0x119E3, 0x119E3, prN}, // Lo NANDINAGARI HEADSTROKE + {0x119E4, 0x119E4, prN}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A00, 0x11A00, prN}, // Lo ZANABAZAR SQUARE LETTER A + {0x11A01, 0x11A0A, prN}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A0B, 0x11A32, prN}, // Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA + {0x11A33, 0x11A38, prN}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prN}, // Mc ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prN}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prN}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A3F, 0x11A46, prN}, // Po [8] ZANABAZAR SQUARE INITIAL HEAD MARK..ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK + {0x11A47, 0x11A47, prN}, // Mn ZANABAZAR SQUARE SUBJOINER + {0x11A50, 0x11A50, prN}, // Lo SOYOMBO LETTER A + {0x11A51, 0x11A56, prN}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prN}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prN}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A5C, 0x11A89, prN}, // Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prN}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prN}, // Mc SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prN}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11A9A, 0x11A9C, prN}, // Po [3] SOYOMBO MARK TSHEG..SOYOMBO MARK DOUBLE SHAD + {0x11A9D, 0x11A9D, prN}, // Lo SOYOMBO MARK PLUTA + {0x11A9E, 0x11AA2, prN}, // Po [5] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO TERMINAL MARK-2 + {0x11AB0, 0x11ABF, prN}, // Lo [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA + {0x11AC0, 0x11AF8, prN}, // Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL + {0x11B00, 0x11B09, prN}, // Po [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU + {0x11C00, 0x11C08, prN}, // Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L + {0x11C0A, 0x11C2E, prN}, // Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA + {0x11C2F, 0x11C2F, prN}, // Mc BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prN}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prN}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prN}, // Mc BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prN}, // Mn BHAIKSUKI SIGN VIRAMA + {0x11C40, 0x11C40, prN}, // Lo BHAIKSUKI SIGN AVAGRAHA + {0x11C41, 0x11C45, prN}, // Po [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2 + {0x11C50, 0x11C59, prN}, // Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE + {0x11C5A, 0x11C6C, prN}, // No [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK + {0x11C70, 0x11C71, prN}, // Po [2] MARCHEN HEAD MARK..MARCHEN MARK SHAD + {0x11C72, 0x11C8F, prN}, // Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A + {0x11C92, 0x11CA7, prN}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prN}, // Mc MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prN}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prN}, // Mc MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prN}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prN}, // Mc MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prN}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D00, 0x11D06, prN}, // Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E + {0x11D08, 0x11D09, prN}, // Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O + {0x11D0B, 0x11D30, prN}, // Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA + {0x11D31, 0x11D36, prN}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prN}, // Mn MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prN}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prN}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prN}, // Lo MASARAM GONDI REPHA + {0x11D47, 0x11D47, prN}, // Mn MASARAM GONDI RA-KARA + {0x11D50, 0x11D59, prN}, // Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE + {0x11D60, 0x11D65, prN}, // Lo [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU + {0x11D67, 0x11D68, prN}, // Lo [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI + {0x11D6A, 0x11D89, prN}, // Lo [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA + {0x11D8A, 0x11D8E, prN}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prN}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prN}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prN}, // Mn GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prN}, // Mc GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prN}, // Mn GUNJALA GONDI VIRAMA + {0x11D98, 0x11D98, prN}, // Lo GUNJALA GONDI OM + {0x11DA0, 0x11DA9, prN}, // Nd [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE + {0x11EE0, 0x11EF2, prN}, // Lo [19] MAKASAR LETTER KA..MAKASAR ANGKA + {0x11EF3, 0x11EF4, prN}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prN}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11EF7, 0x11EF8, prN}, // Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION + {0x11F00, 0x11F01, prN}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prN}, // Lo KAWI SIGN REPHA + {0x11F03, 0x11F03, prN}, // Mc KAWI SIGN VISARGA + {0x11F04, 0x11F10, prN}, // Lo [13] KAWI LETTER A..KAWI LETTER O + {0x11F12, 0x11F33, prN}, // Lo [34] KAWI LETTER KA..KAWI LETTER JNYA + {0x11F34, 0x11F35, prN}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prN}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prN}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prN}, // Mn KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prN}, // Mc KAWI SIGN KILLER + {0x11F42, 0x11F42, prN}, // Mn KAWI CONJOINER + {0x11F43, 0x11F4F, prN}, // Po [13] KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL + {0x11F50, 0x11F59, prN}, // Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE + {0x11FB0, 0x11FB0, prN}, // Lo LISU LETTER YHA + {0x11FC0, 0x11FD4, prN}, // No [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH + {0x11FD5, 0x11FDC, prN}, // So [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI + {0x11FDD, 0x11FE0, prN}, // Sc [4] TAMIL SIGN KAACU..TAMIL SIGN VARAAKAN + {0x11FE1, 0x11FF1, prN}, // So [17] TAMIL SIGN PAARAM..TAMIL SIGN VAKAIYARAA + {0x11FFF, 0x11FFF, prN}, // Po TAMIL PUNCTUATION END OF TEXT + {0x12000, 0x12399, prN}, // Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U + {0x12400, 0x1246E, prN}, // Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM + {0x12470, 0x12474, prN}, // Po [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON + {0x12480, 0x12543, prN}, // Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU + {0x12F90, 0x12FF0, prN}, // Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 + {0x12FF1, 0x12FF2, prN}, // Po [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302 + {0x13000, 0x1342F, prN}, // Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D + {0x13430, 0x1343F, prN}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prN}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13441, 0x13446, prN}, // Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN + {0x13447, 0x13455, prN}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x14400, 0x14646, prN}, // Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 + {0x16800, 0x16A38, prN}, // Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ + {0x16A40, 0x16A5E, prN}, // Lo [31] MRO LETTER TA..MRO LETTER TEK + {0x16A60, 0x16A69, prN}, // Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE + {0x16A6E, 0x16A6F, prN}, // Po [2] MRO DANDA..MRO DOUBLE DANDA + {0x16A70, 0x16ABE, prN}, // Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA + {0x16AC0, 0x16AC9, prN}, // Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE + {0x16AD0, 0x16AED, prN}, // Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I + {0x16AF0, 0x16AF4, prN}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16AF5, 0x16AF5, prN}, // Po BASSA VAH FULL STOP + {0x16B00, 0x16B2F, prN}, // Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU + {0x16B30, 0x16B36, prN}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16B37, 0x16B3B, prN}, // Po [5] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS FEEM + {0x16B3C, 0x16B3F, prN}, // So [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB + {0x16B40, 0x16B43, prN}, // Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM + {0x16B44, 0x16B44, prN}, // Po PAHAWH HMONG SIGN XAUS + {0x16B45, 0x16B45, prN}, // So PAHAWH HMONG SIGN CIM TSOV ROG + {0x16B50, 0x16B59, prN}, // Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE + {0x16B5B, 0x16B61, prN}, // No [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS + {0x16B63, 0x16B77, prN}, // Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS + {0x16B7D, 0x16B8F, prN}, // Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ + {0x16E40, 0x16E7F, prN}, // L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y + {0x16E80, 0x16E96, prN}, // No [23] MEDEFAIDRIN DIGIT ZERO..MEDEFAIDRIN DIGIT THREE ALTERNATE FORM + {0x16E97, 0x16E9A, prN}, // Po [4] MEDEFAIDRIN COMMA..MEDEFAIDRIN EXCLAMATION OH + {0x16F00, 0x16F4A, prN}, // Lo [75] MIAO LETTER PA..MIAO LETTER RTE + {0x16F4F, 0x16F4F, prN}, // Mn MIAO SIGN CONSONANT MODIFIER BAR + {0x16F50, 0x16F50, prN}, // Lo MIAO LETTER NASALIZATION + {0x16F51, 0x16F87, prN}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prN}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16F93, 0x16F9F, prN}, // Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 + {0x16FE0, 0x16FE1, prW}, // Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK + {0x16FE2, 0x16FE2, prW}, // Po OLD CHINESE HOOK MARK + {0x16FE3, 0x16FE3, prW}, // Lm OLD CHINESE ITERATION MARK + {0x16FE4, 0x16FE4, prW}, // Mn KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prW}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x17000, 0x187F7, prW}, // Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 + {0x18800, 0x18AFF, prW}, // Lo [768] TANGUT COMPONENT-001..TANGUT COMPONENT-768 + {0x18B00, 0x18CD5, prW}, // Lo [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5 + {0x18D00, 0x18D08, prW}, // Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 + {0x1AFF0, 0x1AFF3, prW}, // Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 + {0x1AFF5, 0x1AFFB, prW}, // Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 + {0x1AFFD, 0x1AFFE, prW}, // Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 + {0x1B000, 0x1B0FF, prW}, // Lo [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2 + {0x1B100, 0x1B122, prW}, // Lo [35] HENTAIGANA LETTER RE-3..KATAKANA LETTER ARCHAIC WU + {0x1B132, 0x1B132, prW}, // Lo HIRAGANA LETTER SMALL KO + {0x1B150, 0x1B152, prW}, // Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO + {0x1B155, 0x1B155, prW}, // Lo KATAKANA LETTER SMALL KO + {0x1B164, 0x1B167, prW}, // Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N + {0x1B170, 0x1B2FB, prW}, // Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB + {0x1BC00, 0x1BC6A, prN}, // Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M + {0x1BC70, 0x1BC7C, prN}, // Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK + {0x1BC80, 0x1BC88, prN}, // Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL + {0x1BC90, 0x1BC99, prN}, // Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW + {0x1BC9C, 0x1BC9C, prN}, // So DUPLOYAN SIGN O WITH CROSS + {0x1BC9D, 0x1BC9E, prN}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BC9F, 0x1BC9F, prN}, // Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP + {0x1BCA0, 0x1BCA3, prN}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prN}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prN}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1CF50, 0x1CFC3, prN}, // So [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK + {0x1D000, 0x1D0F5, prN}, // So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO + {0x1D100, 0x1D126, prN}, // So [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2 + {0x1D129, 0x1D164, prN}, // So [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE + {0x1D165, 0x1D166, prN}, // Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prN}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16A, 0x1D16C, prN}, // So [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3 + {0x1D16D, 0x1D172, prN}, // Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prN}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prN}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D183, 0x1D184, prN}, // So [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN + {0x1D185, 0x1D18B, prN}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D18C, 0x1D1A9, prN}, // So [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH + {0x1D1AA, 0x1D1AD, prN}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D1AE, 0x1D1EA, prN}, // So [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON + {0x1D200, 0x1D241, prN}, // So [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54 + {0x1D242, 0x1D244, prN}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1D245, 0x1D245, prN}, // So GREEK MUSICAL LEIMMA + {0x1D2C0, 0x1D2D3, prN}, // No [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN + {0x1D2E0, 0x1D2F3, prN}, // No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN + {0x1D300, 0x1D356, prN}, // So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING + {0x1D360, 0x1D378, prN}, // No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE + {0x1D400, 0x1D454, prN}, // L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G + {0x1D456, 0x1D49C, prN}, // L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A + {0x1D49E, 0x1D49F, prN}, // Lu [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D + {0x1D4A2, 0x1D4A2, prN}, // Lu MATHEMATICAL SCRIPT CAPITAL G + {0x1D4A5, 0x1D4A6, prN}, // Lu [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K + {0x1D4A9, 0x1D4AC, prN}, // Lu [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q + {0x1D4AE, 0x1D4B9, prN}, // L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D + {0x1D4BB, 0x1D4BB, prN}, // Ll MATHEMATICAL SCRIPT SMALL F + {0x1D4BD, 0x1D4C3, prN}, // Ll [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N + {0x1D4C5, 0x1D505, prN}, // L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B + {0x1D507, 0x1D50A, prN}, // Lu [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G + {0x1D50D, 0x1D514, prN}, // Lu [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q + {0x1D516, 0x1D51C, prN}, // Lu [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y + {0x1D51E, 0x1D539, prN}, // L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B + {0x1D53B, 0x1D53E, prN}, // Lu [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G + {0x1D540, 0x1D544, prN}, // Lu [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M + {0x1D546, 0x1D546, prN}, // Lu MATHEMATICAL DOUBLE-STRUCK CAPITAL O + {0x1D54A, 0x1D550, prN}, // Lu [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + {0x1D552, 0x1D6A5, prN}, // L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J + {0x1D6A8, 0x1D6C0, prN}, // Lu [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA + {0x1D6C1, 0x1D6C1, prN}, // Sm MATHEMATICAL BOLD NABLA + {0x1D6C2, 0x1D6DA, prN}, // Ll [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA + {0x1D6DB, 0x1D6DB, prN}, // Sm MATHEMATICAL BOLD PARTIAL DIFFERENTIAL + {0x1D6DC, 0x1D6FA, prN}, // L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA + {0x1D6FB, 0x1D6FB, prN}, // Sm MATHEMATICAL ITALIC NABLA + {0x1D6FC, 0x1D714, prN}, // Ll [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA + {0x1D715, 0x1D715, prN}, // Sm MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL + {0x1D716, 0x1D734, prN}, // L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA + {0x1D735, 0x1D735, prN}, // Sm MATHEMATICAL BOLD ITALIC NABLA + {0x1D736, 0x1D74E, prN}, // Ll [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA + {0x1D74F, 0x1D74F, prN}, // Sm MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL + {0x1D750, 0x1D76E, prN}, // L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA + {0x1D76F, 0x1D76F, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD NABLA + {0x1D770, 0x1D788, prN}, // Ll [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA + {0x1D789, 0x1D789, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL + {0x1D78A, 0x1D7A8, prN}, // L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA + {0x1D7A9, 0x1D7A9, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA + {0x1D7AA, 0x1D7C2, prN}, // Ll [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA + {0x1D7C3, 0x1D7C3, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL + {0x1D7C4, 0x1D7CB, prN}, // L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA + {0x1D7CE, 0x1D7FF, prN}, // Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + {0x1D800, 0x1D9FF, prN}, // So [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD + {0x1DA00, 0x1DA36, prN}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA37, 0x1DA3A, prN}, // So [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE + {0x1DA3B, 0x1DA6C, prN}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA6D, 0x1DA74, prN}, // So [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING + {0x1DA75, 0x1DA75, prN}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA76, 0x1DA83, prN}, // So [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH + {0x1DA84, 0x1DA84, prN}, // Mn SIGNWRITING LOCATION HEAD NECK + {0x1DA85, 0x1DA86, prN}, // So [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS + {0x1DA87, 0x1DA8B, prN}, // Po [5] SIGNWRITING COMMA..SIGNWRITING PARENTHESIS + {0x1DA9B, 0x1DA9F, prN}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prN}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1DF00, 0x1DF09, prN}, // Ll [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK + {0x1DF0A, 0x1DF0A, prN}, // Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK + {0x1DF0B, 0x1DF1E, prN}, // Ll [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL + {0x1DF25, 0x1DF2A, prN}, // Ll [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK + {0x1E000, 0x1E006, prN}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prN}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prN}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prN}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prN}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E030, 0x1E06D, prN}, // Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE + {0x1E08F, 0x1E08F, prN}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E100, 0x1E12C, prN}, // Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W + {0x1E130, 0x1E136, prN}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E137, 0x1E13D, prN}, // Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER + {0x1E140, 0x1E149, prN}, // Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE + {0x1E14E, 0x1E14E, prN}, // Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ + {0x1E14F, 0x1E14F, prN}, // So NYIAKENG PUACHUE HMONG CIRCLED CA + {0x1E290, 0x1E2AD, prN}, // Lo [30] TOTO LETTER PA..TOTO LETTER A + {0x1E2AE, 0x1E2AE, prN}, // Mn TOTO SIGN RISING TONE + {0x1E2C0, 0x1E2EB, prN}, // Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH + {0x1E2EC, 0x1E2EF, prN}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E2F0, 0x1E2F9, prN}, // Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE + {0x1E2FF, 0x1E2FF, prN}, // Sc WANCHO NGUN SIGN + {0x1E4D0, 0x1E4EA, prN}, // Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL + {0x1E4EB, 0x1E4EB, prN}, // Lm NAG MUNDARI SIGN OJOD + {0x1E4EC, 0x1E4EF, prN}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E4F0, 0x1E4F9, prN}, // Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE + {0x1E7E0, 0x1E7E6, prN}, // Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO + {0x1E7E8, 0x1E7EB, prN}, // Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE + {0x1E7ED, 0x1E7EE, prN}, // Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE + {0x1E7F0, 0x1E7FE, prN}, // Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE + {0x1E800, 0x1E8C4, prN}, // Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON + {0x1E8C7, 0x1E8CF, prN}, // No [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE + {0x1E8D0, 0x1E8D6, prN}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E900, 0x1E943, prN}, // L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA + {0x1E944, 0x1E94A, prN}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1E94B, 0x1E94B, prN}, // Lm ADLAM NASALIZATION MARK + {0x1E950, 0x1E959, prN}, // Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE + {0x1E95E, 0x1E95F, prN}, // Po [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK + {0x1EC71, 0x1ECAB, prN}, // No [59] INDIC SIYAQ NUMBER ONE..INDIC SIYAQ NUMBER PREFIXED NINE + {0x1ECAC, 0x1ECAC, prN}, // So INDIC SIYAQ PLACEHOLDER + {0x1ECAD, 0x1ECAF, prN}, // No [3] INDIC SIYAQ FRACTION ONE QUARTER..INDIC SIYAQ FRACTION THREE QUARTERS + {0x1ECB0, 0x1ECB0, prN}, // Sc INDIC SIYAQ RUPEE MARK + {0x1ECB1, 0x1ECB4, prN}, // No [4] INDIC SIYAQ NUMBER ALTERNATE ONE..INDIC SIYAQ ALTERNATE LAKH MARK + {0x1ED01, 0x1ED2D, prN}, // No [45] OTTOMAN SIYAQ NUMBER ONE..OTTOMAN SIYAQ NUMBER NINETY THOUSAND + {0x1ED2E, 0x1ED2E, prN}, // So OTTOMAN SIYAQ MARRATAN + {0x1ED2F, 0x1ED3D, prN}, // No [15] OTTOMAN SIYAQ ALTERNATE NUMBER TWO..OTTOMAN SIYAQ FRACTION ONE SIXTH + {0x1EE00, 0x1EE03, prN}, // Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL + {0x1EE05, 0x1EE1F, prN}, // Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF + {0x1EE21, 0x1EE22, prN}, // Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM + {0x1EE24, 0x1EE24, prN}, // Lo ARABIC MATHEMATICAL INITIAL HEH + {0x1EE27, 0x1EE27, prN}, // Lo ARABIC MATHEMATICAL INITIAL HAH + {0x1EE29, 0x1EE32, prN}, // Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF + {0x1EE34, 0x1EE37, prN}, // Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH + {0x1EE39, 0x1EE39, prN}, // Lo ARABIC MATHEMATICAL INITIAL DAD + {0x1EE3B, 0x1EE3B, prN}, // Lo ARABIC MATHEMATICAL INITIAL GHAIN + {0x1EE42, 0x1EE42, prN}, // Lo ARABIC MATHEMATICAL TAILED JEEM + {0x1EE47, 0x1EE47, prN}, // Lo ARABIC MATHEMATICAL TAILED HAH + {0x1EE49, 0x1EE49, prN}, // Lo ARABIC MATHEMATICAL TAILED YEH + {0x1EE4B, 0x1EE4B, prN}, // Lo ARABIC MATHEMATICAL TAILED LAM + {0x1EE4D, 0x1EE4F, prN}, // Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN + {0x1EE51, 0x1EE52, prN}, // Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF + {0x1EE54, 0x1EE54, prN}, // Lo ARABIC MATHEMATICAL TAILED SHEEN + {0x1EE57, 0x1EE57, prN}, // Lo ARABIC MATHEMATICAL TAILED KHAH + {0x1EE59, 0x1EE59, prN}, // Lo ARABIC MATHEMATICAL TAILED DAD + {0x1EE5B, 0x1EE5B, prN}, // Lo ARABIC MATHEMATICAL TAILED GHAIN + {0x1EE5D, 0x1EE5D, prN}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON + {0x1EE5F, 0x1EE5F, prN}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF + {0x1EE61, 0x1EE62, prN}, // Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM + {0x1EE64, 0x1EE64, prN}, // Lo ARABIC MATHEMATICAL STRETCHED HEH + {0x1EE67, 0x1EE6A, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF + {0x1EE6C, 0x1EE72, prN}, // Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF + {0x1EE74, 0x1EE77, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH + {0x1EE79, 0x1EE7C, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH + {0x1EE7E, 0x1EE7E, prN}, // Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH + {0x1EE80, 0x1EE89, prN}, // Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH + {0x1EE8B, 0x1EE9B, prN}, // Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN + {0x1EEA1, 0x1EEA3, prN}, // Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL + {0x1EEA5, 0x1EEA9, prN}, // Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH + {0x1EEAB, 0x1EEBB, prN}, // Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN + {0x1EEF0, 0x1EEF1, prN}, // Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL + {0x1F000, 0x1F003, prN}, // So [4] MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND + {0x1F004, 0x1F004, prW}, // So MAHJONG TILE RED DRAGON + {0x1F005, 0x1F02B, prN}, // So [39] MAHJONG TILE GREEN DRAGON..MAHJONG TILE BACK + {0x1F030, 0x1F093, prN}, // So [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06 + {0x1F0A0, 0x1F0AE, prN}, // So [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES + {0x1F0B1, 0x1F0BF, prN}, // So [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER + {0x1F0C1, 0x1F0CE, prN}, // So [14] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD KING OF DIAMONDS + {0x1F0CF, 0x1F0CF, prW}, // So PLAYING CARD BLACK JOKER + {0x1F0D1, 0x1F0F5, prN}, // So [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21 + {0x1F100, 0x1F10A, prA}, // No [11] DIGIT ZERO FULL STOP..DIGIT NINE COMMA + {0x1F10B, 0x1F10C, prN}, // No [2] DINGBAT CIRCLED SANS-SERIF DIGIT ZERO..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO + {0x1F10D, 0x1F10F, prN}, // So [3] CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH + {0x1F110, 0x1F12D, prA}, // So [30] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED CD + {0x1F12E, 0x1F12F, prN}, // So [2] CIRCLED WZ..COPYLEFT SYMBOL + {0x1F130, 0x1F169, prA}, // So [58] SQUARED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z + {0x1F16A, 0x1F16F, prN}, // So [6] RAISED MC SIGN..CIRCLED HUMAN FIGURE + {0x1F170, 0x1F18D, prA}, // So [30] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED SA + {0x1F18E, 0x1F18E, prW}, // So NEGATIVE SQUARED AB + {0x1F18F, 0x1F190, prA}, // So [2] NEGATIVE SQUARED WC..SQUARE DJ + {0x1F191, 0x1F19A, prW}, // So [10] SQUARED CL..SQUARED VS + {0x1F19B, 0x1F1AC, prA}, // So [18] SQUARED THREE D..SQUARED VOD + {0x1F1AD, 0x1F1AD, prN}, // So MASK WORK SYMBOL + {0x1F1E6, 0x1F1FF, prN}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z + {0x1F200, 0x1F202, prW}, // So [3] SQUARE HIRAGANA HOKA..SQUARED KATAKANA SA + {0x1F210, 0x1F23B, prW}, // So [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D + {0x1F240, 0x1F248, prW}, // So [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 + {0x1F250, 0x1F251, prW}, // So [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT + {0x1F260, 0x1F265, prW}, // So [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI + {0x1F300, 0x1F320, prW}, // So [33] CYCLONE..SHOOTING STAR + {0x1F321, 0x1F32C, prN}, // So [12] THERMOMETER..WIND BLOWING FACE + {0x1F32D, 0x1F335, prW}, // So [9] HOT DOG..CACTUS + {0x1F336, 0x1F336, prN}, // So HOT PEPPER + {0x1F337, 0x1F37C, prW}, // So [70] TULIP..BABY BOTTLE + {0x1F37D, 0x1F37D, prN}, // So FORK AND KNIFE WITH PLATE + {0x1F37E, 0x1F393, prW}, // So [22] BOTTLE WITH POPPING CORK..GRADUATION CAP + {0x1F394, 0x1F39F, prN}, // So [12] HEART WITH TIP ON THE LEFT..ADMISSION TICKETS + {0x1F3A0, 0x1F3CA, prW}, // So [43] CAROUSEL HORSE..SWIMMER + {0x1F3CB, 0x1F3CE, prN}, // So [4] WEIGHT LIFTER..RACING CAR + {0x1F3CF, 0x1F3D3, prW}, // So [5] CRICKET BAT AND BALL..TABLE TENNIS PADDLE AND BALL + {0x1F3D4, 0x1F3DF, prN}, // So [12] SNOW CAPPED MOUNTAIN..STADIUM + {0x1F3E0, 0x1F3F0, prW}, // So [17] HOUSE BUILDING..EUROPEAN CASTLE + {0x1F3F1, 0x1F3F3, prN}, // So [3] WHITE PENNANT..WAVING WHITE FLAG + {0x1F3F4, 0x1F3F4, prW}, // So WAVING BLACK FLAG + {0x1F3F5, 0x1F3F7, prN}, // So [3] ROSETTE..LABEL + {0x1F3F8, 0x1F3FA, prW}, // So [3] BADMINTON RACQUET AND SHUTTLECOCK..AMPHORA + {0x1F3FB, 0x1F3FF, prW}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + {0x1F400, 0x1F43E, prW}, // So [63] RAT..PAW PRINTS + {0x1F43F, 0x1F43F, prN}, // So CHIPMUNK + {0x1F440, 0x1F440, prW}, // So EYES + {0x1F441, 0x1F441, prN}, // So EYE + {0x1F442, 0x1F4FC, prW}, // So [187] EAR..VIDEOCASSETTE + {0x1F4FD, 0x1F4FE, prN}, // So [2] FILM PROJECTOR..PORTABLE STEREO + {0x1F4FF, 0x1F53D, prW}, // So [63] PRAYER BEADS..DOWN-POINTING SMALL RED TRIANGLE + {0x1F53E, 0x1F54A, prN}, // So [13] LOWER RIGHT SHADOWED WHITE CIRCLE..DOVE OF PEACE + {0x1F54B, 0x1F54E, prW}, // So [4] KAABA..MENORAH WITH NINE BRANCHES + {0x1F54F, 0x1F54F, prN}, // So BOWL OF HYGIEIA + {0x1F550, 0x1F567, prW}, // So [24] CLOCK FACE ONE OCLOCK..CLOCK FACE TWELVE-THIRTY + {0x1F568, 0x1F579, prN}, // So [18] RIGHT SPEAKER..JOYSTICK + {0x1F57A, 0x1F57A, prW}, // So MAN DANCING + {0x1F57B, 0x1F594, prN}, // So [26] LEFT HAND TELEPHONE RECEIVER..REVERSED VICTORY HAND + {0x1F595, 0x1F596, prW}, // So [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS + {0x1F597, 0x1F5A3, prN}, // So [13] WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX + {0x1F5A4, 0x1F5A4, prW}, // So BLACK HEART + {0x1F5A5, 0x1F5FA, prN}, // So [86] DESKTOP COMPUTER..WORLD MAP + {0x1F5FB, 0x1F5FF, prW}, // So [5] MOUNT FUJI..MOYAI + {0x1F600, 0x1F64F, prW}, // So [80] GRINNING FACE..PERSON WITH FOLDED HANDS + {0x1F650, 0x1F67F, prN}, // So [48] NORTH WEST POINTING LEAF..REVERSE CHECKER BOARD + {0x1F680, 0x1F6C5, prW}, // So [70] ROCKET..LEFT LUGGAGE + {0x1F6C6, 0x1F6CB, prN}, // So [6] TRIANGLE WITH ROUNDED CORNERS..COUCH AND LAMP + {0x1F6CC, 0x1F6CC, prW}, // So SLEEPING ACCOMMODATION + {0x1F6CD, 0x1F6CF, prN}, // So [3] SHOPPING BAGS..BED + {0x1F6D0, 0x1F6D2, prW}, // So [3] PLACE OF WORSHIP..SHOPPING TROLLEY + {0x1F6D3, 0x1F6D4, prN}, // So [2] STUPA..PAGODA + {0x1F6D5, 0x1F6D7, prW}, // So [3] HINDU TEMPLE..ELEVATOR + {0x1F6DC, 0x1F6DF, prW}, // So [4] WIRELESS..RING BUOY + {0x1F6E0, 0x1F6EA, prN}, // So [11] HAMMER AND WRENCH..NORTHEAST-POINTING AIRPLANE + {0x1F6EB, 0x1F6EC, prW}, // So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING + {0x1F6F0, 0x1F6F3, prN}, // So [4] SATELLITE..PASSENGER SHIP + {0x1F6F4, 0x1F6FC, prW}, // So [9] SCOOTER..ROLLER SKATE + {0x1F700, 0x1F776, prN}, // So [119] ALCHEMICAL SYMBOL FOR QUINTESSENCE..LUNAR ECLIPSE + {0x1F77B, 0x1F77F, prN}, // So [5] HAUMEA..ORCUS + {0x1F780, 0x1F7D9, prN}, // So [90] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NINE POINTED WHITE STAR + {0x1F7E0, 0x1F7EB, prW}, // So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE + {0x1F7F0, 0x1F7F0, prW}, // So HEAVY EQUALS SIGN + {0x1F800, 0x1F80B, prN}, // So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD + {0x1F810, 0x1F847, prN}, // So [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW + {0x1F850, 0x1F859, prN}, // So [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW + {0x1F860, 0x1F887, prN}, // So [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW + {0x1F890, 0x1F8AD, prN}, // So [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS + {0x1F8B0, 0x1F8B1, prN}, // So [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST + {0x1F900, 0x1F90B, prN}, // So [12] CIRCLED CROSS FORMEE WITH FOUR DOTS..DOWNWARD FACING NOTCHED HOOK WITH DOT + {0x1F90C, 0x1F93A, prW}, // So [47] PINCHED FINGERS..FENCER + {0x1F93B, 0x1F93B, prN}, // So MODERN PENTATHLON + {0x1F93C, 0x1F945, prW}, // So [10] WRESTLERS..GOAL NET + {0x1F946, 0x1F946, prN}, // So RIFLE + {0x1F947, 0x1F9FF, prW}, // So [185] FIRST PLACE MEDAL..NAZAR AMULET + {0x1FA00, 0x1FA53, prN}, // So [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP + {0x1FA60, 0x1FA6D, prN}, // So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER + {0x1FA70, 0x1FA7C, prW}, // So [13] BALLET SHOES..CRUTCH + {0x1FA80, 0x1FA88, prW}, // So [9] YO-YO..FLUTE + {0x1FA90, 0x1FABD, prW}, // So [46] RINGED PLANET..WING + {0x1FABF, 0x1FAC5, prW}, // So [7] GOOSE..PERSON WITH CROWN + {0x1FACE, 0x1FADB, prW}, // So [14] MOOSE..PEA POD + {0x1FAE0, 0x1FAE8, prW}, // So [9] MELTING FACE..SHAKING FACE + {0x1FAF0, 0x1FAF8, prW}, // So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND + {0x1FB00, 0x1FB92, prN}, // So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK + {0x1FB94, 0x1FBCA, prN}, // So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON + {0x1FBF0, 0x1FBF9, prN}, // Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE + {0x20000, 0x2A6DF, prW}, // Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF + {0x2A6E0, 0x2A6FF, prW}, // Cn [32] .. + {0x2A700, 0x2B739, prW}, // Lo [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739 + {0x2B73A, 0x2B73F, prW}, // Cn [6] .. + {0x2B740, 0x2B81D, prW}, // Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D + {0x2B81E, 0x2B81F, prW}, // Cn [2] .. + {0x2B820, 0x2CEA1, prW}, // Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 + {0x2CEA2, 0x2CEAF, prW}, // Cn [14] .. + {0x2CEB0, 0x2EBE0, prW}, // Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 + {0x2EBE1, 0x2F7FF, prW}, // Cn [3103] .. + {0x2F800, 0x2FA1D, prW}, // Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + {0x2FA1E, 0x2FA1F, prW}, // Cn [2] .. + {0x2FA20, 0x2FFFD, prW}, // Cn [1502] .. + {0x30000, 0x3134A, prW}, // Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A + {0x3134B, 0x3134F, prW}, // Cn [5] .. + {0x31350, 0x323AF, prW}, // Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF + {0x323B0, 0x3FFFD, prW}, // Cn [56398] .. + {0xE0001, 0xE0001, prN}, // Cf LANGUAGE TAG + {0xE0020, 0xE007F, prN}, // Cf [96] TAG SPACE..CANCEL TAG + {0xE0100, 0xE01EF, prA}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + {0xF0000, 0xFFFFD, prA}, // Co [65534] .. + {0x100000, 0x10FFFD, prA}, // Co [65534] .. +} diff --git a/vendor/github.com/rivo/uniseg/emojipresentation.go b/vendor/github.com/rivo/uniseg/emojipresentation.go new file mode 100644 index 000000000..9b5f499c4 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/emojipresentation.go @@ -0,0 +1,295 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// emojiPresentation are taken from +// +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var emojiPresentation = [][3]int{ + {0x231A, 0x231B, prEmojiPresentation}, // E0.6 [2] (⌚..⌛) watch..hourglass done + {0x23E9, 0x23EC, prEmojiPresentation}, // E0.6 [4] (⏩..⏬) fast-forward button..fast down button + {0x23F0, 0x23F0, prEmojiPresentation}, // E0.6 [1] (⏰) alarm clock + {0x23F3, 0x23F3, prEmojiPresentation}, // E0.6 [1] (⏳) hourglass not done + {0x25FD, 0x25FE, prEmojiPresentation}, // E0.6 [2] (◽..◾) white medium-small square..black medium-small square + {0x2614, 0x2615, prEmojiPresentation}, // E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage + {0x2648, 0x2653, prEmojiPresentation}, // E0.6 [12] (♈..♓) Aries..Pisces + {0x267F, 0x267F, prEmojiPresentation}, // E0.6 [1] (♿) wheelchair symbol + {0x2693, 0x2693, prEmojiPresentation}, // E0.6 [1] (⚓) anchor + {0x26A1, 0x26A1, prEmojiPresentation}, // E0.6 [1] (⚡) high voltage + {0x26AA, 0x26AB, prEmojiPresentation}, // E0.6 [2] (⚪..⚫) white circle..black circle + {0x26BD, 0x26BE, prEmojiPresentation}, // E0.6 [2] (⚽..⚾) soccer ball..baseball + {0x26C4, 0x26C5, prEmojiPresentation}, // E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud + {0x26CE, 0x26CE, prEmojiPresentation}, // E0.6 [1] (⛎) Ophiuchus + {0x26D4, 0x26D4, prEmojiPresentation}, // E0.6 [1] (⛔) no entry + {0x26EA, 0x26EA, prEmojiPresentation}, // E0.6 [1] (⛪) church + {0x26F2, 0x26F3, prEmojiPresentation}, // E0.6 [2] (⛲..⛳) fountain..flag in hole + {0x26F5, 0x26F5, prEmojiPresentation}, // E0.6 [1] (⛵) sailboat + {0x26FA, 0x26FA, prEmojiPresentation}, // E0.6 [1] (⛺) tent + {0x26FD, 0x26FD, prEmojiPresentation}, // E0.6 [1] (⛽) fuel pump + {0x2705, 0x2705, prEmojiPresentation}, // E0.6 [1] (✅) check mark button + {0x270A, 0x270B, prEmojiPresentation}, // E0.6 [2] (✊..✋) raised fist..raised hand + {0x2728, 0x2728, prEmojiPresentation}, // E0.6 [1] (✨) sparkles + {0x274C, 0x274C, prEmojiPresentation}, // E0.6 [1] (❌) cross mark + {0x274E, 0x274E, prEmojiPresentation}, // E0.6 [1] (❎) cross mark button + {0x2753, 0x2755, prEmojiPresentation}, // E0.6 [3] (❓..❕) red question mark..white exclamation mark + {0x2757, 0x2757, prEmojiPresentation}, // E0.6 [1] (❗) red exclamation mark + {0x2795, 0x2797, prEmojiPresentation}, // E0.6 [3] (➕..➗) plus..divide + {0x27B0, 0x27B0, prEmojiPresentation}, // E0.6 [1] (➰) curly loop + {0x27BF, 0x27BF, prEmojiPresentation}, // E1.0 [1] (➿) double curly loop + {0x2B1B, 0x2B1C, prEmojiPresentation}, // E0.6 [2] (⬛..⬜) black large square..white large square + {0x2B50, 0x2B50, prEmojiPresentation}, // E0.6 [1] (⭐) star + {0x2B55, 0x2B55, prEmojiPresentation}, // E0.6 [1] (⭕) hollow red circle + {0x1F004, 0x1F004, prEmojiPresentation}, // E0.6 [1] (🀄) mahjong red dragon + {0x1F0CF, 0x1F0CF, prEmojiPresentation}, // E0.6 [1] (🃏) joker + {0x1F18E, 0x1F18E, prEmojiPresentation}, // E0.6 [1] (🆎) AB button (blood type) + {0x1F191, 0x1F19A, prEmojiPresentation}, // E0.6 [10] (🆑..🆚) CL button..VS button + {0x1F1E6, 0x1F1FF, prEmojiPresentation}, // E0.0 [26] (🇦..🇿) regional indicator symbol letter a..regional indicator symbol letter z + {0x1F201, 0x1F201, prEmojiPresentation}, // E0.6 [1] (🈁) Japanese “here” button + {0x1F21A, 0x1F21A, prEmojiPresentation}, // E0.6 [1] (🈚) Japanese “free of charge” button + {0x1F22F, 0x1F22F, prEmojiPresentation}, // E0.6 [1] (🈯) Japanese “reserved” button + {0x1F232, 0x1F236, prEmojiPresentation}, // E0.6 [5] (🈲..🈶) Japanese “prohibited” button..Japanese “not free of charge” button + {0x1F238, 0x1F23A, prEmojiPresentation}, // E0.6 [3] (🈸..🈺) Japanese “application” button..Japanese “open for business” button + {0x1F250, 0x1F251, prEmojiPresentation}, // E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button + {0x1F300, 0x1F30C, prEmojiPresentation}, // E0.6 [13] (🌀..🌌) cyclone..milky way + {0x1F30D, 0x1F30E, prEmojiPresentation}, // E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas + {0x1F30F, 0x1F30F, prEmojiPresentation}, // E0.6 [1] (🌏) globe showing Asia-Australia + {0x1F310, 0x1F310, prEmojiPresentation}, // E1.0 [1] (🌐) globe with meridians + {0x1F311, 0x1F311, prEmojiPresentation}, // E0.6 [1] (🌑) new moon + {0x1F312, 0x1F312, prEmojiPresentation}, // E1.0 [1] (🌒) waxing crescent moon + {0x1F313, 0x1F315, prEmojiPresentation}, // E0.6 [3] (🌓..🌕) first quarter moon..full moon + {0x1F316, 0x1F318, prEmojiPresentation}, // E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon + {0x1F319, 0x1F319, prEmojiPresentation}, // E0.6 [1] (🌙) crescent moon + {0x1F31A, 0x1F31A, prEmojiPresentation}, // E1.0 [1] (🌚) new moon face + {0x1F31B, 0x1F31B, prEmojiPresentation}, // E0.6 [1] (🌛) first quarter moon face + {0x1F31C, 0x1F31C, prEmojiPresentation}, // E0.7 [1] (🌜) last quarter moon face + {0x1F31D, 0x1F31E, prEmojiPresentation}, // E1.0 [2] (🌝..🌞) full moon face..sun with face + {0x1F31F, 0x1F320, prEmojiPresentation}, // E0.6 [2] (🌟..🌠) glowing star..shooting star + {0x1F32D, 0x1F32F, prEmojiPresentation}, // E1.0 [3] (🌭..🌯) hot dog..burrito + {0x1F330, 0x1F331, prEmojiPresentation}, // E0.6 [2] (🌰..🌱) chestnut..seedling + {0x1F332, 0x1F333, prEmojiPresentation}, // E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree + {0x1F334, 0x1F335, prEmojiPresentation}, // E0.6 [2] (🌴..🌵) palm tree..cactus + {0x1F337, 0x1F34A, prEmojiPresentation}, // E0.6 [20] (🌷..🍊) tulip..tangerine + {0x1F34B, 0x1F34B, prEmojiPresentation}, // E1.0 [1] (🍋) lemon + {0x1F34C, 0x1F34F, prEmojiPresentation}, // E0.6 [4] (🍌..🍏) banana..green apple + {0x1F350, 0x1F350, prEmojiPresentation}, // E1.0 [1] (🍐) pear + {0x1F351, 0x1F37B, prEmojiPresentation}, // E0.6 [43] (🍑..🍻) peach..clinking beer mugs + {0x1F37C, 0x1F37C, prEmojiPresentation}, // E1.0 [1] (🍼) baby bottle + {0x1F37E, 0x1F37F, prEmojiPresentation}, // E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn + {0x1F380, 0x1F393, prEmojiPresentation}, // E0.6 [20] (🎀..🎓) ribbon..graduation cap + {0x1F3A0, 0x1F3C4, prEmojiPresentation}, // E0.6 [37] (🎠..🏄) carousel horse..person surfing + {0x1F3C5, 0x1F3C5, prEmojiPresentation}, // E1.0 [1] (🏅) sports medal + {0x1F3C6, 0x1F3C6, prEmojiPresentation}, // E0.6 [1] (🏆) trophy + {0x1F3C7, 0x1F3C7, prEmojiPresentation}, // E1.0 [1] (🏇) horse racing + {0x1F3C8, 0x1F3C8, prEmojiPresentation}, // E0.6 [1] (🏈) american football + {0x1F3C9, 0x1F3C9, prEmojiPresentation}, // E1.0 [1] (🏉) rugby football + {0x1F3CA, 0x1F3CA, prEmojiPresentation}, // E0.6 [1] (🏊) person swimming + {0x1F3CF, 0x1F3D3, prEmojiPresentation}, // E1.0 [5] (🏏..🏓) cricket game..ping pong + {0x1F3E0, 0x1F3E3, prEmojiPresentation}, // E0.6 [4] (🏠..🏣) house..Japanese post office + {0x1F3E4, 0x1F3E4, prEmojiPresentation}, // E1.0 [1] (🏤) post office + {0x1F3E5, 0x1F3F0, prEmojiPresentation}, // E0.6 [12] (🏥..🏰) hospital..castle + {0x1F3F4, 0x1F3F4, prEmojiPresentation}, // E1.0 [1] (🏴) black flag + {0x1F3F8, 0x1F407, prEmojiPresentation}, // E1.0 [16] (🏸..🐇) badminton..rabbit + {0x1F408, 0x1F408, prEmojiPresentation}, // E0.7 [1] (🐈) cat + {0x1F409, 0x1F40B, prEmojiPresentation}, // E1.0 [3] (🐉..🐋) dragon..whale + {0x1F40C, 0x1F40E, prEmojiPresentation}, // E0.6 [3] (🐌..🐎) snail..horse + {0x1F40F, 0x1F410, prEmojiPresentation}, // E1.0 [2] (🐏..🐐) ram..goat + {0x1F411, 0x1F412, prEmojiPresentation}, // E0.6 [2] (🐑..🐒) ewe..monkey + {0x1F413, 0x1F413, prEmojiPresentation}, // E1.0 [1] (🐓) rooster + {0x1F414, 0x1F414, prEmojiPresentation}, // E0.6 [1] (🐔) chicken + {0x1F415, 0x1F415, prEmojiPresentation}, // E0.7 [1] (🐕) dog + {0x1F416, 0x1F416, prEmojiPresentation}, // E1.0 [1] (🐖) pig + {0x1F417, 0x1F429, prEmojiPresentation}, // E0.6 [19] (🐗..🐩) boar..poodle + {0x1F42A, 0x1F42A, prEmojiPresentation}, // E1.0 [1] (🐪) camel + {0x1F42B, 0x1F43E, prEmojiPresentation}, // E0.6 [20] (🐫..🐾) two-hump camel..paw prints + {0x1F440, 0x1F440, prEmojiPresentation}, // E0.6 [1] (👀) eyes + {0x1F442, 0x1F464, prEmojiPresentation}, // E0.6 [35] (👂..👤) ear..bust in silhouette + {0x1F465, 0x1F465, prEmojiPresentation}, // E1.0 [1] (👥) busts in silhouette + {0x1F466, 0x1F46B, prEmojiPresentation}, // E0.6 [6] (👦..👫) boy..woman and man holding hands + {0x1F46C, 0x1F46D, prEmojiPresentation}, // E1.0 [2] (👬..👭) men holding hands..women holding hands + {0x1F46E, 0x1F4AC, prEmojiPresentation}, // E0.6 [63] (👮..💬) police officer..speech balloon + {0x1F4AD, 0x1F4AD, prEmojiPresentation}, // E1.0 [1] (💭) thought balloon + {0x1F4AE, 0x1F4B5, prEmojiPresentation}, // E0.6 [8] (💮..💵) white flower..dollar banknote + {0x1F4B6, 0x1F4B7, prEmojiPresentation}, // E1.0 [2] (💶..💷) euro banknote..pound banknote + {0x1F4B8, 0x1F4EB, prEmojiPresentation}, // E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag + {0x1F4EC, 0x1F4ED, prEmojiPresentation}, // E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag + {0x1F4EE, 0x1F4EE, prEmojiPresentation}, // E0.6 [1] (📮) postbox + {0x1F4EF, 0x1F4EF, prEmojiPresentation}, // E1.0 [1] (📯) postal horn + {0x1F4F0, 0x1F4F4, prEmojiPresentation}, // E0.6 [5] (📰..📴) newspaper..mobile phone off + {0x1F4F5, 0x1F4F5, prEmojiPresentation}, // E1.0 [1] (📵) no mobile phones + {0x1F4F6, 0x1F4F7, prEmojiPresentation}, // E0.6 [2] (📶..📷) antenna bars..camera + {0x1F4F8, 0x1F4F8, prEmojiPresentation}, // E1.0 [1] (📸) camera with flash + {0x1F4F9, 0x1F4FC, prEmojiPresentation}, // E0.6 [4] (📹..📼) video camera..videocassette + {0x1F4FF, 0x1F502, prEmojiPresentation}, // E1.0 [4] (📿..🔂) prayer beads..repeat single button + {0x1F503, 0x1F503, prEmojiPresentation}, // E0.6 [1] (🔃) clockwise vertical arrows + {0x1F504, 0x1F507, prEmojiPresentation}, // E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker + {0x1F508, 0x1F508, prEmojiPresentation}, // E0.7 [1] (🔈) speaker low volume + {0x1F509, 0x1F509, prEmojiPresentation}, // E1.0 [1] (🔉) speaker medium volume + {0x1F50A, 0x1F514, prEmojiPresentation}, // E0.6 [11] (🔊..🔔) speaker high volume..bell + {0x1F515, 0x1F515, prEmojiPresentation}, // E1.0 [1] (🔕) bell with slash + {0x1F516, 0x1F52B, prEmojiPresentation}, // E0.6 [22] (🔖..🔫) bookmark..water pistol + {0x1F52C, 0x1F52D, prEmojiPresentation}, // E1.0 [2] (🔬..🔭) microscope..telescope + {0x1F52E, 0x1F53D, prEmojiPresentation}, // E0.6 [16] (🔮..🔽) crystal ball..downwards button + {0x1F54B, 0x1F54E, prEmojiPresentation}, // E1.0 [4] (🕋..🕎) kaaba..menorah + {0x1F550, 0x1F55B, prEmojiPresentation}, // E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock + {0x1F55C, 0x1F567, prEmojiPresentation}, // E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty + {0x1F57A, 0x1F57A, prEmojiPresentation}, // E3.0 [1] (🕺) man dancing + {0x1F595, 0x1F596, prEmojiPresentation}, // E1.0 [2] (🖕..🖖) middle finger..vulcan salute + {0x1F5A4, 0x1F5A4, prEmojiPresentation}, // E3.0 [1] (🖤) black heart + {0x1F5FB, 0x1F5FF, prEmojiPresentation}, // E0.6 [5] (🗻..🗿) mount fuji..moai + {0x1F600, 0x1F600, prEmojiPresentation}, // E1.0 [1] (😀) grinning face + {0x1F601, 0x1F606, prEmojiPresentation}, // E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face + {0x1F607, 0x1F608, prEmojiPresentation}, // E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns + {0x1F609, 0x1F60D, prEmojiPresentation}, // E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes + {0x1F60E, 0x1F60E, prEmojiPresentation}, // E1.0 [1] (😎) smiling face with sunglasses + {0x1F60F, 0x1F60F, prEmojiPresentation}, // E0.6 [1] (😏) smirking face + {0x1F610, 0x1F610, prEmojiPresentation}, // E0.7 [1] (😐) neutral face + {0x1F611, 0x1F611, prEmojiPresentation}, // E1.0 [1] (😑) expressionless face + {0x1F612, 0x1F614, prEmojiPresentation}, // E0.6 [3] (😒..😔) unamused face..pensive face + {0x1F615, 0x1F615, prEmojiPresentation}, // E1.0 [1] (😕) confused face + {0x1F616, 0x1F616, prEmojiPresentation}, // E0.6 [1] (😖) confounded face + {0x1F617, 0x1F617, prEmojiPresentation}, // E1.0 [1] (😗) kissing face + {0x1F618, 0x1F618, prEmojiPresentation}, // E0.6 [1] (😘) face blowing a kiss + {0x1F619, 0x1F619, prEmojiPresentation}, // E1.0 [1] (😙) kissing face with smiling eyes + {0x1F61A, 0x1F61A, prEmojiPresentation}, // E0.6 [1] (😚) kissing face with closed eyes + {0x1F61B, 0x1F61B, prEmojiPresentation}, // E1.0 [1] (😛) face with tongue + {0x1F61C, 0x1F61E, prEmojiPresentation}, // E0.6 [3] (😜..😞) winking face with tongue..disappointed face + {0x1F61F, 0x1F61F, prEmojiPresentation}, // E1.0 [1] (😟) worried face + {0x1F620, 0x1F625, prEmojiPresentation}, // E0.6 [6] (😠..😥) angry face..sad but relieved face + {0x1F626, 0x1F627, prEmojiPresentation}, // E1.0 [2] (😦..😧) frowning face with open mouth..anguished face + {0x1F628, 0x1F62B, prEmojiPresentation}, // E0.6 [4] (😨..😫) fearful face..tired face + {0x1F62C, 0x1F62C, prEmojiPresentation}, // E1.0 [1] (😬) grimacing face + {0x1F62D, 0x1F62D, prEmojiPresentation}, // E0.6 [1] (😭) loudly crying face + {0x1F62E, 0x1F62F, prEmojiPresentation}, // E1.0 [2] (😮..😯) face with open mouth..hushed face + {0x1F630, 0x1F633, prEmojiPresentation}, // E0.6 [4] (😰..😳) anxious face with sweat..flushed face + {0x1F634, 0x1F634, prEmojiPresentation}, // E1.0 [1] (😴) sleeping face + {0x1F635, 0x1F635, prEmojiPresentation}, // E0.6 [1] (😵) face with crossed-out eyes + {0x1F636, 0x1F636, prEmojiPresentation}, // E1.0 [1] (😶) face without mouth + {0x1F637, 0x1F640, prEmojiPresentation}, // E0.6 [10] (😷..🙀) face with medical mask..weary cat + {0x1F641, 0x1F644, prEmojiPresentation}, // E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes + {0x1F645, 0x1F64F, prEmojiPresentation}, // E0.6 [11] (🙅..🙏) person gesturing NO..folded hands + {0x1F680, 0x1F680, prEmojiPresentation}, // E0.6 [1] (🚀) rocket + {0x1F681, 0x1F682, prEmojiPresentation}, // E1.0 [2] (🚁..🚂) helicopter..locomotive + {0x1F683, 0x1F685, prEmojiPresentation}, // E0.6 [3] (🚃..🚅) railway car..bullet train + {0x1F686, 0x1F686, prEmojiPresentation}, // E1.0 [1] (🚆) train + {0x1F687, 0x1F687, prEmojiPresentation}, // E0.6 [1] (🚇) metro + {0x1F688, 0x1F688, prEmojiPresentation}, // E1.0 [1] (🚈) light rail + {0x1F689, 0x1F689, prEmojiPresentation}, // E0.6 [1] (🚉) station + {0x1F68A, 0x1F68B, prEmojiPresentation}, // E1.0 [2] (🚊..🚋) tram..tram car + {0x1F68C, 0x1F68C, prEmojiPresentation}, // E0.6 [1] (🚌) bus + {0x1F68D, 0x1F68D, prEmojiPresentation}, // E0.7 [1] (🚍) oncoming bus + {0x1F68E, 0x1F68E, prEmojiPresentation}, // E1.0 [1] (🚎) trolleybus + {0x1F68F, 0x1F68F, prEmojiPresentation}, // E0.6 [1] (🚏) bus stop + {0x1F690, 0x1F690, prEmojiPresentation}, // E1.0 [1] (🚐) minibus + {0x1F691, 0x1F693, prEmojiPresentation}, // E0.6 [3] (🚑..🚓) ambulance..police car + {0x1F694, 0x1F694, prEmojiPresentation}, // E0.7 [1] (🚔) oncoming police car + {0x1F695, 0x1F695, prEmojiPresentation}, // E0.6 [1] (🚕) taxi + {0x1F696, 0x1F696, prEmojiPresentation}, // E1.0 [1] (🚖) oncoming taxi + {0x1F697, 0x1F697, prEmojiPresentation}, // E0.6 [1] (🚗) automobile + {0x1F698, 0x1F698, prEmojiPresentation}, // E0.7 [1] (🚘) oncoming automobile + {0x1F699, 0x1F69A, prEmojiPresentation}, // E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck + {0x1F69B, 0x1F6A1, prEmojiPresentation}, // E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway + {0x1F6A2, 0x1F6A2, prEmojiPresentation}, // E0.6 [1] (🚢) ship + {0x1F6A3, 0x1F6A3, prEmojiPresentation}, // E1.0 [1] (🚣) person rowing boat + {0x1F6A4, 0x1F6A5, prEmojiPresentation}, // E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light + {0x1F6A6, 0x1F6A6, prEmojiPresentation}, // E1.0 [1] (🚦) vertical traffic light + {0x1F6A7, 0x1F6AD, prEmojiPresentation}, // E0.6 [7] (🚧..🚭) construction..no smoking + {0x1F6AE, 0x1F6B1, prEmojiPresentation}, // E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water + {0x1F6B2, 0x1F6B2, prEmojiPresentation}, // E0.6 [1] (🚲) bicycle + {0x1F6B3, 0x1F6B5, prEmojiPresentation}, // E1.0 [3] (🚳..🚵) no bicycles..person mountain biking + {0x1F6B6, 0x1F6B6, prEmojiPresentation}, // E0.6 [1] (🚶) person walking + {0x1F6B7, 0x1F6B8, prEmojiPresentation}, // E1.0 [2] (🚷..🚸) no pedestrians..children crossing + {0x1F6B9, 0x1F6BE, prEmojiPresentation}, // E0.6 [6] (🚹..🚾) men’s room..water closet + {0x1F6BF, 0x1F6BF, prEmojiPresentation}, // E1.0 [1] (🚿) shower + {0x1F6C0, 0x1F6C0, prEmojiPresentation}, // E0.6 [1] (🛀) person taking bath + {0x1F6C1, 0x1F6C5, prEmojiPresentation}, // E1.0 [5] (🛁..🛅) bathtub..left luggage + {0x1F6CC, 0x1F6CC, prEmojiPresentation}, // E1.0 [1] (🛌) person in bed + {0x1F6D0, 0x1F6D0, prEmojiPresentation}, // E1.0 [1] (🛐) place of worship + {0x1F6D1, 0x1F6D2, prEmojiPresentation}, // E3.0 [2] (🛑..🛒) stop sign..shopping cart + {0x1F6D5, 0x1F6D5, prEmojiPresentation}, // E12.0 [1] (🛕) hindu temple + {0x1F6D6, 0x1F6D7, prEmojiPresentation}, // E13.0 [2] (🛖..🛗) hut..elevator + {0x1F6DC, 0x1F6DC, prEmojiPresentation}, // E15.0 [1] (🛜) wireless + {0x1F6DD, 0x1F6DF, prEmojiPresentation}, // E14.0 [3] (🛝..🛟) playground slide..ring buoy + {0x1F6EB, 0x1F6EC, prEmojiPresentation}, // E1.0 [2] (🛫..🛬) airplane departure..airplane arrival + {0x1F6F4, 0x1F6F6, prEmojiPresentation}, // E3.0 [3] (🛴..🛶) kick scooter..canoe + {0x1F6F7, 0x1F6F8, prEmojiPresentation}, // E5.0 [2] (🛷..🛸) sled..flying saucer + {0x1F6F9, 0x1F6F9, prEmojiPresentation}, // E11.0 [1] (🛹) skateboard + {0x1F6FA, 0x1F6FA, prEmojiPresentation}, // E12.0 [1] (🛺) auto rickshaw + {0x1F6FB, 0x1F6FC, prEmojiPresentation}, // E13.0 [2] (🛻..🛼) pickup truck..roller skate + {0x1F7E0, 0x1F7EB, prEmojiPresentation}, // E12.0 [12] (🟠..🟫) orange circle..brown square + {0x1F7F0, 0x1F7F0, prEmojiPresentation}, // E14.0 [1] (🟰) heavy equals sign + {0x1F90C, 0x1F90C, prEmojiPresentation}, // E13.0 [1] (🤌) pinched fingers + {0x1F90D, 0x1F90F, prEmojiPresentation}, // E12.0 [3] (🤍..🤏) white heart..pinching hand + {0x1F910, 0x1F918, prEmojiPresentation}, // E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns + {0x1F919, 0x1F91E, prEmojiPresentation}, // E3.0 [6] (🤙..🤞) call me hand..crossed fingers + {0x1F91F, 0x1F91F, prEmojiPresentation}, // E5.0 [1] (🤟) love-you gesture + {0x1F920, 0x1F927, prEmojiPresentation}, // E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face + {0x1F928, 0x1F92F, prEmojiPresentation}, // E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head + {0x1F930, 0x1F930, prEmojiPresentation}, // E3.0 [1] (🤰) pregnant woman + {0x1F931, 0x1F932, prEmojiPresentation}, // E5.0 [2] (🤱..🤲) breast-feeding..palms up together + {0x1F933, 0x1F93A, prEmojiPresentation}, // E3.0 [8] (🤳..🤺) selfie..person fencing + {0x1F93C, 0x1F93E, prEmojiPresentation}, // E3.0 [3] (🤼..🤾) people wrestling..person playing handball + {0x1F93F, 0x1F93F, prEmojiPresentation}, // E12.0 [1] (🤿) diving mask + {0x1F940, 0x1F945, prEmojiPresentation}, // E3.0 [6] (🥀..🥅) wilted flower..goal net + {0x1F947, 0x1F94B, prEmojiPresentation}, // E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform + {0x1F94C, 0x1F94C, prEmojiPresentation}, // E5.0 [1] (🥌) curling stone + {0x1F94D, 0x1F94F, prEmojiPresentation}, // E11.0 [3] (🥍..🥏) lacrosse..flying disc + {0x1F950, 0x1F95E, prEmojiPresentation}, // E3.0 [15] (🥐..🥞) croissant..pancakes + {0x1F95F, 0x1F96B, prEmojiPresentation}, // E5.0 [13] (🥟..🥫) dumpling..canned food + {0x1F96C, 0x1F970, prEmojiPresentation}, // E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts + {0x1F971, 0x1F971, prEmojiPresentation}, // E12.0 [1] (🥱) yawning face + {0x1F972, 0x1F972, prEmojiPresentation}, // E13.0 [1] (🥲) smiling face with tear + {0x1F973, 0x1F976, prEmojiPresentation}, // E11.0 [4] (🥳..🥶) partying face..cold face + {0x1F977, 0x1F978, prEmojiPresentation}, // E13.0 [2] (🥷..🥸) ninja..disguised face + {0x1F979, 0x1F979, prEmojiPresentation}, // E14.0 [1] (🥹) face holding back tears + {0x1F97A, 0x1F97A, prEmojiPresentation}, // E11.0 [1] (🥺) pleading face + {0x1F97B, 0x1F97B, prEmojiPresentation}, // E12.0 [1] (🥻) sari + {0x1F97C, 0x1F97F, prEmojiPresentation}, // E11.0 [4] (🥼..🥿) lab coat..flat shoe + {0x1F980, 0x1F984, prEmojiPresentation}, // E1.0 [5] (🦀..🦄) crab..unicorn + {0x1F985, 0x1F991, prEmojiPresentation}, // E3.0 [13] (🦅..🦑) eagle..squid + {0x1F992, 0x1F997, prEmojiPresentation}, // E5.0 [6] (🦒..🦗) giraffe..cricket + {0x1F998, 0x1F9A2, prEmojiPresentation}, // E11.0 [11] (🦘..🦢) kangaroo..swan + {0x1F9A3, 0x1F9A4, prEmojiPresentation}, // E13.0 [2] (🦣..🦤) mammoth..dodo + {0x1F9A5, 0x1F9AA, prEmojiPresentation}, // E12.0 [6] (🦥..🦪) sloth..oyster + {0x1F9AB, 0x1F9AD, prEmojiPresentation}, // E13.0 [3] (🦫..🦭) beaver..seal + {0x1F9AE, 0x1F9AF, prEmojiPresentation}, // E12.0 [2] (🦮..🦯) guide dog..white cane + {0x1F9B0, 0x1F9B9, prEmojiPresentation}, // E11.0 [10] (🦰..🦹) red hair..supervillain + {0x1F9BA, 0x1F9BF, prEmojiPresentation}, // E12.0 [6] (🦺..🦿) safety vest..mechanical leg + {0x1F9C0, 0x1F9C0, prEmojiPresentation}, // E1.0 [1] (🧀) cheese wedge + {0x1F9C1, 0x1F9C2, prEmojiPresentation}, // E11.0 [2] (🧁..🧂) cupcake..salt + {0x1F9C3, 0x1F9CA, prEmojiPresentation}, // E12.0 [8] (🧃..🧊) beverage box..ice + {0x1F9CB, 0x1F9CB, prEmojiPresentation}, // E13.0 [1] (🧋) bubble tea + {0x1F9CC, 0x1F9CC, prEmojiPresentation}, // E14.0 [1] (🧌) troll + {0x1F9CD, 0x1F9CF, prEmojiPresentation}, // E12.0 [3] (🧍..🧏) person standing..deaf person + {0x1F9D0, 0x1F9E6, prEmojiPresentation}, // E5.0 [23] (🧐..🧦) face with monocle..socks + {0x1F9E7, 0x1F9FF, prEmojiPresentation}, // E11.0 [25] (🧧..🧿) red envelope..nazar amulet + {0x1FA70, 0x1FA73, prEmojiPresentation}, // E12.0 [4] (🩰..🩳) ballet shoes..shorts + {0x1FA74, 0x1FA74, prEmojiPresentation}, // E13.0 [1] (🩴) thong sandal + {0x1FA75, 0x1FA77, prEmojiPresentation}, // E15.0 [3] (🩵..🩷) light blue heart..pink heart + {0x1FA78, 0x1FA7A, prEmojiPresentation}, // E12.0 [3] (🩸..🩺) drop of blood..stethoscope + {0x1FA7B, 0x1FA7C, prEmojiPresentation}, // E14.0 [2] (🩻..🩼) x-ray..crutch + {0x1FA80, 0x1FA82, prEmojiPresentation}, // E12.0 [3] (🪀..🪂) yo-yo..parachute + {0x1FA83, 0x1FA86, prEmojiPresentation}, // E13.0 [4] (🪃..🪆) boomerang..nesting dolls + {0x1FA87, 0x1FA88, prEmojiPresentation}, // E15.0 [2] (🪇..🪈) maracas..flute + {0x1FA90, 0x1FA95, prEmojiPresentation}, // E12.0 [6] (🪐..🪕) ringed planet..banjo + {0x1FA96, 0x1FAA8, prEmojiPresentation}, // E13.0 [19] (🪖..🪨) military helmet..rock + {0x1FAA9, 0x1FAAC, prEmojiPresentation}, // E14.0 [4] (🪩..🪬) mirror ball..hamsa + {0x1FAAD, 0x1FAAF, prEmojiPresentation}, // E15.0 [3] (🪭..🪯) folding hand fan..khanda + {0x1FAB0, 0x1FAB6, prEmojiPresentation}, // E13.0 [7] (🪰..🪶) fly..feather + {0x1FAB7, 0x1FABA, prEmojiPresentation}, // E14.0 [4] (🪷..🪺) lotus..nest with eggs + {0x1FABB, 0x1FABD, prEmojiPresentation}, // E15.0 [3] (🪻..🪽) hyacinth..wing + {0x1FABF, 0x1FABF, prEmojiPresentation}, // E15.0 [1] (🪿) goose + {0x1FAC0, 0x1FAC2, prEmojiPresentation}, // E13.0 [3] (🫀..🫂) anatomical heart..people hugging + {0x1FAC3, 0x1FAC5, prEmojiPresentation}, // E14.0 [3] (🫃..🫅) pregnant man..person with crown + {0x1FACE, 0x1FACF, prEmojiPresentation}, // E15.0 [2] (🫎..🫏) moose..donkey + {0x1FAD0, 0x1FAD6, prEmojiPresentation}, // E13.0 [7] (🫐..🫖) blueberries..teapot + {0x1FAD7, 0x1FAD9, prEmojiPresentation}, // E14.0 [3] (🫗..🫙) pouring liquid..jar + {0x1FADA, 0x1FADB, prEmojiPresentation}, // E15.0 [2] (🫚..🫛) ginger root..pea pod + {0x1FAE0, 0x1FAE7, prEmojiPresentation}, // E14.0 [8] (🫠..🫧) melting face..bubbles + {0x1FAE8, 0x1FAE8, prEmojiPresentation}, // E15.0 [1] (🫨) shaking face + {0x1FAF0, 0x1FAF6, prEmojiPresentation}, // E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands + {0x1FAF7, 0x1FAF8, prEmojiPresentation}, // E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand +} diff --git a/vendor/github.com/rivo/uniseg/gen_breaktest.go b/vendor/github.com/rivo/uniseg/gen_breaktest.go new file mode 100644 index 000000000..6bfbeb5e7 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/gen_breaktest.go @@ -0,0 +1,215 @@ +//go:build generate + +// This program generates a Go containing a slice of test cases based on the +// Unicode Character Database auxiliary data files. The command line arguments +// are as follows: +// +// 1. The name of the Unicode data file (just the filename, without extension). +// 2. The name of the locally generated Go file. +// 3. The name of the slice containing the test cases. +// 4. The name of the generator, for logging purposes. +// +//go:generate go run gen_breaktest.go GraphemeBreakTest graphemebreak_test.go graphemeBreakTestCases graphemes +//go:generate go run gen_breaktest.go WordBreakTest wordbreak_test.go wordBreakTestCases words +//go:generate go run gen_breaktest.go SentenceBreakTest sentencebreak_test.go sentenceBreakTestCases sentences +//go:generate go run gen_breaktest.go LineBreakTest linebreak_test.go lineBreakTestCases lines + +package main + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "go/format" + "io/ioutil" + "log" + "net/http" + "os" + "time" +) + +// We want to test against a specific version rather than the latest. When the +// package is upgraded to a new version, change these to generate new tests. +const ( + testCaseURL = `https://www.unicode.org/Public/15.0.0/ucd/auxiliary/%s.txt` +) + +func main() { + if len(os.Args) < 5 { + fmt.Println("Not enough arguments, see code for details") + os.Exit(1) + } + + log.SetPrefix("gen_breaktest (" + os.Args[4] + "): ") + log.SetFlags(0) + + // Read text of testcases and parse into Go source code. + src, err := parse(fmt.Sprintf(testCaseURL, os.Args[1])) + if err != nil { + log.Fatal(err) + } + + // Format the Go code. + formatted, err := format.Source(src) + if err != nil { + log.Fatalln("gofmt:", err) + } + + // Write it out. + log.Print("Writing to ", os.Args[2]) + if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil { + log.Fatal(err) + } +} + +// parse reads a break text file, either from a local file or from a URL. It +// parses the file data into Go source code representing the test cases. +func parse(url string) ([]byte, error) { + log.Printf("Parsing %s", url) + res, err := http.Get(url) + if err != nil { + return nil, err + } + body := res.Body + defer body.Close() + + buf := new(bytes.Buffer) + buf.Grow(120 << 10) + buf.WriteString(`// Code generated via go generate from gen_breaktest.go. DO NOT EDIT. + +package uniseg + +// ` + os.Args[3] + ` are Grapheme testcases taken from +// ` + url + ` +// on ` + time.Now().Format("January 2, 2006") + `. See +// https://www.unicode.org/license.html for the Unicode license agreement. +var ` + os.Args[3] + ` = []testCase { +`) + + sc := bufio.NewScanner(body) + num := 1 + var line []byte + original := make([]byte, 0, 64) + expected := make([]byte, 0, 64) + for sc.Scan() { + num++ + line = sc.Bytes() + if len(line) == 0 || line[0] == '#' { + continue + } + var comment []byte + if i := bytes.IndexByte(line, '#'); i >= 0 { + comment = bytes.TrimSpace(line[i+1:]) + line = bytes.TrimSpace(line[:i]) + } + original, expected, err := parseRuneSequence(line, original[:0], expected[:0]) + if err != nil { + return nil, fmt.Errorf(`line %d: %v: %q`, num, err, line) + } + fmt.Fprintf(buf, "\t{original: \"%s\", expected: %s}, // %s\n", original, expected, comment) + } + if err := sc.Err(); err != nil { + return nil, err + } + + // Check for final "# EOF", useful check if we're streaming via HTTP + if !bytes.Equal(line, []byte("# EOF")) { + return nil, fmt.Errorf(`line %d: exected "# EOF" as final line, got %q`, num, line) + } + buf.WriteString("}\n") + return buf.Bytes(), nil +} + +// Used by parseRuneSequence to match input via bytes.HasPrefix. +var ( + prefixBreak = []byte("÷ ") + prefixDontBreak = []byte("× ") + breakOk = []byte("÷") + breakNo = []byte("×") +) + +// parseRuneSequence parses a rune + breaking opportunity sequence from b +// and appends the Go code for testcase.original to orig +// and appends the Go code for testcase.expected to exp. +// It retuns the new orig and exp slices. +// +// E.g. for the input b="÷ 0020 × 0308 ÷ 1F1E6 ÷" +// it will append +// +// "\u0020\u0308\U0001F1E6" +// +// and "[][]rune{{0x0020,0x0308},{0x1F1E6},}" +// to orig and exp respectively. +// +// The formatting of exp is expected to be cleaned up by gofmt or format.Source. +// Note we explicitly require the sequence to start with ÷ and we implicitly +// require it to end with ÷. +func parseRuneSequence(b, orig, exp []byte) ([]byte, []byte, error) { + // Check for and remove first ÷ or ×. + if !bytes.HasPrefix(b, prefixBreak) && !bytes.HasPrefix(b, prefixDontBreak) { + return nil, nil, errors.New("expected ÷ or × as first character") + } + if bytes.HasPrefix(b, prefixBreak) { + b = b[len(prefixBreak):] + } else { + b = b[len(prefixDontBreak):] + } + + boundary := true + exp = append(exp, "[][]rune{"...) + for len(b) > 0 { + if boundary { + exp = append(exp, '{') + } + exp = append(exp, "0x"...) + // Find end of hex digits. + var i int + for i = 0; i < len(b) && b[i] != ' '; i++ { + if d := b[i]; ('0' <= d || d <= '9') || + ('A' <= d || d <= 'F') || + ('a' <= d || d <= 'f') { + continue + } + return nil, nil, errors.New("bad hex digit") + } + switch i { + case 4: + orig = append(orig, "\\u"...) + case 5: + orig = append(orig, "\\U000"...) + default: + return nil, nil, errors.New("unsupport code point hex length") + } + orig = append(orig, b[:i]...) + exp = append(exp, b[:i]...) + b = b[i:] + + // Check for space between hex and ÷ or ×. + if len(b) < 1 || b[0] != ' ' { + return nil, nil, errors.New("bad input") + } + b = b[1:] + + // Check for next boundary. + switch { + case bytes.HasPrefix(b, breakOk): + boundary = true + b = b[len(breakOk):] + case bytes.HasPrefix(b, breakNo): + boundary = false + b = b[len(breakNo):] + default: + return nil, nil, errors.New("missing ÷ or ×") + } + if boundary { + exp = append(exp, '}') + } + exp = append(exp, ',') + if len(b) > 0 && b[0] == ' ' { + b = b[1:] + } + } + exp = append(exp, '}') + return orig, exp, nil +} diff --git a/vendor/github.com/rivo/uniseg/gen_properties.go b/vendor/github.com/rivo/uniseg/gen_properties.go new file mode 100644 index 000000000..8992d2c5f --- /dev/null +++ b/vendor/github.com/rivo/uniseg/gen_properties.go @@ -0,0 +1,261 @@ +//go:build generate + +// This program generates a property file in Go file from Unicode Character +// Database auxiliary data files. The command line arguments are as follows: +// +// 1. The name of the Unicode data file (just the filename, without extension). +// Can be "-" (to skip) if the emoji flag is included. +// 2. The name of the locally generated Go file. +// 3. The name of the slice mapping code points to properties. +// 4. The name of the generator, for logging purposes. +// 5. (Optional) Flags, comma-separated. The following flags are available: +// - "emojis=": include the specified emoji properties (e.g. +// "Extended_Pictographic"). +// - "gencat": include general category properties. +// +//go:generate go run gen_properties.go auxiliary/GraphemeBreakProperty graphemeproperties.go graphemeCodePoints graphemes emojis=Extended_Pictographic +//go:generate go run gen_properties.go auxiliary/WordBreakProperty wordproperties.go workBreakCodePoints words emojis=Extended_Pictographic +//go:generate go run gen_properties.go auxiliary/SentenceBreakProperty sentenceproperties.go sentenceBreakCodePoints sentences +//go:generate go run gen_properties.go LineBreak lineproperties.go lineBreakCodePoints lines gencat +//go:generate go run gen_properties.go EastAsianWidth eastasianwidth.go eastAsianWidth eastasianwidth +//go:generate go run gen_properties.go - emojipresentation.go emojiPresentation emojipresentation emojis=Emoji_Presentation +package main + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "go/format" + "io/ioutil" + "log" + "net/http" + "os" + "regexp" + "sort" + "strconv" + "strings" + "time" +) + +// We want to test against a specific version rather than the latest. When the +// package is upgraded to a new version, change these to generate new tests. +const ( + propertyURL = `https://www.unicode.org/Public/15.0.0/ucd/%s.txt` + emojiURL = `https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt` +) + +// The regular expression for a line containing a code point range property. +var propertyPattern = regexp.MustCompile(`^([0-9A-F]{4,6})(\.\.([0-9A-F]{4,6}))?\s*;\s*([A-Za-z0-9_]+)\s*#\s(.+)$`) + +func main() { + if len(os.Args) < 5 { + fmt.Println("Not enough arguments, see code for details") + os.Exit(1) + } + + log.SetPrefix("gen_properties (" + os.Args[4] + "): ") + log.SetFlags(0) + + // Parse flags. + flags := make(map[string]string) + if len(os.Args) >= 6 { + for _, flag := range strings.Split(os.Args[5], ",") { + flagFields := strings.Split(flag, "=") + if len(flagFields) == 1 { + flags[flagFields[0]] = "yes" + } else { + flags[flagFields[0]] = flagFields[1] + } + } + } + + // Parse the text file and generate Go source code from it. + _, includeGeneralCategory := flags["gencat"] + var mainURL string + if os.Args[1] != "-" { + mainURL = fmt.Sprintf(propertyURL, os.Args[1]) + } + src, err := parse(mainURL, flags["emojis"], includeGeneralCategory) + if err != nil { + log.Fatal(err) + } + + // Format the Go code. + formatted, err := format.Source([]byte(src)) + if err != nil { + log.Fatal("gofmt:", err) + } + + // Save it to the (local) target file. + log.Print("Writing to ", os.Args[2]) + if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil { + log.Fatal(err) + } +} + +// parse parses the Unicode Properties text files located at the given URLs and +// returns their equivalent Go source code to be used in the uniseg package. If +// "emojiProperty" is not an empty string, emoji code points for that emoji +// property (e.g. "Extended_Pictographic") will be included. In those cases, you +// may pass an empty "propertyURL" to skip parsing the main properties file. If +// "includeGeneralCategory" is true, the Unicode General Category property will +// be extracted from the comments and included in the output. +func parse(propertyURL, emojiProperty string, includeGeneralCategory bool) (string, error) { + if propertyURL == "" && emojiProperty == "" { + return "", errors.New("no properties to parse") + } + + // Temporary buffer to hold properties. + var properties [][4]string + + // Open the first URL. + if propertyURL != "" { + log.Printf("Parsing %s", propertyURL) + res, err := http.Get(propertyURL) + if err != nil { + return "", err + } + in1 := res.Body + defer in1.Close() + + // Parse it. + scanner := bufio.NewScanner(in1) + num := 0 + for scanner.Scan() { + num++ + line := strings.TrimSpace(scanner.Text()) + + // Skip comments and empty lines. + if strings.HasPrefix(line, "#") || line == "" { + continue + } + + // Everything else must be a code point range, a property and a comment. + from, to, property, comment, err := parseProperty(line) + if err != nil { + return "", fmt.Errorf("%s line %d: %v", os.Args[4], num, err) + } + properties = append(properties, [4]string{from, to, property, comment}) + } + if err := scanner.Err(); err != nil { + return "", err + } + } + + // Open the second URL. + if emojiProperty != "" { + log.Printf("Parsing %s", emojiURL) + res, err := http.Get(emojiURL) + if err != nil { + return "", err + } + in2 := res.Body + defer in2.Close() + + // Parse it. + scanner := bufio.NewScanner(in2) + num := 0 + for scanner.Scan() { + num++ + line := scanner.Text() + + // Skip comments, empty lines, and everything not containing + // "Extended_Pictographic". + if strings.HasPrefix(line, "#") || line == "" || !strings.Contains(line, emojiProperty) { + continue + } + + // Everything else must be a code point range, a property and a comment. + from, to, property, comment, err := parseProperty(line) + if err != nil { + return "", fmt.Errorf("emojis line %d: %v", num, err) + } + properties = append(properties, [4]string{from, to, property, comment}) + } + if err := scanner.Err(); err != nil { + return "", err + } + } + + // Avoid overflow during binary search. + if len(properties) >= 1<<31 { + return "", errors.New("too many properties") + } + + // Sort properties. + sort.Slice(properties, func(i, j int) bool { + left, _ := strconv.ParseUint(properties[i][0], 16, 64) + right, _ := strconv.ParseUint(properties[j][0], 16, 64) + return left < right + }) + + // Header. + var ( + buf bytes.Buffer + emojiComment string + ) + columns := 3 + if includeGeneralCategory { + columns = 4 + } + if emojiURL != "" { + emojiComment = ` +// and +// ` + emojiURL + ` +// ("Extended_Pictographic" only)` + } + buf.WriteString(`// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// ` + os.Args[3] + ` are taken from +// ` + propertyURL + emojiComment + ` +// on ` + time.Now().Format("January 2, 2006") + `. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var ` + os.Args[3] + ` = [][` + strconv.Itoa(columns) + `]int{ + `) + + // Properties. + for _, prop := range properties { + if includeGeneralCategory { + generalCategory := "gc" + prop[3][:2] + if generalCategory == "gcL&" { + generalCategory = "gcLC" + } + prop[3] = prop[3][3:] + fmt.Fprintf(&buf, "{0x%s,0x%s,%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), generalCategory, prop[3]) + } else { + fmt.Fprintf(&buf, "{0x%s,0x%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), prop[3]) + } + } + + // Tail. + buf.WriteString("}") + + return buf.String(), nil +} + +// parseProperty parses a line of the Unicode properties text file containing a +// property for a code point range and returns it along with its comment. +func parseProperty(line string) (from, to, property, comment string, err error) { + fields := propertyPattern.FindStringSubmatch(line) + if fields == nil { + err = errors.New("no property found") + return + } + from = fields[1] + to = fields[3] + if to == "" { + to = from + } + property = fields[4] + comment = fields[5] + return +} + +// translateProperty translates a property name as used in the Unicode data file +// to a variable used in the Go code. +func translateProperty(prefix, property string) string { + return prefix + strings.ReplaceAll(property, "_", "") +} diff --git a/vendor/github.com/rivo/uniseg/grapheme.go b/vendor/github.com/rivo/uniseg/grapheme.go new file mode 100644 index 000000000..b12403d43 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/grapheme.go @@ -0,0 +1,331 @@ +package uniseg + +import "unicode/utf8" + +// Graphemes implements an iterator over Unicode grapheme clusters, or +// user-perceived characters. While iterating, it also provides information +// about word boundaries, sentence boundaries, line breaks, and monospace +// character widths. +// +// After constructing the class via [NewGraphemes] for a given string "str", +// [Graphemes.Next] is called for every grapheme cluster in a loop until it +// returns false. Inside the loop, information about the grapheme cluster as +// well as boundary information and character width is available via the various +// methods (see examples below). +// +// This class basically wraps the [StepString] parser and provides a convenient +// interface to it. If you are only interested in some parts of this package's +// functionality, using the specialized functions starting with "First" is +// almost always faster. +type Graphemes struct { + // The original string. + original string + + // The remaining string to be parsed. + remaining string + + // The current grapheme cluster. + cluster string + + // The byte offset of the current grapheme cluster relative to the original + // string. + offset int + + // The current boundary information of the [Step] parser. + boundaries int + + // The current state of the [Step] parser. + state int +} + +// NewGraphemes returns a new grapheme cluster iterator. +func NewGraphemes(str string) *Graphemes { + return &Graphemes{ + original: str, + remaining: str, + state: -1, + } +} + +// Next advances the iterator by one grapheme cluster and returns false if no +// clusters are left. This function must be called before the first cluster is +// accessed. +func (g *Graphemes) Next() bool { + if len(g.remaining) == 0 { + // We're already past the end. + g.state = -2 + g.cluster = "" + return false + } + g.offset += len(g.cluster) + g.cluster, g.remaining, g.boundaries, g.state = StepString(g.remaining, g.state) + return true +} + +// Runes returns a slice of runes (code points) which corresponds to the current +// grapheme cluster. If the iterator is already past the end or [Graphemes.Next] +// has not yet been called, nil is returned. +func (g *Graphemes) Runes() []rune { + if g.state < 0 { + return nil + } + return []rune(g.cluster) +} + +// Str returns a substring of the original string which corresponds to the +// current grapheme cluster. If the iterator is already past the end or +// [Graphemes.Next] has not yet been called, an empty string is returned. +func (g *Graphemes) Str() string { + return g.cluster +} + +// Bytes returns a byte slice which corresponds to the current grapheme cluster. +// If the iterator is already past the end or [Graphemes.Next] has not yet been +// called, nil is returned. +func (g *Graphemes) Bytes() []byte { + if g.state < 0 { + return nil + } + return []byte(g.cluster) +} + +// Positions returns the interval of the current grapheme cluster as byte +// positions into the original string. The first returned value "from" indexes +// the first byte and the second returned value "to" indexes the first byte that +// is not included anymore, i.e. str[from:to] is the current grapheme cluster of +// the original string "str". If [Graphemes.Next] has not yet been called, both +// values are 0. If the iterator is already past the end, both values are 1. +func (g *Graphemes) Positions() (int, int) { + if g.state == -1 { + return 0, 0 + } else if g.state == -2 { + return 1, 1 + } + return g.offset, g.offset + len(g.cluster) +} + +// IsWordBoundary returns true if a word ends after the current grapheme +// cluster. +func (g *Graphemes) IsWordBoundary() bool { + if g.state < 0 { + return true + } + return g.boundaries&MaskWord != 0 +} + +// IsSentenceBoundary returns true if a sentence ends after the current +// grapheme cluster. +func (g *Graphemes) IsSentenceBoundary() bool { + if g.state < 0 { + return true + } + return g.boundaries&MaskSentence != 0 +} + +// LineBreak returns whether the line can be broken after the current grapheme +// cluster. A value of [LineDontBreak] means the line may not be broken, a value +// of [LineMustBreak] means the line must be broken, and a value of +// [LineCanBreak] means the line may or may not be broken. +func (g *Graphemes) LineBreak() int { + if g.state == -1 { + return LineDontBreak + } + if g.state == -2 { + return LineMustBreak + } + return g.boundaries & MaskLine +} + +// Width returns the monospace width of the current grapheme cluster. +func (g *Graphemes) Width() int { + if g.state < 0 { + return 0 + } + return g.boundaries >> ShiftWidth +} + +// Reset puts the iterator into its initial state such that the next call to +// [Graphemes.Next] sets it to the first grapheme cluster again. +func (g *Graphemes) Reset() { + g.state = -1 + g.offset = 0 + g.cluster = "" + g.remaining = g.original +} + +// GraphemeClusterCount returns the number of user-perceived characters +// (grapheme clusters) for the given string. +func GraphemeClusterCount(s string) (n int) { + state := -1 + for len(s) > 0 { + _, s, _, state = FirstGraphemeClusterInString(s, state) + n++ + } + return +} + +// ReverseString reverses the given string while observing grapheme cluster +// boundaries. +func ReverseString(s string) string { + str := []byte(s) + reversed := make([]byte, len(str)) + state := -1 + index := len(str) + for len(str) > 0 { + var cluster []byte + cluster, str, _, state = FirstGraphemeCluster(str, state) + index -= len(cluster) + copy(reversed[index:], cluster) + if index <= len(str)/2 { + break + } + } + return string(reversed) +} + +// The number of bits the grapheme property must be shifted to make place for +// grapheme states. +const shiftGraphemePropState = 4 + +// FirstGraphemeCluster returns the first grapheme cluster found in the given +// byte slice according to the rules of [Unicode Standard Annex #29, Grapheme +// Cluster Boundaries]. This function can be called continuously to extract all +// grapheme clusters from a byte slice, as illustrated in the example below. +// +// If you don't know the current state, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified grapheme cluster. If the length of the +// "rest" slice is 0, the entire byte slice "b" has been processed. The +// "cluster" byte slice is the sub-slice of the input slice containing the +// identified grapheme cluster. +// +// The returned width is the width of the grapheme cluster for most monospace +// fonts where a value of 1 represents one character cell. +// +// Given an empty byte slice "b", the function returns nil values. +// +// While slightly less convenient than using the Graphemes class, this function +// has much better performance and makes no allocations. It lends itself well to +// large byte slices. +// +// [Unicode Standard Annex #29, Grapheme Cluster Boundaries]: http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries +func FirstGraphemeCluster(b []byte, state int) (cluster, rest []byte, width, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + var prop int + if state < 0 { + prop = propertyGraphemes(r) + } else { + prop = state >> shiftGraphemePropState + } + return b, nil, runeWidth(r, prop), grAny | (prop << shiftGraphemePropState) + } + + // If we don't know the state, determine it now. + var firstProp int + if state < 0 { + state, firstProp, _ = transitionGraphemeState(state, r) + } else { + firstProp = state >> shiftGraphemePropState + } + width += runeWidth(r, firstProp) + + // Transition until we find a boundary. + for { + var ( + prop int + boundary bool + ) + + r, l := utf8.DecodeRune(b[length:]) + state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r) + + if boundary { + return b[:length], b[length:], width, state | (prop << shiftGraphemePropState) + } + + if firstProp == prExtendedPictographic { + if r == vs15 { + width = 1 + } else if r == vs16 { + width = 2 + } + } else if firstProp != prRegionalIndicator && firstProp != prL { + width += runeWidth(r, prop) + } + + length += l + if len(b) <= length { + return b, nil, width, grAny | (prop << shiftGraphemePropState) + } + } +} + +// FirstGraphemeClusterInString is like [FirstGraphemeCluster] but its input and +// outputs are strings. +func FirstGraphemeClusterInString(str string, state int) (cluster, rest string, width, newState int) { + // An empty string returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + var prop int + if state < 0 { + prop = propertyGraphemes(r) + } else { + prop = state >> shiftGraphemePropState + } + return str, "", runeWidth(r, prop), grAny | (prop << shiftGraphemePropState) + } + + // If we don't know the state, determine it now. + var firstProp int + if state < 0 { + state, firstProp, _ = transitionGraphemeState(state, r) + } else { + firstProp = state >> shiftGraphemePropState + } + width += runeWidth(r, firstProp) + + // Transition until we find a boundary. + for { + var ( + prop int + boundary bool + ) + + r, l := utf8.DecodeRuneInString(str[length:]) + state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r) + + if boundary { + return str[:length], str[length:], width, state | (prop << shiftGraphemePropState) + } + + if firstProp == prExtendedPictographic { + if r == vs15 { + width = 1 + } else if r == vs16 { + width = 2 + } + } else if firstProp != prRegionalIndicator && firstProp != prL { + width += runeWidth(r, prop) + } + + length += l + if len(str) <= length { + return str, "", width, grAny | (prop << shiftGraphemePropState) + } + } +} diff --git a/vendor/github.com/rivo/uniseg/graphemeproperties.go b/vendor/github.com/rivo/uniseg/graphemeproperties.go new file mode 100644 index 000000000..0aff4a619 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/graphemeproperties.go @@ -0,0 +1,1915 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// graphemeCodePoints are taken from +// https://www.unicode.org/Public/15.0.0/ucd/auxiliary/GraphemeBreakProperty.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var graphemeCodePoints = [][3]int{ + {0x0000, 0x0009, prControl}, // Cc [10] .. + {0x000A, 0x000A, prLF}, // Cc + {0x000B, 0x000C, prControl}, // Cc [2] .. + {0x000D, 0x000D, prCR}, // Cc + {0x000E, 0x001F, prControl}, // Cc [18] .. + {0x007F, 0x009F, prControl}, // Cc [33] .. + {0x00A9, 0x00A9, prExtendedPictographic}, // E0.6 [1] (©️) copyright + {0x00AD, 0x00AD, prControl}, // Cf SOFT HYPHEN + {0x00AE, 0x00AE, prExtendedPictographic}, // E0.6 [1] (®️) registered + {0x0300, 0x036F, prExtend}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X + {0x0483, 0x0487, prExtend}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prExtend}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x0591, 0x05BD, prExtend}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BF, 0x05BF, prExtend}, // Mn HEBREW POINT RAFE + {0x05C1, 0x05C2, prExtend}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C4, 0x05C5, prExtend}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C7, 0x05C7, prExtend}, // Mn HEBREW POINT QAMATS QATAN + {0x0600, 0x0605, prPrepend}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x0610, 0x061A, prExtend}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061C, 0x061C, prControl}, // Cf ARABIC LETTER MARK + {0x064B, 0x065F, prExtend}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0670, 0x0670, prExtend}, // Mn ARABIC LETTER SUPERSCRIPT ALEF + {0x06D6, 0x06DC, prExtend}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prPrepend}, // Cf ARABIC END OF AYAH + {0x06DF, 0x06E4, prExtend}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E7, 0x06E8, prExtend}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06EA, 0x06ED, prExtend}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x070F, 0x070F, prPrepend}, // Cf SYRIAC ABBREVIATION MARK + {0x0711, 0x0711, prExtend}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0730, 0x074A, prExtend}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x07A6, 0x07B0, prExtend}, // Mn [11] THAANA ABAFILI..THAANA SUKUN + {0x07EB, 0x07F3, prExtend}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07FD, 0x07FD, prExtend}, // Mn NKO DANTAYALAN + {0x0816, 0x0819, prExtend}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081B, 0x0823, prExtend}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0825, 0x0827, prExtend}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0829, 0x082D, prExtend}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0859, 0x085B, prExtend}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x0890, 0x0891, prPrepend}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prExtend}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08CA, 0x08E1, prExtend}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prPrepend}, // Cf ARABIC DISPUTED END OF AYAH + {0x08E3, 0x0902, prExtend}, // Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prSpacingMark}, // Mc DEVANAGARI SIGN VISARGA + {0x093A, 0x093A, prExtend}, // Mn DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prSpacingMark}, // Mc DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prExtend}, // Mn DEVANAGARI SIGN NUKTA + {0x093E, 0x0940, prSpacingMark}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prExtend}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prSpacingMark}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prExtend}, // Mn DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prSpacingMark}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0951, 0x0957, prExtend}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0962, 0x0963, prExtend}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0981, 0x0981, prExtend}, // Mn BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prSpacingMark}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x09BC, 0x09BC, prExtend}, // Mn BENGALI SIGN NUKTA + {0x09BE, 0x09BE, prExtend}, // Mc BENGALI VOWEL SIGN AA + {0x09BF, 0x09C0, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN I..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prExtend}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prExtend}, // Mn BENGALI SIGN VIRAMA + {0x09D7, 0x09D7, prExtend}, // Mc BENGALI AU LENGTH MARK + {0x09E2, 0x09E3, prExtend}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09FE, 0x09FE, prExtend}, // Mn BENGALI SANDHI MARK + {0x0A01, 0x0A02, prExtend}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prSpacingMark}, // Mc GURMUKHI SIGN VISARGA + {0x0A3C, 0x0A3C, prExtend}, // Mn GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prSpacingMark}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prExtend}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prExtend}, // Mn GURMUKHI SIGN UDAAT + {0x0A70, 0x0A71, prExtend}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A75, 0x0A75, prExtend}, // Mn GURMUKHI SIGN YAKASH + {0x0A81, 0x0A82, prExtend}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prSpacingMark}, // Mc GUJARATI SIGN VISARGA + {0x0ABC, 0x0ABC, prExtend}, // Mn GUJARATI SIGN NUKTA + {0x0ABE, 0x0AC0, prSpacingMark}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prExtend}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prExtend}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prSpacingMark}, // Mc GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prSpacingMark}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prExtend}, // Mn GUJARATI SIGN VIRAMA + {0x0AE2, 0x0AE3, prExtend}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AFA, 0x0AFF, prExtend}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prExtend}, // Mn ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prSpacingMark}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B3C, 0x0B3C, prExtend}, // Mn ORIYA SIGN NUKTA + {0x0B3E, 0x0B3E, prExtend}, // Mc ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prExtend}, // Mn ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prSpacingMark}, // Mc ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prExtend}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prSpacingMark}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prSpacingMark}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prExtend}, // Mn ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prExtend}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prExtend}, // Mc ORIYA AU LENGTH MARK + {0x0B62, 0x0B63, prExtend}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B82, 0x0B82, prExtend}, // Mn TAMIL SIGN ANUSVARA + {0x0BBE, 0x0BBE, prExtend}, // Mc TAMIL VOWEL SIGN AA + {0x0BBF, 0x0BBF, prSpacingMark}, // Mc TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prExtend}, // Mn TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prSpacingMark}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prSpacingMark}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prSpacingMark}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prExtend}, // Mn TAMIL SIGN VIRAMA + {0x0BD7, 0x0BD7, prExtend}, // Mc TAMIL AU LENGTH MARK + {0x0C00, 0x0C00, prExtend}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prSpacingMark}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prExtend}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C3C, 0x0C3C, prExtend}, // Mn TELUGU SIGN NUKTA + {0x0C3E, 0x0C40, prExtend}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prSpacingMark}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prExtend}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prExtend}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prExtend}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C62, 0x0C63, prExtend}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C81, 0x0C81, prExtend}, // Mn KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prSpacingMark}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0CBC, 0x0CBC, prExtend}, // Mn KANNADA SIGN NUKTA + {0x0CBE, 0x0CBE, prSpacingMark}, // Mc KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prExtend}, // Mn KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC1, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN U + {0x0CC2, 0x0CC2, prExtend}, // Mc KANNADA VOWEL SIGN UU + {0x0CC3, 0x0CC4, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN VOCALIC R..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prExtend}, // Mn KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prExtend}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prExtend}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CE2, 0x0CE3, prExtend}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CF3, 0x0CF3, prSpacingMark}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prExtend}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prSpacingMark}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D3B, 0x0D3C, prExtend}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3E, 0x0D3E, prExtend}, // Mc MALAYALAM VOWEL SIGN AA + {0x0D3F, 0x0D40, prSpacingMark}, // Mc [2] MALAYALAM VOWEL SIGN I..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prExtend}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prSpacingMark}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prSpacingMark}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prExtend}, // Mn MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prPrepend}, // Lo MALAYALAM LETTER DOT REPH + {0x0D57, 0x0D57, prExtend}, // Mc MALAYALAM AU LENGTH MARK + {0x0D62, 0x0D63, prExtend}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D81, 0x0D81, prExtend}, // Mn SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prSpacingMark}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0DCA, 0x0DCA, prExtend}, // Mn SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DCF, prExtend}, // Mc SINHALA VOWEL SIGN AELA-PILLA + {0x0DD0, 0x0DD1, prSpacingMark}, // Mc [2] SINHALA VOWEL SIGN KETTI AEDA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prExtend}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prExtend}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDE, prSpacingMark}, // Mc [7] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA + {0x0DDF, 0x0DDF, prExtend}, // Mc SINHALA VOWEL SIGN GAYANUKITTA + {0x0DF2, 0x0DF3, prSpacingMark}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0E31, 0x0E31, prExtend}, // Mn THAI CHARACTER MAI HAN-AKAT + {0x0E33, 0x0E33, prSpacingMark}, // Lo THAI CHARACTER SARA AM + {0x0E34, 0x0E3A, prExtend}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E47, 0x0E4E, prExtend}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0EB1, 0x0EB1, prExtend}, // Mn LAO VOWEL SIGN MAI KAN + {0x0EB3, 0x0EB3, prSpacingMark}, // Lo LAO VOWEL SIGN AM + {0x0EB4, 0x0EBC, prExtend}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EC8, 0x0ECE, prExtend}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0F18, 0x0F19, prExtend}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F35, 0x0F35, prExtend}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F37, 0x0F37, prExtend}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F39, 0x0F39, prExtend}, // Mn TIBETAN MARK TSA -PHRU + {0x0F3E, 0x0F3F, prSpacingMark}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F71, 0x0F7E, prExtend}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prSpacingMark}, // Mc TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prExtend}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F86, 0x0F87, prExtend}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F8D, 0x0F97, prExtend}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prExtend}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FC6, 0x0FC6, prExtend}, // Mn TIBETAN SYMBOL PADMA GDAN + {0x102D, 0x1030, prExtend}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prSpacingMark}, // Mc MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prExtend}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1039, 0x103A, prExtend}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prSpacingMark}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prExtend}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x1056, 0x1057, prSpacingMark}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prExtend}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105E, 0x1060, prExtend}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1071, 0x1074, prExtend}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1082, 0x1082, prExtend}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1084, 0x1084, prSpacingMark}, // Mc MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prExtend}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x108D, 0x108D, prExtend}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x109D, 0x109D, prExtend}, // Mn MYANMAR VOWEL SIGN AITON AI + {0x1100, 0x115F, prL}, // Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER + {0x1160, 0x11A7, prV}, // Lo [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE + {0x11A8, 0x11FF, prT}, // Lo [88] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG SSANGNIEUN + {0x135D, 0x135F, prExtend}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1712, 0x1714, prExtend}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prSpacingMark}, // Mc TAGALOG SIGN PAMUDPOD + {0x1732, 0x1733, prExtend}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prSpacingMark}, // Mc HANUNOO SIGN PAMUDPOD + {0x1752, 0x1753, prExtend}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1772, 0x1773, prExtend}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x17B4, 0x17B5, prExtend}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prSpacingMark}, // Mc KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prExtend}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prSpacingMark}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prExtend}, // Mn KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prSpacingMark}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prExtend}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17DD, 0x17DD, prExtend}, // Mn KHMER SIGN ATTHACAN + {0x180B, 0x180D, prExtend}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prControl}, // Cf MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prExtend}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1885, 0x1886, prExtend}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x18A9, 0x18A9, prExtend}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA + {0x1920, 0x1922, prExtend}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prSpacingMark}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prExtend}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prSpacingMark}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prSpacingMark}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prExtend}, // Mn LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prSpacingMark}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prExtend}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1A17, 0x1A18, prExtend}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prSpacingMark}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prExtend}, // Mn BUGINESE VOWEL SIGN AE + {0x1A55, 0x1A55, prSpacingMark}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prExtend}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prSpacingMark}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prExtend}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prExtend}, // Mn TAI THAM SIGN SAKOT + {0x1A62, 0x1A62, prExtend}, // Mn TAI THAM VOWEL SIGN MAI SAT + {0x1A65, 0x1A6C, prExtend}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prSpacingMark}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prExtend}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prExtend}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1AB0, 0x1ABD, prExtend}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prExtend}, // Me COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prExtend}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prExtend}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prSpacingMark}, // Mc BALINESE SIGN BISAH + {0x1B34, 0x1B34, prExtend}, // Mn BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prExtend}, // Mc BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prExtend}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prSpacingMark}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prExtend}, // Mn BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prSpacingMark}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prExtend}, // Mn BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prSpacingMark}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B6B, 0x1B73, prExtend}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B80, 0x1B81, prExtend}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prSpacingMark}, // Mc SUNDANESE SIGN PANGWISAD + {0x1BA1, 0x1BA1, prSpacingMark}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prExtend}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prSpacingMark}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prExtend}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prSpacingMark}, // Mc SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prExtend}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BE6, 0x1BE6, prExtend}, // Mn BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prSpacingMark}, // Mc BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prExtend}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prSpacingMark}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prExtend}, // Mn BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prSpacingMark}, // Mc BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prExtend}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prSpacingMark}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1C24, 0x1C2B, prSpacingMark}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prExtend}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prSpacingMark}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prExtend}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1CD0, 0x1CD2, prExtend}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD4, 0x1CE0, prExtend}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prSpacingMark}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prExtend}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CED, 0x1CED, prExtend}, // Mn VEDIC SIGN TIRYAK + {0x1CF4, 0x1CF4, prExtend}, // Mn VEDIC TONE CANDRA ABOVE + {0x1CF7, 0x1CF7, prSpacingMark}, // Mc VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prExtend}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1DC0, 0x1DFF, prExtend}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x200B, 0x200B, prControl}, // Cf ZERO WIDTH SPACE + {0x200C, 0x200C, prExtend}, // Cf ZERO WIDTH NON-JOINER + {0x200D, 0x200D, prZWJ}, // Cf ZERO WIDTH JOINER + {0x200E, 0x200F, prControl}, // Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK + {0x2028, 0x2028, prControl}, // Zl LINE SEPARATOR + {0x2029, 0x2029, prControl}, // Zp PARAGRAPH SEPARATOR + {0x202A, 0x202E, prControl}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x203C, 0x203C, prExtendedPictographic}, // E0.6 [1] (‼️) double exclamation mark + {0x2049, 0x2049, prExtendedPictographic}, // E0.6 [1] (⁉️) exclamation question mark + {0x2060, 0x2064, prControl}, // Cf [5] WORD JOINER..INVISIBLE PLUS + {0x2065, 0x2065, prControl}, // Cn + {0x2066, 0x206F, prControl}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x20D0, 0x20DC, prExtend}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prExtend}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prExtend}, // Mn COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prExtend}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prExtend}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2122, 0x2122, prExtendedPictographic}, // E0.6 [1] (™️) trade mark + {0x2139, 0x2139, prExtendedPictographic}, // E0.6 [1] (ℹ️) information + {0x2194, 0x2199, prExtendedPictographic}, // E0.6 [6] (↔️..↙️) left-right arrow..down-left arrow + {0x21A9, 0x21AA, prExtendedPictographic}, // E0.6 [2] (↩️..↪️) right arrow curving left..left arrow curving right + {0x231A, 0x231B, prExtendedPictographic}, // E0.6 [2] (⌚..⌛) watch..hourglass done + {0x2328, 0x2328, prExtendedPictographic}, // E1.0 [1] (⌨️) keyboard + {0x2388, 0x2388, prExtendedPictographic}, // E0.0 [1] (⎈) HELM SYMBOL + {0x23CF, 0x23CF, prExtendedPictographic}, // E1.0 [1] (⏏️) eject button + {0x23E9, 0x23EC, prExtendedPictographic}, // E0.6 [4] (⏩..⏬) fast-forward button..fast down button + {0x23ED, 0x23EE, prExtendedPictographic}, // E0.7 [2] (⏭️..⏮️) next track button..last track button + {0x23EF, 0x23EF, prExtendedPictographic}, // E1.0 [1] (⏯️) play or pause button + {0x23F0, 0x23F0, prExtendedPictographic}, // E0.6 [1] (⏰) alarm clock + {0x23F1, 0x23F2, prExtendedPictographic}, // E1.0 [2] (⏱️..⏲️) stopwatch..timer clock + {0x23F3, 0x23F3, prExtendedPictographic}, // E0.6 [1] (⏳) hourglass not done + {0x23F8, 0x23FA, prExtendedPictographic}, // E0.7 [3] (⏸️..⏺️) pause button..record button + {0x24C2, 0x24C2, prExtendedPictographic}, // E0.6 [1] (Ⓜ️) circled M + {0x25AA, 0x25AB, prExtendedPictographic}, // E0.6 [2] (▪️..▫️) black small square..white small square + {0x25B6, 0x25B6, prExtendedPictographic}, // E0.6 [1] (▶️) play button + {0x25C0, 0x25C0, prExtendedPictographic}, // E0.6 [1] (◀️) reverse button + {0x25FB, 0x25FE, prExtendedPictographic}, // E0.6 [4] (◻️..◾) white medium square..black medium-small square + {0x2600, 0x2601, prExtendedPictographic}, // E0.6 [2] (☀️..☁️) sun..cloud + {0x2602, 0x2603, prExtendedPictographic}, // E0.7 [2] (☂️..☃️) umbrella..snowman + {0x2604, 0x2604, prExtendedPictographic}, // E1.0 [1] (☄️) comet + {0x2605, 0x2605, prExtendedPictographic}, // E0.0 [1] (★) BLACK STAR + {0x2607, 0x260D, prExtendedPictographic}, // E0.0 [7] (☇..☍) LIGHTNING..OPPOSITION + {0x260E, 0x260E, prExtendedPictographic}, // E0.6 [1] (☎️) telephone + {0x260F, 0x2610, prExtendedPictographic}, // E0.0 [2] (☏..☐) WHITE TELEPHONE..BALLOT BOX + {0x2611, 0x2611, prExtendedPictographic}, // E0.6 [1] (☑️) check box with check + {0x2612, 0x2612, prExtendedPictographic}, // E0.0 [1] (☒) BALLOT BOX WITH X + {0x2614, 0x2615, prExtendedPictographic}, // E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage + {0x2616, 0x2617, prExtendedPictographic}, // E0.0 [2] (☖..☗) WHITE SHOGI PIECE..BLACK SHOGI PIECE + {0x2618, 0x2618, prExtendedPictographic}, // E1.0 [1] (☘️) shamrock + {0x2619, 0x261C, prExtendedPictographic}, // E0.0 [4] (☙..☜) REVERSED ROTATED FLORAL HEART BULLET..WHITE LEFT POINTING INDEX + {0x261D, 0x261D, prExtendedPictographic}, // E0.6 [1] (☝️) index pointing up + {0x261E, 0x261F, prExtendedPictographic}, // E0.0 [2] (☞..☟) WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX + {0x2620, 0x2620, prExtendedPictographic}, // E1.0 [1] (☠️) skull and crossbones + {0x2621, 0x2621, prExtendedPictographic}, // E0.0 [1] (☡) CAUTION SIGN + {0x2622, 0x2623, prExtendedPictographic}, // E1.0 [2] (☢️..☣️) radioactive..biohazard + {0x2624, 0x2625, prExtendedPictographic}, // E0.0 [2] (☤..☥) CADUCEUS..ANKH + {0x2626, 0x2626, prExtendedPictographic}, // E1.0 [1] (☦️) orthodox cross + {0x2627, 0x2629, prExtendedPictographic}, // E0.0 [3] (☧..☩) CHI RHO..CROSS OF JERUSALEM + {0x262A, 0x262A, prExtendedPictographic}, // E0.7 [1] (☪️) star and crescent + {0x262B, 0x262D, prExtendedPictographic}, // E0.0 [3] (☫..☭) FARSI SYMBOL..HAMMER AND SICKLE + {0x262E, 0x262E, prExtendedPictographic}, // E1.0 [1] (☮️) peace symbol + {0x262F, 0x262F, prExtendedPictographic}, // E0.7 [1] (☯️) yin yang + {0x2630, 0x2637, prExtendedPictographic}, // E0.0 [8] (☰..☷) TRIGRAM FOR HEAVEN..TRIGRAM FOR EARTH + {0x2638, 0x2639, prExtendedPictographic}, // E0.7 [2] (☸️..☹️) wheel of dharma..frowning face + {0x263A, 0x263A, prExtendedPictographic}, // E0.6 [1] (☺️) smiling face + {0x263B, 0x263F, prExtendedPictographic}, // E0.0 [5] (☻..☿) BLACK SMILING FACE..MERCURY + {0x2640, 0x2640, prExtendedPictographic}, // E4.0 [1] (♀️) female sign + {0x2641, 0x2641, prExtendedPictographic}, // E0.0 [1] (♁) EARTH + {0x2642, 0x2642, prExtendedPictographic}, // E4.0 [1] (♂️) male sign + {0x2643, 0x2647, prExtendedPictographic}, // E0.0 [5] (♃..♇) JUPITER..PLUTO + {0x2648, 0x2653, prExtendedPictographic}, // E0.6 [12] (♈..♓) Aries..Pisces + {0x2654, 0x265E, prExtendedPictographic}, // E0.0 [11] (♔..♞) WHITE CHESS KING..BLACK CHESS KNIGHT + {0x265F, 0x265F, prExtendedPictographic}, // E11.0 [1] (♟️) chess pawn + {0x2660, 0x2660, prExtendedPictographic}, // E0.6 [1] (♠️) spade suit + {0x2661, 0x2662, prExtendedPictographic}, // E0.0 [2] (♡..♢) WHITE HEART SUIT..WHITE DIAMOND SUIT + {0x2663, 0x2663, prExtendedPictographic}, // E0.6 [1] (♣️) club suit + {0x2664, 0x2664, prExtendedPictographic}, // E0.0 [1] (♤) WHITE SPADE SUIT + {0x2665, 0x2666, prExtendedPictographic}, // E0.6 [2] (♥️..♦️) heart suit..diamond suit + {0x2667, 0x2667, prExtendedPictographic}, // E0.0 [1] (♧) WHITE CLUB SUIT + {0x2668, 0x2668, prExtendedPictographic}, // E0.6 [1] (♨️) hot springs + {0x2669, 0x267A, prExtendedPictographic}, // E0.0 [18] (♩..♺) QUARTER NOTE..RECYCLING SYMBOL FOR GENERIC MATERIALS + {0x267B, 0x267B, prExtendedPictographic}, // E0.6 [1] (♻️) recycling symbol + {0x267C, 0x267D, prExtendedPictographic}, // E0.0 [2] (♼..♽) RECYCLED PAPER SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL + {0x267E, 0x267E, prExtendedPictographic}, // E11.0 [1] (♾️) infinity + {0x267F, 0x267F, prExtendedPictographic}, // E0.6 [1] (♿) wheelchair symbol + {0x2680, 0x2685, prExtendedPictographic}, // E0.0 [6] (⚀..⚅) DIE FACE-1..DIE FACE-6 + {0x2690, 0x2691, prExtendedPictographic}, // E0.0 [2] (⚐..⚑) WHITE FLAG..BLACK FLAG + {0x2692, 0x2692, prExtendedPictographic}, // E1.0 [1] (⚒️) hammer and pick + {0x2693, 0x2693, prExtendedPictographic}, // E0.6 [1] (⚓) anchor + {0x2694, 0x2694, prExtendedPictographic}, // E1.0 [1] (⚔️) crossed swords + {0x2695, 0x2695, prExtendedPictographic}, // E4.0 [1] (⚕️) medical symbol + {0x2696, 0x2697, prExtendedPictographic}, // E1.0 [2] (⚖️..⚗️) balance scale..alembic + {0x2698, 0x2698, prExtendedPictographic}, // E0.0 [1] (⚘) FLOWER + {0x2699, 0x2699, prExtendedPictographic}, // E1.0 [1] (⚙️) gear + {0x269A, 0x269A, prExtendedPictographic}, // E0.0 [1] (⚚) STAFF OF HERMES + {0x269B, 0x269C, prExtendedPictographic}, // E1.0 [2] (⚛️..⚜️) atom symbol..fleur-de-lis + {0x269D, 0x269F, prExtendedPictographic}, // E0.0 [3] (⚝..⚟) OUTLINED WHITE STAR..THREE LINES CONVERGING LEFT + {0x26A0, 0x26A1, prExtendedPictographic}, // E0.6 [2] (⚠️..⚡) warning..high voltage + {0x26A2, 0x26A6, prExtendedPictographic}, // E0.0 [5] (⚢..⚦) DOUBLED FEMALE SIGN..MALE WITH STROKE SIGN + {0x26A7, 0x26A7, prExtendedPictographic}, // E13.0 [1] (⚧️) transgender symbol + {0x26A8, 0x26A9, prExtendedPictographic}, // E0.0 [2] (⚨..⚩) VERTICAL MALE WITH STROKE SIGN..HORIZONTAL MALE WITH STROKE SIGN + {0x26AA, 0x26AB, prExtendedPictographic}, // E0.6 [2] (⚪..⚫) white circle..black circle + {0x26AC, 0x26AF, prExtendedPictographic}, // E0.0 [4] (⚬..⚯) MEDIUM SMALL WHITE CIRCLE..UNMARRIED PARTNERSHIP SYMBOL + {0x26B0, 0x26B1, prExtendedPictographic}, // E1.0 [2] (⚰️..⚱️) coffin..funeral urn + {0x26B2, 0x26BC, prExtendedPictographic}, // E0.0 [11] (⚲..⚼) NEUTER..SESQUIQUADRATE + {0x26BD, 0x26BE, prExtendedPictographic}, // E0.6 [2] (⚽..⚾) soccer ball..baseball + {0x26BF, 0x26C3, prExtendedPictographic}, // E0.0 [5] (⚿..⛃) SQUARED KEY..BLACK DRAUGHTS KING + {0x26C4, 0x26C5, prExtendedPictographic}, // E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud + {0x26C6, 0x26C7, prExtendedPictographic}, // E0.0 [2] (⛆..⛇) RAIN..BLACK SNOWMAN + {0x26C8, 0x26C8, prExtendedPictographic}, // E0.7 [1] (⛈️) cloud with lightning and rain + {0x26C9, 0x26CD, prExtendedPictographic}, // E0.0 [5] (⛉..⛍) TURNED WHITE SHOGI PIECE..DISABLED CAR + {0x26CE, 0x26CE, prExtendedPictographic}, // E0.6 [1] (⛎) Ophiuchus + {0x26CF, 0x26CF, prExtendedPictographic}, // E0.7 [1] (⛏️) pick + {0x26D0, 0x26D0, prExtendedPictographic}, // E0.0 [1] (⛐) CAR SLIDING + {0x26D1, 0x26D1, prExtendedPictographic}, // E0.7 [1] (⛑️) rescue worker’s helmet + {0x26D2, 0x26D2, prExtendedPictographic}, // E0.0 [1] (⛒) CIRCLED CROSSING LANES + {0x26D3, 0x26D3, prExtendedPictographic}, // E0.7 [1] (⛓️) chains + {0x26D4, 0x26D4, prExtendedPictographic}, // E0.6 [1] (⛔) no entry + {0x26D5, 0x26E8, prExtendedPictographic}, // E0.0 [20] (⛕..⛨) ALTERNATE ONE-WAY LEFT WAY TRAFFIC..BLACK CROSS ON SHIELD + {0x26E9, 0x26E9, prExtendedPictographic}, // E0.7 [1] (⛩️) shinto shrine + {0x26EA, 0x26EA, prExtendedPictographic}, // E0.6 [1] (⛪) church + {0x26EB, 0x26EF, prExtendedPictographic}, // E0.0 [5] (⛫..⛯) CASTLE..MAP SYMBOL FOR LIGHTHOUSE + {0x26F0, 0x26F1, prExtendedPictographic}, // E0.7 [2] (⛰️..⛱️) mountain..umbrella on ground + {0x26F2, 0x26F3, prExtendedPictographic}, // E0.6 [2] (⛲..⛳) fountain..flag in hole + {0x26F4, 0x26F4, prExtendedPictographic}, // E0.7 [1] (⛴️) ferry + {0x26F5, 0x26F5, prExtendedPictographic}, // E0.6 [1] (⛵) sailboat + {0x26F6, 0x26F6, prExtendedPictographic}, // E0.0 [1] (⛶) SQUARE FOUR CORNERS + {0x26F7, 0x26F9, prExtendedPictographic}, // E0.7 [3] (⛷️..⛹️) skier..person bouncing ball + {0x26FA, 0x26FA, prExtendedPictographic}, // E0.6 [1] (⛺) tent + {0x26FB, 0x26FC, prExtendedPictographic}, // E0.0 [2] (⛻..⛼) JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL + {0x26FD, 0x26FD, prExtendedPictographic}, // E0.6 [1] (⛽) fuel pump + {0x26FE, 0x2701, prExtendedPictographic}, // E0.0 [4] (⛾..✁) CUP ON BLACK SQUARE..UPPER BLADE SCISSORS + {0x2702, 0x2702, prExtendedPictographic}, // E0.6 [1] (✂️) scissors + {0x2703, 0x2704, prExtendedPictographic}, // E0.0 [2] (✃..✄) LOWER BLADE SCISSORS..WHITE SCISSORS + {0x2705, 0x2705, prExtendedPictographic}, // E0.6 [1] (✅) check mark button + {0x2708, 0x270C, prExtendedPictographic}, // E0.6 [5] (✈️..✌️) airplane..victory hand + {0x270D, 0x270D, prExtendedPictographic}, // E0.7 [1] (✍️) writing hand + {0x270E, 0x270E, prExtendedPictographic}, // E0.0 [1] (✎) LOWER RIGHT PENCIL + {0x270F, 0x270F, prExtendedPictographic}, // E0.6 [1] (✏️) pencil + {0x2710, 0x2711, prExtendedPictographic}, // E0.0 [2] (✐..✑) UPPER RIGHT PENCIL..WHITE NIB + {0x2712, 0x2712, prExtendedPictographic}, // E0.6 [1] (✒️) black nib + {0x2714, 0x2714, prExtendedPictographic}, // E0.6 [1] (✔️) check mark + {0x2716, 0x2716, prExtendedPictographic}, // E0.6 [1] (✖️) multiply + {0x271D, 0x271D, prExtendedPictographic}, // E0.7 [1] (✝️) latin cross + {0x2721, 0x2721, prExtendedPictographic}, // E0.7 [1] (✡️) star of David + {0x2728, 0x2728, prExtendedPictographic}, // E0.6 [1] (✨) sparkles + {0x2733, 0x2734, prExtendedPictographic}, // E0.6 [2] (✳️..✴️) eight-spoked asterisk..eight-pointed star + {0x2744, 0x2744, prExtendedPictographic}, // E0.6 [1] (❄️) snowflake + {0x2747, 0x2747, prExtendedPictographic}, // E0.6 [1] (❇️) sparkle + {0x274C, 0x274C, prExtendedPictographic}, // E0.6 [1] (❌) cross mark + {0x274E, 0x274E, prExtendedPictographic}, // E0.6 [1] (❎) cross mark button + {0x2753, 0x2755, prExtendedPictographic}, // E0.6 [3] (❓..❕) red question mark..white exclamation mark + {0x2757, 0x2757, prExtendedPictographic}, // E0.6 [1] (❗) red exclamation mark + {0x2763, 0x2763, prExtendedPictographic}, // E1.0 [1] (❣️) heart exclamation + {0x2764, 0x2764, prExtendedPictographic}, // E0.6 [1] (❤️) red heart + {0x2765, 0x2767, prExtendedPictographic}, // E0.0 [3] (❥..❧) ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET + {0x2795, 0x2797, prExtendedPictographic}, // E0.6 [3] (➕..➗) plus..divide + {0x27A1, 0x27A1, prExtendedPictographic}, // E0.6 [1] (➡️) right arrow + {0x27B0, 0x27B0, prExtendedPictographic}, // E0.6 [1] (➰) curly loop + {0x27BF, 0x27BF, prExtendedPictographic}, // E1.0 [1] (➿) double curly loop + {0x2934, 0x2935, prExtendedPictographic}, // E0.6 [2] (⤴️..⤵️) right arrow curving up..right arrow curving down + {0x2B05, 0x2B07, prExtendedPictographic}, // E0.6 [3] (⬅️..⬇️) left arrow..down arrow + {0x2B1B, 0x2B1C, prExtendedPictographic}, // E0.6 [2] (⬛..⬜) black large square..white large square + {0x2B50, 0x2B50, prExtendedPictographic}, // E0.6 [1] (⭐) star + {0x2B55, 0x2B55, prExtendedPictographic}, // E0.6 [1] (⭕) hollow red circle + {0x2CEF, 0x2CF1, prExtend}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2D7F, 0x2D7F, prExtend}, // Mn TIFINAGH CONSONANT JOINER + {0x2DE0, 0x2DFF, prExtend}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x302A, 0x302D, prExtend}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prExtend}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3030, 0x3030, prExtendedPictographic}, // E0.6 [1] (〰️) wavy dash + {0x303D, 0x303D, prExtendedPictographic}, // E0.6 [1] (〽️) part alternation mark + {0x3099, 0x309A, prExtend}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x3297, 0x3297, prExtendedPictographic}, // E0.6 [1] (㊗️) Japanese “congratulations” button + {0x3299, 0x3299, prExtendedPictographic}, // E0.6 [1] (㊙️) Japanese “secret” button + {0xA66F, 0xA66F, prExtend}, // Mn COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prExtend}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA674, 0xA67D, prExtend}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA69E, 0xA69F, prExtend}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6F0, 0xA6F1, prExtend}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA802, 0xA802, prExtend}, // Mn SYLOTI NAGRI SIGN DVISVARA + {0xA806, 0xA806, prExtend}, // Mn SYLOTI NAGRI SIGN HASANTA + {0xA80B, 0xA80B, prExtend}, // Mn SYLOTI NAGRI SIGN ANUSVARA + {0xA823, 0xA824, prSpacingMark}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prExtend}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prSpacingMark}, // Mc SYLOTI NAGRI VOWEL SIGN OO + {0xA82C, 0xA82C, prExtend}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA880, 0xA881, prSpacingMark}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA8B4, 0xA8C3, prSpacingMark}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prExtend}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8E0, 0xA8F1, prExtend}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8FF, 0xA8FF, prExtend}, // Mn DEVANAGARI VOWEL SIGN AY + {0xA926, 0xA92D, prExtend}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA947, 0xA951, prExtend}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prSpacingMark}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA960, 0xA97C, prL}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prExtend}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prSpacingMark}, // Mc JAVANESE SIGN WIGNYAN + {0xA9B3, 0xA9B3, prExtend}, // Mn JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prSpacingMark}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prExtend}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prSpacingMark}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prExtend}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prSpacingMark}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9E5, 0xA9E5, prExtend}, // Mn MYANMAR SIGN SHAN SAW + {0xAA29, 0xAA2E, prExtend}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prSpacingMark}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prExtend}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prSpacingMark}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prExtend}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA43, 0xAA43, prExtend}, // Mn CHAM CONSONANT SIGN FINAL NG + {0xAA4C, 0xAA4C, prExtend}, // Mn CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prSpacingMark}, // Mc CHAM CONSONANT SIGN FINAL H + {0xAA7C, 0xAA7C, prExtend}, // Mn MYANMAR SIGN TAI LAING TONE-2 + {0xAAB0, 0xAAB0, prExtend}, // Mn TAI VIET MAI KANG + {0xAAB2, 0xAAB4, prExtend}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB7, 0xAAB8, prExtend}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAABE, 0xAABF, prExtend}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC1, 0xAAC1, prExtend}, // Mn TAI VIET TONE MAI THO + {0xAAEB, 0xAAEB, prSpacingMark}, // Mc MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prExtend}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF5, 0xAAF5, prSpacingMark}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prExtend}, // Mn MEETEI MAYEK VIRAMA + {0xABE3, 0xABE4, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEC, 0xABEC, prSpacingMark}, // Mc MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prExtend}, // Mn MEETEI MAYEK APUN IYEK + {0xAC00, 0xAC00, prLV}, // Lo HANGUL SYLLABLE GA + {0xAC01, 0xAC1B, prLVT}, // Lo [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH + {0xAC1C, 0xAC1C, prLV}, // Lo HANGUL SYLLABLE GAE + {0xAC1D, 0xAC37, prLVT}, // Lo [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH + {0xAC38, 0xAC38, prLV}, // Lo HANGUL SYLLABLE GYA + {0xAC39, 0xAC53, prLVT}, // Lo [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH + {0xAC54, 0xAC54, prLV}, // Lo HANGUL SYLLABLE GYAE + {0xAC55, 0xAC6F, prLVT}, // Lo [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH + {0xAC70, 0xAC70, prLV}, // Lo HANGUL SYLLABLE GEO + {0xAC71, 0xAC8B, prLVT}, // Lo [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH + {0xAC8C, 0xAC8C, prLV}, // Lo HANGUL SYLLABLE GE + {0xAC8D, 0xACA7, prLVT}, // Lo [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH + {0xACA8, 0xACA8, prLV}, // Lo HANGUL SYLLABLE GYEO + {0xACA9, 0xACC3, prLVT}, // Lo [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH + {0xACC4, 0xACC4, prLV}, // Lo HANGUL SYLLABLE GYE + {0xACC5, 0xACDF, prLVT}, // Lo [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH + {0xACE0, 0xACE0, prLV}, // Lo HANGUL SYLLABLE GO + {0xACE1, 0xACFB, prLVT}, // Lo [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH + {0xACFC, 0xACFC, prLV}, // Lo HANGUL SYLLABLE GWA + {0xACFD, 0xAD17, prLVT}, // Lo [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH + {0xAD18, 0xAD18, prLV}, // Lo HANGUL SYLLABLE GWAE + {0xAD19, 0xAD33, prLVT}, // Lo [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH + {0xAD34, 0xAD34, prLV}, // Lo HANGUL SYLLABLE GOE + {0xAD35, 0xAD4F, prLVT}, // Lo [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH + {0xAD50, 0xAD50, prLV}, // Lo HANGUL SYLLABLE GYO + {0xAD51, 0xAD6B, prLVT}, // Lo [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH + {0xAD6C, 0xAD6C, prLV}, // Lo HANGUL SYLLABLE GU + {0xAD6D, 0xAD87, prLVT}, // Lo [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH + {0xAD88, 0xAD88, prLV}, // Lo HANGUL SYLLABLE GWEO + {0xAD89, 0xADA3, prLVT}, // Lo [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH + {0xADA4, 0xADA4, prLV}, // Lo HANGUL SYLLABLE GWE + {0xADA5, 0xADBF, prLVT}, // Lo [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH + {0xADC0, 0xADC0, prLV}, // Lo HANGUL SYLLABLE GWI + {0xADC1, 0xADDB, prLVT}, // Lo [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH + {0xADDC, 0xADDC, prLV}, // Lo HANGUL SYLLABLE GYU + {0xADDD, 0xADF7, prLVT}, // Lo [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH + {0xADF8, 0xADF8, prLV}, // Lo HANGUL SYLLABLE GEU + {0xADF9, 0xAE13, prLVT}, // Lo [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH + {0xAE14, 0xAE14, prLV}, // Lo HANGUL SYLLABLE GYI + {0xAE15, 0xAE2F, prLVT}, // Lo [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH + {0xAE30, 0xAE30, prLV}, // Lo HANGUL SYLLABLE GI + {0xAE31, 0xAE4B, prLVT}, // Lo [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH + {0xAE4C, 0xAE4C, prLV}, // Lo HANGUL SYLLABLE GGA + {0xAE4D, 0xAE67, prLVT}, // Lo [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH + {0xAE68, 0xAE68, prLV}, // Lo HANGUL SYLLABLE GGAE + {0xAE69, 0xAE83, prLVT}, // Lo [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH + {0xAE84, 0xAE84, prLV}, // Lo HANGUL SYLLABLE GGYA + {0xAE85, 0xAE9F, prLVT}, // Lo [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH + {0xAEA0, 0xAEA0, prLV}, // Lo HANGUL SYLLABLE GGYAE + {0xAEA1, 0xAEBB, prLVT}, // Lo [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH + {0xAEBC, 0xAEBC, prLV}, // Lo HANGUL SYLLABLE GGEO + {0xAEBD, 0xAED7, prLVT}, // Lo [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH + {0xAED8, 0xAED8, prLV}, // Lo HANGUL SYLLABLE GGE + {0xAED9, 0xAEF3, prLVT}, // Lo [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH + {0xAEF4, 0xAEF4, prLV}, // Lo HANGUL SYLLABLE GGYEO + {0xAEF5, 0xAF0F, prLVT}, // Lo [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH + {0xAF10, 0xAF10, prLV}, // Lo HANGUL SYLLABLE GGYE + {0xAF11, 0xAF2B, prLVT}, // Lo [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH + {0xAF2C, 0xAF2C, prLV}, // Lo HANGUL SYLLABLE GGO + {0xAF2D, 0xAF47, prLVT}, // Lo [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH + {0xAF48, 0xAF48, prLV}, // Lo HANGUL SYLLABLE GGWA + {0xAF49, 0xAF63, prLVT}, // Lo [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH + {0xAF64, 0xAF64, prLV}, // Lo HANGUL SYLLABLE GGWAE + {0xAF65, 0xAF7F, prLVT}, // Lo [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH + {0xAF80, 0xAF80, prLV}, // Lo HANGUL SYLLABLE GGOE + {0xAF81, 0xAF9B, prLVT}, // Lo [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH + {0xAF9C, 0xAF9C, prLV}, // Lo HANGUL SYLLABLE GGYO + {0xAF9D, 0xAFB7, prLVT}, // Lo [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH + {0xAFB8, 0xAFB8, prLV}, // Lo HANGUL SYLLABLE GGU + {0xAFB9, 0xAFD3, prLVT}, // Lo [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH + {0xAFD4, 0xAFD4, prLV}, // Lo HANGUL SYLLABLE GGWEO + {0xAFD5, 0xAFEF, prLVT}, // Lo [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH + {0xAFF0, 0xAFF0, prLV}, // Lo HANGUL SYLLABLE GGWE + {0xAFF1, 0xB00B, prLVT}, // Lo [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH + {0xB00C, 0xB00C, prLV}, // Lo HANGUL SYLLABLE GGWI + {0xB00D, 0xB027, prLVT}, // Lo [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH + {0xB028, 0xB028, prLV}, // Lo HANGUL SYLLABLE GGYU + {0xB029, 0xB043, prLVT}, // Lo [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH + {0xB044, 0xB044, prLV}, // Lo HANGUL SYLLABLE GGEU + {0xB045, 0xB05F, prLVT}, // Lo [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH + {0xB060, 0xB060, prLV}, // Lo HANGUL SYLLABLE GGYI + {0xB061, 0xB07B, prLVT}, // Lo [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH + {0xB07C, 0xB07C, prLV}, // Lo HANGUL SYLLABLE GGI + {0xB07D, 0xB097, prLVT}, // Lo [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH + {0xB098, 0xB098, prLV}, // Lo HANGUL SYLLABLE NA + {0xB099, 0xB0B3, prLVT}, // Lo [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH + {0xB0B4, 0xB0B4, prLV}, // Lo HANGUL SYLLABLE NAE + {0xB0B5, 0xB0CF, prLVT}, // Lo [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH + {0xB0D0, 0xB0D0, prLV}, // Lo HANGUL SYLLABLE NYA + {0xB0D1, 0xB0EB, prLVT}, // Lo [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH + {0xB0EC, 0xB0EC, prLV}, // Lo HANGUL SYLLABLE NYAE + {0xB0ED, 0xB107, prLVT}, // Lo [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH + {0xB108, 0xB108, prLV}, // Lo HANGUL SYLLABLE NEO + {0xB109, 0xB123, prLVT}, // Lo [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH + {0xB124, 0xB124, prLV}, // Lo HANGUL SYLLABLE NE + {0xB125, 0xB13F, prLVT}, // Lo [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH + {0xB140, 0xB140, prLV}, // Lo HANGUL SYLLABLE NYEO + {0xB141, 0xB15B, prLVT}, // Lo [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH + {0xB15C, 0xB15C, prLV}, // Lo HANGUL SYLLABLE NYE + {0xB15D, 0xB177, prLVT}, // Lo [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH + {0xB178, 0xB178, prLV}, // Lo HANGUL SYLLABLE NO + {0xB179, 0xB193, prLVT}, // Lo [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH + {0xB194, 0xB194, prLV}, // Lo HANGUL SYLLABLE NWA + {0xB195, 0xB1AF, prLVT}, // Lo [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH + {0xB1B0, 0xB1B0, prLV}, // Lo HANGUL SYLLABLE NWAE + {0xB1B1, 0xB1CB, prLVT}, // Lo [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH + {0xB1CC, 0xB1CC, prLV}, // Lo HANGUL SYLLABLE NOE + {0xB1CD, 0xB1E7, prLVT}, // Lo [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH + {0xB1E8, 0xB1E8, prLV}, // Lo HANGUL SYLLABLE NYO + {0xB1E9, 0xB203, prLVT}, // Lo [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH + {0xB204, 0xB204, prLV}, // Lo HANGUL SYLLABLE NU + {0xB205, 0xB21F, prLVT}, // Lo [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH + {0xB220, 0xB220, prLV}, // Lo HANGUL SYLLABLE NWEO + {0xB221, 0xB23B, prLVT}, // Lo [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH + {0xB23C, 0xB23C, prLV}, // Lo HANGUL SYLLABLE NWE + {0xB23D, 0xB257, prLVT}, // Lo [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH + {0xB258, 0xB258, prLV}, // Lo HANGUL SYLLABLE NWI + {0xB259, 0xB273, prLVT}, // Lo [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH + {0xB274, 0xB274, prLV}, // Lo HANGUL SYLLABLE NYU + {0xB275, 0xB28F, prLVT}, // Lo [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH + {0xB290, 0xB290, prLV}, // Lo HANGUL SYLLABLE NEU + {0xB291, 0xB2AB, prLVT}, // Lo [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH + {0xB2AC, 0xB2AC, prLV}, // Lo HANGUL SYLLABLE NYI + {0xB2AD, 0xB2C7, prLVT}, // Lo [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH + {0xB2C8, 0xB2C8, prLV}, // Lo HANGUL SYLLABLE NI + {0xB2C9, 0xB2E3, prLVT}, // Lo [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH + {0xB2E4, 0xB2E4, prLV}, // Lo HANGUL SYLLABLE DA + {0xB2E5, 0xB2FF, prLVT}, // Lo [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH + {0xB300, 0xB300, prLV}, // Lo HANGUL SYLLABLE DAE + {0xB301, 0xB31B, prLVT}, // Lo [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH + {0xB31C, 0xB31C, prLV}, // Lo HANGUL SYLLABLE DYA + {0xB31D, 0xB337, prLVT}, // Lo [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH + {0xB338, 0xB338, prLV}, // Lo HANGUL SYLLABLE DYAE + {0xB339, 0xB353, prLVT}, // Lo [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH + {0xB354, 0xB354, prLV}, // Lo HANGUL SYLLABLE DEO + {0xB355, 0xB36F, prLVT}, // Lo [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH + {0xB370, 0xB370, prLV}, // Lo HANGUL SYLLABLE DE + {0xB371, 0xB38B, prLVT}, // Lo [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH + {0xB38C, 0xB38C, prLV}, // Lo HANGUL SYLLABLE DYEO + {0xB38D, 0xB3A7, prLVT}, // Lo [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH + {0xB3A8, 0xB3A8, prLV}, // Lo HANGUL SYLLABLE DYE + {0xB3A9, 0xB3C3, prLVT}, // Lo [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH + {0xB3C4, 0xB3C4, prLV}, // Lo HANGUL SYLLABLE DO + {0xB3C5, 0xB3DF, prLVT}, // Lo [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH + {0xB3E0, 0xB3E0, prLV}, // Lo HANGUL SYLLABLE DWA + {0xB3E1, 0xB3FB, prLVT}, // Lo [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH + {0xB3FC, 0xB3FC, prLV}, // Lo HANGUL SYLLABLE DWAE + {0xB3FD, 0xB417, prLVT}, // Lo [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH + {0xB418, 0xB418, prLV}, // Lo HANGUL SYLLABLE DOE + {0xB419, 0xB433, prLVT}, // Lo [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH + {0xB434, 0xB434, prLV}, // Lo HANGUL SYLLABLE DYO + {0xB435, 0xB44F, prLVT}, // Lo [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH + {0xB450, 0xB450, prLV}, // Lo HANGUL SYLLABLE DU + {0xB451, 0xB46B, prLVT}, // Lo [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH + {0xB46C, 0xB46C, prLV}, // Lo HANGUL SYLLABLE DWEO + {0xB46D, 0xB487, prLVT}, // Lo [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH + {0xB488, 0xB488, prLV}, // Lo HANGUL SYLLABLE DWE + {0xB489, 0xB4A3, prLVT}, // Lo [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH + {0xB4A4, 0xB4A4, prLV}, // Lo HANGUL SYLLABLE DWI + {0xB4A5, 0xB4BF, prLVT}, // Lo [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH + {0xB4C0, 0xB4C0, prLV}, // Lo HANGUL SYLLABLE DYU + {0xB4C1, 0xB4DB, prLVT}, // Lo [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH + {0xB4DC, 0xB4DC, prLV}, // Lo HANGUL SYLLABLE DEU + {0xB4DD, 0xB4F7, prLVT}, // Lo [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH + {0xB4F8, 0xB4F8, prLV}, // Lo HANGUL SYLLABLE DYI + {0xB4F9, 0xB513, prLVT}, // Lo [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH + {0xB514, 0xB514, prLV}, // Lo HANGUL SYLLABLE DI + {0xB515, 0xB52F, prLVT}, // Lo [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH + {0xB530, 0xB530, prLV}, // Lo HANGUL SYLLABLE DDA + {0xB531, 0xB54B, prLVT}, // Lo [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH + {0xB54C, 0xB54C, prLV}, // Lo HANGUL SYLLABLE DDAE + {0xB54D, 0xB567, prLVT}, // Lo [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH + {0xB568, 0xB568, prLV}, // Lo HANGUL SYLLABLE DDYA + {0xB569, 0xB583, prLVT}, // Lo [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH + {0xB584, 0xB584, prLV}, // Lo HANGUL SYLLABLE DDYAE + {0xB585, 0xB59F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH + {0xB5A0, 0xB5A0, prLV}, // Lo HANGUL SYLLABLE DDEO + {0xB5A1, 0xB5BB, prLVT}, // Lo [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH + {0xB5BC, 0xB5BC, prLV}, // Lo HANGUL SYLLABLE DDE + {0xB5BD, 0xB5D7, prLVT}, // Lo [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH + {0xB5D8, 0xB5D8, prLV}, // Lo HANGUL SYLLABLE DDYEO + {0xB5D9, 0xB5F3, prLVT}, // Lo [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH + {0xB5F4, 0xB5F4, prLV}, // Lo HANGUL SYLLABLE DDYE + {0xB5F5, 0xB60F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH + {0xB610, 0xB610, prLV}, // Lo HANGUL SYLLABLE DDO + {0xB611, 0xB62B, prLVT}, // Lo [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH + {0xB62C, 0xB62C, prLV}, // Lo HANGUL SYLLABLE DDWA + {0xB62D, 0xB647, prLVT}, // Lo [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH + {0xB648, 0xB648, prLV}, // Lo HANGUL SYLLABLE DDWAE + {0xB649, 0xB663, prLVT}, // Lo [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH + {0xB664, 0xB664, prLV}, // Lo HANGUL SYLLABLE DDOE + {0xB665, 0xB67F, prLVT}, // Lo [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH + {0xB680, 0xB680, prLV}, // Lo HANGUL SYLLABLE DDYO + {0xB681, 0xB69B, prLVT}, // Lo [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH + {0xB69C, 0xB69C, prLV}, // Lo HANGUL SYLLABLE DDU + {0xB69D, 0xB6B7, prLVT}, // Lo [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH + {0xB6B8, 0xB6B8, prLV}, // Lo HANGUL SYLLABLE DDWEO + {0xB6B9, 0xB6D3, prLVT}, // Lo [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH + {0xB6D4, 0xB6D4, prLV}, // Lo HANGUL SYLLABLE DDWE + {0xB6D5, 0xB6EF, prLVT}, // Lo [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH + {0xB6F0, 0xB6F0, prLV}, // Lo HANGUL SYLLABLE DDWI + {0xB6F1, 0xB70B, prLVT}, // Lo [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH + {0xB70C, 0xB70C, prLV}, // Lo HANGUL SYLLABLE DDYU + {0xB70D, 0xB727, prLVT}, // Lo [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH + {0xB728, 0xB728, prLV}, // Lo HANGUL SYLLABLE DDEU + {0xB729, 0xB743, prLVT}, // Lo [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH + {0xB744, 0xB744, prLV}, // Lo HANGUL SYLLABLE DDYI + {0xB745, 0xB75F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH + {0xB760, 0xB760, prLV}, // Lo HANGUL SYLLABLE DDI + {0xB761, 0xB77B, prLVT}, // Lo [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH + {0xB77C, 0xB77C, prLV}, // Lo HANGUL SYLLABLE RA + {0xB77D, 0xB797, prLVT}, // Lo [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH + {0xB798, 0xB798, prLV}, // Lo HANGUL SYLLABLE RAE + {0xB799, 0xB7B3, prLVT}, // Lo [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH + {0xB7B4, 0xB7B4, prLV}, // Lo HANGUL SYLLABLE RYA + {0xB7B5, 0xB7CF, prLVT}, // Lo [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH + {0xB7D0, 0xB7D0, prLV}, // Lo HANGUL SYLLABLE RYAE + {0xB7D1, 0xB7EB, prLVT}, // Lo [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH + {0xB7EC, 0xB7EC, prLV}, // Lo HANGUL SYLLABLE REO + {0xB7ED, 0xB807, prLVT}, // Lo [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH + {0xB808, 0xB808, prLV}, // Lo HANGUL SYLLABLE RE + {0xB809, 0xB823, prLVT}, // Lo [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH + {0xB824, 0xB824, prLV}, // Lo HANGUL SYLLABLE RYEO + {0xB825, 0xB83F, prLVT}, // Lo [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH + {0xB840, 0xB840, prLV}, // Lo HANGUL SYLLABLE RYE + {0xB841, 0xB85B, prLVT}, // Lo [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH + {0xB85C, 0xB85C, prLV}, // Lo HANGUL SYLLABLE RO + {0xB85D, 0xB877, prLVT}, // Lo [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH + {0xB878, 0xB878, prLV}, // Lo HANGUL SYLLABLE RWA + {0xB879, 0xB893, prLVT}, // Lo [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH + {0xB894, 0xB894, prLV}, // Lo HANGUL SYLLABLE RWAE + {0xB895, 0xB8AF, prLVT}, // Lo [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH + {0xB8B0, 0xB8B0, prLV}, // Lo HANGUL SYLLABLE ROE + {0xB8B1, 0xB8CB, prLVT}, // Lo [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH + {0xB8CC, 0xB8CC, prLV}, // Lo HANGUL SYLLABLE RYO + {0xB8CD, 0xB8E7, prLVT}, // Lo [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH + {0xB8E8, 0xB8E8, prLV}, // Lo HANGUL SYLLABLE RU + {0xB8E9, 0xB903, prLVT}, // Lo [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH + {0xB904, 0xB904, prLV}, // Lo HANGUL SYLLABLE RWEO + {0xB905, 0xB91F, prLVT}, // Lo [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH + {0xB920, 0xB920, prLV}, // Lo HANGUL SYLLABLE RWE + {0xB921, 0xB93B, prLVT}, // Lo [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH + {0xB93C, 0xB93C, prLV}, // Lo HANGUL SYLLABLE RWI + {0xB93D, 0xB957, prLVT}, // Lo [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH + {0xB958, 0xB958, prLV}, // Lo HANGUL SYLLABLE RYU + {0xB959, 0xB973, prLVT}, // Lo [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH + {0xB974, 0xB974, prLV}, // Lo HANGUL SYLLABLE REU + {0xB975, 0xB98F, prLVT}, // Lo [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH + {0xB990, 0xB990, prLV}, // Lo HANGUL SYLLABLE RYI + {0xB991, 0xB9AB, prLVT}, // Lo [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH + {0xB9AC, 0xB9AC, prLV}, // Lo HANGUL SYLLABLE RI + {0xB9AD, 0xB9C7, prLVT}, // Lo [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH + {0xB9C8, 0xB9C8, prLV}, // Lo HANGUL SYLLABLE MA + {0xB9C9, 0xB9E3, prLVT}, // Lo [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH + {0xB9E4, 0xB9E4, prLV}, // Lo HANGUL SYLLABLE MAE + {0xB9E5, 0xB9FF, prLVT}, // Lo [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH + {0xBA00, 0xBA00, prLV}, // Lo HANGUL SYLLABLE MYA + {0xBA01, 0xBA1B, prLVT}, // Lo [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH + {0xBA1C, 0xBA1C, prLV}, // Lo HANGUL SYLLABLE MYAE + {0xBA1D, 0xBA37, prLVT}, // Lo [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH + {0xBA38, 0xBA38, prLV}, // Lo HANGUL SYLLABLE MEO + {0xBA39, 0xBA53, prLVT}, // Lo [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH + {0xBA54, 0xBA54, prLV}, // Lo HANGUL SYLLABLE ME + {0xBA55, 0xBA6F, prLVT}, // Lo [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH + {0xBA70, 0xBA70, prLV}, // Lo HANGUL SYLLABLE MYEO + {0xBA71, 0xBA8B, prLVT}, // Lo [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH + {0xBA8C, 0xBA8C, prLV}, // Lo HANGUL SYLLABLE MYE + {0xBA8D, 0xBAA7, prLVT}, // Lo [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH + {0xBAA8, 0xBAA8, prLV}, // Lo HANGUL SYLLABLE MO + {0xBAA9, 0xBAC3, prLVT}, // Lo [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH + {0xBAC4, 0xBAC4, prLV}, // Lo HANGUL SYLLABLE MWA + {0xBAC5, 0xBADF, prLVT}, // Lo [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH + {0xBAE0, 0xBAE0, prLV}, // Lo HANGUL SYLLABLE MWAE + {0xBAE1, 0xBAFB, prLVT}, // Lo [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH + {0xBAFC, 0xBAFC, prLV}, // Lo HANGUL SYLLABLE MOE + {0xBAFD, 0xBB17, prLVT}, // Lo [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH + {0xBB18, 0xBB18, prLV}, // Lo HANGUL SYLLABLE MYO + {0xBB19, 0xBB33, prLVT}, // Lo [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH + {0xBB34, 0xBB34, prLV}, // Lo HANGUL SYLLABLE MU + {0xBB35, 0xBB4F, prLVT}, // Lo [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH + {0xBB50, 0xBB50, prLV}, // Lo HANGUL SYLLABLE MWEO + {0xBB51, 0xBB6B, prLVT}, // Lo [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH + {0xBB6C, 0xBB6C, prLV}, // Lo HANGUL SYLLABLE MWE + {0xBB6D, 0xBB87, prLVT}, // Lo [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH + {0xBB88, 0xBB88, prLV}, // Lo HANGUL SYLLABLE MWI + {0xBB89, 0xBBA3, prLVT}, // Lo [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH + {0xBBA4, 0xBBA4, prLV}, // Lo HANGUL SYLLABLE MYU + {0xBBA5, 0xBBBF, prLVT}, // Lo [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH + {0xBBC0, 0xBBC0, prLV}, // Lo HANGUL SYLLABLE MEU + {0xBBC1, 0xBBDB, prLVT}, // Lo [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH + {0xBBDC, 0xBBDC, prLV}, // Lo HANGUL SYLLABLE MYI + {0xBBDD, 0xBBF7, prLVT}, // Lo [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH + {0xBBF8, 0xBBF8, prLV}, // Lo HANGUL SYLLABLE MI + {0xBBF9, 0xBC13, prLVT}, // Lo [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH + {0xBC14, 0xBC14, prLV}, // Lo HANGUL SYLLABLE BA + {0xBC15, 0xBC2F, prLVT}, // Lo [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH + {0xBC30, 0xBC30, prLV}, // Lo HANGUL SYLLABLE BAE + {0xBC31, 0xBC4B, prLVT}, // Lo [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH + {0xBC4C, 0xBC4C, prLV}, // Lo HANGUL SYLLABLE BYA + {0xBC4D, 0xBC67, prLVT}, // Lo [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH + {0xBC68, 0xBC68, prLV}, // Lo HANGUL SYLLABLE BYAE + {0xBC69, 0xBC83, prLVT}, // Lo [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH + {0xBC84, 0xBC84, prLV}, // Lo HANGUL SYLLABLE BEO + {0xBC85, 0xBC9F, prLVT}, // Lo [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH + {0xBCA0, 0xBCA0, prLV}, // Lo HANGUL SYLLABLE BE + {0xBCA1, 0xBCBB, prLVT}, // Lo [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH + {0xBCBC, 0xBCBC, prLV}, // Lo HANGUL SYLLABLE BYEO + {0xBCBD, 0xBCD7, prLVT}, // Lo [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH + {0xBCD8, 0xBCD8, prLV}, // Lo HANGUL SYLLABLE BYE + {0xBCD9, 0xBCF3, prLVT}, // Lo [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH + {0xBCF4, 0xBCF4, prLV}, // Lo HANGUL SYLLABLE BO + {0xBCF5, 0xBD0F, prLVT}, // Lo [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH + {0xBD10, 0xBD10, prLV}, // Lo HANGUL SYLLABLE BWA + {0xBD11, 0xBD2B, prLVT}, // Lo [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH + {0xBD2C, 0xBD2C, prLV}, // Lo HANGUL SYLLABLE BWAE + {0xBD2D, 0xBD47, prLVT}, // Lo [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH + {0xBD48, 0xBD48, prLV}, // Lo HANGUL SYLLABLE BOE + {0xBD49, 0xBD63, prLVT}, // Lo [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH + {0xBD64, 0xBD64, prLV}, // Lo HANGUL SYLLABLE BYO + {0xBD65, 0xBD7F, prLVT}, // Lo [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH + {0xBD80, 0xBD80, prLV}, // Lo HANGUL SYLLABLE BU + {0xBD81, 0xBD9B, prLVT}, // Lo [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH + {0xBD9C, 0xBD9C, prLV}, // Lo HANGUL SYLLABLE BWEO + {0xBD9D, 0xBDB7, prLVT}, // Lo [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH + {0xBDB8, 0xBDB8, prLV}, // Lo HANGUL SYLLABLE BWE + {0xBDB9, 0xBDD3, prLVT}, // Lo [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH + {0xBDD4, 0xBDD4, prLV}, // Lo HANGUL SYLLABLE BWI + {0xBDD5, 0xBDEF, prLVT}, // Lo [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH + {0xBDF0, 0xBDF0, prLV}, // Lo HANGUL SYLLABLE BYU + {0xBDF1, 0xBE0B, prLVT}, // Lo [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH + {0xBE0C, 0xBE0C, prLV}, // Lo HANGUL SYLLABLE BEU + {0xBE0D, 0xBE27, prLVT}, // Lo [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH + {0xBE28, 0xBE28, prLV}, // Lo HANGUL SYLLABLE BYI + {0xBE29, 0xBE43, prLVT}, // Lo [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH + {0xBE44, 0xBE44, prLV}, // Lo HANGUL SYLLABLE BI + {0xBE45, 0xBE5F, prLVT}, // Lo [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH + {0xBE60, 0xBE60, prLV}, // Lo HANGUL SYLLABLE BBA + {0xBE61, 0xBE7B, prLVT}, // Lo [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH + {0xBE7C, 0xBE7C, prLV}, // Lo HANGUL SYLLABLE BBAE + {0xBE7D, 0xBE97, prLVT}, // Lo [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH + {0xBE98, 0xBE98, prLV}, // Lo HANGUL SYLLABLE BBYA + {0xBE99, 0xBEB3, prLVT}, // Lo [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH + {0xBEB4, 0xBEB4, prLV}, // Lo HANGUL SYLLABLE BBYAE + {0xBEB5, 0xBECF, prLVT}, // Lo [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH + {0xBED0, 0xBED0, prLV}, // Lo HANGUL SYLLABLE BBEO + {0xBED1, 0xBEEB, prLVT}, // Lo [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH + {0xBEEC, 0xBEEC, prLV}, // Lo HANGUL SYLLABLE BBE + {0xBEED, 0xBF07, prLVT}, // Lo [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH + {0xBF08, 0xBF08, prLV}, // Lo HANGUL SYLLABLE BBYEO + {0xBF09, 0xBF23, prLVT}, // Lo [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH + {0xBF24, 0xBF24, prLV}, // Lo HANGUL SYLLABLE BBYE + {0xBF25, 0xBF3F, prLVT}, // Lo [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH + {0xBF40, 0xBF40, prLV}, // Lo HANGUL SYLLABLE BBO + {0xBF41, 0xBF5B, prLVT}, // Lo [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH + {0xBF5C, 0xBF5C, prLV}, // Lo HANGUL SYLLABLE BBWA + {0xBF5D, 0xBF77, prLVT}, // Lo [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH + {0xBF78, 0xBF78, prLV}, // Lo HANGUL SYLLABLE BBWAE + {0xBF79, 0xBF93, prLVT}, // Lo [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH + {0xBF94, 0xBF94, prLV}, // Lo HANGUL SYLLABLE BBOE + {0xBF95, 0xBFAF, prLVT}, // Lo [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH + {0xBFB0, 0xBFB0, prLV}, // Lo HANGUL SYLLABLE BBYO + {0xBFB1, 0xBFCB, prLVT}, // Lo [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH + {0xBFCC, 0xBFCC, prLV}, // Lo HANGUL SYLLABLE BBU + {0xBFCD, 0xBFE7, prLVT}, // Lo [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH + {0xBFE8, 0xBFE8, prLV}, // Lo HANGUL SYLLABLE BBWEO + {0xBFE9, 0xC003, prLVT}, // Lo [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH + {0xC004, 0xC004, prLV}, // Lo HANGUL SYLLABLE BBWE + {0xC005, 0xC01F, prLVT}, // Lo [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH + {0xC020, 0xC020, prLV}, // Lo HANGUL SYLLABLE BBWI + {0xC021, 0xC03B, prLVT}, // Lo [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH + {0xC03C, 0xC03C, prLV}, // Lo HANGUL SYLLABLE BBYU + {0xC03D, 0xC057, prLVT}, // Lo [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH + {0xC058, 0xC058, prLV}, // Lo HANGUL SYLLABLE BBEU + {0xC059, 0xC073, prLVT}, // Lo [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH + {0xC074, 0xC074, prLV}, // Lo HANGUL SYLLABLE BBYI + {0xC075, 0xC08F, prLVT}, // Lo [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH + {0xC090, 0xC090, prLV}, // Lo HANGUL SYLLABLE BBI + {0xC091, 0xC0AB, prLVT}, // Lo [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH + {0xC0AC, 0xC0AC, prLV}, // Lo HANGUL SYLLABLE SA + {0xC0AD, 0xC0C7, prLVT}, // Lo [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH + {0xC0C8, 0xC0C8, prLV}, // Lo HANGUL SYLLABLE SAE + {0xC0C9, 0xC0E3, prLVT}, // Lo [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH + {0xC0E4, 0xC0E4, prLV}, // Lo HANGUL SYLLABLE SYA + {0xC0E5, 0xC0FF, prLVT}, // Lo [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH + {0xC100, 0xC100, prLV}, // Lo HANGUL SYLLABLE SYAE + {0xC101, 0xC11B, prLVT}, // Lo [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH + {0xC11C, 0xC11C, prLV}, // Lo HANGUL SYLLABLE SEO + {0xC11D, 0xC137, prLVT}, // Lo [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH + {0xC138, 0xC138, prLV}, // Lo HANGUL SYLLABLE SE + {0xC139, 0xC153, prLVT}, // Lo [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH + {0xC154, 0xC154, prLV}, // Lo HANGUL SYLLABLE SYEO + {0xC155, 0xC16F, prLVT}, // Lo [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH + {0xC170, 0xC170, prLV}, // Lo HANGUL SYLLABLE SYE + {0xC171, 0xC18B, prLVT}, // Lo [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH + {0xC18C, 0xC18C, prLV}, // Lo HANGUL SYLLABLE SO + {0xC18D, 0xC1A7, prLVT}, // Lo [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH + {0xC1A8, 0xC1A8, prLV}, // Lo HANGUL SYLLABLE SWA + {0xC1A9, 0xC1C3, prLVT}, // Lo [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH + {0xC1C4, 0xC1C4, prLV}, // Lo HANGUL SYLLABLE SWAE + {0xC1C5, 0xC1DF, prLVT}, // Lo [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH + {0xC1E0, 0xC1E0, prLV}, // Lo HANGUL SYLLABLE SOE + {0xC1E1, 0xC1FB, prLVT}, // Lo [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH + {0xC1FC, 0xC1FC, prLV}, // Lo HANGUL SYLLABLE SYO + {0xC1FD, 0xC217, prLVT}, // Lo [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH + {0xC218, 0xC218, prLV}, // Lo HANGUL SYLLABLE SU + {0xC219, 0xC233, prLVT}, // Lo [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH + {0xC234, 0xC234, prLV}, // Lo HANGUL SYLLABLE SWEO + {0xC235, 0xC24F, prLVT}, // Lo [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH + {0xC250, 0xC250, prLV}, // Lo HANGUL SYLLABLE SWE + {0xC251, 0xC26B, prLVT}, // Lo [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH + {0xC26C, 0xC26C, prLV}, // Lo HANGUL SYLLABLE SWI + {0xC26D, 0xC287, prLVT}, // Lo [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH + {0xC288, 0xC288, prLV}, // Lo HANGUL SYLLABLE SYU + {0xC289, 0xC2A3, prLVT}, // Lo [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH + {0xC2A4, 0xC2A4, prLV}, // Lo HANGUL SYLLABLE SEU + {0xC2A5, 0xC2BF, prLVT}, // Lo [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH + {0xC2C0, 0xC2C0, prLV}, // Lo HANGUL SYLLABLE SYI + {0xC2C1, 0xC2DB, prLVT}, // Lo [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH + {0xC2DC, 0xC2DC, prLV}, // Lo HANGUL SYLLABLE SI + {0xC2DD, 0xC2F7, prLVT}, // Lo [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH + {0xC2F8, 0xC2F8, prLV}, // Lo HANGUL SYLLABLE SSA + {0xC2F9, 0xC313, prLVT}, // Lo [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH + {0xC314, 0xC314, prLV}, // Lo HANGUL SYLLABLE SSAE + {0xC315, 0xC32F, prLVT}, // Lo [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH + {0xC330, 0xC330, prLV}, // Lo HANGUL SYLLABLE SSYA + {0xC331, 0xC34B, prLVT}, // Lo [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH + {0xC34C, 0xC34C, prLV}, // Lo HANGUL SYLLABLE SSYAE + {0xC34D, 0xC367, prLVT}, // Lo [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH + {0xC368, 0xC368, prLV}, // Lo HANGUL SYLLABLE SSEO + {0xC369, 0xC383, prLVT}, // Lo [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH + {0xC384, 0xC384, prLV}, // Lo HANGUL SYLLABLE SSE + {0xC385, 0xC39F, prLVT}, // Lo [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH + {0xC3A0, 0xC3A0, prLV}, // Lo HANGUL SYLLABLE SSYEO + {0xC3A1, 0xC3BB, prLVT}, // Lo [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH + {0xC3BC, 0xC3BC, prLV}, // Lo HANGUL SYLLABLE SSYE + {0xC3BD, 0xC3D7, prLVT}, // Lo [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH + {0xC3D8, 0xC3D8, prLV}, // Lo HANGUL SYLLABLE SSO + {0xC3D9, 0xC3F3, prLVT}, // Lo [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH + {0xC3F4, 0xC3F4, prLV}, // Lo HANGUL SYLLABLE SSWA + {0xC3F5, 0xC40F, prLVT}, // Lo [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH + {0xC410, 0xC410, prLV}, // Lo HANGUL SYLLABLE SSWAE + {0xC411, 0xC42B, prLVT}, // Lo [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH + {0xC42C, 0xC42C, prLV}, // Lo HANGUL SYLLABLE SSOE + {0xC42D, 0xC447, prLVT}, // Lo [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH + {0xC448, 0xC448, prLV}, // Lo HANGUL SYLLABLE SSYO + {0xC449, 0xC463, prLVT}, // Lo [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH + {0xC464, 0xC464, prLV}, // Lo HANGUL SYLLABLE SSU + {0xC465, 0xC47F, prLVT}, // Lo [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH + {0xC480, 0xC480, prLV}, // Lo HANGUL SYLLABLE SSWEO + {0xC481, 0xC49B, prLVT}, // Lo [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH + {0xC49C, 0xC49C, prLV}, // Lo HANGUL SYLLABLE SSWE + {0xC49D, 0xC4B7, prLVT}, // Lo [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH + {0xC4B8, 0xC4B8, prLV}, // Lo HANGUL SYLLABLE SSWI + {0xC4B9, 0xC4D3, prLVT}, // Lo [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH + {0xC4D4, 0xC4D4, prLV}, // Lo HANGUL SYLLABLE SSYU + {0xC4D5, 0xC4EF, prLVT}, // Lo [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH + {0xC4F0, 0xC4F0, prLV}, // Lo HANGUL SYLLABLE SSEU + {0xC4F1, 0xC50B, prLVT}, // Lo [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH + {0xC50C, 0xC50C, prLV}, // Lo HANGUL SYLLABLE SSYI + {0xC50D, 0xC527, prLVT}, // Lo [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH + {0xC528, 0xC528, prLV}, // Lo HANGUL SYLLABLE SSI + {0xC529, 0xC543, prLVT}, // Lo [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH + {0xC544, 0xC544, prLV}, // Lo HANGUL SYLLABLE A + {0xC545, 0xC55F, prLVT}, // Lo [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH + {0xC560, 0xC560, prLV}, // Lo HANGUL SYLLABLE AE + {0xC561, 0xC57B, prLVT}, // Lo [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH + {0xC57C, 0xC57C, prLV}, // Lo HANGUL SYLLABLE YA + {0xC57D, 0xC597, prLVT}, // Lo [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH + {0xC598, 0xC598, prLV}, // Lo HANGUL SYLLABLE YAE + {0xC599, 0xC5B3, prLVT}, // Lo [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH + {0xC5B4, 0xC5B4, prLV}, // Lo HANGUL SYLLABLE EO + {0xC5B5, 0xC5CF, prLVT}, // Lo [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH + {0xC5D0, 0xC5D0, prLV}, // Lo HANGUL SYLLABLE E + {0xC5D1, 0xC5EB, prLVT}, // Lo [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH + {0xC5EC, 0xC5EC, prLV}, // Lo HANGUL SYLLABLE YEO + {0xC5ED, 0xC607, prLVT}, // Lo [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH + {0xC608, 0xC608, prLV}, // Lo HANGUL SYLLABLE YE + {0xC609, 0xC623, prLVT}, // Lo [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH + {0xC624, 0xC624, prLV}, // Lo HANGUL SYLLABLE O + {0xC625, 0xC63F, prLVT}, // Lo [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH + {0xC640, 0xC640, prLV}, // Lo HANGUL SYLLABLE WA + {0xC641, 0xC65B, prLVT}, // Lo [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH + {0xC65C, 0xC65C, prLV}, // Lo HANGUL SYLLABLE WAE + {0xC65D, 0xC677, prLVT}, // Lo [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH + {0xC678, 0xC678, prLV}, // Lo HANGUL SYLLABLE OE + {0xC679, 0xC693, prLVT}, // Lo [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH + {0xC694, 0xC694, prLV}, // Lo HANGUL SYLLABLE YO + {0xC695, 0xC6AF, prLVT}, // Lo [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH + {0xC6B0, 0xC6B0, prLV}, // Lo HANGUL SYLLABLE U + {0xC6B1, 0xC6CB, prLVT}, // Lo [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH + {0xC6CC, 0xC6CC, prLV}, // Lo HANGUL SYLLABLE WEO + {0xC6CD, 0xC6E7, prLVT}, // Lo [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH + {0xC6E8, 0xC6E8, prLV}, // Lo HANGUL SYLLABLE WE + {0xC6E9, 0xC703, prLVT}, // Lo [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH + {0xC704, 0xC704, prLV}, // Lo HANGUL SYLLABLE WI + {0xC705, 0xC71F, prLVT}, // Lo [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH + {0xC720, 0xC720, prLV}, // Lo HANGUL SYLLABLE YU + {0xC721, 0xC73B, prLVT}, // Lo [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH + {0xC73C, 0xC73C, prLV}, // Lo HANGUL SYLLABLE EU + {0xC73D, 0xC757, prLVT}, // Lo [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH + {0xC758, 0xC758, prLV}, // Lo HANGUL SYLLABLE YI + {0xC759, 0xC773, prLVT}, // Lo [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH + {0xC774, 0xC774, prLV}, // Lo HANGUL SYLLABLE I + {0xC775, 0xC78F, prLVT}, // Lo [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH + {0xC790, 0xC790, prLV}, // Lo HANGUL SYLLABLE JA + {0xC791, 0xC7AB, prLVT}, // Lo [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH + {0xC7AC, 0xC7AC, prLV}, // Lo HANGUL SYLLABLE JAE + {0xC7AD, 0xC7C7, prLVT}, // Lo [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH + {0xC7C8, 0xC7C8, prLV}, // Lo HANGUL SYLLABLE JYA + {0xC7C9, 0xC7E3, prLVT}, // Lo [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH + {0xC7E4, 0xC7E4, prLV}, // Lo HANGUL SYLLABLE JYAE + {0xC7E5, 0xC7FF, prLVT}, // Lo [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH + {0xC800, 0xC800, prLV}, // Lo HANGUL SYLLABLE JEO + {0xC801, 0xC81B, prLVT}, // Lo [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH + {0xC81C, 0xC81C, prLV}, // Lo HANGUL SYLLABLE JE + {0xC81D, 0xC837, prLVT}, // Lo [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH + {0xC838, 0xC838, prLV}, // Lo HANGUL SYLLABLE JYEO + {0xC839, 0xC853, prLVT}, // Lo [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH + {0xC854, 0xC854, prLV}, // Lo HANGUL SYLLABLE JYE + {0xC855, 0xC86F, prLVT}, // Lo [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH + {0xC870, 0xC870, prLV}, // Lo HANGUL SYLLABLE JO + {0xC871, 0xC88B, prLVT}, // Lo [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH + {0xC88C, 0xC88C, prLV}, // Lo HANGUL SYLLABLE JWA + {0xC88D, 0xC8A7, prLVT}, // Lo [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH + {0xC8A8, 0xC8A8, prLV}, // Lo HANGUL SYLLABLE JWAE + {0xC8A9, 0xC8C3, prLVT}, // Lo [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH + {0xC8C4, 0xC8C4, prLV}, // Lo HANGUL SYLLABLE JOE + {0xC8C5, 0xC8DF, prLVT}, // Lo [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH + {0xC8E0, 0xC8E0, prLV}, // Lo HANGUL SYLLABLE JYO + {0xC8E1, 0xC8FB, prLVT}, // Lo [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH + {0xC8FC, 0xC8FC, prLV}, // Lo HANGUL SYLLABLE JU + {0xC8FD, 0xC917, prLVT}, // Lo [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH + {0xC918, 0xC918, prLV}, // Lo HANGUL SYLLABLE JWEO + {0xC919, 0xC933, prLVT}, // Lo [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH + {0xC934, 0xC934, prLV}, // Lo HANGUL SYLLABLE JWE + {0xC935, 0xC94F, prLVT}, // Lo [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH + {0xC950, 0xC950, prLV}, // Lo HANGUL SYLLABLE JWI + {0xC951, 0xC96B, prLVT}, // Lo [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH + {0xC96C, 0xC96C, prLV}, // Lo HANGUL SYLLABLE JYU + {0xC96D, 0xC987, prLVT}, // Lo [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH + {0xC988, 0xC988, prLV}, // Lo HANGUL SYLLABLE JEU + {0xC989, 0xC9A3, prLVT}, // Lo [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH + {0xC9A4, 0xC9A4, prLV}, // Lo HANGUL SYLLABLE JYI + {0xC9A5, 0xC9BF, prLVT}, // Lo [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH + {0xC9C0, 0xC9C0, prLV}, // Lo HANGUL SYLLABLE JI + {0xC9C1, 0xC9DB, prLVT}, // Lo [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH + {0xC9DC, 0xC9DC, prLV}, // Lo HANGUL SYLLABLE JJA + {0xC9DD, 0xC9F7, prLVT}, // Lo [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH + {0xC9F8, 0xC9F8, prLV}, // Lo HANGUL SYLLABLE JJAE + {0xC9F9, 0xCA13, prLVT}, // Lo [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH + {0xCA14, 0xCA14, prLV}, // Lo HANGUL SYLLABLE JJYA + {0xCA15, 0xCA2F, prLVT}, // Lo [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH + {0xCA30, 0xCA30, prLV}, // Lo HANGUL SYLLABLE JJYAE + {0xCA31, 0xCA4B, prLVT}, // Lo [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH + {0xCA4C, 0xCA4C, prLV}, // Lo HANGUL SYLLABLE JJEO + {0xCA4D, 0xCA67, prLVT}, // Lo [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH + {0xCA68, 0xCA68, prLV}, // Lo HANGUL SYLLABLE JJE + {0xCA69, 0xCA83, prLVT}, // Lo [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH + {0xCA84, 0xCA84, prLV}, // Lo HANGUL SYLLABLE JJYEO + {0xCA85, 0xCA9F, prLVT}, // Lo [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH + {0xCAA0, 0xCAA0, prLV}, // Lo HANGUL SYLLABLE JJYE + {0xCAA1, 0xCABB, prLVT}, // Lo [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH + {0xCABC, 0xCABC, prLV}, // Lo HANGUL SYLLABLE JJO + {0xCABD, 0xCAD7, prLVT}, // Lo [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH + {0xCAD8, 0xCAD8, prLV}, // Lo HANGUL SYLLABLE JJWA + {0xCAD9, 0xCAF3, prLVT}, // Lo [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH + {0xCAF4, 0xCAF4, prLV}, // Lo HANGUL SYLLABLE JJWAE + {0xCAF5, 0xCB0F, prLVT}, // Lo [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH + {0xCB10, 0xCB10, prLV}, // Lo HANGUL SYLLABLE JJOE + {0xCB11, 0xCB2B, prLVT}, // Lo [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH + {0xCB2C, 0xCB2C, prLV}, // Lo HANGUL SYLLABLE JJYO + {0xCB2D, 0xCB47, prLVT}, // Lo [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH + {0xCB48, 0xCB48, prLV}, // Lo HANGUL SYLLABLE JJU + {0xCB49, 0xCB63, prLVT}, // Lo [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH + {0xCB64, 0xCB64, prLV}, // Lo HANGUL SYLLABLE JJWEO + {0xCB65, 0xCB7F, prLVT}, // Lo [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH + {0xCB80, 0xCB80, prLV}, // Lo HANGUL SYLLABLE JJWE + {0xCB81, 0xCB9B, prLVT}, // Lo [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH + {0xCB9C, 0xCB9C, prLV}, // Lo HANGUL SYLLABLE JJWI + {0xCB9D, 0xCBB7, prLVT}, // Lo [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH + {0xCBB8, 0xCBB8, prLV}, // Lo HANGUL SYLLABLE JJYU + {0xCBB9, 0xCBD3, prLVT}, // Lo [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH + {0xCBD4, 0xCBD4, prLV}, // Lo HANGUL SYLLABLE JJEU + {0xCBD5, 0xCBEF, prLVT}, // Lo [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH + {0xCBF0, 0xCBF0, prLV}, // Lo HANGUL SYLLABLE JJYI + {0xCBF1, 0xCC0B, prLVT}, // Lo [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH + {0xCC0C, 0xCC0C, prLV}, // Lo HANGUL SYLLABLE JJI + {0xCC0D, 0xCC27, prLVT}, // Lo [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH + {0xCC28, 0xCC28, prLV}, // Lo HANGUL SYLLABLE CA + {0xCC29, 0xCC43, prLVT}, // Lo [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH + {0xCC44, 0xCC44, prLV}, // Lo HANGUL SYLLABLE CAE + {0xCC45, 0xCC5F, prLVT}, // Lo [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH + {0xCC60, 0xCC60, prLV}, // Lo HANGUL SYLLABLE CYA + {0xCC61, 0xCC7B, prLVT}, // Lo [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH + {0xCC7C, 0xCC7C, prLV}, // Lo HANGUL SYLLABLE CYAE + {0xCC7D, 0xCC97, prLVT}, // Lo [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH + {0xCC98, 0xCC98, prLV}, // Lo HANGUL SYLLABLE CEO + {0xCC99, 0xCCB3, prLVT}, // Lo [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH + {0xCCB4, 0xCCB4, prLV}, // Lo HANGUL SYLLABLE CE + {0xCCB5, 0xCCCF, prLVT}, // Lo [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH + {0xCCD0, 0xCCD0, prLV}, // Lo HANGUL SYLLABLE CYEO + {0xCCD1, 0xCCEB, prLVT}, // Lo [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH + {0xCCEC, 0xCCEC, prLV}, // Lo HANGUL SYLLABLE CYE + {0xCCED, 0xCD07, prLVT}, // Lo [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH + {0xCD08, 0xCD08, prLV}, // Lo HANGUL SYLLABLE CO + {0xCD09, 0xCD23, prLVT}, // Lo [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH + {0xCD24, 0xCD24, prLV}, // Lo HANGUL SYLLABLE CWA + {0xCD25, 0xCD3F, prLVT}, // Lo [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH + {0xCD40, 0xCD40, prLV}, // Lo HANGUL SYLLABLE CWAE + {0xCD41, 0xCD5B, prLVT}, // Lo [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH + {0xCD5C, 0xCD5C, prLV}, // Lo HANGUL SYLLABLE COE + {0xCD5D, 0xCD77, prLVT}, // Lo [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH + {0xCD78, 0xCD78, prLV}, // Lo HANGUL SYLLABLE CYO + {0xCD79, 0xCD93, prLVT}, // Lo [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH + {0xCD94, 0xCD94, prLV}, // Lo HANGUL SYLLABLE CU + {0xCD95, 0xCDAF, prLVT}, // Lo [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH + {0xCDB0, 0xCDB0, prLV}, // Lo HANGUL SYLLABLE CWEO + {0xCDB1, 0xCDCB, prLVT}, // Lo [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH + {0xCDCC, 0xCDCC, prLV}, // Lo HANGUL SYLLABLE CWE + {0xCDCD, 0xCDE7, prLVT}, // Lo [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH + {0xCDE8, 0xCDE8, prLV}, // Lo HANGUL SYLLABLE CWI + {0xCDE9, 0xCE03, prLVT}, // Lo [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH + {0xCE04, 0xCE04, prLV}, // Lo HANGUL SYLLABLE CYU + {0xCE05, 0xCE1F, prLVT}, // Lo [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH + {0xCE20, 0xCE20, prLV}, // Lo HANGUL SYLLABLE CEU + {0xCE21, 0xCE3B, prLVT}, // Lo [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH + {0xCE3C, 0xCE3C, prLV}, // Lo HANGUL SYLLABLE CYI + {0xCE3D, 0xCE57, prLVT}, // Lo [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH + {0xCE58, 0xCE58, prLV}, // Lo HANGUL SYLLABLE CI + {0xCE59, 0xCE73, prLVT}, // Lo [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH + {0xCE74, 0xCE74, prLV}, // Lo HANGUL SYLLABLE KA + {0xCE75, 0xCE8F, prLVT}, // Lo [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH + {0xCE90, 0xCE90, prLV}, // Lo HANGUL SYLLABLE KAE + {0xCE91, 0xCEAB, prLVT}, // Lo [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH + {0xCEAC, 0xCEAC, prLV}, // Lo HANGUL SYLLABLE KYA + {0xCEAD, 0xCEC7, prLVT}, // Lo [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH + {0xCEC8, 0xCEC8, prLV}, // Lo HANGUL SYLLABLE KYAE + {0xCEC9, 0xCEE3, prLVT}, // Lo [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH + {0xCEE4, 0xCEE4, prLV}, // Lo HANGUL SYLLABLE KEO + {0xCEE5, 0xCEFF, prLVT}, // Lo [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH + {0xCF00, 0xCF00, prLV}, // Lo HANGUL SYLLABLE KE + {0xCF01, 0xCF1B, prLVT}, // Lo [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH + {0xCF1C, 0xCF1C, prLV}, // Lo HANGUL SYLLABLE KYEO + {0xCF1D, 0xCF37, prLVT}, // Lo [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH + {0xCF38, 0xCF38, prLV}, // Lo HANGUL SYLLABLE KYE + {0xCF39, 0xCF53, prLVT}, // Lo [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH + {0xCF54, 0xCF54, prLV}, // Lo HANGUL SYLLABLE KO + {0xCF55, 0xCF6F, prLVT}, // Lo [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH + {0xCF70, 0xCF70, prLV}, // Lo HANGUL SYLLABLE KWA + {0xCF71, 0xCF8B, prLVT}, // Lo [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH + {0xCF8C, 0xCF8C, prLV}, // Lo HANGUL SYLLABLE KWAE + {0xCF8D, 0xCFA7, prLVT}, // Lo [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH + {0xCFA8, 0xCFA8, prLV}, // Lo HANGUL SYLLABLE KOE + {0xCFA9, 0xCFC3, prLVT}, // Lo [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH + {0xCFC4, 0xCFC4, prLV}, // Lo HANGUL SYLLABLE KYO + {0xCFC5, 0xCFDF, prLVT}, // Lo [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH + {0xCFE0, 0xCFE0, prLV}, // Lo HANGUL SYLLABLE KU + {0xCFE1, 0xCFFB, prLVT}, // Lo [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH + {0xCFFC, 0xCFFC, prLV}, // Lo HANGUL SYLLABLE KWEO + {0xCFFD, 0xD017, prLVT}, // Lo [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH + {0xD018, 0xD018, prLV}, // Lo HANGUL SYLLABLE KWE + {0xD019, 0xD033, prLVT}, // Lo [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH + {0xD034, 0xD034, prLV}, // Lo HANGUL SYLLABLE KWI + {0xD035, 0xD04F, prLVT}, // Lo [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH + {0xD050, 0xD050, prLV}, // Lo HANGUL SYLLABLE KYU + {0xD051, 0xD06B, prLVT}, // Lo [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH + {0xD06C, 0xD06C, prLV}, // Lo HANGUL SYLLABLE KEU + {0xD06D, 0xD087, prLVT}, // Lo [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH + {0xD088, 0xD088, prLV}, // Lo HANGUL SYLLABLE KYI + {0xD089, 0xD0A3, prLVT}, // Lo [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH + {0xD0A4, 0xD0A4, prLV}, // Lo HANGUL SYLLABLE KI + {0xD0A5, 0xD0BF, prLVT}, // Lo [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH + {0xD0C0, 0xD0C0, prLV}, // Lo HANGUL SYLLABLE TA + {0xD0C1, 0xD0DB, prLVT}, // Lo [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH + {0xD0DC, 0xD0DC, prLV}, // Lo HANGUL SYLLABLE TAE + {0xD0DD, 0xD0F7, prLVT}, // Lo [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH + {0xD0F8, 0xD0F8, prLV}, // Lo HANGUL SYLLABLE TYA + {0xD0F9, 0xD113, prLVT}, // Lo [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH + {0xD114, 0xD114, prLV}, // Lo HANGUL SYLLABLE TYAE + {0xD115, 0xD12F, prLVT}, // Lo [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH + {0xD130, 0xD130, prLV}, // Lo HANGUL SYLLABLE TEO + {0xD131, 0xD14B, prLVT}, // Lo [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH + {0xD14C, 0xD14C, prLV}, // Lo HANGUL SYLLABLE TE + {0xD14D, 0xD167, prLVT}, // Lo [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH + {0xD168, 0xD168, prLV}, // Lo HANGUL SYLLABLE TYEO + {0xD169, 0xD183, prLVT}, // Lo [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH + {0xD184, 0xD184, prLV}, // Lo HANGUL SYLLABLE TYE + {0xD185, 0xD19F, prLVT}, // Lo [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH + {0xD1A0, 0xD1A0, prLV}, // Lo HANGUL SYLLABLE TO + {0xD1A1, 0xD1BB, prLVT}, // Lo [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH + {0xD1BC, 0xD1BC, prLV}, // Lo HANGUL SYLLABLE TWA + {0xD1BD, 0xD1D7, prLVT}, // Lo [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH + {0xD1D8, 0xD1D8, prLV}, // Lo HANGUL SYLLABLE TWAE + {0xD1D9, 0xD1F3, prLVT}, // Lo [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH + {0xD1F4, 0xD1F4, prLV}, // Lo HANGUL SYLLABLE TOE + {0xD1F5, 0xD20F, prLVT}, // Lo [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH + {0xD210, 0xD210, prLV}, // Lo HANGUL SYLLABLE TYO + {0xD211, 0xD22B, prLVT}, // Lo [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH + {0xD22C, 0xD22C, prLV}, // Lo HANGUL SYLLABLE TU + {0xD22D, 0xD247, prLVT}, // Lo [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH + {0xD248, 0xD248, prLV}, // Lo HANGUL SYLLABLE TWEO + {0xD249, 0xD263, prLVT}, // Lo [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH + {0xD264, 0xD264, prLV}, // Lo HANGUL SYLLABLE TWE + {0xD265, 0xD27F, prLVT}, // Lo [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH + {0xD280, 0xD280, prLV}, // Lo HANGUL SYLLABLE TWI + {0xD281, 0xD29B, prLVT}, // Lo [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH + {0xD29C, 0xD29C, prLV}, // Lo HANGUL SYLLABLE TYU + {0xD29D, 0xD2B7, prLVT}, // Lo [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH + {0xD2B8, 0xD2B8, prLV}, // Lo HANGUL SYLLABLE TEU + {0xD2B9, 0xD2D3, prLVT}, // Lo [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH + {0xD2D4, 0xD2D4, prLV}, // Lo HANGUL SYLLABLE TYI + {0xD2D5, 0xD2EF, prLVT}, // Lo [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH + {0xD2F0, 0xD2F0, prLV}, // Lo HANGUL SYLLABLE TI + {0xD2F1, 0xD30B, prLVT}, // Lo [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH + {0xD30C, 0xD30C, prLV}, // Lo HANGUL SYLLABLE PA + {0xD30D, 0xD327, prLVT}, // Lo [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH + {0xD328, 0xD328, prLV}, // Lo HANGUL SYLLABLE PAE + {0xD329, 0xD343, prLVT}, // Lo [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH + {0xD344, 0xD344, prLV}, // Lo HANGUL SYLLABLE PYA + {0xD345, 0xD35F, prLVT}, // Lo [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH + {0xD360, 0xD360, prLV}, // Lo HANGUL SYLLABLE PYAE + {0xD361, 0xD37B, prLVT}, // Lo [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH + {0xD37C, 0xD37C, prLV}, // Lo HANGUL SYLLABLE PEO + {0xD37D, 0xD397, prLVT}, // Lo [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH + {0xD398, 0xD398, prLV}, // Lo HANGUL SYLLABLE PE + {0xD399, 0xD3B3, prLVT}, // Lo [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH + {0xD3B4, 0xD3B4, prLV}, // Lo HANGUL SYLLABLE PYEO + {0xD3B5, 0xD3CF, prLVT}, // Lo [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH + {0xD3D0, 0xD3D0, prLV}, // Lo HANGUL SYLLABLE PYE + {0xD3D1, 0xD3EB, prLVT}, // Lo [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH + {0xD3EC, 0xD3EC, prLV}, // Lo HANGUL SYLLABLE PO + {0xD3ED, 0xD407, prLVT}, // Lo [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH + {0xD408, 0xD408, prLV}, // Lo HANGUL SYLLABLE PWA + {0xD409, 0xD423, prLVT}, // Lo [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH + {0xD424, 0xD424, prLV}, // Lo HANGUL SYLLABLE PWAE + {0xD425, 0xD43F, prLVT}, // Lo [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH + {0xD440, 0xD440, prLV}, // Lo HANGUL SYLLABLE POE + {0xD441, 0xD45B, prLVT}, // Lo [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH + {0xD45C, 0xD45C, prLV}, // Lo HANGUL SYLLABLE PYO + {0xD45D, 0xD477, prLVT}, // Lo [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH + {0xD478, 0xD478, prLV}, // Lo HANGUL SYLLABLE PU + {0xD479, 0xD493, prLVT}, // Lo [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH + {0xD494, 0xD494, prLV}, // Lo HANGUL SYLLABLE PWEO + {0xD495, 0xD4AF, prLVT}, // Lo [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH + {0xD4B0, 0xD4B0, prLV}, // Lo HANGUL SYLLABLE PWE + {0xD4B1, 0xD4CB, prLVT}, // Lo [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH + {0xD4CC, 0xD4CC, prLV}, // Lo HANGUL SYLLABLE PWI + {0xD4CD, 0xD4E7, prLVT}, // Lo [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH + {0xD4E8, 0xD4E8, prLV}, // Lo HANGUL SYLLABLE PYU + {0xD4E9, 0xD503, prLVT}, // Lo [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH + {0xD504, 0xD504, prLV}, // Lo HANGUL SYLLABLE PEU + {0xD505, 0xD51F, prLVT}, // Lo [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH + {0xD520, 0xD520, prLV}, // Lo HANGUL SYLLABLE PYI + {0xD521, 0xD53B, prLVT}, // Lo [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH + {0xD53C, 0xD53C, prLV}, // Lo HANGUL SYLLABLE PI + {0xD53D, 0xD557, prLVT}, // Lo [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH + {0xD558, 0xD558, prLV}, // Lo HANGUL SYLLABLE HA + {0xD559, 0xD573, prLVT}, // Lo [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH + {0xD574, 0xD574, prLV}, // Lo HANGUL SYLLABLE HAE + {0xD575, 0xD58F, prLVT}, // Lo [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH + {0xD590, 0xD590, prLV}, // Lo HANGUL SYLLABLE HYA + {0xD591, 0xD5AB, prLVT}, // Lo [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH + {0xD5AC, 0xD5AC, prLV}, // Lo HANGUL SYLLABLE HYAE + {0xD5AD, 0xD5C7, prLVT}, // Lo [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH + {0xD5C8, 0xD5C8, prLV}, // Lo HANGUL SYLLABLE HEO + {0xD5C9, 0xD5E3, prLVT}, // Lo [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH + {0xD5E4, 0xD5E4, prLV}, // Lo HANGUL SYLLABLE HE + {0xD5E5, 0xD5FF, prLVT}, // Lo [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH + {0xD600, 0xD600, prLV}, // Lo HANGUL SYLLABLE HYEO + {0xD601, 0xD61B, prLVT}, // Lo [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH + {0xD61C, 0xD61C, prLV}, // Lo HANGUL SYLLABLE HYE + {0xD61D, 0xD637, prLVT}, // Lo [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH + {0xD638, 0xD638, prLV}, // Lo HANGUL SYLLABLE HO + {0xD639, 0xD653, prLVT}, // Lo [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH + {0xD654, 0xD654, prLV}, // Lo HANGUL SYLLABLE HWA + {0xD655, 0xD66F, prLVT}, // Lo [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH + {0xD670, 0xD670, prLV}, // Lo HANGUL SYLLABLE HWAE + {0xD671, 0xD68B, prLVT}, // Lo [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH + {0xD68C, 0xD68C, prLV}, // Lo HANGUL SYLLABLE HOE + {0xD68D, 0xD6A7, prLVT}, // Lo [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH + {0xD6A8, 0xD6A8, prLV}, // Lo HANGUL SYLLABLE HYO + {0xD6A9, 0xD6C3, prLVT}, // Lo [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH + {0xD6C4, 0xD6C4, prLV}, // Lo HANGUL SYLLABLE HU + {0xD6C5, 0xD6DF, prLVT}, // Lo [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH + {0xD6E0, 0xD6E0, prLV}, // Lo HANGUL SYLLABLE HWEO + {0xD6E1, 0xD6FB, prLVT}, // Lo [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH + {0xD6FC, 0xD6FC, prLV}, // Lo HANGUL SYLLABLE HWE + {0xD6FD, 0xD717, prLVT}, // Lo [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH + {0xD718, 0xD718, prLV}, // Lo HANGUL SYLLABLE HWI + {0xD719, 0xD733, prLVT}, // Lo [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH + {0xD734, 0xD734, prLV}, // Lo HANGUL SYLLABLE HYU + {0xD735, 0xD74F, prLVT}, // Lo [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH + {0xD750, 0xD750, prLV}, // Lo HANGUL SYLLABLE HEU + {0xD751, 0xD76B, prLVT}, // Lo [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH + {0xD76C, 0xD76C, prLV}, // Lo HANGUL SYLLABLE HYI + {0xD76D, 0xD787, prLVT}, // Lo [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH + {0xD788, 0xD788, prLV}, // Lo HANGUL SYLLABLE HI + {0xD789, 0xD7A3, prLVT}, // Lo [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prV}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prT}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xFB1E, 0xFB1E, prExtend}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA + {0xFE00, 0xFE0F, prExtend}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE20, 0xFE2F, prExtend}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFEFF, 0xFEFF, prControl}, // Cf ZERO WIDTH NO-BREAK SPACE + {0xFF9E, 0xFF9F, prExtend}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFF0, 0xFFF8, prControl}, // Cn [9] .. + {0xFFF9, 0xFFFB, prControl}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0x101FD, 0x101FD, prExtend}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x102E0, 0x102E0, prExtend}, // Mn COPTIC EPACT THOUSANDS MARK + {0x10376, 0x1037A, prExtend}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10A01, 0x10A03, prExtend}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prExtend}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prExtend}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A38, 0x10A3A, prExtend}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prExtend}, // Mn KHAROSHTHI VIRAMA + {0x10AE5, 0x10AE6, prExtend}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10D24, 0x10D27, prExtend}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10EAB, 0x10EAC, prExtend}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EFD, 0x10EFF, prExtend}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F46, 0x10F50, prExtend}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F82, 0x10F85, prExtend}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x11000, 0x11000, prSpacingMark}, // Mc BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prExtend}, // Mn BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prSpacingMark}, // Mc BRAHMI SIGN VISARGA + {0x11038, 0x11046, prExtend}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11070, 0x11070, prExtend}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA + {0x11073, 0x11074, prExtend}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x1107F, 0x11081, prExtend}, // Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prSpacingMark}, // Mc KAITHI SIGN VISARGA + {0x110B0, 0x110B2, prSpacingMark}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prExtend}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prSpacingMark}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prExtend}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BD, 0x110BD, prPrepend}, // Cf KAITHI NUMBER SIGN + {0x110C2, 0x110C2, prExtend}, // Mn KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prPrepend}, // Cf KAITHI NUMBER SIGN ABOVE + {0x11100, 0x11102, prExtend}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11127, 0x1112B, prExtend}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prSpacingMark}, // Mc CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prExtend}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11145, 0x11146, prSpacingMark}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11173, 0x11173, prExtend}, // Mn MAHAJANI SIGN NUKTA + {0x11180, 0x11181, prExtend}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prSpacingMark}, // Mc SHARADA SIGN VISARGA + {0x111B3, 0x111B5, prSpacingMark}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prExtend}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prSpacingMark}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C2, 0x111C3, prPrepend}, // Lo [2] SHARADA SIGN JIHVAMULIYA..SHARADA SIGN UPADHMANIYA + {0x111C9, 0x111CC, prExtend}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CE, 0x111CE, prSpacingMark}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prExtend}, // Mn SHARADA SIGN INVERTED CANDRABINDU + {0x1122C, 0x1122E, prSpacingMark}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prExtend}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prSpacingMark}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prExtend}, // Mn KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prSpacingMark}, // Mc KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prExtend}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x1123E, 0x1123E, prExtend}, // Mn KHOJKI SIGN SUKUN + {0x11241, 0x11241, prExtend}, // Mn KHOJKI VOWEL SIGN VOCALIC R + {0x112DF, 0x112DF, prExtend}, // Mn KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prSpacingMark}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prExtend}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x11300, 0x11301, prExtend}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prSpacingMark}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x1133B, 0x1133C, prExtend}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133E, 0x1133E, prExtend}, // Mc GRANTHA VOWEL SIGN AA + {0x1133F, 0x1133F, prSpacingMark}, // Mc GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prExtend}, // Mn GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prSpacingMark}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prSpacingMark}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prSpacingMark}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11357, 0x11357, prExtend}, // Mc GRANTHA AU LENGTH MARK + {0x11362, 0x11363, prSpacingMark}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prExtend}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prExtend}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11435, 0x11437, prSpacingMark}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prExtend}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prSpacingMark}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prExtend}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prSpacingMark}, // Mc NEWA SIGN VISARGA + {0x11446, 0x11446, prExtend}, // Mn NEWA SIGN NUKTA + {0x1145E, 0x1145E, prExtend}, // Mn NEWA SANDHI MARK + {0x114B0, 0x114B0, prExtend}, // Mc TIRHUTA VOWEL SIGN AA + {0x114B1, 0x114B2, prSpacingMark}, // Mc [2] TIRHUTA VOWEL SIGN I..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prExtend}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prSpacingMark}, // Mc TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prExtend}, // Mn TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BC, prSpacingMark}, // Mc [2] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN O + {0x114BD, 0x114BD, prExtend}, // Mc TIRHUTA VOWEL SIGN SHORT O + {0x114BE, 0x114BE, prSpacingMark}, // Mc TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prExtend}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prSpacingMark}, // Mc TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prExtend}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x115AF, 0x115AF, prExtend}, // Mc SIDDHAM VOWEL SIGN AA + {0x115B0, 0x115B1, prSpacingMark}, // Mc [2] SIDDHAM VOWEL SIGN I..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prExtend}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prSpacingMark}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prExtend}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prSpacingMark}, // Mc SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prExtend}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115DC, 0x115DD, prExtend}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11630, 0x11632, prSpacingMark}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prExtend}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prSpacingMark}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prExtend}, // Mn MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prSpacingMark}, // Mc MODI SIGN VISARGA + {0x1163F, 0x11640, prExtend}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x116AB, 0x116AB, prExtend}, // Mn TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prSpacingMark}, // Mc TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prExtend}, // Mn TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prSpacingMark}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prExtend}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prSpacingMark}, // Mc TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prExtend}, // Mn TAKRI SIGN NUKTA + {0x1171D, 0x1171F, prExtend}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11722, 0x11725, prExtend}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prSpacingMark}, // Mc AHOM VOWEL SIGN E + {0x11727, 0x1172B, prExtend}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x1182C, 0x1182E, prSpacingMark}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prExtend}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prSpacingMark}, // Mc DOGRA SIGN VISARGA + {0x11839, 0x1183A, prExtend}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x11930, 0x11930, prExtend}, // Mc DIVES AKURU VOWEL SIGN AA + {0x11931, 0x11935, prSpacingMark}, // Mc [5] DIVES AKURU VOWEL SIGN I..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prSpacingMark}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prExtend}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prSpacingMark}, // Mc DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prExtend}, // Mn DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prPrepend}, // Lo DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prSpacingMark}, // Mc DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prPrepend}, // Lo DIVES AKURU INITIAL RA + {0x11942, 0x11942, prSpacingMark}, // Mc DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prExtend}, // Mn DIVES AKURU SIGN NUKTA + {0x119D1, 0x119D3, prSpacingMark}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prExtend}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prExtend}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prSpacingMark}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prExtend}, // Mn NANDINAGARI SIGN VIRAMA + {0x119E4, 0x119E4, prSpacingMark}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A01, 0x11A0A, prExtend}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A33, 0x11A38, prExtend}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prSpacingMark}, // Mc ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prPrepend}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prExtend}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A47, 0x11A47, prExtend}, // Mn ZANABAZAR SQUARE SUBJOINER + {0x11A51, 0x11A56, prExtend}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prSpacingMark}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prExtend}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A84, 0x11A89, prPrepend}, // Lo [6] SOYOMBO SIGN JIHVAMULIYA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prExtend}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prSpacingMark}, // Mc SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prExtend}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11C2F, 0x11C2F, prSpacingMark}, // Mc BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prExtend}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prExtend}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prSpacingMark}, // Mc BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prExtend}, // Mn BHAIKSUKI SIGN VIRAMA + {0x11C92, 0x11CA7, prExtend}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prSpacingMark}, // Mc MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prExtend}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prSpacingMark}, // Mc MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prExtend}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prSpacingMark}, // Mc MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prExtend}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D31, 0x11D36, prExtend}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prExtend}, // Mn MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prExtend}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prExtend}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prPrepend}, // Lo MASARAM GONDI REPHA + {0x11D47, 0x11D47, prExtend}, // Mn MASARAM GONDI RA-KARA + {0x11D8A, 0x11D8E, prSpacingMark}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prExtend}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prSpacingMark}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prExtend}, // Mn GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prSpacingMark}, // Mc GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prExtend}, // Mn GUNJALA GONDI VIRAMA + {0x11EF3, 0x11EF4, prExtend}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prSpacingMark}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11F00, 0x11F01, prExtend}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prPrepend}, // Lo KAWI SIGN REPHA + {0x11F03, 0x11F03, prSpacingMark}, // Mc KAWI SIGN VISARGA + {0x11F34, 0x11F35, prSpacingMark}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prExtend}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prSpacingMark}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prExtend}, // Mn KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prSpacingMark}, // Mc KAWI SIGN KILLER + {0x11F42, 0x11F42, prExtend}, // Mn KAWI CONJOINER + {0x13430, 0x1343F, prControl}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prExtend}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13447, 0x13455, prExtend}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x16AF0, 0x16AF4, prExtend}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16B30, 0x16B36, prExtend}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16F4F, 0x16F4F, prExtend}, // Mn MIAO SIGN CONSONANT MODIFIER BAR + {0x16F51, 0x16F87, prSpacingMark}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prExtend}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16FE4, 0x16FE4, prExtend}, // Mn KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prSpacingMark}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x1BC9D, 0x1BC9E, prExtend}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BCA0, 0x1BCA3, prControl}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prExtend}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prExtend}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1D165, 0x1D165, prExtend}, // Mc MUSICAL SYMBOL COMBINING STEM + {0x1D166, 0x1D166, prSpacingMark}, // Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prExtend}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16D, 0x1D16D, prSpacingMark}, // Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT + {0x1D16E, 0x1D172, prExtend}, // Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prControl}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prExtend}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D185, 0x1D18B, prExtend}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D1AA, 0x1D1AD, prExtend}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D242, 0x1D244, prExtend}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1DA00, 0x1DA36, prExtend}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA3B, 0x1DA6C, prExtend}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA75, 0x1DA75, prExtend}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA84, 0x1DA84, prExtend}, // Mn SIGNWRITING LOCATION HEAD NECK + {0x1DA9B, 0x1DA9F, prExtend}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prExtend}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1E000, 0x1E006, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prExtend}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prExtend}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prExtend}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E08F, 0x1E08F, prExtend}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E130, 0x1E136, prExtend}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E2AE, 0x1E2AE, prExtend}, // Mn TOTO SIGN RISING TONE + {0x1E2EC, 0x1E2EF, prExtend}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E4EC, 0x1E4EF, prExtend}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E8D0, 0x1E8D6, prExtend}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E944, 0x1E94A, prExtend}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1F000, 0x1F003, prExtendedPictographic}, // E0.0 [4] (🀀..🀃) MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND + {0x1F004, 0x1F004, prExtendedPictographic}, // E0.6 [1] (🀄) mahjong red dragon + {0x1F005, 0x1F0CE, prExtendedPictographic}, // E0.0 [202] (🀅..🃎) MAHJONG TILE GREEN DRAGON..PLAYING CARD KING OF DIAMONDS + {0x1F0CF, 0x1F0CF, prExtendedPictographic}, // E0.6 [1] (🃏) joker + {0x1F0D0, 0x1F0FF, prExtendedPictographic}, // E0.0 [48] (🃐..🃿) .. + {0x1F10D, 0x1F10F, prExtendedPictographic}, // E0.0 [3] (🄍..🄏) CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH + {0x1F12F, 0x1F12F, prExtendedPictographic}, // E0.0 [1] (🄯) COPYLEFT SYMBOL + {0x1F16C, 0x1F16F, prExtendedPictographic}, // E0.0 [4] (🅬..🅯) RAISED MR SIGN..CIRCLED HUMAN FIGURE + {0x1F170, 0x1F171, prExtendedPictographic}, // E0.6 [2] (🅰️..🅱️) A button (blood type)..B button (blood type) + {0x1F17E, 0x1F17F, prExtendedPictographic}, // E0.6 [2] (🅾️..🅿️) O button (blood type)..P button + {0x1F18E, 0x1F18E, prExtendedPictographic}, // E0.6 [1] (🆎) AB button (blood type) + {0x1F191, 0x1F19A, prExtendedPictographic}, // E0.6 [10] (🆑..🆚) CL button..VS button + {0x1F1AD, 0x1F1E5, prExtendedPictographic}, // E0.0 [57] (🆭..🇥) MASK WORK SYMBOL.. + {0x1F1E6, 0x1F1FF, prRegionalIndicator}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z + {0x1F201, 0x1F202, prExtendedPictographic}, // E0.6 [2] (🈁..🈂️) Japanese “here” button..Japanese “service charge” button + {0x1F203, 0x1F20F, prExtendedPictographic}, // E0.0 [13] (🈃..🈏) .. + {0x1F21A, 0x1F21A, prExtendedPictographic}, // E0.6 [1] (🈚) Japanese “free of charge” button + {0x1F22F, 0x1F22F, prExtendedPictographic}, // E0.6 [1] (🈯) Japanese “reserved” button + {0x1F232, 0x1F23A, prExtendedPictographic}, // E0.6 [9] (🈲..🈺) Japanese “prohibited” button..Japanese “open for business” button + {0x1F23C, 0x1F23F, prExtendedPictographic}, // E0.0 [4] (🈼..🈿) .. + {0x1F249, 0x1F24F, prExtendedPictographic}, // E0.0 [7] (🉉..🉏) .. + {0x1F250, 0x1F251, prExtendedPictographic}, // E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button + {0x1F252, 0x1F2FF, prExtendedPictographic}, // E0.0 [174] (🉒..🋿) .. + {0x1F300, 0x1F30C, prExtendedPictographic}, // E0.6 [13] (🌀..🌌) cyclone..milky way + {0x1F30D, 0x1F30E, prExtendedPictographic}, // E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas + {0x1F30F, 0x1F30F, prExtendedPictographic}, // E0.6 [1] (🌏) globe showing Asia-Australia + {0x1F310, 0x1F310, prExtendedPictographic}, // E1.0 [1] (🌐) globe with meridians + {0x1F311, 0x1F311, prExtendedPictographic}, // E0.6 [1] (🌑) new moon + {0x1F312, 0x1F312, prExtendedPictographic}, // E1.0 [1] (🌒) waxing crescent moon + {0x1F313, 0x1F315, prExtendedPictographic}, // E0.6 [3] (🌓..🌕) first quarter moon..full moon + {0x1F316, 0x1F318, prExtendedPictographic}, // E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon + {0x1F319, 0x1F319, prExtendedPictographic}, // E0.6 [1] (🌙) crescent moon + {0x1F31A, 0x1F31A, prExtendedPictographic}, // E1.0 [1] (🌚) new moon face + {0x1F31B, 0x1F31B, prExtendedPictographic}, // E0.6 [1] (🌛) first quarter moon face + {0x1F31C, 0x1F31C, prExtendedPictographic}, // E0.7 [1] (🌜) last quarter moon face + {0x1F31D, 0x1F31E, prExtendedPictographic}, // E1.0 [2] (🌝..🌞) full moon face..sun with face + {0x1F31F, 0x1F320, prExtendedPictographic}, // E0.6 [2] (🌟..🌠) glowing star..shooting star + {0x1F321, 0x1F321, prExtendedPictographic}, // E0.7 [1] (🌡️) thermometer + {0x1F322, 0x1F323, prExtendedPictographic}, // E0.0 [2] (🌢..🌣) BLACK DROPLET..WHITE SUN + {0x1F324, 0x1F32C, prExtendedPictographic}, // E0.7 [9] (🌤️..🌬️) sun behind small cloud..wind face + {0x1F32D, 0x1F32F, prExtendedPictographic}, // E1.0 [3] (🌭..🌯) hot dog..burrito + {0x1F330, 0x1F331, prExtendedPictographic}, // E0.6 [2] (🌰..🌱) chestnut..seedling + {0x1F332, 0x1F333, prExtendedPictographic}, // E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree + {0x1F334, 0x1F335, prExtendedPictographic}, // E0.6 [2] (🌴..🌵) palm tree..cactus + {0x1F336, 0x1F336, prExtendedPictographic}, // E0.7 [1] (🌶️) hot pepper + {0x1F337, 0x1F34A, prExtendedPictographic}, // E0.6 [20] (🌷..🍊) tulip..tangerine + {0x1F34B, 0x1F34B, prExtendedPictographic}, // E1.0 [1] (🍋) lemon + {0x1F34C, 0x1F34F, prExtendedPictographic}, // E0.6 [4] (🍌..🍏) banana..green apple + {0x1F350, 0x1F350, prExtendedPictographic}, // E1.0 [1] (🍐) pear + {0x1F351, 0x1F37B, prExtendedPictographic}, // E0.6 [43] (🍑..🍻) peach..clinking beer mugs + {0x1F37C, 0x1F37C, prExtendedPictographic}, // E1.0 [1] (🍼) baby bottle + {0x1F37D, 0x1F37D, prExtendedPictographic}, // E0.7 [1] (🍽️) fork and knife with plate + {0x1F37E, 0x1F37F, prExtendedPictographic}, // E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn + {0x1F380, 0x1F393, prExtendedPictographic}, // E0.6 [20] (🎀..🎓) ribbon..graduation cap + {0x1F394, 0x1F395, prExtendedPictographic}, // E0.0 [2] (🎔..🎕) HEART WITH TIP ON THE LEFT..BOUQUET OF FLOWERS + {0x1F396, 0x1F397, prExtendedPictographic}, // E0.7 [2] (🎖️..🎗️) military medal..reminder ribbon + {0x1F398, 0x1F398, prExtendedPictographic}, // E0.0 [1] (🎘) MUSICAL KEYBOARD WITH JACKS + {0x1F399, 0x1F39B, prExtendedPictographic}, // E0.7 [3] (🎙️..🎛️) studio microphone..control knobs + {0x1F39C, 0x1F39D, prExtendedPictographic}, // E0.0 [2] (🎜..🎝) BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES + {0x1F39E, 0x1F39F, prExtendedPictographic}, // E0.7 [2] (🎞️..🎟️) film frames..admission tickets + {0x1F3A0, 0x1F3C4, prExtendedPictographic}, // E0.6 [37] (🎠..🏄) carousel horse..person surfing + {0x1F3C5, 0x1F3C5, prExtendedPictographic}, // E1.0 [1] (🏅) sports medal + {0x1F3C6, 0x1F3C6, prExtendedPictographic}, // E0.6 [1] (🏆) trophy + {0x1F3C7, 0x1F3C7, prExtendedPictographic}, // E1.0 [1] (🏇) horse racing + {0x1F3C8, 0x1F3C8, prExtendedPictographic}, // E0.6 [1] (🏈) american football + {0x1F3C9, 0x1F3C9, prExtendedPictographic}, // E1.0 [1] (🏉) rugby football + {0x1F3CA, 0x1F3CA, prExtendedPictographic}, // E0.6 [1] (🏊) person swimming + {0x1F3CB, 0x1F3CE, prExtendedPictographic}, // E0.7 [4] (🏋️..🏎️) person lifting weights..racing car + {0x1F3CF, 0x1F3D3, prExtendedPictographic}, // E1.0 [5] (🏏..🏓) cricket game..ping pong + {0x1F3D4, 0x1F3DF, prExtendedPictographic}, // E0.7 [12] (🏔️..🏟️) snow-capped mountain..stadium + {0x1F3E0, 0x1F3E3, prExtendedPictographic}, // E0.6 [4] (🏠..🏣) house..Japanese post office + {0x1F3E4, 0x1F3E4, prExtendedPictographic}, // E1.0 [1] (🏤) post office + {0x1F3E5, 0x1F3F0, prExtendedPictographic}, // E0.6 [12] (🏥..🏰) hospital..castle + {0x1F3F1, 0x1F3F2, prExtendedPictographic}, // E0.0 [2] (🏱..🏲) WHITE PENNANT..BLACK PENNANT + {0x1F3F3, 0x1F3F3, prExtendedPictographic}, // E0.7 [1] (🏳️) white flag + {0x1F3F4, 0x1F3F4, prExtendedPictographic}, // E1.0 [1] (🏴) black flag + {0x1F3F5, 0x1F3F5, prExtendedPictographic}, // E0.7 [1] (🏵️) rosette + {0x1F3F6, 0x1F3F6, prExtendedPictographic}, // E0.0 [1] (🏶) BLACK ROSETTE + {0x1F3F7, 0x1F3F7, prExtendedPictographic}, // E0.7 [1] (🏷️) label + {0x1F3F8, 0x1F3FA, prExtendedPictographic}, // E1.0 [3] (🏸..🏺) badminton..amphora + {0x1F3FB, 0x1F3FF, prExtend}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + {0x1F400, 0x1F407, prExtendedPictographic}, // E1.0 [8] (🐀..🐇) rat..rabbit + {0x1F408, 0x1F408, prExtendedPictographic}, // E0.7 [1] (🐈) cat + {0x1F409, 0x1F40B, prExtendedPictographic}, // E1.0 [3] (🐉..🐋) dragon..whale + {0x1F40C, 0x1F40E, prExtendedPictographic}, // E0.6 [3] (🐌..🐎) snail..horse + {0x1F40F, 0x1F410, prExtendedPictographic}, // E1.0 [2] (🐏..🐐) ram..goat + {0x1F411, 0x1F412, prExtendedPictographic}, // E0.6 [2] (🐑..🐒) ewe..monkey + {0x1F413, 0x1F413, prExtendedPictographic}, // E1.0 [1] (🐓) rooster + {0x1F414, 0x1F414, prExtendedPictographic}, // E0.6 [1] (🐔) chicken + {0x1F415, 0x1F415, prExtendedPictographic}, // E0.7 [1] (🐕) dog + {0x1F416, 0x1F416, prExtendedPictographic}, // E1.0 [1] (🐖) pig + {0x1F417, 0x1F429, prExtendedPictographic}, // E0.6 [19] (🐗..🐩) boar..poodle + {0x1F42A, 0x1F42A, prExtendedPictographic}, // E1.0 [1] (🐪) camel + {0x1F42B, 0x1F43E, prExtendedPictographic}, // E0.6 [20] (🐫..🐾) two-hump camel..paw prints + {0x1F43F, 0x1F43F, prExtendedPictographic}, // E0.7 [1] (🐿️) chipmunk + {0x1F440, 0x1F440, prExtendedPictographic}, // E0.6 [1] (👀) eyes + {0x1F441, 0x1F441, prExtendedPictographic}, // E0.7 [1] (👁️) eye + {0x1F442, 0x1F464, prExtendedPictographic}, // E0.6 [35] (👂..👤) ear..bust in silhouette + {0x1F465, 0x1F465, prExtendedPictographic}, // E1.0 [1] (👥) busts in silhouette + {0x1F466, 0x1F46B, prExtendedPictographic}, // E0.6 [6] (👦..👫) boy..woman and man holding hands + {0x1F46C, 0x1F46D, prExtendedPictographic}, // E1.0 [2] (👬..👭) men holding hands..women holding hands + {0x1F46E, 0x1F4AC, prExtendedPictographic}, // E0.6 [63] (👮..💬) police officer..speech balloon + {0x1F4AD, 0x1F4AD, prExtendedPictographic}, // E1.0 [1] (💭) thought balloon + {0x1F4AE, 0x1F4B5, prExtendedPictographic}, // E0.6 [8] (💮..💵) white flower..dollar banknote + {0x1F4B6, 0x1F4B7, prExtendedPictographic}, // E1.0 [2] (💶..💷) euro banknote..pound banknote + {0x1F4B8, 0x1F4EB, prExtendedPictographic}, // E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag + {0x1F4EC, 0x1F4ED, prExtendedPictographic}, // E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag + {0x1F4EE, 0x1F4EE, prExtendedPictographic}, // E0.6 [1] (📮) postbox + {0x1F4EF, 0x1F4EF, prExtendedPictographic}, // E1.0 [1] (📯) postal horn + {0x1F4F0, 0x1F4F4, prExtendedPictographic}, // E0.6 [5] (📰..📴) newspaper..mobile phone off + {0x1F4F5, 0x1F4F5, prExtendedPictographic}, // E1.0 [1] (📵) no mobile phones + {0x1F4F6, 0x1F4F7, prExtendedPictographic}, // E0.6 [2] (📶..📷) antenna bars..camera + {0x1F4F8, 0x1F4F8, prExtendedPictographic}, // E1.0 [1] (📸) camera with flash + {0x1F4F9, 0x1F4FC, prExtendedPictographic}, // E0.6 [4] (📹..📼) video camera..videocassette + {0x1F4FD, 0x1F4FD, prExtendedPictographic}, // E0.7 [1] (📽️) film projector + {0x1F4FE, 0x1F4FE, prExtendedPictographic}, // E0.0 [1] (📾) PORTABLE STEREO + {0x1F4FF, 0x1F502, prExtendedPictographic}, // E1.0 [4] (📿..🔂) prayer beads..repeat single button + {0x1F503, 0x1F503, prExtendedPictographic}, // E0.6 [1] (🔃) clockwise vertical arrows + {0x1F504, 0x1F507, prExtendedPictographic}, // E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker + {0x1F508, 0x1F508, prExtendedPictographic}, // E0.7 [1] (🔈) speaker low volume + {0x1F509, 0x1F509, prExtendedPictographic}, // E1.0 [1] (🔉) speaker medium volume + {0x1F50A, 0x1F514, prExtendedPictographic}, // E0.6 [11] (🔊..🔔) speaker high volume..bell + {0x1F515, 0x1F515, prExtendedPictographic}, // E1.0 [1] (🔕) bell with slash + {0x1F516, 0x1F52B, prExtendedPictographic}, // E0.6 [22] (🔖..🔫) bookmark..water pistol + {0x1F52C, 0x1F52D, prExtendedPictographic}, // E1.0 [2] (🔬..🔭) microscope..telescope + {0x1F52E, 0x1F53D, prExtendedPictographic}, // E0.6 [16] (🔮..🔽) crystal ball..downwards button + {0x1F546, 0x1F548, prExtendedPictographic}, // E0.0 [3] (🕆..🕈) WHITE LATIN CROSS..CELTIC CROSS + {0x1F549, 0x1F54A, prExtendedPictographic}, // E0.7 [2] (🕉️..🕊️) om..dove + {0x1F54B, 0x1F54E, prExtendedPictographic}, // E1.0 [4] (🕋..🕎) kaaba..menorah + {0x1F54F, 0x1F54F, prExtendedPictographic}, // E0.0 [1] (🕏) BOWL OF HYGIEIA + {0x1F550, 0x1F55B, prExtendedPictographic}, // E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock + {0x1F55C, 0x1F567, prExtendedPictographic}, // E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty + {0x1F568, 0x1F56E, prExtendedPictographic}, // E0.0 [7] (🕨..🕮) RIGHT SPEAKER..BOOK + {0x1F56F, 0x1F570, prExtendedPictographic}, // E0.7 [2] (🕯️..🕰️) candle..mantelpiece clock + {0x1F571, 0x1F572, prExtendedPictographic}, // E0.0 [2] (🕱..🕲) BLACK SKULL AND CROSSBONES..NO PIRACY + {0x1F573, 0x1F579, prExtendedPictographic}, // E0.7 [7] (🕳️..🕹️) hole..joystick + {0x1F57A, 0x1F57A, prExtendedPictographic}, // E3.0 [1] (🕺) man dancing + {0x1F57B, 0x1F586, prExtendedPictographic}, // E0.0 [12] (🕻..🖆) LEFT HAND TELEPHONE RECEIVER..PEN OVER STAMPED ENVELOPE + {0x1F587, 0x1F587, prExtendedPictographic}, // E0.7 [1] (🖇️) linked paperclips + {0x1F588, 0x1F589, prExtendedPictographic}, // E0.0 [2] (🖈..🖉) BLACK PUSHPIN..LOWER LEFT PENCIL + {0x1F58A, 0x1F58D, prExtendedPictographic}, // E0.7 [4] (🖊️..🖍️) pen..crayon + {0x1F58E, 0x1F58F, prExtendedPictographic}, // E0.0 [2] (🖎..🖏) LEFT WRITING HAND..TURNED OK HAND SIGN + {0x1F590, 0x1F590, prExtendedPictographic}, // E0.7 [1] (🖐️) hand with fingers splayed + {0x1F591, 0x1F594, prExtendedPictographic}, // E0.0 [4] (🖑..🖔) REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND + {0x1F595, 0x1F596, prExtendedPictographic}, // E1.0 [2] (🖕..🖖) middle finger..vulcan salute + {0x1F597, 0x1F5A3, prExtendedPictographic}, // E0.0 [13] (🖗..🖣) WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX + {0x1F5A4, 0x1F5A4, prExtendedPictographic}, // E3.0 [1] (🖤) black heart + {0x1F5A5, 0x1F5A5, prExtendedPictographic}, // E0.7 [1] (🖥️) desktop computer + {0x1F5A6, 0x1F5A7, prExtendedPictographic}, // E0.0 [2] (🖦..🖧) KEYBOARD AND MOUSE..THREE NETWORKED COMPUTERS + {0x1F5A8, 0x1F5A8, prExtendedPictographic}, // E0.7 [1] (🖨️) printer + {0x1F5A9, 0x1F5B0, prExtendedPictographic}, // E0.0 [8] (🖩..🖰) POCKET CALCULATOR..TWO BUTTON MOUSE + {0x1F5B1, 0x1F5B2, prExtendedPictographic}, // E0.7 [2] (🖱️..🖲️) computer mouse..trackball + {0x1F5B3, 0x1F5BB, prExtendedPictographic}, // E0.0 [9] (🖳..🖻) OLD PERSONAL COMPUTER..DOCUMENT WITH PICTURE + {0x1F5BC, 0x1F5BC, prExtendedPictographic}, // E0.7 [1] (🖼️) framed picture + {0x1F5BD, 0x1F5C1, prExtendedPictographic}, // E0.0 [5] (🖽..🗁) FRAME WITH TILES..OPEN FOLDER + {0x1F5C2, 0x1F5C4, prExtendedPictographic}, // E0.7 [3] (🗂️..🗄️) card index dividers..file cabinet + {0x1F5C5, 0x1F5D0, prExtendedPictographic}, // E0.0 [12] (🗅..🗐) EMPTY NOTE..PAGES + {0x1F5D1, 0x1F5D3, prExtendedPictographic}, // E0.7 [3] (🗑️..🗓️) wastebasket..spiral calendar + {0x1F5D4, 0x1F5DB, prExtendedPictographic}, // E0.0 [8] (🗔..🗛) DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL + {0x1F5DC, 0x1F5DE, prExtendedPictographic}, // E0.7 [3] (🗜️..🗞️) clamp..rolled-up newspaper + {0x1F5DF, 0x1F5E0, prExtendedPictographic}, // E0.0 [2] (🗟..🗠) PAGE WITH CIRCLED TEXT..STOCK CHART + {0x1F5E1, 0x1F5E1, prExtendedPictographic}, // E0.7 [1] (🗡️) dagger + {0x1F5E2, 0x1F5E2, prExtendedPictographic}, // E0.0 [1] (🗢) LIPS + {0x1F5E3, 0x1F5E3, prExtendedPictographic}, // E0.7 [1] (🗣️) speaking head + {0x1F5E4, 0x1F5E7, prExtendedPictographic}, // E0.0 [4] (🗤..🗧) THREE RAYS ABOVE..THREE RAYS RIGHT + {0x1F5E8, 0x1F5E8, prExtendedPictographic}, // E2.0 [1] (🗨️) left speech bubble + {0x1F5E9, 0x1F5EE, prExtendedPictographic}, // E0.0 [6] (🗩..🗮) RIGHT SPEECH BUBBLE..LEFT ANGER BUBBLE + {0x1F5EF, 0x1F5EF, prExtendedPictographic}, // E0.7 [1] (🗯️) right anger bubble + {0x1F5F0, 0x1F5F2, prExtendedPictographic}, // E0.0 [3] (🗰..🗲) MOOD BUBBLE..LIGHTNING MOOD + {0x1F5F3, 0x1F5F3, prExtendedPictographic}, // E0.7 [1] (🗳️) ballot box with ballot + {0x1F5F4, 0x1F5F9, prExtendedPictographic}, // E0.0 [6] (🗴..🗹) BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK + {0x1F5FA, 0x1F5FA, prExtendedPictographic}, // E0.7 [1] (🗺️) world map + {0x1F5FB, 0x1F5FF, prExtendedPictographic}, // E0.6 [5] (🗻..🗿) mount fuji..moai + {0x1F600, 0x1F600, prExtendedPictographic}, // E1.0 [1] (😀) grinning face + {0x1F601, 0x1F606, prExtendedPictographic}, // E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face + {0x1F607, 0x1F608, prExtendedPictographic}, // E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns + {0x1F609, 0x1F60D, prExtendedPictographic}, // E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes + {0x1F60E, 0x1F60E, prExtendedPictographic}, // E1.0 [1] (😎) smiling face with sunglasses + {0x1F60F, 0x1F60F, prExtendedPictographic}, // E0.6 [1] (😏) smirking face + {0x1F610, 0x1F610, prExtendedPictographic}, // E0.7 [1] (😐) neutral face + {0x1F611, 0x1F611, prExtendedPictographic}, // E1.0 [1] (😑) expressionless face + {0x1F612, 0x1F614, prExtendedPictographic}, // E0.6 [3] (😒..😔) unamused face..pensive face + {0x1F615, 0x1F615, prExtendedPictographic}, // E1.0 [1] (😕) confused face + {0x1F616, 0x1F616, prExtendedPictographic}, // E0.6 [1] (😖) confounded face + {0x1F617, 0x1F617, prExtendedPictographic}, // E1.0 [1] (😗) kissing face + {0x1F618, 0x1F618, prExtendedPictographic}, // E0.6 [1] (😘) face blowing a kiss + {0x1F619, 0x1F619, prExtendedPictographic}, // E1.0 [1] (😙) kissing face with smiling eyes + {0x1F61A, 0x1F61A, prExtendedPictographic}, // E0.6 [1] (😚) kissing face with closed eyes + {0x1F61B, 0x1F61B, prExtendedPictographic}, // E1.0 [1] (😛) face with tongue + {0x1F61C, 0x1F61E, prExtendedPictographic}, // E0.6 [3] (😜..😞) winking face with tongue..disappointed face + {0x1F61F, 0x1F61F, prExtendedPictographic}, // E1.0 [1] (😟) worried face + {0x1F620, 0x1F625, prExtendedPictographic}, // E0.6 [6] (😠..😥) angry face..sad but relieved face + {0x1F626, 0x1F627, prExtendedPictographic}, // E1.0 [2] (😦..😧) frowning face with open mouth..anguished face + {0x1F628, 0x1F62B, prExtendedPictographic}, // E0.6 [4] (😨..😫) fearful face..tired face + {0x1F62C, 0x1F62C, prExtendedPictographic}, // E1.0 [1] (😬) grimacing face + {0x1F62D, 0x1F62D, prExtendedPictographic}, // E0.6 [1] (😭) loudly crying face + {0x1F62E, 0x1F62F, prExtendedPictographic}, // E1.0 [2] (😮..😯) face with open mouth..hushed face + {0x1F630, 0x1F633, prExtendedPictographic}, // E0.6 [4] (😰..😳) anxious face with sweat..flushed face + {0x1F634, 0x1F634, prExtendedPictographic}, // E1.0 [1] (😴) sleeping face + {0x1F635, 0x1F635, prExtendedPictographic}, // E0.6 [1] (😵) face with crossed-out eyes + {0x1F636, 0x1F636, prExtendedPictographic}, // E1.0 [1] (😶) face without mouth + {0x1F637, 0x1F640, prExtendedPictographic}, // E0.6 [10] (😷..🙀) face with medical mask..weary cat + {0x1F641, 0x1F644, prExtendedPictographic}, // E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes + {0x1F645, 0x1F64F, prExtendedPictographic}, // E0.6 [11] (🙅..🙏) person gesturing NO..folded hands + {0x1F680, 0x1F680, prExtendedPictographic}, // E0.6 [1] (🚀) rocket + {0x1F681, 0x1F682, prExtendedPictographic}, // E1.0 [2] (🚁..🚂) helicopter..locomotive + {0x1F683, 0x1F685, prExtendedPictographic}, // E0.6 [3] (🚃..🚅) railway car..bullet train + {0x1F686, 0x1F686, prExtendedPictographic}, // E1.0 [1] (🚆) train + {0x1F687, 0x1F687, prExtendedPictographic}, // E0.6 [1] (🚇) metro + {0x1F688, 0x1F688, prExtendedPictographic}, // E1.0 [1] (🚈) light rail + {0x1F689, 0x1F689, prExtendedPictographic}, // E0.6 [1] (🚉) station + {0x1F68A, 0x1F68B, prExtendedPictographic}, // E1.0 [2] (🚊..🚋) tram..tram car + {0x1F68C, 0x1F68C, prExtendedPictographic}, // E0.6 [1] (🚌) bus + {0x1F68D, 0x1F68D, prExtendedPictographic}, // E0.7 [1] (🚍) oncoming bus + {0x1F68E, 0x1F68E, prExtendedPictographic}, // E1.0 [1] (🚎) trolleybus + {0x1F68F, 0x1F68F, prExtendedPictographic}, // E0.6 [1] (🚏) bus stop + {0x1F690, 0x1F690, prExtendedPictographic}, // E1.0 [1] (🚐) minibus + {0x1F691, 0x1F693, prExtendedPictographic}, // E0.6 [3] (🚑..🚓) ambulance..police car + {0x1F694, 0x1F694, prExtendedPictographic}, // E0.7 [1] (🚔) oncoming police car + {0x1F695, 0x1F695, prExtendedPictographic}, // E0.6 [1] (🚕) taxi + {0x1F696, 0x1F696, prExtendedPictographic}, // E1.0 [1] (🚖) oncoming taxi + {0x1F697, 0x1F697, prExtendedPictographic}, // E0.6 [1] (🚗) automobile + {0x1F698, 0x1F698, prExtendedPictographic}, // E0.7 [1] (🚘) oncoming automobile + {0x1F699, 0x1F69A, prExtendedPictographic}, // E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck + {0x1F69B, 0x1F6A1, prExtendedPictographic}, // E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway + {0x1F6A2, 0x1F6A2, prExtendedPictographic}, // E0.6 [1] (🚢) ship + {0x1F6A3, 0x1F6A3, prExtendedPictographic}, // E1.0 [1] (🚣) person rowing boat + {0x1F6A4, 0x1F6A5, prExtendedPictographic}, // E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light + {0x1F6A6, 0x1F6A6, prExtendedPictographic}, // E1.0 [1] (🚦) vertical traffic light + {0x1F6A7, 0x1F6AD, prExtendedPictographic}, // E0.6 [7] (🚧..🚭) construction..no smoking + {0x1F6AE, 0x1F6B1, prExtendedPictographic}, // E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water + {0x1F6B2, 0x1F6B2, prExtendedPictographic}, // E0.6 [1] (🚲) bicycle + {0x1F6B3, 0x1F6B5, prExtendedPictographic}, // E1.0 [3] (🚳..🚵) no bicycles..person mountain biking + {0x1F6B6, 0x1F6B6, prExtendedPictographic}, // E0.6 [1] (🚶) person walking + {0x1F6B7, 0x1F6B8, prExtendedPictographic}, // E1.0 [2] (🚷..🚸) no pedestrians..children crossing + {0x1F6B9, 0x1F6BE, prExtendedPictographic}, // E0.6 [6] (🚹..🚾) men’s room..water closet + {0x1F6BF, 0x1F6BF, prExtendedPictographic}, // E1.0 [1] (🚿) shower + {0x1F6C0, 0x1F6C0, prExtendedPictographic}, // E0.6 [1] (🛀) person taking bath + {0x1F6C1, 0x1F6C5, prExtendedPictographic}, // E1.0 [5] (🛁..🛅) bathtub..left luggage + {0x1F6C6, 0x1F6CA, prExtendedPictographic}, // E0.0 [5] (🛆..🛊) TRIANGLE WITH ROUNDED CORNERS..GIRLS SYMBOL + {0x1F6CB, 0x1F6CB, prExtendedPictographic}, // E0.7 [1] (🛋️) couch and lamp + {0x1F6CC, 0x1F6CC, prExtendedPictographic}, // E1.0 [1] (🛌) person in bed + {0x1F6CD, 0x1F6CF, prExtendedPictographic}, // E0.7 [3] (🛍️..🛏️) shopping bags..bed + {0x1F6D0, 0x1F6D0, prExtendedPictographic}, // E1.0 [1] (🛐) place of worship + {0x1F6D1, 0x1F6D2, prExtendedPictographic}, // E3.0 [2] (🛑..🛒) stop sign..shopping cart + {0x1F6D3, 0x1F6D4, prExtendedPictographic}, // E0.0 [2] (🛓..🛔) STUPA..PAGODA + {0x1F6D5, 0x1F6D5, prExtendedPictographic}, // E12.0 [1] (🛕) hindu temple + {0x1F6D6, 0x1F6D7, prExtendedPictographic}, // E13.0 [2] (🛖..🛗) hut..elevator + {0x1F6D8, 0x1F6DB, prExtendedPictographic}, // E0.0 [4] (🛘..🛛) .. + {0x1F6DC, 0x1F6DC, prExtendedPictographic}, // E15.0 [1] (🛜) wireless + {0x1F6DD, 0x1F6DF, prExtendedPictographic}, // E14.0 [3] (🛝..🛟) playground slide..ring buoy + {0x1F6E0, 0x1F6E5, prExtendedPictographic}, // E0.7 [6] (🛠️..🛥️) hammer and wrench..motor boat + {0x1F6E6, 0x1F6E8, prExtendedPictographic}, // E0.0 [3] (🛦..🛨) UP-POINTING MILITARY AIRPLANE..UP-POINTING SMALL AIRPLANE + {0x1F6E9, 0x1F6E9, prExtendedPictographic}, // E0.7 [1] (🛩️) small airplane + {0x1F6EA, 0x1F6EA, prExtendedPictographic}, // E0.0 [1] (🛪) NORTHEAST-POINTING AIRPLANE + {0x1F6EB, 0x1F6EC, prExtendedPictographic}, // E1.0 [2] (🛫..🛬) airplane departure..airplane arrival + {0x1F6ED, 0x1F6EF, prExtendedPictographic}, // E0.0 [3] (🛭..🛯) .. + {0x1F6F0, 0x1F6F0, prExtendedPictographic}, // E0.7 [1] (🛰️) satellite + {0x1F6F1, 0x1F6F2, prExtendedPictographic}, // E0.0 [2] (🛱..🛲) ONCOMING FIRE ENGINE..DIESEL LOCOMOTIVE + {0x1F6F3, 0x1F6F3, prExtendedPictographic}, // E0.7 [1] (🛳️) passenger ship + {0x1F6F4, 0x1F6F6, prExtendedPictographic}, // E3.0 [3] (🛴..🛶) kick scooter..canoe + {0x1F6F7, 0x1F6F8, prExtendedPictographic}, // E5.0 [2] (🛷..🛸) sled..flying saucer + {0x1F6F9, 0x1F6F9, prExtendedPictographic}, // E11.0 [1] (🛹) skateboard + {0x1F6FA, 0x1F6FA, prExtendedPictographic}, // E12.0 [1] (🛺) auto rickshaw + {0x1F6FB, 0x1F6FC, prExtendedPictographic}, // E13.0 [2] (🛻..🛼) pickup truck..roller skate + {0x1F6FD, 0x1F6FF, prExtendedPictographic}, // E0.0 [3] (🛽..🛿) .. + {0x1F774, 0x1F77F, prExtendedPictographic}, // E0.0 [12] (🝴..🝿) LOT OF FORTUNE..ORCUS + {0x1F7D5, 0x1F7DF, prExtendedPictographic}, // E0.0 [11] (🟕..🟟) CIRCLED TRIANGLE.. + {0x1F7E0, 0x1F7EB, prExtendedPictographic}, // E12.0 [12] (🟠..🟫) orange circle..brown square + {0x1F7EC, 0x1F7EF, prExtendedPictographic}, // E0.0 [4] (🟬..🟯) .. + {0x1F7F0, 0x1F7F0, prExtendedPictographic}, // E14.0 [1] (🟰) heavy equals sign + {0x1F7F1, 0x1F7FF, prExtendedPictographic}, // E0.0 [15] (🟱..🟿) .. + {0x1F80C, 0x1F80F, prExtendedPictographic}, // E0.0 [4] (🠌..🠏) .. + {0x1F848, 0x1F84F, prExtendedPictographic}, // E0.0 [8] (🡈..🡏) .. + {0x1F85A, 0x1F85F, prExtendedPictographic}, // E0.0 [6] (🡚..🡟) .. + {0x1F888, 0x1F88F, prExtendedPictographic}, // E0.0 [8] (🢈..🢏) .. + {0x1F8AE, 0x1F8FF, prExtendedPictographic}, // E0.0 [82] (🢮..🣿) .. + {0x1F90C, 0x1F90C, prExtendedPictographic}, // E13.0 [1] (🤌) pinched fingers + {0x1F90D, 0x1F90F, prExtendedPictographic}, // E12.0 [3] (🤍..🤏) white heart..pinching hand + {0x1F910, 0x1F918, prExtendedPictographic}, // E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns + {0x1F919, 0x1F91E, prExtendedPictographic}, // E3.0 [6] (🤙..🤞) call me hand..crossed fingers + {0x1F91F, 0x1F91F, prExtendedPictographic}, // E5.0 [1] (🤟) love-you gesture + {0x1F920, 0x1F927, prExtendedPictographic}, // E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face + {0x1F928, 0x1F92F, prExtendedPictographic}, // E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head + {0x1F930, 0x1F930, prExtendedPictographic}, // E3.0 [1] (🤰) pregnant woman + {0x1F931, 0x1F932, prExtendedPictographic}, // E5.0 [2] (🤱..🤲) breast-feeding..palms up together + {0x1F933, 0x1F93A, prExtendedPictographic}, // E3.0 [8] (🤳..🤺) selfie..person fencing + {0x1F93C, 0x1F93E, prExtendedPictographic}, // E3.0 [3] (🤼..🤾) people wrestling..person playing handball + {0x1F93F, 0x1F93F, prExtendedPictographic}, // E12.0 [1] (🤿) diving mask + {0x1F940, 0x1F945, prExtendedPictographic}, // E3.0 [6] (🥀..🥅) wilted flower..goal net + {0x1F947, 0x1F94B, prExtendedPictographic}, // E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform + {0x1F94C, 0x1F94C, prExtendedPictographic}, // E5.0 [1] (🥌) curling stone + {0x1F94D, 0x1F94F, prExtendedPictographic}, // E11.0 [3] (🥍..🥏) lacrosse..flying disc + {0x1F950, 0x1F95E, prExtendedPictographic}, // E3.0 [15] (🥐..🥞) croissant..pancakes + {0x1F95F, 0x1F96B, prExtendedPictographic}, // E5.0 [13] (🥟..🥫) dumpling..canned food + {0x1F96C, 0x1F970, prExtendedPictographic}, // E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts + {0x1F971, 0x1F971, prExtendedPictographic}, // E12.0 [1] (🥱) yawning face + {0x1F972, 0x1F972, prExtendedPictographic}, // E13.0 [1] (🥲) smiling face with tear + {0x1F973, 0x1F976, prExtendedPictographic}, // E11.0 [4] (🥳..🥶) partying face..cold face + {0x1F977, 0x1F978, prExtendedPictographic}, // E13.0 [2] (🥷..🥸) ninja..disguised face + {0x1F979, 0x1F979, prExtendedPictographic}, // E14.0 [1] (🥹) face holding back tears + {0x1F97A, 0x1F97A, prExtendedPictographic}, // E11.0 [1] (🥺) pleading face + {0x1F97B, 0x1F97B, prExtendedPictographic}, // E12.0 [1] (🥻) sari + {0x1F97C, 0x1F97F, prExtendedPictographic}, // E11.0 [4] (🥼..🥿) lab coat..flat shoe + {0x1F980, 0x1F984, prExtendedPictographic}, // E1.0 [5] (🦀..🦄) crab..unicorn + {0x1F985, 0x1F991, prExtendedPictographic}, // E3.0 [13] (🦅..🦑) eagle..squid + {0x1F992, 0x1F997, prExtendedPictographic}, // E5.0 [6] (🦒..🦗) giraffe..cricket + {0x1F998, 0x1F9A2, prExtendedPictographic}, // E11.0 [11] (🦘..🦢) kangaroo..swan + {0x1F9A3, 0x1F9A4, prExtendedPictographic}, // E13.0 [2] (🦣..🦤) mammoth..dodo + {0x1F9A5, 0x1F9AA, prExtendedPictographic}, // E12.0 [6] (🦥..🦪) sloth..oyster + {0x1F9AB, 0x1F9AD, prExtendedPictographic}, // E13.0 [3] (🦫..🦭) beaver..seal + {0x1F9AE, 0x1F9AF, prExtendedPictographic}, // E12.0 [2] (🦮..🦯) guide dog..white cane + {0x1F9B0, 0x1F9B9, prExtendedPictographic}, // E11.0 [10] (🦰..🦹) red hair..supervillain + {0x1F9BA, 0x1F9BF, prExtendedPictographic}, // E12.0 [6] (🦺..🦿) safety vest..mechanical leg + {0x1F9C0, 0x1F9C0, prExtendedPictographic}, // E1.0 [1] (🧀) cheese wedge + {0x1F9C1, 0x1F9C2, prExtendedPictographic}, // E11.0 [2] (🧁..🧂) cupcake..salt + {0x1F9C3, 0x1F9CA, prExtendedPictographic}, // E12.0 [8] (🧃..🧊) beverage box..ice + {0x1F9CB, 0x1F9CB, prExtendedPictographic}, // E13.0 [1] (🧋) bubble tea + {0x1F9CC, 0x1F9CC, prExtendedPictographic}, // E14.0 [1] (🧌) troll + {0x1F9CD, 0x1F9CF, prExtendedPictographic}, // E12.0 [3] (🧍..🧏) person standing..deaf person + {0x1F9D0, 0x1F9E6, prExtendedPictographic}, // E5.0 [23] (🧐..🧦) face with monocle..socks + {0x1F9E7, 0x1F9FF, prExtendedPictographic}, // E11.0 [25] (🧧..🧿) red envelope..nazar amulet + {0x1FA00, 0x1FA6F, prExtendedPictographic}, // E0.0 [112] (🨀..🩯) NEUTRAL CHESS KING.. + {0x1FA70, 0x1FA73, prExtendedPictographic}, // E12.0 [4] (🩰..🩳) ballet shoes..shorts + {0x1FA74, 0x1FA74, prExtendedPictographic}, // E13.0 [1] (🩴) thong sandal + {0x1FA75, 0x1FA77, prExtendedPictographic}, // E15.0 [3] (🩵..🩷) light blue heart..pink heart + {0x1FA78, 0x1FA7A, prExtendedPictographic}, // E12.0 [3] (🩸..🩺) drop of blood..stethoscope + {0x1FA7B, 0x1FA7C, prExtendedPictographic}, // E14.0 [2] (🩻..🩼) x-ray..crutch + {0x1FA7D, 0x1FA7F, prExtendedPictographic}, // E0.0 [3] (🩽..🩿) .. + {0x1FA80, 0x1FA82, prExtendedPictographic}, // E12.0 [3] (🪀..🪂) yo-yo..parachute + {0x1FA83, 0x1FA86, prExtendedPictographic}, // E13.0 [4] (🪃..🪆) boomerang..nesting dolls + {0x1FA87, 0x1FA88, prExtendedPictographic}, // E15.0 [2] (🪇..🪈) maracas..flute + {0x1FA89, 0x1FA8F, prExtendedPictographic}, // E0.0 [7] (🪉..🪏) .. + {0x1FA90, 0x1FA95, prExtendedPictographic}, // E12.0 [6] (🪐..🪕) ringed planet..banjo + {0x1FA96, 0x1FAA8, prExtendedPictographic}, // E13.0 [19] (🪖..🪨) military helmet..rock + {0x1FAA9, 0x1FAAC, prExtendedPictographic}, // E14.0 [4] (🪩..🪬) mirror ball..hamsa + {0x1FAAD, 0x1FAAF, prExtendedPictographic}, // E15.0 [3] (🪭..🪯) folding hand fan..khanda + {0x1FAB0, 0x1FAB6, prExtendedPictographic}, // E13.0 [7] (🪰..🪶) fly..feather + {0x1FAB7, 0x1FABA, prExtendedPictographic}, // E14.0 [4] (🪷..🪺) lotus..nest with eggs + {0x1FABB, 0x1FABD, prExtendedPictographic}, // E15.0 [3] (🪻..🪽) hyacinth..wing + {0x1FABE, 0x1FABE, prExtendedPictographic}, // E0.0 [1] (🪾) + {0x1FABF, 0x1FABF, prExtendedPictographic}, // E15.0 [1] (🪿) goose + {0x1FAC0, 0x1FAC2, prExtendedPictographic}, // E13.0 [3] (🫀..🫂) anatomical heart..people hugging + {0x1FAC3, 0x1FAC5, prExtendedPictographic}, // E14.0 [3] (🫃..🫅) pregnant man..person with crown + {0x1FAC6, 0x1FACD, prExtendedPictographic}, // E0.0 [8] (🫆..🫍) .. + {0x1FACE, 0x1FACF, prExtendedPictographic}, // E15.0 [2] (🫎..🫏) moose..donkey + {0x1FAD0, 0x1FAD6, prExtendedPictographic}, // E13.0 [7] (🫐..🫖) blueberries..teapot + {0x1FAD7, 0x1FAD9, prExtendedPictographic}, // E14.0 [3] (🫗..🫙) pouring liquid..jar + {0x1FADA, 0x1FADB, prExtendedPictographic}, // E15.0 [2] (🫚..🫛) ginger root..pea pod + {0x1FADC, 0x1FADF, prExtendedPictographic}, // E0.0 [4] (🫜..🫟) .. + {0x1FAE0, 0x1FAE7, prExtendedPictographic}, // E14.0 [8] (🫠..🫧) melting face..bubbles + {0x1FAE8, 0x1FAE8, prExtendedPictographic}, // E15.0 [1] (🫨) shaking face + {0x1FAE9, 0x1FAEF, prExtendedPictographic}, // E0.0 [7] (🫩..🫯) .. + {0x1FAF0, 0x1FAF6, prExtendedPictographic}, // E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands + {0x1FAF7, 0x1FAF8, prExtendedPictographic}, // E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand + {0x1FAF9, 0x1FAFF, prExtendedPictographic}, // E0.0 [7] (🫹..🫿) .. + {0x1FC00, 0x1FFFD, prExtendedPictographic}, // E0.0[1022] (🰀..🿽) .. + {0xE0000, 0xE0000, prControl}, // Cn + {0xE0001, 0xE0001, prControl}, // Cf LANGUAGE TAG + {0xE0002, 0xE001F, prControl}, // Cn [30] .. + {0xE0020, 0xE007F, prExtend}, // Cf [96] TAG SPACE..CANCEL TAG + {0xE0080, 0xE00FF, prControl}, // Cn [128] .. + {0xE0100, 0xE01EF, prExtend}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + {0xE01F0, 0xE0FFF, prControl}, // Cn [3600] .. +} diff --git a/vendor/github.com/rivo/uniseg/graphemerules.go b/vendor/github.com/rivo/uniseg/graphemerules.go new file mode 100644 index 000000000..5d399d29c --- /dev/null +++ b/vendor/github.com/rivo/uniseg/graphemerules.go @@ -0,0 +1,176 @@ +package uniseg + +// The states of the grapheme cluster parser. +const ( + grAny = iota + grCR + grControlLF + grL + grLVV + grLVTT + grPrepend + grExtendedPictographic + grExtendedPictographicZWJ + grRIOdd + grRIEven +) + +// The grapheme cluster parser's breaking instructions. +const ( + grNoBoundary = iota + grBoundary +) + +// grTransitions implements the grapheme cluster parser's state transitions. +// Maps state and property to a new state, a breaking instruction, and rule +// number. The breaking instruction always refers to the boundary between the +// last and next code point. Returns negative values if no transition is found. +// +// This function is used as follows: +// +// 1. Find specific state + specific property. Stop if found. +// 2. Find specific state + any property. +// 3. Find any state + specific property. +// 4. If only (2) or (3) (but not both) was found, stop. +// 5. If both (2) and (3) were found, use state from (3) and breaking instruction +// from the transition with the lower rule number, prefer (3) if rule numbers +// are equal. Stop. +// 6. Assume grAny and grBoundary. +// +// Unicode version 15.0.0. +func grTransitions(state, prop int) (newState int, newProp int, boundary int) { + // It turns out that using a big switch statement is much faster than using + // a map. + + switch uint64(state) | uint64(prop)<<32 { + // GB5 + case grAny | prCR<<32: + return grCR, grBoundary, 50 + case grAny | prLF<<32: + return grControlLF, grBoundary, 50 + case grAny | prControl<<32: + return grControlLF, grBoundary, 50 + + // GB4 + case grCR | prAny<<32: + return grAny, grBoundary, 40 + case grControlLF | prAny<<32: + return grAny, grBoundary, 40 + + // GB3 + case grCR | prLF<<32: + return grControlLF, grNoBoundary, 30 + + // GB6 + case grAny | prL<<32: + return grL, grBoundary, 9990 + case grL | prL<<32: + return grL, grNoBoundary, 60 + case grL | prV<<32: + return grLVV, grNoBoundary, 60 + case grL | prLV<<32: + return grLVV, grNoBoundary, 60 + case grL | prLVT<<32: + return grLVTT, grNoBoundary, 60 + + // GB7 + case grAny | prLV<<32: + return grLVV, grBoundary, 9990 + case grAny | prV<<32: + return grLVV, grBoundary, 9990 + case grLVV | prV<<32: + return grLVV, grNoBoundary, 70 + case grLVV | prT<<32: + return grLVTT, grNoBoundary, 70 + + // GB8 + case grAny | prLVT<<32: + return grLVTT, grBoundary, 9990 + case grAny | prT<<32: + return grLVTT, grBoundary, 9990 + case grLVTT | prT<<32: + return grLVTT, grNoBoundary, 80 + + // GB9 + case grAny | prExtend<<32: + return grAny, grNoBoundary, 90 + case grAny | prZWJ<<32: + return grAny, grNoBoundary, 90 + + // GB9a + case grAny | prSpacingMark<<32: + return grAny, grNoBoundary, 91 + + // GB9b + case grAny | prPrepend<<32: + return grPrepend, grBoundary, 9990 + case grPrepend | prAny<<32: + return grAny, grNoBoundary, 92 + + // GB11 + case grAny | prExtendedPictographic<<32: + return grExtendedPictographic, grBoundary, 9990 + case grExtendedPictographic | prExtend<<32: + return grExtendedPictographic, grNoBoundary, 110 + case grExtendedPictographic | prZWJ<<32: + return grExtendedPictographicZWJ, grNoBoundary, 110 + case grExtendedPictographicZWJ | prExtendedPictographic<<32: + return grExtendedPictographic, grNoBoundary, 110 + + // GB12 / GB13 + case grAny | prRegionalIndicator<<32: + return grRIOdd, grBoundary, 9990 + case grRIOdd | prRegionalIndicator<<32: + return grRIEven, grNoBoundary, 120 + case grRIEven | prRegionalIndicator<<32: + return grRIOdd, grBoundary, 120 + default: + return -1, -1, -1 + } +} + +// transitionGraphemeState determines the new state of the grapheme cluster +// parser given the current state and the next code point. It also returns the +// code point's grapheme property (the value mapped by the [graphemeCodePoints] +// table) and whether a cluster boundary was detected. +func transitionGraphemeState(state int, r rune) (newState, prop int, boundary bool) { + // Determine the property of the next character. + prop = propertyGraphemes(r) + + // Find the applicable transition. + nextState, nextProp, _ := grTransitions(state, prop) + if nextState >= 0 { + // We have a specific transition. We'll use it. + return nextState, prop, nextProp == grBoundary + } + + // No specific transition found. Try the less specific ones. + anyPropState, anyPropProp, anyPropRule := grTransitions(state, prAny) + anyStateState, anyStateProp, anyStateRule := grTransitions(grAny, prop) + if anyPropState >= 0 && anyStateState >= 0 { + // Both apply. We'll use a mix (see comments for grTransitions). + newState = anyStateState + boundary = anyStateProp == grBoundary + if anyPropRule < anyStateRule { + boundary = anyPropProp == grBoundary + } + return + } + + if anyPropState >= 0 { + // We only have a specific state. + return anyPropState, prop, anyPropProp == grBoundary + // This branch will probably never be reached because okAnyState will + // always be true given the current transition map. But we keep it here + // for future modifications to the transition map where this may not be + // true anymore. + } + + if anyStateState >= 0 { + // We only have a specific property. + return anyStateState, prop, anyStateProp == grBoundary + } + + // No known transition. GB999: Any ÷ Any. + return grAny, prop, true +} diff --git a/vendor/github.com/rivo/uniseg/line.go b/vendor/github.com/rivo/uniseg/line.go new file mode 100644 index 000000000..7a46318d9 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/line.go @@ -0,0 +1,134 @@ +package uniseg + +import "unicode/utf8" + +// FirstLineSegment returns the prefix of the given byte slice after which a +// decision to break the string over to the next line can or must be made, +// according to the rules of [Unicode Standard Annex #14]. This is used to +// implement line breaking. +// +// Line breaking, also known as word wrapping, is the process of breaking a +// section of text into lines such that it will fit in the available width of a +// page, window or other display area. +// +// The returned "segment" may not be broken into smaller parts, unless no other +// breaking opportunities present themselves, in which case you may break by +// grapheme clusters (using the [FirstGraphemeCluster] function to determine the +// grapheme clusters). +// +// The "mustBreak" flag indicates whether you MUST break the line after the +// given segment (true), for example after newline characters, or you MAY break +// the line after the given segment (false). +// +// This function can be called continuously to extract all non-breaking sub-sets +// from a byte slice, as illustrated in the example below. +// +// If you don't know the current state, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified line segment. If the length of the +// "rest" slice is 0, the entire byte slice "b" has been processed. The +// "segment" byte slice is the sub-slice of the input slice containing the +// identified line segment. +// +// Given an empty byte slice "b", the function returns nil values. +// +// Note that in accordance with [UAX #14 LB3], the final segment will end with +// "mustBreak" set to true. You can choose to ignore this by checking if the +// length of the "rest" slice is 0 and calling [HasTrailingLineBreak] or +// [HasTrailingLineBreakInString] on the last rune. +// +// Note also that this algorithm may break within grapheme clusters. This is +// addressed in Section 8.2 Example 6 of UAX #14. To avoid this, you can use +// the [Step] function instead. +// +// [Unicode Standard Annex #14]: https://www.unicode.org/reports/tr14/ +// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm +func FirstLineSegment(b []byte, state int) (segment, rest []byte, mustBreak bool, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + return b, nil, true, lbAny // LB3. + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionLineBreakState(state, r, b[length:], "") + } + + // Transition until we find a boundary. + var boundary int + for { + r, l := utf8.DecodeRune(b[length:]) + state, boundary = transitionLineBreakState(state, r, b[length+l:], "") + + if boundary != LineDontBreak { + return b[:length], b[length:], boundary == LineMustBreak, state + } + + length += l + if len(b) <= length { + return b, nil, true, lbAny // LB3 + } + } +} + +// FirstLineSegmentInString is like [FirstLineSegment] but its input and outputs +// are strings. +func FirstLineSegmentInString(str string, state int) (segment, rest string, mustBreak bool, newState int) { + // An empty byte slice returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + return str, "", true, lbAny // LB3. + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionLineBreakState(state, r, nil, str[length:]) + } + + // Transition until we find a boundary. + var boundary int + for { + r, l := utf8.DecodeRuneInString(str[length:]) + state, boundary = transitionLineBreakState(state, r, nil, str[length+l:]) + + if boundary != LineDontBreak { + return str[:length], str[length:], boundary == LineMustBreak, state + } + + length += l + if len(str) <= length { + return str, "", true, lbAny // LB3. + } + } +} + +// HasTrailingLineBreak returns true if the last rune in the given byte slice is +// one of the hard line break code points defined in LB4 and LB5 of [UAX #14]. +// +// [UAX #14]: https://www.unicode.org/reports/tr14/#Algorithm +func HasTrailingLineBreak(b []byte) bool { + r, _ := utf8.DecodeLastRune(b) + property, _ := propertyLineBreak(r) + return property == prBK || property == prCR || property == prLF || property == prNL +} + +// HasTrailingLineBreakInString is like [HasTrailingLineBreak] but for a string. +func HasTrailingLineBreakInString(str string) bool { + r, _ := utf8.DecodeLastRuneInString(str) + property, _ := propertyLineBreak(r) + return property == prBK || property == prCR || property == prLF || property == prNL +} diff --git a/vendor/github.com/rivo/uniseg/lineproperties.go b/vendor/github.com/rivo/uniseg/lineproperties.go new file mode 100644 index 000000000..ac7fac4c0 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/lineproperties.go @@ -0,0 +1,3554 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// lineBreakCodePoints are taken from +// https://www.unicode.org/Public/15.0.0/ucd/LineBreak.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var lineBreakCodePoints = [][4]int{ + {0x0000, 0x0008, prCM, gcCc}, // [9] .. + {0x0009, 0x0009, prBA, gcCc}, // + {0x000A, 0x000A, prLF, gcCc}, // + {0x000B, 0x000C, prBK, gcCc}, // [2] .. + {0x000D, 0x000D, prCR, gcCc}, // + {0x000E, 0x001F, prCM, gcCc}, // [18] .. + {0x0020, 0x0020, prSP, gcZs}, // SPACE + {0x0021, 0x0021, prEX, gcPo}, // EXCLAMATION MARK + {0x0022, 0x0022, prQU, gcPo}, // QUOTATION MARK + {0x0023, 0x0023, prAL, gcPo}, // NUMBER SIGN + {0x0024, 0x0024, prPR, gcSc}, // DOLLAR SIGN + {0x0025, 0x0025, prPO, gcPo}, // PERCENT SIGN + {0x0026, 0x0026, prAL, gcPo}, // AMPERSAND + {0x0027, 0x0027, prQU, gcPo}, // APOSTROPHE + {0x0028, 0x0028, prOP, gcPs}, // LEFT PARENTHESIS + {0x0029, 0x0029, prCP, gcPe}, // RIGHT PARENTHESIS + {0x002A, 0x002A, prAL, gcPo}, // ASTERISK + {0x002B, 0x002B, prPR, gcSm}, // PLUS SIGN + {0x002C, 0x002C, prIS, gcPo}, // COMMA + {0x002D, 0x002D, prHY, gcPd}, // HYPHEN-MINUS + {0x002E, 0x002E, prIS, gcPo}, // FULL STOP + {0x002F, 0x002F, prSY, gcPo}, // SOLIDUS + {0x0030, 0x0039, prNU, gcNd}, // [10] DIGIT ZERO..DIGIT NINE + {0x003A, 0x003B, prIS, gcPo}, // [2] COLON..SEMICOLON + {0x003C, 0x003E, prAL, gcSm}, // [3] LESS-THAN SIGN..GREATER-THAN SIGN + {0x003F, 0x003F, prEX, gcPo}, // QUESTION MARK + {0x0040, 0x0040, prAL, gcPo}, // COMMERCIAL AT + {0x0041, 0x005A, prAL, gcLu}, // [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z + {0x005B, 0x005B, prOP, gcPs}, // LEFT SQUARE BRACKET + {0x005C, 0x005C, prPR, gcPo}, // REVERSE SOLIDUS + {0x005D, 0x005D, prCP, gcPe}, // RIGHT SQUARE BRACKET + {0x005E, 0x005E, prAL, gcSk}, // CIRCUMFLEX ACCENT + {0x005F, 0x005F, prAL, gcPc}, // LOW LINE + {0x0060, 0x0060, prAL, gcSk}, // GRAVE ACCENT + {0x0061, 0x007A, prAL, gcLl}, // [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z + {0x007B, 0x007B, prOP, gcPs}, // LEFT CURLY BRACKET + {0x007C, 0x007C, prBA, gcSm}, // VERTICAL LINE + {0x007D, 0x007D, prCL, gcPe}, // RIGHT CURLY BRACKET + {0x007E, 0x007E, prAL, gcSm}, // TILDE + {0x007F, 0x007F, prCM, gcCc}, // + {0x0080, 0x0084, prCM, gcCc}, // [5] .. + {0x0085, 0x0085, prNL, gcCc}, // + {0x0086, 0x009F, prCM, gcCc}, // [26] .. + {0x00A0, 0x00A0, prGL, gcZs}, // NO-BREAK SPACE + {0x00A1, 0x00A1, prOP, gcPo}, // INVERTED EXCLAMATION MARK + {0x00A2, 0x00A2, prPO, gcSc}, // CENT SIGN + {0x00A3, 0x00A5, prPR, gcSc}, // [3] POUND SIGN..YEN SIGN + {0x00A6, 0x00A6, prAL, gcSo}, // BROKEN BAR + {0x00A7, 0x00A7, prAI, gcPo}, // SECTION SIGN + {0x00A8, 0x00A8, prAI, gcSk}, // DIAERESIS + {0x00A9, 0x00A9, prAL, gcSo}, // COPYRIGHT SIGN + {0x00AA, 0x00AA, prAI, gcLo}, // FEMININE ORDINAL INDICATOR + {0x00AB, 0x00AB, prQU, gcPi}, // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00AC, 0x00AC, prAL, gcSm}, // NOT SIGN + {0x00AD, 0x00AD, prBA, gcCf}, // SOFT HYPHEN + {0x00AE, 0x00AE, prAL, gcSo}, // REGISTERED SIGN + {0x00AF, 0x00AF, prAL, gcSk}, // MACRON + {0x00B0, 0x00B0, prPO, gcSo}, // DEGREE SIGN + {0x00B1, 0x00B1, prPR, gcSm}, // PLUS-MINUS SIGN + {0x00B2, 0x00B3, prAI, gcNo}, // [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE + {0x00B4, 0x00B4, prBB, gcSk}, // ACUTE ACCENT + {0x00B5, 0x00B5, prAL, gcLl}, // MICRO SIGN + {0x00B6, 0x00B7, prAI, gcPo}, // [2] PILCROW SIGN..MIDDLE DOT + {0x00B8, 0x00B8, prAI, gcSk}, // CEDILLA + {0x00B9, 0x00B9, prAI, gcNo}, // SUPERSCRIPT ONE + {0x00BA, 0x00BA, prAI, gcLo}, // MASCULINE ORDINAL INDICATOR + {0x00BB, 0x00BB, prQU, gcPf}, // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00BC, 0x00BE, prAI, gcNo}, // [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS + {0x00BF, 0x00BF, prOP, gcPo}, // INVERTED QUESTION MARK + {0x00C0, 0x00D6, prAL, gcLu}, // [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS + {0x00D7, 0x00D7, prAI, gcSm}, // MULTIPLICATION SIGN + {0x00D8, 0x00F6, prAL, gcLC}, // [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS + {0x00F7, 0x00F7, prAI, gcSm}, // DIVISION SIGN + {0x00F8, 0x00FF, prAL, gcLl}, // [8] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS + {0x0100, 0x017F, prAL, gcLC}, // [128] LATIN CAPITAL LETTER A WITH MACRON..LATIN SMALL LETTER LONG S + {0x0180, 0x01BA, prAL, gcLC}, // [59] LATIN SMALL LETTER B WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL + {0x01BB, 0x01BB, prAL, gcLo}, // LATIN LETTER TWO WITH STROKE + {0x01BC, 0x01BF, prAL, gcLC}, // [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN + {0x01C0, 0x01C3, prAL, gcLo}, // [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK + {0x01C4, 0x024F, prAL, gcLC}, // [140] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER Y WITH STROKE + {0x0250, 0x0293, prAL, gcLl}, // [68] LATIN SMALL LETTER TURNED A..LATIN SMALL LETTER EZH WITH CURL + {0x0294, 0x0294, prAL, gcLo}, // LATIN LETTER GLOTTAL STOP + {0x0295, 0x02AF, prAL, gcLl}, // [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL + {0x02B0, 0x02C1, prAL, gcLm}, // [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP + {0x02C2, 0x02C5, prAL, gcSk}, // [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD + {0x02C6, 0x02C6, prAL, gcLm}, // MODIFIER LETTER CIRCUMFLEX ACCENT + {0x02C7, 0x02C7, prAI, gcLm}, // CARON + {0x02C8, 0x02C8, prBB, gcLm}, // MODIFIER LETTER VERTICAL LINE + {0x02C9, 0x02CB, prAI, gcLm}, // [3] MODIFIER LETTER MACRON..MODIFIER LETTER GRAVE ACCENT + {0x02CC, 0x02CC, prBB, gcLm}, // MODIFIER LETTER LOW VERTICAL LINE + {0x02CD, 0x02CD, prAI, gcLm}, // MODIFIER LETTER LOW MACRON + {0x02CE, 0x02CF, prAL, gcLm}, // [2] MODIFIER LETTER LOW GRAVE ACCENT..MODIFIER LETTER LOW ACUTE ACCENT + {0x02D0, 0x02D0, prAI, gcLm}, // MODIFIER LETTER TRIANGULAR COLON + {0x02D1, 0x02D1, prAL, gcLm}, // MODIFIER LETTER HALF TRIANGULAR COLON + {0x02D2, 0x02D7, prAL, gcSk}, // [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN + {0x02D8, 0x02DB, prAI, gcSk}, // [4] BREVE..OGONEK + {0x02DC, 0x02DC, prAL, gcSk}, // SMALL TILDE + {0x02DD, 0x02DD, prAI, gcSk}, // DOUBLE ACUTE ACCENT + {0x02DE, 0x02DE, prAL, gcSk}, // MODIFIER LETTER RHOTIC HOOK + {0x02DF, 0x02DF, prBB, gcSk}, // MODIFIER LETTER CROSS ACCENT + {0x02E0, 0x02E4, prAL, gcLm}, // [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP + {0x02E5, 0x02EB, prAL, gcSk}, // [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK + {0x02EC, 0x02EC, prAL, gcLm}, // MODIFIER LETTER VOICING + {0x02ED, 0x02ED, prAL, gcSk}, // MODIFIER LETTER UNASPIRATED + {0x02EE, 0x02EE, prAL, gcLm}, // MODIFIER LETTER DOUBLE APOSTROPHE + {0x02EF, 0x02FF, prAL, gcSk}, // [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW + {0x0300, 0x034E, prCM, gcMn}, // [79] COMBINING GRAVE ACCENT..COMBINING UPWARDS ARROW BELOW + {0x034F, 0x034F, prGL, gcMn}, // COMBINING GRAPHEME JOINER + {0x0350, 0x035B, prCM, gcMn}, // [12] COMBINING RIGHT ARROWHEAD ABOVE..COMBINING ZIGZAG ABOVE + {0x035C, 0x0362, prGL, gcMn}, // [7] COMBINING DOUBLE BREVE BELOW..COMBINING DOUBLE RIGHTWARDS ARROW BELOW + {0x0363, 0x036F, prCM, gcMn}, // [13] COMBINING LATIN SMALL LETTER A..COMBINING LATIN SMALL LETTER X + {0x0370, 0x0373, prAL, gcLC}, // [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI + {0x0374, 0x0374, prAL, gcLm}, // GREEK NUMERAL SIGN + {0x0375, 0x0375, prAL, gcSk}, // GREEK LOWER NUMERAL SIGN + {0x0376, 0x0377, prAL, gcLC}, // [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA + {0x037A, 0x037A, prAL, gcLm}, // GREEK YPOGEGRAMMENI + {0x037B, 0x037D, prAL, gcLl}, // [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x037E, 0x037E, prIS, gcPo}, // GREEK QUESTION MARK + {0x037F, 0x037F, prAL, gcLu}, // GREEK CAPITAL LETTER YOT + {0x0384, 0x0385, prAL, gcSk}, // [2] GREEK TONOS..GREEK DIALYTIKA TONOS + {0x0386, 0x0386, prAL, gcLu}, // GREEK CAPITAL LETTER ALPHA WITH TONOS + {0x0387, 0x0387, prAL, gcPo}, // GREEK ANO TELEIA + {0x0388, 0x038A, prAL, gcLu}, // [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS + {0x038C, 0x038C, prAL, gcLu}, // GREEK CAPITAL LETTER OMICRON WITH TONOS + {0x038E, 0x03A1, prAL, gcLC}, // [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO + {0x03A3, 0x03F5, prAL, gcLC}, // [83] GREEK CAPITAL LETTER SIGMA..GREEK LUNATE EPSILON SYMBOL + {0x03F6, 0x03F6, prAL, gcSm}, // GREEK REVERSED LUNATE EPSILON SYMBOL + {0x03F7, 0x03FF, prAL, gcLC}, // [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x0400, 0x0481, prAL, gcLC}, // [130] CYRILLIC CAPITAL LETTER IE WITH GRAVE..CYRILLIC SMALL LETTER KOPPA + {0x0482, 0x0482, prAL, gcSo}, // CYRILLIC THOUSANDS SIGN + {0x0483, 0x0487, prCM, gcMn}, // [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prCM, gcMe}, // [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x048A, 0x04FF, prAL, gcLC}, // [118] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER HA WITH STROKE + {0x0500, 0x052F, prAL, gcLC}, // [48] CYRILLIC CAPITAL LETTER KOMI DE..CYRILLIC SMALL LETTER EL WITH DESCENDER + {0x0531, 0x0556, prAL, gcLu}, // [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH + {0x0559, 0x0559, prAL, gcLm}, // ARMENIAN MODIFIER LETTER LEFT HALF RING + {0x055A, 0x055F, prAL, gcPo}, // [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK + {0x0560, 0x0588, prAL, gcLl}, // [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE + {0x0589, 0x0589, prIS, gcPo}, // ARMENIAN FULL STOP + {0x058A, 0x058A, prBA, gcPd}, // ARMENIAN HYPHEN + {0x058D, 0x058E, prAL, gcSo}, // [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN + {0x058F, 0x058F, prPR, gcSc}, // ARMENIAN DRAM SIGN + {0x0591, 0x05BD, prCM, gcMn}, // [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BE, 0x05BE, prBA, gcPd}, // HEBREW PUNCTUATION MAQAF + {0x05BF, 0x05BF, prCM, gcMn}, // HEBREW POINT RAFE + {0x05C0, 0x05C0, prAL, gcPo}, // HEBREW PUNCTUATION PASEQ + {0x05C1, 0x05C2, prCM, gcMn}, // [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C3, 0x05C3, prAL, gcPo}, // HEBREW PUNCTUATION SOF PASUQ + {0x05C4, 0x05C5, prCM, gcMn}, // [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C6, 0x05C6, prEX, gcPo}, // HEBREW PUNCTUATION NUN HAFUKHA + {0x05C7, 0x05C7, prCM, gcMn}, // HEBREW POINT QAMATS QATAN + {0x05D0, 0x05EA, prHL, gcLo}, // [27] HEBREW LETTER ALEF..HEBREW LETTER TAV + {0x05EF, 0x05F2, prHL, gcLo}, // [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD + {0x05F3, 0x05F4, prAL, gcPo}, // [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM + {0x0600, 0x0605, prAL, gcCf}, // [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x0606, 0x0608, prAL, gcSm}, // [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY + {0x0609, 0x060A, prPO, gcPo}, // [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN + {0x060B, 0x060B, prPO, gcSc}, // AFGHANI SIGN + {0x060C, 0x060D, prIS, gcPo}, // [2] ARABIC COMMA..ARABIC DATE SEPARATOR + {0x060E, 0x060F, prAL, gcSo}, // [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA + {0x0610, 0x061A, prCM, gcMn}, // [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061B, 0x061B, prEX, gcPo}, // ARABIC SEMICOLON + {0x061C, 0x061C, prCM, gcCf}, // ARABIC LETTER MARK + {0x061D, 0x061F, prEX, gcPo}, // [3] ARABIC END OF TEXT MARK..ARABIC QUESTION MARK + {0x0620, 0x063F, prAL, gcLo}, // [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE + {0x0640, 0x0640, prAL, gcLm}, // ARABIC TATWEEL + {0x0641, 0x064A, prAL, gcLo}, // [10] ARABIC LETTER FEH..ARABIC LETTER YEH + {0x064B, 0x065F, prCM, gcMn}, // [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0660, 0x0669, prNU, gcNd}, // [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE + {0x066A, 0x066A, prPO, gcPo}, // ARABIC PERCENT SIGN + {0x066B, 0x066C, prNU, gcPo}, // [2] ARABIC DECIMAL SEPARATOR..ARABIC THOUSANDS SEPARATOR + {0x066D, 0x066D, prAL, gcPo}, // ARABIC FIVE POINTED STAR + {0x066E, 0x066F, prAL, gcLo}, // [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF + {0x0670, 0x0670, prCM, gcMn}, // ARABIC LETTER SUPERSCRIPT ALEF + {0x0671, 0x06D3, prAL, gcLo}, // [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE + {0x06D4, 0x06D4, prEX, gcPo}, // ARABIC FULL STOP + {0x06D5, 0x06D5, prAL, gcLo}, // ARABIC LETTER AE + {0x06D6, 0x06DC, prCM, gcMn}, // [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prAL, gcCf}, // ARABIC END OF AYAH + {0x06DE, 0x06DE, prAL, gcSo}, // ARABIC START OF RUB EL HIZB + {0x06DF, 0x06E4, prCM, gcMn}, // [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E5, 0x06E6, prAL, gcLm}, // [2] ARABIC SMALL WAW..ARABIC SMALL YEH + {0x06E7, 0x06E8, prCM, gcMn}, // [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06E9, 0x06E9, prAL, gcSo}, // ARABIC PLACE OF SAJDAH + {0x06EA, 0x06ED, prCM, gcMn}, // [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x06EE, 0x06EF, prAL, gcLo}, // [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V + {0x06F0, 0x06F9, prNU, gcNd}, // [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE + {0x06FA, 0x06FC, prAL, gcLo}, // [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW + {0x06FD, 0x06FE, prAL, gcSo}, // [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN + {0x06FF, 0x06FF, prAL, gcLo}, // ARABIC LETTER HEH WITH INVERTED V + {0x0700, 0x070D, prAL, gcPo}, // [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS + {0x070F, 0x070F, prAL, gcCf}, // SYRIAC ABBREVIATION MARK + {0x0710, 0x0710, prAL, gcLo}, // SYRIAC LETTER ALAPH + {0x0711, 0x0711, prCM, gcMn}, // SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0712, 0x072F, prAL, gcLo}, // [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH + {0x0730, 0x074A, prCM, gcMn}, // [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x074D, 0x074F, prAL, gcLo}, // [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE + {0x0750, 0x077F, prAL, gcLo}, // [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE + {0x0780, 0x07A5, prAL, gcLo}, // [38] THAANA LETTER HAA..THAANA LETTER WAAVU + {0x07A6, 0x07B0, prCM, gcMn}, // [11] THAANA ABAFILI..THAANA SUKUN + {0x07B1, 0x07B1, prAL, gcLo}, // THAANA LETTER NAA + {0x07C0, 0x07C9, prNU, gcNd}, // [10] NKO DIGIT ZERO..NKO DIGIT NINE + {0x07CA, 0x07EA, prAL, gcLo}, // [33] NKO LETTER A..NKO LETTER JONA RA + {0x07EB, 0x07F3, prCM, gcMn}, // [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07F4, 0x07F5, prAL, gcLm}, // [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE + {0x07F6, 0x07F6, prAL, gcSo}, // NKO SYMBOL OO DENNEN + {0x07F7, 0x07F7, prAL, gcPo}, // NKO SYMBOL GBAKURUNEN + {0x07F8, 0x07F8, prIS, gcPo}, // NKO COMMA + {0x07F9, 0x07F9, prEX, gcPo}, // NKO EXCLAMATION MARK + {0x07FA, 0x07FA, prAL, gcLm}, // NKO LAJANYALAN + {0x07FD, 0x07FD, prCM, gcMn}, // NKO DANTAYALAN + {0x07FE, 0x07FF, prPR, gcSc}, // [2] NKO DOROME SIGN..NKO TAMAN SIGN + {0x0800, 0x0815, prAL, gcLo}, // [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF + {0x0816, 0x0819, prCM, gcMn}, // [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081A, 0x081A, prAL, gcLm}, // SAMARITAN MODIFIER LETTER EPENTHETIC YUT + {0x081B, 0x0823, prCM, gcMn}, // [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0824, 0x0824, prAL, gcLm}, // SAMARITAN MODIFIER LETTER SHORT A + {0x0825, 0x0827, prCM, gcMn}, // [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0828, 0x0828, prAL, gcLm}, // SAMARITAN MODIFIER LETTER I + {0x0829, 0x082D, prCM, gcMn}, // [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0830, 0x083E, prAL, gcPo}, // [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU + {0x0840, 0x0858, prAL, gcLo}, // [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN + {0x0859, 0x085B, prCM, gcMn}, // [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x085E, 0x085E, prAL, gcPo}, // MANDAIC PUNCTUATION + {0x0860, 0x086A, prAL, gcLo}, // [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA + {0x0870, 0x0887, prAL, gcLo}, // [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT + {0x0888, 0x0888, prAL, gcSk}, // ARABIC RAISED ROUND DOT + {0x0889, 0x088E, prAL, gcLo}, // [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL + {0x0890, 0x0891, prAL, gcCf}, // [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prCM, gcMn}, // [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08A0, 0x08C8, prAL, gcLo}, // [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF + {0x08C9, 0x08C9, prAL, gcLm}, // ARABIC SMALL FARSI YEH + {0x08CA, 0x08E1, prCM, gcMn}, // [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prAL, gcCf}, // ARABIC DISPUTED END OF AYAH + {0x08E3, 0x08FF, prCM, gcMn}, // [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA + {0x0900, 0x0902, prCM, gcMn}, // [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prCM, gcMc}, // DEVANAGARI SIGN VISARGA + {0x0904, 0x0939, prAL, gcLo}, // [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA + {0x093A, 0x093A, prCM, gcMn}, // DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prCM, gcMc}, // DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prCM, gcMn}, // DEVANAGARI SIGN NUKTA + {0x093D, 0x093D, prAL, gcLo}, // DEVANAGARI SIGN AVAGRAHA + {0x093E, 0x0940, prCM, gcMc}, // [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prCM, gcMn}, // [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prCM, gcMc}, // [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prCM, gcMn}, // DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prCM, gcMc}, // [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0950, 0x0950, prAL, gcLo}, // DEVANAGARI OM + {0x0951, 0x0957, prCM, gcMn}, // [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0958, 0x0961, prAL, gcLo}, // [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL + {0x0962, 0x0963, prCM, gcMn}, // [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0964, 0x0965, prBA, gcPo}, // [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA + {0x0966, 0x096F, prNU, gcNd}, // [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE + {0x0970, 0x0970, prAL, gcPo}, // DEVANAGARI ABBREVIATION SIGN + {0x0971, 0x0971, prAL, gcLm}, // DEVANAGARI SIGN HIGH SPACING DOT + {0x0972, 0x097F, prAL, gcLo}, // [14] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER BBA + {0x0980, 0x0980, prAL, gcLo}, // BENGALI ANJI + {0x0981, 0x0981, prCM, gcMn}, // BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prCM, gcMc}, // [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x0985, 0x098C, prAL, gcLo}, // [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L + {0x098F, 0x0990, prAL, gcLo}, // [2] BENGALI LETTER E..BENGALI LETTER AI + {0x0993, 0x09A8, prAL, gcLo}, // [22] BENGALI LETTER O..BENGALI LETTER NA + {0x09AA, 0x09B0, prAL, gcLo}, // [7] BENGALI LETTER PA..BENGALI LETTER RA + {0x09B2, 0x09B2, prAL, gcLo}, // BENGALI LETTER LA + {0x09B6, 0x09B9, prAL, gcLo}, // [4] BENGALI LETTER SHA..BENGALI LETTER HA + {0x09BC, 0x09BC, prCM, gcMn}, // BENGALI SIGN NUKTA + {0x09BD, 0x09BD, prAL, gcLo}, // BENGALI SIGN AVAGRAHA + {0x09BE, 0x09C0, prCM, gcMc}, // [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prCM, gcMn}, // [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prCM, gcMc}, // [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prCM, gcMc}, // [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prCM, gcMn}, // BENGALI SIGN VIRAMA + {0x09CE, 0x09CE, prAL, gcLo}, // BENGALI LETTER KHANDA TA + {0x09D7, 0x09D7, prCM, gcMc}, // BENGALI AU LENGTH MARK + {0x09DC, 0x09DD, prAL, gcLo}, // [2] BENGALI LETTER RRA..BENGALI LETTER RHA + {0x09DF, 0x09E1, prAL, gcLo}, // [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL + {0x09E2, 0x09E3, prCM, gcMn}, // [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09E6, 0x09EF, prNU, gcNd}, // [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE + {0x09F0, 0x09F1, prAL, gcLo}, // [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL + {0x09F2, 0x09F3, prPO, gcSc}, // [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN + {0x09F4, 0x09F8, prAL, gcNo}, // [5] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR + {0x09F9, 0x09F9, prPO, gcNo}, // BENGALI CURRENCY DENOMINATOR SIXTEEN + {0x09FA, 0x09FA, prAL, gcSo}, // BENGALI ISSHAR + {0x09FB, 0x09FB, prPR, gcSc}, // BENGALI GANDA MARK + {0x09FC, 0x09FC, prAL, gcLo}, // BENGALI LETTER VEDIC ANUSVARA + {0x09FD, 0x09FD, prAL, gcPo}, // BENGALI ABBREVIATION SIGN + {0x09FE, 0x09FE, prCM, gcMn}, // BENGALI SANDHI MARK + {0x0A01, 0x0A02, prCM, gcMn}, // [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prCM, gcMc}, // GURMUKHI SIGN VISARGA + {0x0A05, 0x0A0A, prAL, gcLo}, // [6] GURMUKHI LETTER A..GURMUKHI LETTER UU + {0x0A0F, 0x0A10, prAL, gcLo}, // [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI + {0x0A13, 0x0A28, prAL, gcLo}, // [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA + {0x0A2A, 0x0A30, prAL, gcLo}, // [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA + {0x0A32, 0x0A33, prAL, gcLo}, // [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA + {0x0A35, 0x0A36, prAL, gcLo}, // [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA + {0x0A38, 0x0A39, prAL, gcLo}, // [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA + {0x0A3C, 0x0A3C, prCM, gcMn}, // GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prCM, gcMc}, // [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prCM, gcMn}, // [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prCM, gcMn}, // [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prCM, gcMn}, // [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prCM, gcMn}, // GURMUKHI SIGN UDAAT + {0x0A59, 0x0A5C, prAL, gcLo}, // [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA + {0x0A5E, 0x0A5E, prAL, gcLo}, // GURMUKHI LETTER FA + {0x0A66, 0x0A6F, prNU, gcNd}, // [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE + {0x0A70, 0x0A71, prCM, gcMn}, // [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A72, 0x0A74, prAL, gcLo}, // [3] GURMUKHI IRI..GURMUKHI EK ONKAR + {0x0A75, 0x0A75, prCM, gcMn}, // GURMUKHI SIGN YAKASH + {0x0A76, 0x0A76, prAL, gcPo}, // GURMUKHI ABBREVIATION SIGN + {0x0A81, 0x0A82, prCM, gcMn}, // [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prCM, gcMc}, // GUJARATI SIGN VISARGA + {0x0A85, 0x0A8D, prAL, gcLo}, // [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E + {0x0A8F, 0x0A91, prAL, gcLo}, // [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O + {0x0A93, 0x0AA8, prAL, gcLo}, // [22] GUJARATI LETTER O..GUJARATI LETTER NA + {0x0AAA, 0x0AB0, prAL, gcLo}, // [7] GUJARATI LETTER PA..GUJARATI LETTER RA + {0x0AB2, 0x0AB3, prAL, gcLo}, // [2] GUJARATI LETTER LA..GUJARATI LETTER LLA + {0x0AB5, 0x0AB9, prAL, gcLo}, // [5] GUJARATI LETTER VA..GUJARATI LETTER HA + {0x0ABC, 0x0ABC, prCM, gcMn}, // GUJARATI SIGN NUKTA + {0x0ABD, 0x0ABD, prAL, gcLo}, // GUJARATI SIGN AVAGRAHA + {0x0ABE, 0x0AC0, prCM, gcMc}, // [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prCM, gcMn}, // [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prCM, gcMn}, // [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prCM, gcMc}, // GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prCM, gcMc}, // [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prCM, gcMn}, // GUJARATI SIGN VIRAMA + {0x0AD0, 0x0AD0, prAL, gcLo}, // GUJARATI OM + {0x0AE0, 0x0AE1, prAL, gcLo}, // [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL + {0x0AE2, 0x0AE3, prCM, gcMn}, // [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AE6, 0x0AEF, prNU, gcNd}, // [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE + {0x0AF0, 0x0AF0, prAL, gcPo}, // GUJARATI ABBREVIATION SIGN + {0x0AF1, 0x0AF1, prPR, gcSc}, // GUJARATI RUPEE SIGN + {0x0AF9, 0x0AF9, prAL, gcLo}, // GUJARATI LETTER ZHA + {0x0AFA, 0x0AFF, prCM, gcMn}, // [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prCM, gcMn}, // ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prCM, gcMc}, // [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B05, 0x0B0C, prAL, gcLo}, // [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L + {0x0B0F, 0x0B10, prAL, gcLo}, // [2] ORIYA LETTER E..ORIYA LETTER AI + {0x0B13, 0x0B28, prAL, gcLo}, // [22] ORIYA LETTER O..ORIYA LETTER NA + {0x0B2A, 0x0B30, prAL, gcLo}, // [7] ORIYA LETTER PA..ORIYA LETTER RA + {0x0B32, 0x0B33, prAL, gcLo}, // [2] ORIYA LETTER LA..ORIYA LETTER LLA + {0x0B35, 0x0B39, prAL, gcLo}, // [5] ORIYA LETTER VA..ORIYA LETTER HA + {0x0B3C, 0x0B3C, prCM, gcMn}, // ORIYA SIGN NUKTA + {0x0B3D, 0x0B3D, prAL, gcLo}, // ORIYA SIGN AVAGRAHA + {0x0B3E, 0x0B3E, prCM, gcMc}, // ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prCM, gcMn}, // ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prCM, gcMc}, // ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prCM, gcMn}, // [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prCM, gcMc}, // [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prCM, gcMc}, // [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prCM, gcMn}, // ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prCM, gcMn}, // [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prCM, gcMc}, // ORIYA AU LENGTH MARK + {0x0B5C, 0x0B5D, prAL, gcLo}, // [2] ORIYA LETTER RRA..ORIYA LETTER RHA + {0x0B5F, 0x0B61, prAL, gcLo}, // [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL + {0x0B62, 0x0B63, prCM, gcMn}, // [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B66, 0x0B6F, prNU, gcNd}, // [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE + {0x0B70, 0x0B70, prAL, gcSo}, // ORIYA ISSHAR + {0x0B71, 0x0B71, prAL, gcLo}, // ORIYA LETTER WA + {0x0B72, 0x0B77, prAL, gcNo}, // [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS + {0x0B82, 0x0B82, prCM, gcMn}, // TAMIL SIGN ANUSVARA + {0x0B83, 0x0B83, prAL, gcLo}, // TAMIL SIGN VISARGA + {0x0B85, 0x0B8A, prAL, gcLo}, // [6] TAMIL LETTER A..TAMIL LETTER UU + {0x0B8E, 0x0B90, prAL, gcLo}, // [3] TAMIL LETTER E..TAMIL LETTER AI + {0x0B92, 0x0B95, prAL, gcLo}, // [4] TAMIL LETTER O..TAMIL LETTER KA + {0x0B99, 0x0B9A, prAL, gcLo}, // [2] TAMIL LETTER NGA..TAMIL LETTER CA + {0x0B9C, 0x0B9C, prAL, gcLo}, // TAMIL LETTER JA + {0x0B9E, 0x0B9F, prAL, gcLo}, // [2] TAMIL LETTER NYA..TAMIL LETTER TTA + {0x0BA3, 0x0BA4, prAL, gcLo}, // [2] TAMIL LETTER NNA..TAMIL LETTER TA + {0x0BA8, 0x0BAA, prAL, gcLo}, // [3] TAMIL LETTER NA..TAMIL LETTER PA + {0x0BAE, 0x0BB9, prAL, gcLo}, // [12] TAMIL LETTER MA..TAMIL LETTER HA + {0x0BBE, 0x0BBF, prCM, gcMc}, // [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prCM, gcMn}, // TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prCM, gcMc}, // [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prCM, gcMc}, // [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prCM, gcMc}, // [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prCM, gcMn}, // TAMIL SIGN VIRAMA + {0x0BD0, 0x0BD0, prAL, gcLo}, // TAMIL OM + {0x0BD7, 0x0BD7, prCM, gcMc}, // TAMIL AU LENGTH MARK + {0x0BE6, 0x0BEF, prNU, gcNd}, // [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE + {0x0BF0, 0x0BF2, prAL, gcNo}, // [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND + {0x0BF3, 0x0BF8, prAL, gcSo}, // [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN + {0x0BF9, 0x0BF9, prPR, gcSc}, // TAMIL RUPEE SIGN + {0x0BFA, 0x0BFA, prAL, gcSo}, // TAMIL NUMBER SIGN + {0x0C00, 0x0C00, prCM, gcMn}, // TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prCM, gcMc}, // [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prCM, gcMn}, // TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C05, 0x0C0C, prAL, gcLo}, // [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L + {0x0C0E, 0x0C10, prAL, gcLo}, // [3] TELUGU LETTER E..TELUGU LETTER AI + {0x0C12, 0x0C28, prAL, gcLo}, // [23] TELUGU LETTER O..TELUGU LETTER NA + {0x0C2A, 0x0C39, prAL, gcLo}, // [16] TELUGU LETTER PA..TELUGU LETTER HA + {0x0C3C, 0x0C3C, prCM, gcMn}, // TELUGU SIGN NUKTA + {0x0C3D, 0x0C3D, prAL, gcLo}, // TELUGU SIGN AVAGRAHA + {0x0C3E, 0x0C40, prCM, gcMn}, // [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prCM, gcMc}, // [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prCM, gcMn}, // [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prCM, gcMn}, // [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prCM, gcMn}, // [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C58, 0x0C5A, prAL, gcLo}, // [3] TELUGU LETTER TSA..TELUGU LETTER RRRA + {0x0C5D, 0x0C5D, prAL, gcLo}, // TELUGU LETTER NAKAARA POLLU + {0x0C60, 0x0C61, prAL, gcLo}, // [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL + {0x0C62, 0x0C63, prCM, gcMn}, // [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C66, 0x0C6F, prNU, gcNd}, // [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE + {0x0C77, 0x0C77, prBB, gcPo}, // TELUGU SIGN SIDDHAM + {0x0C78, 0x0C7E, prAL, gcNo}, // [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR + {0x0C7F, 0x0C7F, prAL, gcSo}, // TELUGU SIGN TUUMU + {0x0C80, 0x0C80, prAL, gcLo}, // KANNADA SIGN SPACING CANDRABINDU + {0x0C81, 0x0C81, prCM, gcMn}, // KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prCM, gcMc}, // [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0C84, 0x0C84, prBB, gcPo}, // KANNADA SIGN SIDDHAM + {0x0C85, 0x0C8C, prAL, gcLo}, // [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L + {0x0C8E, 0x0C90, prAL, gcLo}, // [3] KANNADA LETTER E..KANNADA LETTER AI + {0x0C92, 0x0CA8, prAL, gcLo}, // [23] KANNADA LETTER O..KANNADA LETTER NA + {0x0CAA, 0x0CB3, prAL, gcLo}, // [10] KANNADA LETTER PA..KANNADA LETTER LLA + {0x0CB5, 0x0CB9, prAL, gcLo}, // [5] KANNADA LETTER VA..KANNADA LETTER HA + {0x0CBC, 0x0CBC, prCM, gcMn}, // KANNADA SIGN NUKTA + {0x0CBD, 0x0CBD, prAL, gcLo}, // KANNADA SIGN AVAGRAHA + {0x0CBE, 0x0CBE, prCM, gcMc}, // KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prCM, gcMn}, // KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC4, prCM, gcMc}, // [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prCM, gcMn}, // KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prCM, gcMc}, // [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prCM, gcMc}, // [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prCM, gcMn}, // [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prCM, gcMc}, // [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CDD, 0x0CDE, prAL, gcLo}, // [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA + {0x0CE0, 0x0CE1, prAL, gcLo}, // [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL + {0x0CE2, 0x0CE3, prCM, gcMn}, // [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CE6, 0x0CEF, prNU, gcNd}, // [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE + {0x0CF1, 0x0CF2, prAL, gcLo}, // [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA + {0x0CF3, 0x0CF3, prCM, gcMc}, // KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prCM, gcMn}, // [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prCM, gcMc}, // [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D04, 0x0D0C, prAL, gcLo}, // [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L + {0x0D0E, 0x0D10, prAL, gcLo}, // [3] MALAYALAM LETTER E..MALAYALAM LETTER AI + {0x0D12, 0x0D3A, prAL, gcLo}, // [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA + {0x0D3B, 0x0D3C, prCM, gcMn}, // [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3D, 0x0D3D, prAL, gcLo}, // MALAYALAM SIGN AVAGRAHA + {0x0D3E, 0x0D40, prCM, gcMc}, // [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prCM, gcMn}, // [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prCM, gcMc}, // [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prCM, gcMc}, // [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prCM, gcMn}, // MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prAL, gcLo}, // MALAYALAM LETTER DOT REPH + {0x0D4F, 0x0D4F, prAL, gcSo}, // MALAYALAM SIGN PARA + {0x0D54, 0x0D56, prAL, gcLo}, // [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL + {0x0D57, 0x0D57, prCM, gcMc}, // MALAYALAM AU LENGTH MARK + {0x0D58, 0x0D5E, prAL, gcNo}, // [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH + {0x0D5F, 0x0D61, prAL, gcLo}, // [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL + {0x0D62, 0x0D63, prCM, gcMn}, // [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D66, 0x0D6F, prNU, gcNd}, // [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE + {0x0D70, 0x0D78, prAL, gcNo}, // [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS + {0x0D79, 0x0D79, prPO, gcSo}, // MALAYALAM DATE MARK + {0x0D7A, 0x0D7F, prAL, gcLo}, // [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K + {0x0D81, 0x0D81, prCM, gcMn}, // SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prCM, gcMc}, // [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0D85, 0x0D96, prAL, gcLo}, // [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA + {0x0D9A, 0x0DB1, prAL, gcLo}, // [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA + {0x0DB3, 0x0DBB, prAL, gcLo}, // [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA + {0x0DBD, 0x0DBD, prAL, gcLo}, // SINHALA LETTER DANTAJA LAYANNA + {0x0DC0, 0x0DC6, prAL, gcLo}, // [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA + {0x0DCA, 0x0DCA, prCM, gcMn}, // SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DD1, prCM, gcMc}, // [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prCM, gcMn}, // [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prCM, gcMn}, // SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDF, prCM, gcMc}, // [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA + {0x0DE6, 0x0DEF, prNU, gcNd}, // [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE + {0x0DF2, 0x0DF3, prCM, gcMc}, // [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0DF4, 0x0DF4, prAL, gcPo}, // SINHALA PUNCTUATION KUNDDALIYA + {0x0E01, 0x0E30, prSA, gcLo}, // [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A + {0x0E31, 0x0E31, prSA, gcMn}, // THAI CHARACTER MAI HAN-AKAT + {0x0E32, 0x0E33, prSA, gcLo}, // [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM + {0x0E34, 0x0E3A, prSA, gcMn}, // [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E3F, 0x0E3F, prPR, gcSc}, // THAI CURRENCY SYMBOL BAHT + {0x0E40, 0x0E45, prSA, gcLo}, // [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO + {0x0E46, 0x0E46, prSA, gcLm}, // THAI CHARACTER MAIYAMOK + {0x0E47, 0x0E4E, prSA, gcMn}, // [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0E4F, 0x0E4F, prAL, gcPo}, // THAI CHARACTER FONGMAN + {0x0E50, 0x0E59, prNU, gcNd}, // [10] THAI DIGIT ZERO..THAI DIGIT NINE + {0x0E5A, 0x0E5B, prBA, gcPo}, // [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT + {0x0E81, 0x0E82, prSA, gcLo}, // [2] LAO LETTER KO..LAO LETTER KHO SUNG + {0x0E84, 0x0E84, prSA, gcLo}, // LAO LETTER KHO TAM + {0x0E86, 0x0E8A, prSA, gcLo}, // [5] LAO LETTER PALI GHA..LAO LETTER SO TAM + {0x0E8C, 0x0EA3, prSA, gcLo}, // [24] LAO LETTER PALI JHA..LAO LETTER LO LING + {0x0EA5, 0x0EA5, prSA, gcLo}, // LAO LETTER LO LOOT + {0x0EA7, 0x0EB0, prSA, gcLo}, // [10] LAO LETTER WO..LAO VOWEL SIGN A + {0x0EB1, 0x0EB1, prSA, gcMn}, // LAO VOWEL SIGN MAI KAN + {0x0EB2, 0x0EB3, prSA, gcLo}, // [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM + {0x0EB4, 0x0EBC, prSA, gcMn}, // [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EBD, 0x0EBD, prSA, gcLo}, // LAO SEMIVOWEL SIGN NYO + {0x0EC0, 0x0EC4, prSA, gcLo}, // [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI + {0x0EC6, 0x0EC6, prSA, gcLm}, // LAO KO LA + {0x0EC8, 0x0ECE, prSA, gcMn}, // [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0ED0, 0x0ED9, prNU, gcNd}, // [10] LAO DIGIT ZERO..LAO DIGIT NINE + {0x0EDC, 0x0EDF, prSA, gcLo}, // [4] LAO HO NO..LAO LETTER KHMU NYO + {0x0F00, 0x0F00, prAL, gcLo}, // TIBETAN SYLLABLE OM + {0x0F01, 0x0F03, prBB, gcSo}, // [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA + {0x0F04, 0x0F04, prBB, gcPo}, // TIBETAN MARK INITIAL YIG MGO MDUN MA + {0x0F05, 0x0F05, prAL, gcPo}, // TIBETAN MARK CLOSING YIG MGO SGAB MA + {0x0F06, 0x0F07, prBB, gcPo}, // [2] TIBETAN MARK CARET YIG MGO PHUR SHAD MA..TIBETAN MARK YIG MGO TSHEG SHAD MA + {0x0F08, 0x0F08, prGL, gcPo}, // TIBETAN MARK SBRUL SHAD + {0x0F09, 0x0F0A, prBB, gcPo}, // [2] TIBETAN MARK BSKUR YIG MGO..TIBETAN MARK BKA- SHOG YIG MGO + {0x0F0B, 0x0F0B, prBA, gcPo}, // TIBETAN MARK INTERSYLLABIC TSHEG + {0x0F0C, 0x0F0C, prGL, gcPo}, // TIBETAN MARK DELIMITER TSHEG BSTAR + {0x0F0D, 0x0F11, prEX, gcPo}, // [5] TIBETAN MARK SHAD..TIBETAN MARK RIN CHEN SPUNGS SHAD + {0x0F12, 0x0F12, prGL, gcPo}, // TIBETAN MARK RGYA GRAM SHAD + {0x0F13, 0x0F13, prAL, gcSo}, // TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN + {0x0F14, 0x0F14, prEX, gcPo}, // TIBETAN MARK GTER TSHEG + {0x0F15, 0x0F17, prAL, gcSo}, // [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS + {0x0F18, 0x0F19, prCM, gcMn}, // [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F1A, 0x0F1F, prAL, gcSo}, // [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG + {0x0F20, 0x0F29, prNU, gcNd}, // [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE + {0x0F2A, 0x0F33, prAL, gcNo}, // [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO + {0x0F34, 0x0F34, prBA, gcSo}, // TIBETAN MARK BSDUS RTAGS + {0x0F35, 0x0F35, prCM, gcMn}, // TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F36, 0x0F36, prAL, gcSo}, // TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN + {0x0F37, 0x0F37, prCM, gcMn}, // TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F38, 0x0F38, prAL, gcSo}, // TIBETAN MARK CHE MGO + {0x0F39, 0x0F39, prCM, gcMn}, // TIBETAN MARK TSA -PHRU + {0x0F3A, 0x0F3A, prOP, gcPs}, // TIBETAN MARK GUG RTAGS GYON + {0x0F3B, 0x0F3B, prCL, gcPe}, // TIBETAN MARK GUG RTAGS GYAS + {0x0F3C, 0x0F3C, prOP, gcPs}, // TIBETAN MARK ANG KHANG GYON + {0x0F3D, 0x0F3D, prCL, gcPe}, // TIBETAN MARK ANG KHANG GYAS + {0x0F3E, 0x0F3F, prCM, gcMc}, // [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F40, 0x0F47, prAL, gcLo}, // [8] TIBETAN LETTER KA..TIBETAN LETTER JA + {0x0F49, 0x0F6C, prAL, gcLo}, // [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA + {0x0F71, 0x0F7E, prCM, gcMn}, // [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prBA, gcMc}, // TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prCM, gcMn}, // [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F85, 0x0F85, prBA, gcPo}, // TIBETAN MARK PALUTA + {0x0F86, 0x0F87, prCM, gcMn}, // [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F88, 0x0F8C, prAL, gcLo}, // [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN + {0x0F8D, 0x0F97, prCM, gcMn}, // [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prCM, gcMn}, // [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FBE, 0x0FBF, prBA, gcSo}, // [2] TIBETAN KU RU KHA..TIBETAN KU RU KHA BZHI MIG CAN + {0x0FC0, 0x0FC5, prAL, gcSo}, // [6] TIBETAN CANTILLATION SIGN HEAVY BEAT..TIBETAN SYMBOL RDO RJE + {0x0FC6, 0x0FC6, prCM, gcMn}, // TIBETAN SYMBOL PADMA GDAN + {0x0FC7, 0x0FCC, prAL, gcSo}, // [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL + {0x0FCE, 0x0FCF, prAL, gcSo}, // [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM + {0x0FD0, 0x0FD1, prBB, gcPo}, // [2] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK MNYAM YIG GI MGO RGYAN + {0x0FD2, 0x0FD2, prBA, gcPo}, // TIBETAN MARK NYIS TSHEG + {0x0FD3, 0x0FD3, prBB, gcPo}, // TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA + {0x0FD4, 0x0FD4, prAL, gcPo}, // TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA + {0x0FD5, 0x0FD8, prAL, gcSo}, // [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS + {0x0FD9, 0x0FDA, prGL, gcPo}, // [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS + {0x1000, 0x102A, prSA, gcLo}, // [43] MYANMAR LETTER KA..MYANMAR LETTER AU + {0x102B, 0x102C, prSA, gcMc}, // [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA + {0x102D, 0x1030, prSA, gcMn}, // [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prSA, gcMc}, // MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prSA, gcMn}, // [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1038, 0x1038, prSA, gcMc}, // MYANMAR SIGN VISARGA + {0x1039, 0x103A, prSA, gcMn}, // [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prSA, gcMc}, // [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prSA, gcMn}, // [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x103F, 0x103F, prSA, gcLo}, // MYANMAR LETTER GREAT SA + {0x1040, 0x1049, prNU, gcNd}, // [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE + {0x104A, 0x104B, prBA, gcPo}, // [2] MYANMAR SIGN LITTLE SECTION..MYANMAR SIGN SECTION + {0x104C, 0x104F, prAL, gcPo}, // [4] MYANMAR SYMBOL LOCATIVE..MYANMAR SYMBOL GENITIVE + {0x1050, 0x1055, prSA, gcLo}, // [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL + {0x1056, 0x1057, prSA, gcMc}, // [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prSA, gcMn}, // [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105A, 0x105D, prSA, gcLo}, // [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE + {0x105E, 0x1060, prSA, gcMn}, // [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1061, 0x1061, prSA, gcLo}, // MYANMAR LETTER SGAW KAREN SHA + {0x1062, 0x1064, prSA, gcMc}, // [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO + {0x1065, 0x1066, prSA, gcLo}, // [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA + {0x1067, 0x106D, prSA, gcMc}, // [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 + {0x106E, 0x1070, prSA, gcLo}, // [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA + {0x1071, 0x1074, prSA, gcMn}, // [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1075, 0x1081, prSA, gcLo}, // [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA + {0x1082, 0x1082, prSA, gcMn}, // MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1083, 0x1084, prSA, gcMc}, // [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prSA, gcMn}, // [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x1087, 0x108C, prSA, gcMc}, // [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 + {0x108D, 0x108D, prSA, gcMn}, // MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x108E, 0x108E, prSA, gcLo}, // MYANMAR LETTER RUMAI PALAUNG FA + {0x108F, 0x108F, prSA, gcMc}, // MYANMAR SIGN RUMAI PALAUNG TONE-5 + {0x1090, 0x1099, prNU, gcNd}, // [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE + {0x109A, 0x109C, prSA, gcMc}, // [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A + {0x109D, 0x109D, prSA, gcMn}, // MYANMAR VOWEL SIGN AITON AI + {0x109E, 0x109F, prSA, gcSo}, // [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION + {0x10A0, 0x10C5, prAL, gcLu}, // [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE + {0x10C7, 0x10C7, prAL, gcLu}, // GEORGIAN CAPITAL LETTER YN + {0x10CD, 0x10CD, prAL, gcLu}, // GEORGIAN CAPITAL LETTER AEN + {0x10D0, 0x10FA, prAL, gcLl}, // [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN + {0x10FB, 0x10FB, prAL, gcPo}, // GEORGIAN PARAGRAPH SEPARATOR + {0x10FC, 0x10FC, prAL, gcLm}, // MODIFIER LETTER GEORGIAN NAR + {0x10FD, 0x10FF, prAL, gcLl}, // [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN + {0x1100, 0x115F, prJL, gcLo}, // [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER + {0x1160, 0x11A7, prJV, gcLo}, // [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE + {0x11A8, 0x11FF, prJT, gcLo}, // [88] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG SSANGNIEUN + {0x1200, 0x1248, prAL, gcLo}, // [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA + {0x124A, 0x124D, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE + {0x1250, 0x1256, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO + {0x1258, 0x1258, prAL, gcLo}, // ETHIOPIC SYLLABLE QHWA + {0x125A, 0x125D, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE + {0x1260, 0x1288, prAL, gcLo}, // [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA + {0x128A, 0x128D, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE + {0x1290, 0x12B0, prAL, gcLo}, // [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA + {0x12B2, 0x12B5, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE + {0x12B8, 0x12BE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO + {0x12C0, 0x12C0, prAL, gcLo}, // ETHIOPIC SYLLABLE KXWA + {0x12C2, 0x12C5, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE + {0x12C8, 0x12D6, prAL, gcLo}, // [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O + {0x12D8, 0x1310, prAL, gcLo}, // [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA + {0x1312, 0x1315, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE + {0x1318, 0x135A, prAL, gcLo}, // [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA + {0x135D, 0x135F, prCM, gcMn}, // [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1360, 0x1360, prAL, gcPo}, // ETHIOPIC SECTION MARK + {0x1361, 0x1361, prBA, gcPo}, // ETHIOPIC WORDSPACE + {0x1362, 0x1368, prAL, gcPo}, // [7] ETHIOPIC FULL STOP..ETHIOPIC PARAGRAPH SEPARATOR + {0x1369, 0x137C, prAL, gcNo}, // [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND + {0x1380, 0x138F, prAL, gcLo}, // [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE + {0x1390, 0x1399, prAL, gcSo}, // [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT + {0x13A0, 0x13F5, prAL, gcLu}, // [86] CHEROKEE LETTER A..CHEROKEE LETTER MV + {0x13F8, 0x13FD, prAL, gcLl}, // [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV + {0x1400, 0x1400, prBA, gcPd}, // CANADIAN SYLLABICS HYPHEN + {0x1401, 0x166C, prAL, gcLo}, // [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA + {0x166D, 0x166D, prAL, gcSo}, // CANADIAN SYLLABICS CHI SIGN + {0x166E, 0x166E, prAL, gcPo}, // CANADIAN SYLLABICS FULL STOP + {0x166F, 0x167F, prAL, gcLo}, // [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W + {0x1680, 0x1680, prBA, gcZs}, // OGHAM SPACE MARK + {0x1681, 0x169A, prAL, gcLo}, // [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH + {0x169B, 0x169B, prOP, gcPs}, // OGHAM FEATHER MARK + {0x169C, 0x169C, prCL, gcPe}, // OGHAM REVERSED FEATHER MARK + {0x16A0, 0x16EA, prAL, gcLo}, // [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X + {0x16EB, 0x16ED, prBA, gcPo}, // [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION + {0x16EE, 0x16F0, prAL, gcNl}, // [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL + {0x16F1, 0x16F8, prAL, gcLo}, // [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC + {0x1700, 0x1711, prAL, gcLo}, // [18] TAGALOG LETTER A..TAGALOG LETTER HA + {0x1712, 0x1714, prCM, gcMn}, // [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prCM, gcMc}, // TAGALOG SIGN PAMUDPOD + {0x171F, 0x171F, prAL, gcLo}, // TAGALOG LETTER ARCHAIC RA + {0x1720, 0x1731, prAL, gcLo}, // [18] HANUNOO LETTER A..HANUNOO LETTER HA + {0x1732, 0x1733, prCM, gcMn}, // [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prCM, gcMc}, // HANUNOO SIGN PAMUDPOD + {0x1735, 0x1736, prBA, gcPo}, // [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION + {0x1740, 0x1751, prAL, gcLo}, // [18] BUHID LETTER A..BUHID LETTER HA + {0x1752, 0x1753, prCM, gcMn}, // [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1760, 0x176C, prAL, gcLo}, // [13] TAGBANWA LETTER A..TAGBANWA LETTER YA + {0x176E, 0x1770, prAL, gcLo}, // [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA + {0x1772, 0x1773, prCM, gcMn}, // [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x1780, 0x17B3, prSA, gcLo}, // [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU + {0x17B4, 0x17B5, prSA, gcMn}, // [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prSA, gcMc}, // KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prSA, gcMn}, // [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prSA, gcMc}, // [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prSA, gcMn}, // KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prSA, gcMc}, // [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prSA, gcMn}, // [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17D4, 0x17D5, prBA, gcPo}, // [2] KHMER SIGN KHAN..KHMER SIGN BARIYOOSAN + {0x17D6, 0x17D6, prNS, gcPo}, // KHMER SIGN CAMNUC PII KUUH + {0x17D7, 0x17D7, prSA, gcLm}, // KHMER SIGN LEK TOO + {0x17D8, 0x17D8, prBA, gcPo}, // KHMER SIGN BEYYAL + {0x17D9, 0x17D9, prAL, gcPo}, // KHMER SIGN PHNAEK MUAN + {0x17DA, 0x17DA, prBA, gcPo}, // KHMER SIGN KOOMUUT + {0x17DB, 0x17DB, prPR, gcSc}, // KHMER CURRENCY SYMBOL RIEL + {0x17DC, 0x17DC, prSA, gcLo}, // KHMER SIGN AVAKRAHASANYA + {0x17DD, 0x17DD, prSA, gcMn}, // KHMER SIGN ATTHACAN + {0x17E0, 0x17E9, prNU, gcNd}, // [10] KHMER DIGIT ZERO..KHMER DIGIT NINE + {0x17F0, 0x17F9, prAL, gcNo}, // [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON + {0x1800, 0x1801, prAL, gcPo}, // [2] MONGOLIAN BIRGA..MONGOLIAN ELLIPSIS + {0x1802, 0x1803, prEX, gcPo}, // [2] MONGOLIAN COMMA..MONGOLIAN FULL STOP + {0x1804, 0x1805, prBA, gcPo}, // [2] MONGOLIAN COLON..MONGOLIAN FOUR DOTS + {0x1806, 0x1806, prBB, gcPd}, // MONGOLIAN TODO SOFT HYPHEN + {0x1807, 0x1807, prAL, gcPo}, // MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER + {0x1808, 0x1809, prEX, gcPo}, // [2] MONGOLIAN MANCHU COMMA..MONGOLIAN MANCHU FULL STOP + {0x180A, 0x180A, prAL, gcPo}, // MONGOLIAN NIRUGU + {0x180B, 0x180D, prCM, gcMn}, // [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prGL, gcCf}, // MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prCM, gcMn}, // MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1810, 0x1819, prNU, gcNd}, // [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE + {0x1820, 0x1842, prAL, gcLo}, // [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI + {0x1843, 0x1843, prAL, gcLm}, // MONGOLIAN LETTER TODO LONG VOWEL SIGN + {0x1844, 0x1878, prAL, gcLo}, // [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS + {0x1880, 0x1884, prAL, gcLo}, // [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA + {0x1885, 0x1886, prCM, gcMn}, // [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x1887, 0x18A8, prAL, gcLo}, // [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA + {0x18A9, 0x18A9, prCM, gcMn}, // MONGOLIAN LETTER ALI GALI DAGALGA + {0x18AA, 0x18AA, prAL, gcLo}, // MONGOLIAN LETTER MANCHU ALI GALI LHA + {0x18B0, 0x18F5, prAL, gcLo}, // [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S + {0x1900, 0x191E, prAL, gcLo}, // [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA + {0x1920, 0x1922, prCM, gcMn}, // [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prCM, gcMc}, // [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prCM, gcMn}, // [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prCM, gcMc}, // [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prCM, gcMc}, // [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prCM, gcMn}, // LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prCM, gcMc}, // [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prCM, gcMn}, // [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1940, 0x1940, prAL, gcSo}, // LIMBU SIGN LOO + {0x1944, 0x1945, prEX, gcPo}, // [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK + {0x1946, 0x194F, prNU, gcNd}, // [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE + {0x1950, 0x196D, prSA, gcLo}, // [30] TAI LE LETTER KA..TAI LE LETTER AI + {0x1970, 0x1974, prSA, gcLo}, // [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 + {0x1980, 0x19AB, prSA, gcLo}, // [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA + {0x19B0, 0x19C9, prSA, gcLo}, // [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2 + {0x19D0, 0x19D9, prNU, gcNd}, // [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE + {0x19DA, 0x19DA, prSA, gcNo}, // NEW TAI LUE THAM DIGIT ONE + {0x19DE, 0x19DF, prSA, gcSo}, // [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV + {0x19E0, 0x19FF, prAL, gcSo}, // [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC + {0x1A00, 0x1A16, prAL, gcLo}, // [23] BUGINESE LETTER KA..BUGINESE LETTER HA + {0x1A17, 0x1A18, prCM, gcMn}, // [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prCM, gcMc}, // [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prCM, gcMn}, // BUGINESE VOWEL SIGN AE + {0x1A1E, 0x1A1F, prAL, gcPo}, // [2] BUGINESE PALLAWA..BUGINESE END OF SECTION + {0x1A20, 0x1A54, prSA, gcLo}, // [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA + {0x1A55, 0x1A55, prSA, gcMc}, // TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prSA, gcMn}, // TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prSA, gcMc}, // TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prSA, gcMn}, // [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prSA, gcMn}, // TAI THAM SIGN SAKOT + {0x1A61, 0x1A61, prSA, gcMc}, // TAI THAM VOWEL SIGN A + {0x1A62, 0x1A62, prSA, gcMn}, // TAI THAM VOWEL SIGN MAI SAT + {0x1A63, 0x1A64, prSA, gcMc}, // [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA + {0x1A65, 0x1A6C, prSA, gcMn}, // [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prSA, gcMc}, // [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prSA, gcMn}, // [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prCM, gcMn}, // TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1A80, 0x1A89, prNU, gcNd}, // [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE + {0x1A90, 0x1A99, prNU, gcNd}, // [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE + {0x1AA0, 0x1AA6, prSA, gcPo}, // [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA + {0x1AA7, 0x1AA7, prSA, gcLm}, // TAI THAM SIGN MAI YAMOK + {0x1AA8, 0x1AAD, prSA, gcPo}, // [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG + {0x1AB0, 0x1ABD, prCM, gcMn}, // [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prCM, gcMe}, // COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prCM, gcMn}, // [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prCM, gcMn}, // [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prCM, gcMc}, // BALINESE SIGN BISAH + {0x1B05, 0x1B33, prAL, gcLo}, // [47] BALINESE LETTER AKARA..BALINESE LETTER HA + {0x1B34, 0x1B34, prCM, gcMn}, // BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prCM, gcMc}, // BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prCM, gcMn}, // [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prCM, gcMc}, // BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prCM, gcMn}, // BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prCM, gcMc}, // [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prCM, gcMn}, // BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prCM, gcMc}, // [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B45, 0x1B4C, prAL, gcLo}, // [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA + {0x1B50, 0x1B59, prNU, gcNd}, // [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE + {0x1B5A, 0x1B5B, prBA, gcPo}, // [2] BALINESE PANTI..BALINESE PAMADA + {0x1B5C, 0x1B5C, prAL, gcPo}, // BALINESE WINDU + {0x1B5D, 0x1B60, prBA, gcPo}, // [4] BALINESE CARIK PAMUNGKAH..BALINESE PAMENENG + {0x1B61, 0x1B6A, prAL, gcSo}, // [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE + {0x1B6B, 0x1B73, prCM, gcMn}, // [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B74, 0x1B7C, prAL, gcSo}, // [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING + {0x1B7D, 0x1B7E, prBA, gcPo}, // [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG + {0x1B80, 0x1B81, prCM, gcMn}, // [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prCM, gcMc}, // SUNDANESE SIGN PANGWISAD + {0x1B83, 0x1BA0, prAL, gcLo}, // [30] SUNDANESE LETTER A..SUNDANESE LETTER HA + {0x1BA1, 0x1BA1, prCM, gcMc}, // SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prCM, gcMn}, // [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prCM, gcMc}, // [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prCM, gcMn}, // [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prCM, gcMc}, // SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prCM, gcMn}, // [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BAE, 0x1BAF, prAL, gcLo}, // [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA + {0x1BB0, 0x1BB9, prNU, gcNd}, // [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE + {0x1BBA, 0x1BBF, prAL, gcLo}, // [6] SUNDANESE AVAGRAHA..SUNDANESE LETTER FINAL M + {0x1BC0, 0x1BE5, prAL, gcLo}, // [38] BATAK LETTER A..BATAK LETTER U + {0x1BE6, 0x1BE6, prCM, gcMn}, // BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prCM, gcMc}, // BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prCM, gcMn}, // [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prCM, gcMc}, // [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prCM, gcMn}, // BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prCM, gcMc}, // BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prCM, gcMn}, // [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prCM, gcMc}, // [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1BFC, 0x1BFF, prAL, gcPo}, // [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT + {0x1C00, 0x1C23, prAL, gcLo}, // [36] LEPCHA LETTER KA..LEPCHA LETTER A + {0x1C24, 0x1C2B, prCM, gcMc}, // [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prCM, gcMn}, // [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prCM, gcMc}, // [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prCM, gcMn}, // [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1C3B, 0x1C3F, prBA, gcPo}, // [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK + {0x1C40, 0x1C49, prNU, gcNd}, // [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE + {0x1C4D, 0x1C4F, prAL, gcLo}, // [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA + {0x1C50, 0x1C59, prNU, gcNd}, // [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE + {0x1C5A, 0x1C77, prAL, gcLo}, // [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH + {0x1C78, 0x1C7D, prAL, gcLm}, // [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD + {0x1C7E, 0x1C7F, prBA, gcPo}, // [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD + {0x1C80, 0x1C88, prAL, gcLl}, // [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK + {0x1C90, 0x1CBA, prAL, gcLu}, // [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN + {0x1CBD, 0x1CBF, prAL, gcLu}, // [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN + {0x1CC0, 0x1CC7, prAL, gcPo}, // [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA + {0x1CD0, 0x1CD2, prCM, gcMn}, // [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD3, 0x1CD3, prAL, gcPo}, // VEDIC SIGN NIHSHVASA + {0x1CD4, 0x1CE0, prCM, gcMn}, // [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prCM, gcMc}, // VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prCM, gcMn}, // [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CE9, 0x1CEC, prAL, gcLo}, // [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL + {0x1CED, 0x1CED, prCM, gcMn}, // VEDIC SIGN TIRYAK + {0x1CEE, 0x1CF3, prAL, gcLo}, // [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA + {0x1CF4, 0x1CF4, prCM, gcMn}, // VEDIC TONE CANDRA ABOVE + {0x1CF5, 0x1CF6, prAL, gcLo}, // [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA + {0x1CF7, 0x1CF7, prCM, gcMc}, // VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prCM, gcMn}, // [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1CFA, 0x1CFA, prAL, gcLo}, // VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA + {0x1D00, 0x1D2B, prAL, gcLl}, // [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL + {0x1D2C, 0x1D6A, prAL, gcLm}, // [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI + {0x1D6B, 0x1D77, prAL, gcLl}, // [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G + {0x1D78, 0x1D78, prAL, gcLm}, // MODIFIER LETTER CYRILLIC EN + {0x1D79, 0x1D7F, prAL, gcLl}, // [7] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER UPSILON WITH STROKE + {0x1D80, 0x1D9A, prAL, gcLl}, // [27] LATIN SMALL LETTER B WITH PALATAL HOOK..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK + {0x1D9B, 0x1DBF, prAL, gcLm}, // [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA + {0x1DC0, 0x1DCC, prCM, gcMn}, // [13] COMBINING DOTTED GRAVE ACCENT..COMBINING MACRON-BREVE + {0x1DCD, 0x1DCD, prGL, gcMn}, // COMBINING DOUBLE CIRCUMFLEX ABOVE + {0x1DCE, 0x1DFB, prCM, gcMn}, // [46] COMBINING OGONEK ABOVE..COMBINING DELETION MARK + {0x1DFC, 0x1DFC, prGL, gcMn}, // COMBINING DOUBLE INVERTED BREVE BELOW + {0x1DFD, 0x1DFF, prCM, gcMn}, // [3] COMBINING ALMOST EQUAL TO BELOW..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x1E00, 0x1EFF, prAL, gcLC}, // [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP + {0x1F00, 0x1F15, prAL, gcLC}, // [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA + {0x1F18, 0x1F1D, prAL, gcLu}, // [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA + {0x1F20, 0x1F45, prAL, gcLC}, // [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA + {0x1F48, 0x1F4D, prAL, gcLu}, // [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA + {0x1F50, 0x1F57, prAL, gcLl}, // [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F59, 0x1F59, prAL, gcLu}, // GREEK CAPITAL LETTER UPSILON WITH DASIA + {0x1F5B, 0x1F5B, prAL, gcLu}, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA + {0x1F5D, 0x1F5D, prAL, gcLu}, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA + {0x1F5F, 0x1F7D, prAL, gcLC}, // [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA + {0x1F80, 0x1FB4, prAL, gcLC}, // [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI + {0x1FB6, 0x1FBC, prAL, gcLC}, // [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI + {0x1FBD, 0x1FBD, prAL, gcSk}, // GREEK KORONIS + {0x1FBE, 0x1FBE, prAL, gcLl}, // GREEK PROSGEGRAMMENI + {0x1FBF, 0x1FC1, prAL, gcSk}, // [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI + {0x1FC2, 0x1FC4, prAL, gcLl}, // [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI + {0x1FC6, 0x1FCC, prAL, gcLC}, // [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI + {0x1FCD, 0x1FCF, prAL, gcSk}, // [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI + {0x1FD0, 0x1FD3, prAL, gcLl}, // [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + {0x1FD6, 0x1FDB, prAL, gcLC}, // [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA + {0x1FDD, 0x1FDF, prAL, gcSk}, // [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI + {0x1FE0, 0x1FEC, prAL, gcLC}, // [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA + {0x1FED, 0x1FEF, prAL, gcSk}, // [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA + {0x1FF2, 0x1FF4, prAL, gcLl}, // [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI + {0x1FF6, 0x1FFC, prAL, gcLC}, // [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + {0x1FFD, 0x1FFD, prBB, gcSk}, // GREEK OXIA + {0x1FFE, 0x1FFE, prAL, gcSk}, // GREEK DASIA + {0x2000, 0x2006, prBA, gcZs}, // [7] EN QUAD..SIX-PER-EM SPACE + {0x2007, 0x2007, prGL, gcZs}, // FIGURE SPACE + {0x2008, 0x200A, prBA, gcZs}, // [3] PUNCTUATION SPACE..HAIR SPACE + {0x200B, 0x200B, prZW, gcCf}, // ZERO WIDTH SPACE + {0x200C, 0x200C, prCM, gcCf}, // ZERO WIDTH NON-JOINER + {0x200D, 0x200D, prZWJ, gcCf}, // ZERO WIDTH JOINER + {0x200E, 0x200F, prCM, gcCf}, // [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK + {0x2010, 0x2010, prBA, gcPd}, // HYPHEN + {0x2011, 0x2011, prGL, gcPd}, // NON-BREAKING HYPHEN + {0x2012, 0x2013, prBA, gcPd}, // [2] FIGURE DASH..EN DASH + {0x2014, 0x2014, prB2, gcPd}, // EM DASH + {0x2015, 0x2015, prAI, gcPd}, // HORIZONTAL BAR + {0x2016, 0x2016, prAI, gcPo}, // DOUBLE VERTICAL LINE + {0x2017, 0x2017, prAL, gcPo}, // DOUBLE LOW LINE + {0x2018, 0x2018, prQU, gcPi}, // LEFT SINGLE QUOTATION MARK + {0x2019, 0x2019, prQU, gcPf}, // RIGHT SINGLE QUOTATION MARK + {0x201A, 0x201A, prOP, gcPs}, // SINGLE LOW-9 QUOTATION MARK + {0x201B, 0x201C, prQU, gcPi}, // [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK + {0x201D, 0x201D, prQU, gcPf}, // RIGHT DOUBLE QUOTATION MARK + {0x201E, 0x201E, prOP, gcPs}, // DOUBLE LOW-9 QUOTATION MARK + {0x201F, 0x201F, prQU, gcPi}, // DOUBLE HIGH-REVERSED-9 QUOTATION MARK + {0x2020, 0x2021, prAI, gcPo}, // [2] DAGGER..DOUBLE DAGGER + {0x2022, 0x2023, prAL, gcPo}, // [2] BULLET..TRIANGULAR BULLET + {0x2024, 0x2026, prIN, gcPo}, // [3] ONE DOT LEADER..HORIZONTAL ELLIPSIS + {0x2027, 0x2027, prBA, gcPo}, // HYPHENATION POINT + {0x2028, 0x2028, prBK, gcZl}, // LINE SEPARATOR + {0x2029, 0x2029, prBK, gcZp}, // PARAGRAPH SEPARATOR + {0x202A, 0x202E, prCM, gcCf}, // [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x202F, 0x202F, prGL, gcZs}, // NARROW NO-BREAK SPACE + {0x2030, 0x2037, prPO, gcPo}, // [8] PER MILLE SIGN..REVERSED TRIPLE PRIME + {0x2038, 0x2038, prAL, gcPo}, // CARET + {0x2039, 0x2039, prQU, gcPi}, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK + {0x203A, 0x203A, prQU, gcPf}, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + {0x203B, 0x203B, prAI, gcPo}, // REFERENCE MARK + {0x203C, 0x203D, prNS, gcPo}, // [2] DOUBLE EXCLAMATION MARK..INTERROBANG + {0x203E, 0x203E, prAL, gcPo}, // OVERLINE + {0x203F, 0x2040, prAL, gcPc}, // [2] UNDERTIE..CHARACTER TIE + {0x2041, 0x2043, prAL, gcPo}, // [3] CARET INSERTION POINT..HYPHEN BULLET + {0x2044, 0x2044, prIS, gcSm}, // FRACTION SLASH + {0x2045, 0x2045, prOP, gcPs}, // LEFT SQUARE BRACKET WITH QUILL + {0x2046, 0x2046, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH QUILL + {0x2047, 0x2049, prNS, gcPo}, // [3] DOUBLE QUESTION MARK..EXCLAMATION QUESTION MARK + {0x204A, 0x2051, prAL, gcPo}, // [8] TIRONIAN SIGN ET..TWO ASTERISKS ALIGNED VERTICALLY + {0x2052, 0x2052, prAL, gcSm}, // COMMERCIAL MINUS SIGN + {0x2053, 0x2053, prAL, gcPo}, // SWUNG DASH + {0x2054, 0x2054, prAL, gcPc}, // INVERTED UNDERTIE + {0x2055, 0x2055, prAL, gcPo}, // FLOWER PUNCTUATION MARK + {0x2056, 0x2056, prBA, gcPo}, // THREE DOT PUNCTUATION + {0x2057, 0x2057, prPO, gcPo}, // QUADRUPLE PRIME + {0x2058, 0x205B, prBA, gcPo}, // [4] FOUR DOT PUNCTUATION..FOUR DOT MARK + {0x205C, 0x205C, prAL, gcPo}, // DOTTED CROSS + {0x205D, 0x205E, prBA, gcPo}, // [2] TRICOLON..VERTICAL FOUR DOTS + {0x205F, 0x205F, prBA, gcZs}, // MEDIUM MATHEMATICAL SPACE + {0x2060, 0x2060, prWJ, gcCf}, // WORD JOINER + {0x2061, 0x2064, prAL, gcCf}, // [4] FUNCTION APPLICATION..INVISIBLE PLUS + {0x2066, 0x206F, prCM, gcCf}, // [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x2070, 0x2070, prAL, gcNo}, // SUPERSCRIPT ZERO + {0x2071, 0x2071, prAL, gcLm}, // SUPERSCRIPT LATIN SMALL LETTER I + {0x2074, 0x2074, prAI, gcNo}, // SUPERSCRIPT FOUR + {0x2075, 0x2079, prAL, gcNo}, // [5] SUPERSCRIPT FIVE..SUPERSCRIPT NINE + {0x207A, 0x207C, prAL, gcSm}, // [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN + {0x207D, 0x207D, prOP, gcPs}, // SUPERSCRIPT LEFT PARENTHESIS + {0x207E, 0x207E, prCL, gcPe}, // SUPERSCRIPT RIGHT PARENTHESIS + {0x207F, 0x207F, prAI, gcLm}, // SUPERSCRIPT LATIN SMALL LETTER N + {0x2080, 0x2080, prAL, gcNo}, // SUBSCRIPT ZERO + {0x2081, 0x2084, prAI, gcNo}, // [4] SUBSCRIPT ONE..SUBSCRIPT FOUR + {0x2085, 0x2089, prAL, gcNo}, // [5] SUBSCRIPT FIVE..SUBSCRIPT NINE + {0x208A, 0x208C, prAL, gcSm}, // [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN + {0x208D, 0x208D, prOP, gcPs}, // SUBSCRIPT LEFT PARENTHESIS + {0x208E, 0x208E, prCL, gcPe}, // SUBSCRIPT RIGHT PARENTHESIS + {0x2090, 0x209C, prAL, gcLm}, // [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T + {0x20A0, 0x20A6, prPR, gcSc}, // [7] EURO-CURRENCY SIGN..NAIRA SIGN + {0x20A7, 0x20A7, prPO, gcSc}, // PESETA SIGN + {0x20A8, 0x20B5, prPR, gcSc}, // [14] RUPEE SIGN..CEDI SIGN + {0x20B6, 0x20B6, prPO, gcSc}, // LIVRE TOURNOIS SIGN + {0x20B7, 0x20BA, prPR, gcSc}, // [4] SPESMILO SIGN..TURKISH LIRA SIGN + {0x20BB, 0x20BB, prPO, gcSc}, // NORDIC MARK SIGN + {0x20BC, 0x20BD, prPR, gcSc}, // [2] MANAT SIGN..RUBLE SIGN + {0x20BE, 0x20BE, prPO, gcSc}, // LARI SIGN + {0x20BF, 0x20BF, prPR, gcSc}, // BITCOIN SIGN + {0x20C0, 0x20C0, prPO, gcSc}, // SOM SIGN + {0x20C1, 0x20CF, prPR, gcCn}, // [15] .. + {0x20D0, 0x20DC, prCM, gcMn}, // [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prCM, gcMe}, // [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prCM, gcMn}, // COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prCM, gcMe}, // [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prCM, gcMn}, // [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2100, 0x2101, prAL, gcSo}, // [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT + {0x2102, 0x2102, prAL, gcLu}, // DOUBLE-STRUCK CAPITAL C + {0x2103, 0x2103, prPO, gcSo}, // DEGREE CELSIUS + {0x2104, 0x2104, prAL, gcSo}, // CENTRE LINE SYMBOL + {0x2105, 0x2105, prAI, gcSo}, // CARE OF + {0x2106, 0x2106, prAL, gcSo}, // CADA UNA + {0x2107, 0x2107, prAL, gcLu}, // EULER CONSTANT + {0x2108, 0x2108, prAL, gcSo}, // SCRUPLE + {0x2109, 0x2109, prPO, gcSo}, // DEGREE FAHRENHEIT + {0x210A, 0x2112, prAL, gcLC}, // [9] SCRIPT SMALL G..SCRIPT CAPITAL L + {0x2113, 0x2113, prAI, gcLl}, // SCRIPT SMALL L + {0x2114, 0x2114, prAL, gcSo}, // L B BAR SYMBOL + {0x2115, 0x2115, prAL, gcLu}, // DOUBLE-STRUCK CAPITAL N + {0x2116, 0x2116, prPR, gcSo}, // NUMERO SIGN + {0x2117, 0x2117, prAL, gcSo}, // SOUND RECORDING COPYRIGHT + {0x2118, 0x2118, prAL, gcSm}, // SCRIPT CAPITAL P + {0x2119, 0x211D, prAL, gcLu}, // [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R + {0x211E, 0x2120, prAL, gcSo}, // [3] PRESCRIPTION TAKE..SERVICE MARK + {0x2121, 0x2122, prAI, gcSo}, // [2] TELEPHONE SIGN..TRADE MARK SIGN + {0x2123, 0x2123, prAL, gcSo}, // VERSICLE + {0x2124, 0x2124, prAL, gcLu}, // DOUBLE-STRUCK CAPITAL Z + {0x2125, 0x2125, prAL, gcSo}, // OUNCE SIGN + {0x2126, 0x2126, prAL, gcLu}, // OHM SIGN + {0x2127, 0x2127, prAL, gcSo}, // INVERTED OHM SIGN + {0x2128, 0x2128, prAL, gcLu}, // BLACK-LETTER CAPITAL Z + {0x2129, 0x2129, prAL, gcSo}, // TURNED GREEK SMALL LETTER IOTA + {0x212A, 0x212A, prAL, gcLu}, // KELVIN SIGN + {0x212B, 0x212B, prAI, gcLu}, // ANGSTROM SIGN + {0x212C, 0x212D, prAL, gcLu}, // [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C + {0x212E, 0x212E, prAL, gcSo}, // ESTIMATED SYMBOL + {0x212F, 0x2134, prAL, gcLC}, // [6] SCRIPT SMALL E..SCRIPT SMALL O + {0x2135, 0x2138, prAL, gcLo}, // [4] ALEF SYMBOL..DALET SYMBOL + {0x2139, 0x2139, prAL, gcLl}, // INFORMATION SOURCE + {0x213A, 0x213B, prAL, gcSo}, // [2] ROTATED CAPITAL Q..FACSIMILE SIGN + {0x213C, 0x213F, prAL, gcLC}, // [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI + {0x2140, 0x2144, prAL, gcSm}, // [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y + {0x2145, 0x2149, prAL, gcLC}, // [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J + {0x214A, 0x214A, prAL, gcSo}, // PROPERTY LINE + {0x214B, 0x214B, prAL, gcSm}, // TURNED AMPERSAND + {0x214C, 0x214D, prAL, gcSo}, // [2] PER SIGN..AKTIESELSKAB + {0x214E, 0x214E, prAL, gcLl}, // TURNED SMALL F + {0x214F, 0x214F, prAL, gcSo}, // SYMBOL FOR SAMARITAN SOURCE + {0x2150, 0x2153, prAL, gcNo}, // [4] VULGAR FRACTION ONE SEVENTH..VULGAR FRACTION ONE THIRD + {0x2154, 0x2155, prAI, gcNo}, // [2] VULGAR FRACTION TWO THIRDS..VULGAR FRACTION ONE FIFTH + {0x2156, 0x215A, prAL, gcNo}, // [5] VULGAR FRACTION TWO FIFTHS..VULGAR FRACTION FIVE SIXTHS + {0x215B, 0x215B, prAI, gcNo}, // VULGAR FRACTION ONE EIGHTH + {0x215C, 0x215D, prAL, gcNo}, // [2] VULGAR FRACTION THREE EIGHTHS..VULGAR FRACTION FIVE EIGHTHS + {0x215E, 0x215E, prAI, gcNo}, // VULGAR FRACTION SEVEN EIGHTHS + {0x215F, 0x215F, prAL, gcNo}, // FRACTION NUMERATOR ONE + {0x2160, 0x216B, prAI, gcNl}, // [12] ROMAN NUMERAL ONE..ROMAN NUMERAL TWELVE + {0x216C, 0x216F, prAL, gcNl}, // [4] ROMAN NUMERAL FIFTY..ROMAN NUMERAL ONE THOUSAND + {0x2170, 0x2179, prAI, gcNl}, // [10] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL TEN + {0x217A, 0x2182, prAL, gcNl}, // [9] SMALL ROMAN NUMERAL ELEVEN..ROMAN NUMERAL TEN THOUSAND + {0x2183, 0x2184, prAL, gcLC}, // [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C + {0x2185, 0x2188, prAL, gcNl}, // [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND + {0x2189, 0x2189, prAI, gcNo}, // VULGAR FRACTION ZERO THIRDS + {0x218A, 0x218B, prAL, gcSo}, // [2] TURNED DIGIT TWO..TURNED DIGIT THREE + {0x2190, 0x2194, prAI, gcSm}, // [5] LEFTWARDS ARROW..LEFT RIGHT ARROW + {0x2195, 0x2199, prAI, gcSo}, // [5] UP DOWN ARROW..SOUTH WEST ARROW + {0x219A, 0x219B, prAL, gcSm}, // [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE + {0x219C, 0x219F, prAL, gcSo}, // [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW + {0x21A0, 0x21A0, prAL, gcSm}, // RIGHTWARDS TWO HEADED ARROW + {0x21A1, 0x21A2, prAL, gcSo}, // [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL + {0x21A3, 0x21A3, prAL, gcSm}, // RIGHTWARDS ARROW WITH TAIL + {0x21A4, 0x21A5, prAL, gcSo}, // [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR + {0x21A6, 0x21A6, prAL, gcSm}, // RIGHTWARDS ARROW FROM BAR + {0x21A7, 0x21AD, prAL, gcSo}, // [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW + {0x21AE, 0x21AE, prAL, gcSm}, // LEFT RIGHT ARROW WITH STROKE + {0x21AF, 0x21CD, prAL, gcSo}, // [31] DOWNWARDS ZIGZAG ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE + {0x21CE, 0x21CF, prAL, gcSm}, // [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE + {0x21D0, 0x21D1, prAL, gcSo}, // [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW + {0x21D2, 0x21D2, prAI, gcSm}, // RIGHTWARDS DOUBLE ARROW + {0x21D3, 0x21D3, prAL, gcSo}, // DOWNWARDS DOUBLE ARROW + {0x21D4, 0x21D4, prAI, gcSm}, // LEFT RIGHT DOUBLE ARROW + {0x21D5, 0x21F3, prAL, gcSo}, // [31] UP DOWN DOUBLE ARROW..UP DOWN WHITE ARROW + {0x21F4, 0x21FF, prAL, gcSm}, // [12] RIGHT ARROW WITH SMALL CIRCLE..LEFT RIGHT OPEN-HEADED ARROW + {0x2200, 0x2200, prAI, gcSm}, // FOR ALL + {0x2201, 0x2201, prAL, gcSm}, // COMPLEMENT + {0x2202, 0x2203, prAI, gcSm}, // [2] PARTIAL DIFFERENTIAL..THERE EXISTS + {0x2204, 0x2206, prAL, gcSm}, // [3] THERE DOES NOT EXIST..INCREMENT + {0x2207, 0x2208, prAI, gcSm}, // [2] NABLA..ELEMENT OF + {0x2209, 0x220A, prAL, gcSm}, // [2] NOT AN ELEMENT OF..SMALL ELEMENT OF + {0x220B, 0x220B, prAI, gcSm}, // CONTAINS AS MEMBER + {0x220C, 0x220E, prAL, gcSm}, // [3] DOES NOT CONTAIN AS MEMBER..END OF PROOF + {0x220F, 0x220F, prAI, gcSm}, // N-ARY PRODUCT + {0x2210, 0x2210, prAL, gcSm}, // N-ARY COPRODUCT + {0x2211, 0x2211, prAI, gcSm}, // N-ARY SUMMATION + {0x2212, 0x2213, prPR, gcSm}, // [2] MINUS SIGN..MINUS-OR-PLUS SIGN + {0x2214, 0x2214, prAL, gcSm}, // DOT PLUS + {0x2215, 0x2215, prAI, gcSm}, // DIVISION SLASH + {0x2216, 0x2219, prAL, gcSm}, // [4] SET MINUS..BULLET OPERATOR + {0x221A, 0x221A, prAI, gcSm}, // SQUARE ROOT + {0x221B, 0x221C, prAL, gcSm}, // [2] CUBE ROOT..FOURTH ROOT + {0x221D, 0x2220, prAI, gcSm}, // [4] PROPORTIONAL TO..ANGLE + {0x2221, 0x2222, prAL, gcSm}, // [2] MEASURED ANGLE..SPHERICAL ANGLE + {0x2223, 0x2223, prAI, gcSm}, // DIVIDES + {0x2224, 0x2224, prAL, gcSm}, // DOES NOT DIVIDE + {0x2225, 0x2225, prAI, gcSm}, // PARALLEL TO + {0x2226, 0x2226, prAL, gcSm}, // NOT PARALLEL TO + {0x2227, 0x222C, prAI, gcSm}, // [6] LOGICAL AND..DOUBLE INTEGRAL + {0x222D, 0x222D, prAL, gcSm}, // TRIPLE INTEGRAL + {0x222E, 0x222E, prAI, gcSm}, // CONTOUR INTEGRAL + {0x222F, 0x2233, prAL, gcSm}, // [5] SURFACE INTEGRAL..ANTICLOCKWISE CONTOUR INTEGRAL + {0x2234, 0x2237, prAI, gcSm}, // [4] THEREFORE..PROPORTION + {0x2238, 0x223B, prAL, gcSm}, // [4] DOT MINUS..HOMOTHETIC + {0x223C, 0x223D, prAI, gcSm}, // [2] TILDE OPERATOR..REVERSED TILDE + {0x223E, 0x2247, prAL, gcSm}, // [10] INVERTED LAZY S..NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + {0x2248, 0x2248, prAI, gcSm}, // ALMOST EQUAL TO + {0x2249, 0x224B, prAL, gcSm}, // [3] NOT ALMOST EQUAL TO..TRIPLE TILDE + {0x224C, 0x224C, prAI, gcSm}, // ALL EQUAL TO + {0x224D, 0x2251, prAL, gcSm}, // [5] EQUIVALENT TO..GEOMETRICALLY EQUAL TO + {0x2252, 0x2252, prAI, gcSm}, // APPROXIMATELY EQUAL TO OR THE IMAGE OF + {0x2253, 0x225F, prAL, gcSm}, // [13] IMAGE OF OR APPROXIMATELY EQUAL TO..QUESTIONED EQUAL TO + {0x2260, 0x2261, prAI, gcSm}, // [2] NOT EQUAL TO..IDENTICAL TO + {0x2262, 0x2263, prAL, gcSm}, // [2] NOT IDENTICAL TO..STRICTLY EQUIVALENT TO + {0x2264, 0x2267, prAI, gcSm}, // [4] LESS-THAN OR EQUAL TO..GREATER-THAN OVER EQUAL TO + {0x2268, 0x2269, prAL, gcSm}, // [2] LESS-THAN BUT NOT EQUAL TO..GREATER-THAN BUT NOT EQUAL TO + {0x226A, 0x226B, prAI, gcSm}, // [2] MUCH LESS-THAN..MUCH GREATER-THAN + {0x226C, 0x226D, prAL, gcSm}, // [2] BETWEEN..NOT EQUIVALENT TO + {0x226E, 0x226F, prAI, gcSm}, // [2] NOT LESS-THAN..NOT GREATER-THAN + {0x2270, 0x2281, prAL, gcSm}, // [18] NEITHER LESS-THAN NOR EQUAL TO..DOES NOT SUCCEED + {0x2282, 0x2283, prAI, gcSm}, // [2] SUBSET OF..SUPERSET OF + {0x2284, 0x2285, prAL, gcSm}, // [2] NOT A SUBSET OF..NOT A SUPERSET OF + {0x2286, 0x2287, prAI, gcSm}, // [2] SUBSET OF OR EQUAL TO..SUPERSET OF OR EQUAL TO + {0x2288, 0x2294, prAL, gcSm}, // [13] NEITHER A SUBSET OF NOR EQUAL TO..SQUARE CUP + {0x2295, 0x2295, prAI, gcSm}, // CIRCLED PLUS + {0x2296, 0x2298, prAL, gcSm}, // [3] CIRCLED MINUS..CIRCLED DIVISION SLASH + {0x2299, 0x2299, prAI, gcSm}, // CIRCLED DOT OPERATOR + {0x229A, 0x22A4, prAL, gcSm}, // [11] CIRCLED RING OPERATOR..DOWN TACK + {0x22A5, 0x22A5, prAI, gcSm}, // UP TACK + {0x22A6, 0x22BE, prAL, gcSm}, // [25] ASSERTION..RIGHT ANGLE WITH ARC + {0x22BF, 0x22BF, prAI, gcSm}, // RIGHT TRIANGLE + {0x22C0, 0x22EE, prAL, gcSm}, // [47] N-ARY LOGICAL AND..VERTICAL ELLIPSIS + {0x22EF, 0x22EF, prIN, gcSm}, // MIDLINE HORIZONTAL ELLIPSIS + {0x22F0, 0x22FF, prAL, gcSm}, // [16] UP RIGHT DIAGONAL ELLIPSIS..Z NOTATION BAG MEMBERSHIP + {0x2300, 0x2307, prAL, gcSo}, // [8] DIAMETER SIGN..WAVY LINE + {0x2308, 0x2308, prOP, gcPs}, // LEFT CEILING + {0x2309, 0x2309, prCL, gcPe}, // RIGHT CEILING + {0x230A, 0x230A, prOP, gcPs}, // LEFT FLOOR + {0x230B, 0x230B, prCL, gcPe}, // RIGHT FLOOR + {0x230C, 0x2311, prAL, gcSo}, // [6] BOTTOM RIGHT CROP..SQUARE LOZENGE + {0x2312, 0x2312, prAI, gcSo}, // ARC + {0x2313, 0x2319, prAL, gcSo}, // [7] SEGMENT..TURNED NOT SIGN + {0x231A, 0x231B, prID, gcSo}, // [2] WATCH..HOURGLASS + {0x231C, 0x231F, prAL, gcSo}, // [4] TOP LEFT CORNER..BOTTOM RIGHT CORNER + {0x2320, 0x2321, prAL, gcSm}, // [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL + {0x2322, 0x2328, prAL, gcSo}, // [7] FROWN..KEYBOARD + {0x2329, 0x2329, prOP, gcPs}, // LEFT-POINTING ANGLE BRACKET + {0x232A, 0x232A, prCL, gcPe}, // RIGHT-POINTING ANGLE BRACKET + {0x232B, 0x237B, prAL, gcSo}, // [81] ERASE TO THE LEFT..NOT CHECK MARK + {0x237C, 0x237C, prAL, gcSm}, // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW + {0x237D, 0x239A, prAL, gcSo}, // [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL + {0x239B, 0x23B3, prAL, gcSm}, // [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM + {0x23B4, 0x23DB, prAL, gcSo}, // [40] TOP SQUARE BRACKET..FUSE + {0x23DC, 0x23E1, prAL, gcSm}, // [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET + {0x23E2, 0x23EF, prAL, gcSo}, // [14] WHITE TRAPEZIUM..BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR + {0x23F0, 0x23F3, prID, gcSo}, // [4] ALARM CLOCK..HOURGLASS WITH FLOWING SAND + {0x23F4, 0x23FF, prAL, gcSo}, // [12] BLACK MEDIUM LEFT-POINTING TRIANGLE..OBSERVER EYE SYMBOL + {0x2400, 0x2426, prAL, gcSo}, // [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO + {0x2440, 0x244A, prAL, gcSo}, // [11] OCR HOOK..OCR DOUBLE BACKSLASH + {0x2460, 0x249B, prAI, gcNo}, // [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP + {0x249C, 0x24E9, prAI, gcSo}, // [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z + {0x24EA, 0x24FE, prAI, gcNo}, // [21] CIRCLED DIGIT ZERO..DOUBLE CIRCLED NUMBER TEN + {0x24FF, 0x24FF, prAL, gcNo}, // NEGATIVE CIRCLED DIGIT ZERO + {0x2500, 0x254B, prAI, gcSo}, // [76] BOX DRAWINGS LIGHT HORIZONTAL..BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + {0x254C, 0x254F, prAL, gcSo}, // [4] BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL..BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL + {0x2550, 0x2574, prAI, gcSo}, // [37] BOX DRAWINGS DOUBLE HORIZONTAL..BOX DRAWINGS LIGHT LEFT + {0x2575, 0x257F, prAL, gcSo}, // [11] BOX DRAWINGS LIGHT UP..BOX DRAWINGS HEAVY UP AND LIGHT DOWN + {0x2580, 0x258F, prAI, gcSo}, // [16] UPPER HALF BLOCK..LEFT ONE EIGHTH BLOCK + {0x2590, 0x2591, prAL, gcSo}, // [2] RIGHT HALF BLOCK..LIGHT SHADE + {0x2592, 0x2595, prAI, gcSo}, // [4] MEDIUM SHADE..RIGHT ONE EIGHTH BLOCK + {0x2596, 0x259F, prAL, gcSo}, // [10] QUADRANT LOWER LEFT..QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT + {0x25A0, 0x25A1, prAI, gcSo}, // [2] BLACK SQUARE..WHITE SQUARE + {0x25A2, 0x25A2, prAL, gcSo}, // WHITE SQUARE WITH ROUNDED CORNERS + {0x25A3, 0x25A9, prAI, gcSo}, // [7] WHITE SQUARE CONTAINING BLACK SMALL SQUARE..SQUARE WITH DIAGONAL CROSSHATCH FILL + {0x25AA, 0x25B1, prAL, gcSo}, // [8] BLACK SMALL SQUARE..WHITE PARALLELOGRAM + {0x25B2, 0x25B3, prAI, gcSo}, // [2] BLACK UP-POINTING TRIANGLE..WHITE UP-POINTING TRIANGLE + {0x25B4, 0x25B5, prAL, gcSo}, // [2] BLACK UP-POINTING SMALL TRIANGLE..WHITE UP-POINTING SMALL TRIANGLE + {0x25B6, 0x25B6, prAI, gcSo}, // BLACK RIGHT-POINTING TRIANGLE + {0x25B7, 0x25B7, prAI, gcSm}, // WHITE RIGHT-POINTING TRIANGLE + {0x25B8, 0x25BB, prAL, gcSo}, // [4] BLACK RIGHT-POINTING SMALL TRIANGLE..WHITE RIGHT-POINTING POINTER + {0x25BC, 0x25BD, prAI, gcSo}, // [2] BLACK DOWN-POINTING TRIANGLE..WHITE DOWN-POINTING TRIANGLE + {0x25BE, 0x25BF, prAL, gcSo}, // [2] BLACK DOWN-POINTING SMALL TRIANGLE..WHITE DOWN-POINTING SMALL TRIANGLE + {0x25C0, 0x25C0, prAI, gcSo}, // BLACK LEFT-POINTING TRIANGLE + {0x25C1, 0x25C1, prAI, gcSm}, // WHITE LEFT-POINTING TRIANGLE + {0x25C2, 0x25C5, prAL, gcSo}, // [4] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE LEFT-POINTING POINTER + {0x25C6, 0x25C8, prAI, gcSo}, // [3] BLACK DIAMOND..WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND + {0x25C9, 0x25CA, prAL, gcSo}, // [2] FISHEYE..LOZENGE + {0x25CB, 0x25CB, prAI, gcSo}, // WHITE CIRCLE + {0x25CC, 0x25CD, prAL, gcSo}, // [2] DOTTED CIRCLE..CIRCLE WITH VERTICAL FILL + {0x25CE, 0x25D1, prAI, gcSo}, // [4] BULLSEYE..CIRCLE WITH RIGHT HALF BLACK + {0x25D2, 0x25E1, prAL, gcSo}, // [16] CIRCLE WITH LOWER HALF BLACK..LOWER HALF CIRCLE + {0x25E2, 0x25E5, prAI, gcSo}, // [4] BLACK LOWER RIGHT TRIANGLE..BLACK UPPER RIGHT TRIANGLE + {0x25E6, 0x25EE, prAL, gcSo}, // [9] WHITE BULLET..UP-POINTING TRIANGLE WITH RIGHT HALF BLACK + {0x25EF, 0x25EF, prAI, gcSo}, // LARGE CIRCLE + {0x25F0, 0x25F7, prAL, gcSo}, // [8] WHITE SQUARE WITH UPPER LEFT QUADRANT..WHITE CIRCLE WITH UPPER RIGHT QUADRANT + {0x25F8, 0x25FF, prAL, gcSm}, // [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE + {0x2600, 0x2603, prID, gcSo}, // [4] BLACK SUN WITH RAYS..SNOWMAN + {0x2604, 0x2604, prAL, gcSo}, // COMET + {0x2605, 0x2606, prAI, gcSo}, // [2] BLACK STAR..WHITE STAR + {0x2607, 0x2608, prAL, gcSo}, // [2] LIGHTNING..THUNDERSTORM + {0x2609, 0x2609, prAI, gcSo}, // SUN + {0x260A, 0x260D, prAL, gcSo}, // [4] ASCENDING NODE..OPPOSITION + {0x260E, 0x260F, prAI, gcSo}, // [2] BLACK TELEPHONE..WHITE TELEPHONE + {0x2610, 0x2613, prAL, gcSo}, // [4] BALLOT BOX..SALTIRE + {0x2614, 0x2615, prID, gcSo}, // [2] UMBRELLA WITH RAIN DROPS..HOT BEVERAGE + {0x2616, 0x2617, prAI, gcSo}, // [2] WHITE SHOGI PIECE..BLACK SHOGI PIECE + {0x2618, 0x2618, prID, gcSo}, // SHAMROCK + {0x2619, 0x2619, prAL, gcSo}, // REVERSED ROTATED FLORAL HEART BULLET + {0x261A, 0x261C, prID, gcSo}, // [3] BLACK LEFT POINTING INDEX..WHITE LEFT POINTING INDEX + {0x261D, 0x261D, prEB, gcSo}, // WHITE UP POINTING INDEX + {0x261E, 0x261F, prID, gcSo}, // [2] WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX + {0x2620, 0x2638, prAL, gcSo}, // [25] SKULL AND CROSSBONES..WHEEL OF DHARMA + {0x2639, 0x263B, prID, gcSo}, // [3] WHITE FROWNING FACE..BLACK SMILING FACE + {0x263C, 0x263F, prAL, gcSo}, // [4] WHITE SUN WITH RAYS..MERCURY + {0x2640, 0x2640, prAI, gcSo}, // FEMALE SIGN + {0x2641, 0x2641, prAL, gcSo}, // EARTH + {0x2642, 0x2642, prAI, gcSo}, // MALE SIGN + {0x2643, 0x265F, prAL, gcSo}, // [29] JUPITER..BLACK CHESS PAWN + {0x2660, 0x2661, prAI, gcSo}, // [2] BLACK SPADE SUIT..WHITE HEART SUIT + {0x2662, 0x2662, prAL, gcSo}, // WHITE DIAMOND SUIT + {0x2663, 0x2665, prAI, gcSo}, // [3] BLACK CLUB SUIT..BLACK HEART SUIT + {0x2666, 0x2666, prAL, gcSo}, // BLACK DIAMOND SUIT + {0x2667, 0x2667, prAI, gcSo}, // WHITE CLUB SUIT + {0x2668, 0x2668, prID, gcSo}, // HOT SPRINGS + {0x2669, 0x266A, prAI, gcSo}, // [2] QUARTER NOTE..EIGHTH NOTE + {0x266B, 0x266B, prAL, gcSo}, // BEAMED EIGHTH NOTES + {0x266C, 0x266D, prAI, gcSo}, // [2] BEAMED SIXTEENTH NOTES..MUSIC FLAT SIGN + {0x266E, 0x266E, prAL, gcSo}, // MUSIC NATURAL SIGN + {0x266F, 0x266F, prAI, gcSm}, // MUSIC SHARP SIGN + {0x2670, 0x267E, prAL, gcSo}, // [15] WEST SYRIAC CROSS..PERMANENT PAPER SIGN + {0x267F, 0x267F, prID, gcSo}, // WHEELCHAIR SYMBOL + {0x2680, 0x269D, prAL, gcSo}, // [30] DIE FACE-1..OUTLINED WHITE STAR + {0x269E, 0x269F, prAI, gcSo}, // [2] THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT + {0x26A0, 0x26BC, prAL, gcSo}, // [29] WARNING SIGN..SESQUIQUADRATE + {0x26BD, 0x26C8, prID, gcSo}, // [12] SOCCER BALL..THUNDER CLOUD AND RAIN + {0x26C9, 0x26CC, prAI, gcSo}, // [4] TURNED WHITE SHOGI PIECE..CROSSING LANES + {0x26CD, 0x26CD, prID, gcSo}, // DISABLED CAR + {0x26CE, 0x26CE, prAL, gcSo}, // OPHIUCHUS + {0x26CF, 0x26D1, prID, gcSo}, // [3] PICK..HELMET WITH WHITE CROSS + {0x26D2, 0x26D2, prAI, gcSo}, // CIRCLED CROSSING LANES + {0x26D3, 0x26D4, prID, gcSo}, // [2] CHAINS..NO ENTRY + {0x26D5, 0x26D7, prAI, gcSo}, // [3] ALTERNATE ONE-WAY LEFT WAY TRAFFIC..WHITE TWO-WAY LEFT WAY TRAFFIC + {0x26D8, 0x26D9, prID, gcSo}, // [2] BLACK LEFT LANE MERGE..WHITE LEFT LANE MERGE + {0x26DA, 0x26DB, prAI, gcSo}, // [2] DRIVE SLOW SIGN..HEAVY WHITE DOWN-POINTING TRIANGLE + {0x26DC, 0x26DC, prID, gcSo}, // LEFT CLOSED ENTRY + {0x26DD, 0x26DE, prAI, gcSo}, // [2] SQUARED SALTIRE..FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE + {0x26DF, 0x26E1, prID, gcSo}, // [3] BLACK TRUCK..RESTRICTED LEFT ENTRY-2 + {0x26E2, 0x26E2, prAL, gcSo}, // ASTRONOMICAL SYMBOL FOR URANUS + {0x26E3, 0x26E3, prAI, gcSo}, // HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE + {0x26E4, 0x26E7, prAL, gcSo}, // [4] PENTAGRAM..INVERTED PENTAGRAM + {0x26E8, 0x26E9, prAI, gcSo}, // [2] BLACK CROSS ON SHIELD..SHINTO SHRINE + {0x26EA, 0x26EA, prID, gcSo}, // CHURCH + {0x26EB, 0x26F0, prAI, gcSo}, // [6] CASTLE..MOUNTAIN + {0x26F1, 0x26F5, prID, gcSo}, // [5] UMBRELLA ON GROUND..SAILBOAT + {0x26F6, 0x26F6, prAI, gcSo}, // SQUARE FOUR CORNERS + {0x26F7, 0x26F8, prID, gcSo}, // [2] SKIER..ICE SKATE + {0x26F9, 0x26F9, prEB, gcSo}, // PERSON WITH BALL + {0x26FA, 0x26FA, prID, gcSo}, // TENT + {0x26FB, 0x26FC, prAI, gcSo}, // [2] JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL + {0x26FD, 0x26FF, prID, gcSo}, // [3] FUEL PUMP..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE + {0x2700, 0x2704, prID, gcSo}, // [5] BLACK SAFETY SCISSORS..WHITE SCISSORS + {0x2705, 0x2707, prAL, gcSo}, // [3] WHITE HEAVY CHECK MARK..TAPE DRIVE + {0x2708, 0x2709, prID, gcSo}, // [2] AIRPLANE..ENVELOPE + {0x270A, 0x270D, prEB, gcSo}, // [4] RAISED FIST..WRITING HAND + {0x270E, 0x2756, prAL, gcSo}, // [73] LOWER RIGHT PENCIL..BLACK DIAMOND MINUS WHITE X + {0x2757, 0x2757, prAI, gcSo}, // HEAVY EXCLAMATION MARK SYMBOL + {0x2758, 0x275A, prAL, gcSo}, // [3] LIGHT VERTICAL BAR..HEAVY VERTICAL BAR + {0x275B, 0x2760, prQU, gcSo}, // [6] HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT..HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT + {0x2761, 0x2761, prAL, gcSo}, // CURVED STEM PARAGRAPH SIGN ORNAMENT + {0x2762, 0x2763, prEX, gcSo}, // [2] HEAVY EXCLAMATION MARK ORNAMENT..HEAVY HEART EXCLAMATION MARK ORNAMENT + {0x2764, 0x2764, prID, gcSo}, // HEAVY BLACK HEART + {0x2765, 0x2767, prAL, gcSo}, // [3] ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET + {0x2768, 0x2768, prOP, gcPs}, // MEDIUM LEFT PARENTHESIS ORNAMENT + {0x2769, 0x2769, prCL, gcPe}, // MEDIUM RIGHT PARENTHESIS ORNAMENT + {0x276A, 0x276A, prOP, gcPs}, // MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT + {0x276B, 0x276B, prCL, gcPe}, // MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT + {0x276C, 0x276C, prOP, gcPs}, // MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x276D, 0x276D, prCL, gcPe}, // MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x276E, 0x276E, prOP, gcPs}, // HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x276F, 0x276F, prCL, gcPe}, // HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x2770, 0x2770, prOP, gcPs}, // HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x2771, 0x2771, prCL, gcPe}, // HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x2772, 0x2772, prOP, gcPs}, // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + {0x2773, 0x2773, prCL, gcPe}, // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + {0x2774, 0x2774, prOP, gcPs}, // MEDIUM LEFT CURLY BRACKET ORNAMENT + {0x2775, 0x2775, prCL, gcPe}, // MEDIUM RIGHT CURLY BRACKET ORNAMENT + {0x2776, 0x2793, prAI, gcNo}, // [30] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN + {0x2794, 0x27BF, prAL, gcSo}, // [44] HEAVY WIDE-HEADED RIGHTWARDS ARROW..DOUBLE CURLY LOOP + {0x27C0, 0x27C4, prAL, gcSm}, // [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET + {0x27C5, 0x27C5, prOP, gcPs}, // LEFT S-SHAPED BAG DELIMITER + {0x27C6, 0x27C6, prCL, gcPe}, // RIGHT S-SHAPED BAG DELIMITER + {0x27C7, 0x27E5, prAL, gcSm}, // [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK + {0x27E6, 0x27E6, prOP, gcPs}, // MATHEMATICAL LEFT WHITE SQUARE BRACKET + {0x27E7, 0x27E7, prCL, gcPe}, // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + {0x27E8, 0x27E8, prOP, gcPs}, // MATHEMATICAL LEFT ANGLE BRACKET + {0x27E9, 0x27E9, prCL, gcPe}, // MATHEMATICAL RIGHT ANGLE BRACKET + {0x27EA, 0x27EA, prOP, gcPs}, // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + {0x27EB, 0x27EB, prCL, gcPe}, // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + {0x27EC, 0x27EC, prOP, gcPs}, // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + {0x27ED, 0x27ED, prCL, gcPe}, // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + {0x27EE, 0x27EE, prOP, gcPs}, // MATHEMATICAL LEFT FLATTENED PARENTHESIS + {0x27EF, 0x27EF, prCL, gcPe}, // MATHEMATICAL RIGHT FLATTENED PARENTHESIS + {0x27F0, 0x27FF, prAL, gcSm}, // [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW + {0x2800, 0x28FF, prAL, gcSo}, // [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678 + {0x2900, 0x297F, prAL, gcSm}, // [128] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..DOWN FISH TAIL + {0x2980, 0x2982, prAL, gcSm}, // [3] TRIPLE VERTICAL BAR DELIMITER..Z NOTATION TYPE COLON + {0x2983, 0x2983, prOP, gcPs}, // LEFT WHITE CURLY BRACKET + {0x2984, 0x2984, prCL, gcPe}, // RIGHT WHITE CURLY BRACKET + {0x2985, 0x2985, prOP, gcPs}, // LEFT WHITE PARENTHESIS + {0x2986, 0x2986, prCL, gcPe}, // RIGHT WHITE PARENTHESIS + {0x2987, 0x2987, prOP, gcPs}, // Z NOTATION LEFT IMAGE BRACKET + {0x2988, 0x2988, prCL, gcPe}, // Z NOTATION RIGHT IMAGE BRACKET + {0x2989, 0x2989, prOP, gcPs}, // Z NOTATION LEFT BINDING BRACKET + {0x298A, 0x298A, prCL, gcPe}, // Z NOTATION RIGHT BINDING BRACKET + {0x298B, 0x298B, prOP, gcPs}, // LEFT SQUARE BRACKET WITH UNDERBAR + {0x298C, 0x298C, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH UNDERBAR + {0x298D, 0x298D, prOP, gcPs}, // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x298E, 0x298E, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x298F, 0x298F, prOP, gcPs}, // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x2990, 0x2990, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x2991, 0x2991, prOP, gcPs}, // LEFT ANGLE BRACKET WITH DOT + {0x2992, 0x2992, prCL, gcPe}, // RIGHT ANGLE BRACKET WITH DOT + {0x2993, 0x2993, prOP, gcPs}, // LEFT ARC LESS-THAN BRACKET + {0x2994, 0x2994, prCL, gcPe}, // RIGHT ARC GREATER-THAN BRACKET + {0x2995, 0x2995, prOP, gcPs}, // DOUBLE LEFT ARC GREATER-THAN BRACKET + {0x2996, 0x2996, prCL, gcPe}, // DOUBLE RIGHT ARC LESS-THAN BRACKET + {0x2997, 0x2997, prOP, gcPs}, // LEFT BLACK TORTOISE SHELL BRACKET + {0x2998, 0x2998, prCL, gcPe}, // RIGHT BLACK TORTOISE SHELL BRACKET + {0x2999, 0x29D7, prAL, gcSm}, // [63] DOTTED FENCE..BLACK HOURGLASS + {0x29D8, 0x29D8, prOP, gcPs}, // LEFT WIGGLY FENCE + {0x29D9, 0x29D9, prCL, gcPe}, // RIGHT WIGGLY FENCE + {0x29DA, 0x29DA, prOP, gcPs}, // LEFT DOUBLE WIGGLY FENCE + {0x29DB, 0x29DB, prCL, gcPe}, // RIGHT DOUBLE WIGGLY FENCE + {0x29DC, 0x29FB, prAL, gcSm}, // [32] INCOMPLETE INFINITY..TRIPLE PLUS + {0x29FC, 0x29FC, prOP, gcPs}, // LEFT-POINTING CURVED ANGLE BRACKET + {0x29FD, 0x29FD, prCL, gcPe}, // RIGHT-POINTING CURVED ANGLE BRACKET + {0x29FE, 0x29FF, prAL, gcSm}, // [2] TINY..MINY + {0x2A00, 0x2AFF, prAL, gcSm}, // [256] N-ARY CIRCLED DOT OPERATOR..N-ARY WHITE VERTICAL BAR + {0x2B00, 0x2B2F, prAL, gcSo}, // [48] NORTH EAST WHITE ARROW..WHITE VERTICAL ELLIPSE + {0x2B30, 0x2B44, prAL, gcSm}, // [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET + {0x2B45, 0x2B46, prAL, gcSo}, // [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW + {0x2B47, 0x2B4C, prAL, gcSm}, // [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR + {0x2B4D, 0x2B54, prAL, gcSo}, // [8] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..WHITE RIGHT-POINTING PENTAGON + {0x2B55, 0x2B59, prAI, gcSo}, // [5] HEAVY LARGE CIRCLE..HEAVY CIRCLED SALTIRE + {0x2B5A, 0x2B73, prAL, gcSo}, // [26] SLANTED NORTH ARROW WITH HOOKED HEAD..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR + {0x2B76, 0x2B95, prAL, gcSo}, // [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW + {0x2B97, 0x2BFF, prAL, gcSo}, // [105] SYMBOL FOR TYPE A ELECTRONICS..HELLSCHREIBER PAUSE SYMBOL + {0x2C00, 0x2C5F, prAL, gcLC}, // [96] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI + {0x2C60, 0x2C7B, prAL, gcLC}, // [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E + {0x2C7C, 0x2C7D, prAL, gcLm}, // [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V + {0x2C7E, 0x2C7F, prAL, gcLu}, // [2] LATIN CAPITAL LETTER S WITH SWASH TAIL..LATIN CAPITAL LETTER Z WITH SWASH TAIL + {0x2C80, 0x2CE4, prAL, gcLC}, // [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI + {0x2CE5, 0x2CEA, prAL, gcSo}, // [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA + {0x2CEB, 0x2CEE, prAL, gcLC}, // [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEF, 0x2CF1, prCM, gcMn}, // [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2CF2, 0x2CF3, prAL, gcLC}, // [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI + {0x2CF9, 0x2CF9, prEX, gcPo}, // COPTIC OLD NUBIAN FULL STOP + {0x2CFA, 0x2CFC, prBA, gcPo}, // [3] COPTIC OLD NUBIAN DIRECT QUESTION MARK..COPTIC OLD NUBIAN VERSE DIVIDER + {0x2CFD, 0x2CFD, prAL, gcNo}, // COPTIC FRACTION ONE HALF + {0x2CFE, 0x2CFE, prEX, gcPo}, // COPTIC FULL STOP + {0x2CFF, 0x2CFF, prBA, gcPo}, // COPTIC MORPHOLOGICAL DIVIDER + {0x2D00, 0x2D25, prAL, gcLl}, // [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE + {0x2D27, 0x2D27, prAL, gcLl}, // GEORGIAN SMALL LETTER YN + {0x2D2D, 0x2D2D, prAL, gcLl}, // GEORGIAN SMALL LETTER AEN + {0x2D30, 0x2D67, prAL, gcLo}, // [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO + {0x2D6F, 0x2D6F, prAL, gcLm}, // TIFINAGH MODIFIER LETTER LABIALIZATION MARK + {0x2D70, 0x2D70, prBA, gcPo}, // TIFINAGH SEPARATOR MARK + {0x2D7F, 0x2D7F, prCM, gcMn}, // TIFINAGH CONSONANT JOINER + {0x2D80, 0x2D96, prAL, gcLo}, // [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE + {0x2DA0, 0x2DA6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO + {0x2DA8, 0x2DAE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO + {0x2DB0, 0x2DB6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO + {0x2DB8, 0x2DBE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO + {0x2DC0, 0x2DC6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO + {0x2DC8, 0x2DCE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO + {0x2DD0, 0x2DD6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO + {0x2DD8, 0x2DDE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO + {0x2DE0, 0x2DFF, prCM, gcMn}, // [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x2E00, 0x2E01, prQU, gcPo}, // [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER + {0x2E02, 0x2E02, prQU, gcPi}, // LEFT SUBSTITUTION BRACKET + {0x2E03, 0x2E03, prQU, gcPf}, // RIGHT SUBSTITUTION BRACKET + {0x2E04, 0x2E04, prQU, gcPi}, // LEFT DOTTED SUBSTITUTION BRACKET + {0x2E05, 0x2E05, prQU, gcPf}, // RIGHT DOTTED SUBSTITUTION BRACKET + {0x2E06, 0x2E08, prQU, gcPo}, // [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER + {0x2E09, 0x2E09, prQU, gcPi}, // LEFT TRANSPOSITION BRACKET + {0x2E0A, 0x2E0A, prQU, gcPf}, // RIGHT TRANSPOSITION BRACKET + {0x2E0B, 0x2E0B, prQU, gcPo}, // RAISED SQUARE + {0x2E0C, 0x2E0C, prQU, gcPi}, // LEFT RAISED OMISSION BRACKET + {0x2E0D, 0x2E0D, prQU, gcPf}, // RIGHT RAISED OMISSION BRACKET + {0x2E0E, 0x2E15, prBA, gcPo}, // [8] EDITORIAL CORONIS..UPWARDS ANCORA + {0x2E16, 0x2E16, prAL, gcPo}, // DOTTED RIGHT-POINTING ANGLE + {0x2E17, 0x2E17, prBA, gcPd}, // DOUBLE OBLIQUE HYPHEN + {0x2E18, 0x2E18, prOP, gcPo}, // INVERTED INTERROBANG + {0x2E19, 0x2E19, prBA, gcPo}, // PALM BRANCH + {0x2E1A, 0x2E1A, prAL, gcPd}, // HYPHEN WITH DIAERESIS + {0x2E1B, 0x2E1B, prAL, gcPo}, // TILDE WITH RING ABOVE + {0x2E1C, 0x2E1C, prQU, gcPi}, // LEFT LOW PARAPHRASE BRACKET + {0x2E1D, 0x2E1D, prQU, gcPf}, // RIGHT LOW PARAPHRASE BRACKET + {0x2E1E, 0x2E1F, prAL, gcPo}, // [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW + {0x2E20, 0x2E20, prQU, gcPi}, // LEFT VERTICAL BAR WITH QUILL + {0x2E21, 0x2E21, prQU, gcPf}, // RIGHT VERTICAL BAR WITH QUILL + {0x2E22, 0x2E22, prOP, gcPs}, // TOP LEFT HALF BRACKET + {0x2E23, 0x2E23, prCL, gcPe}, // TOP RIGHT HALF BRACKET + {0x2E24, 0x2E24, prOP, gcPs}, // BOTTOM LEFT HALF BRACKET + {0x2E25, 0x2E25, prCL, gcPe}, // BOTTOM RIGHT HALF BRACKET + {0x2E26, 0x2E26, prOP, gcPs}, // LEFT SIDEWAYS U BRACKET + {0x2E27, 0x2E27, prCL, gcPe}, // RIGHT SIDEWAYS U BRACKET + {0x2E28, 0x2E28, prOP, gcPs}, // LEFT DOUBLE PARENTHESIS + {0x2E29, 0x2E29, prCL, gcPe}, // RIGHT DOUBLE PARENTHESIS + {0x2E2A, 0x2E2D, prBA, gcPo}, // [4] TWO DOTS OVER ONE DOT PUNCTUATION..FIVE DOT MARK + {0x2E2E, 0x2E2E, prEX, gcPo}, // REVERSED QUESTION MARK + {0x2E2F, 0x2E2F, prAL, gcLm}, // VERTICAL TILDE + {0x2E30, 0x2E31, prBA, gcPo}, // [2] RING POINT..WORD SEPARATOR MIDDLE DOT + {0x2E32, 0x2E32, prAL, gcPo}, // TURNED COMMA + {0x2E33, 0x2E34, prBA, gcPo}, // [2] RAISED DOT..RAISED COMMA + {0x2E35, 0x2E39, prAL, gcPo}, // [5] TURNED SEMICOLON..TOP HALF SECTION SIGN + {0x2E3A, 0x2E3B, prB2, gcPd}, // [2] TWO-EM DASH..THREE-EM DASH + {0x2E3C, 0x2E3E, prBA, gcPo}, // [3] STENOGRAPHIC FULL STOP..WIGGLY VERTICAL LINE + {0x2E3F, 0x2E3F, prAL, gcPo}, // CAPITULUM + {0x2E40, 0x2E40, prBA, gcPd}, // DOUBLE HYPHEN + {0x2E41, 0x2E41, prBA, gcPo}, // REVERSED COMMA + {0x2E42, 0x2E42, prOP, gcPs}, // DOUBLE LOW-REVERSED-9 QUOTATION MARK + {0x2E43, 0x2E4A, prBA, gcPo}, // [8] DASH WITH LEFT UPTURN..DOTTED SOLIDUS + {0x2E4B, 0x2E4B, prAL, gcPo}, // TRIPLE DAGGER + {0x2E4C, 0x2E4C, prBA, gcPo}, // MEDIEVAL COMMA + {0x2E4D, 0x2E4D, prAL, gcPo}, // PARAGRAPHUS MARK + {0x2E4E, 0x2E4F, prBA, gcPo}, // [2] PUNCTUS ELEVATUS MARK..CORNISH VERSE DIVIDER + {0x2E50, 0x2E51, prAL, gcSo}, // [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR + {0x2E52, 0x2E52, prAL, gcPo}, // TIRONIAN SIGN CAPITAL ET + {0x2E53, 0x2E54, prEX, gcPo}, // [2] MEDIEVAL EXCLAMATION MARK..MEDIEVAL QUESTION MARK + {0x2E55, 0x2E55, prOP, gcPs}, // LEFT SQUARE BRACKET WITH STROKE + {0x2E56, 0x2E56, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH STROKE + {0x2E57, 0x2E57, prOP, gcPs}, // LEFT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E58, 0x2E58, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E59, 0x2E59, prOP, gcPs}, // TOP HALF LEFT PARENTHESIS + {0x2E5A, 0x2E5A, prCL, gcPe}, // TOP HALF RIGHT PARENTHESIS + {0x2E5B, 0x2E5B, prOP, gcPs}, // BOTTOM HALF LEFT PARENTHESIS + {0x2E5C, 0x2E5C, prCL, gcPe}, // BOTTOM HALF RIGHT PARENTHESIS + {0x2E5D, 0x2E5D, prBA, gcPd}, // OBLIQUE HYPHEN + {0x2E80, 0x2E99, prID, gcSo}, // [26] CJK RADICAL REPEAT..CJK RADICAL RAP + {0x2E9B, 0x2EF3, prID, gcSo}, // [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE + {0x2F00, 0x2FD5, prID, gcSo}, // [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE + {0x2FF0, 0x2FFB, prID, gcSo}, // [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID + {0x3000, 0x3000, prBA, gcZs}, // IDEOGRAPHIC SPACE + {0x3001, 0x3002, prCL, gcPo}, // [2] IDEOGRAPHIC COMMA..IDEOGRAPHIC FULL STOP + {0x3003, 0x3003, prID, gcPo}, // DITTO MARK + {0x3004, 0x3004, prID, gcSo}, // JAPANESE INDUSTRIAL STANDARD SYMBOL + {0x3005, 0x3005, prNS, gcLm}, // IDEOGRAPHIC ITERATION MARK + {0x3006, 0x3006, prID, gcLo}, // IDEOGRAPHIC CLOSING MARK + {0x3007, 0x3007, prID, gcNl}, // IDEOGRAPHIC NUMBER ZERO + {0x3008, 0x3008, prOP, gcPs}, // LEFT ANGLE BRACKET + {0x3009, 0x3009, prCL, gcPe}, // RIGHT ANGLE BRACKET + {0x300A, 0x300A, prOP, gcPs}, // LEFT DOUBLE ANGLE BRACKET + {0x300B, 0x300B, prCL, gcPe}, // RIGHT DOUBLE ANGLE BRACKET + {0x300C, 0x300C, prOP, gcPs}, // LEFT CORNER BRACKET + {0x300D, 0x300D, prCL, gcPe}, // RIGHT CORNER BRACKET + {0x300E, 0x300E, prOP, gcPs}, // LEFT WHITE CORNER BRACKET + {0x300F, 0x300F, prCL, gcPe}, // RIGHT WHITE CORNER BRACKET + {0x3010, 0x3010, prOP, gcPs}, // LEFT BLACK LENTICULAR BRACKET + {0x3011, 0x3011, prCL, gcPe}, // RIGHT BLACK LENTICULAR BRACKET + {0x3012, 0x3013, prID, gcSo}, // [2] POSTAL MARK..GETA MARK + {0x3014, 0x3014, prOP, gcPs}, // LEFT TORTOISE SHELL BRACKET + {0x3015, 0x3015, prCL, gcPe}, // RIGHT TORTOISE SHELL BRACKET + {0x3016, 0x3016, prOP, gcPs}, // LEFT WHITE LENTICULAR BRACKET + {0x3017, 0x3017, prCL, gcPe}, // RIGHT WHITE LENTICULAR BRACKET + {0x3018, 0x3018, prOP, gcPs}, // LEFT WHITE TORTOISE SHELL BRACKET + {0x3019, 0x3019, prCL, gcPe}, // RIGHT WHITE TORTOISE SHELL BRACKET + {0x301A, 0x301A, prOP, gcPs}, // LEFT WHITE SQUARE BRACKET + {0x301B, 0x301B, prCL, gcPe}, // RIGHT WHITE SQUARE BRACKET + {0x301C, 0x301C, prNS, gcPd}, // WAVE DASH + {0x301D, 0x301D, prOP, gcPs}, // REVERSED DOUBLE PRIME QUOTATION MARK + {0x301E, 0x301F, prCL, gcPe}, // [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK + {0x3020, 0x3020, prID, gcSo}, // POSTAL MARK FACE + {0x3021, 0x3029, prID, gcNl}, // [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE + {0x302A, 0x302D, prCM, gcMn}, // [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prCM, gcMc}, // [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3030, 0x3030, prID, gcPd}, // WAVY DASH + {0x3031, 0x3034, prID, gcLm}, // [4] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF + {0x3035, 0x3035, prCM, gcLm}, // VERTICAL KANA REPEAT MARK LOWER HALF + {0x3036, 0x3037, prID, gcSo}, // [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL + {0x3038, 0x303A, prID, gcNl}, // [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY + {0x303B, 0x303B, prNS, gcLm}, // VERTICAL IDEOGRAPHIC ITERATION MARK + {0x303C, 0x303C, prNS, gcLo}, // MASU MARK + {0x303D, 0x303D, prID, gcPo}, // PART ALTERNATION MARK + {0x303E, 0x303F, prID, gcSo}, // [2] IDEOGRAPHIC VARIATION INDICATOR..IDEOGRAPHIC HALF FILL SPACE + {0x3041, 0x3041, prCJ, gcLo}, // HIRAGANA LETTER SMALL A + {0x3042, 0x3042, prID, gcLo}, // HIRAGANA LETTER A + {0x3043, 0x3043, prCJ, gcLo}, // HIRAGANA LETTER SMALL I + {0x3044, 0x3044, prID, gcLo}, // HIRAGANA LETTER I + {0x3045, 0x3045, prCJ, gcLo}, // HIRAGANA LETTER SMALL U + {0x3046, 0x3046, prID, gcLo}, // HIRAGANA LETTER U + {0x3047, 0x3047, prCJ, gcLo}, // HIRAGANA LETTER SMALL E + {0x3048, 0x3048, prID, gcLo}, // HIRAGANA LETTER E + {0x3049, 0x3049, prCJ, gcLo}, // HIRAGANA LETTER SMALL O + {0x304A, 0x3062, prID, gcLo}, // [25] HIRAGANA LETTER O..HIRAGANA LETTER DI + {0x3063, 0x3063, prCJ, gcLo}, // HIRAGANA LETTER SMALL TU + {0x3064, 0x3082, prID, gcLo}, // [31] HIRAGANA LETTER TU..HIRAGANA LETTER MO + {0x3083, 0x3083, prCJ, gcLo}, // HIRAGANA LETTER SMALL YA + {0x3084, 0x3084, prID, gcLo}, // HIRAGANA LETTER YA + {0x3085, 0x3085, prCJ, gcLo}, // HIRAGANA LETTER SMALL YU + {0x3086, 0x3086, prID, gcLo}, // HIRAGANA LETTER YU + {0x3087, 0x3087, prCJ, gcLo}, // HIRAGANA LETTER SMALL YO + {0x3088, 0x308D, prID, gcLo}, // [6] HIRAGANA LETTER YO..HIRAGANA LETTER RO + {0x308E, 0x308E, prCJ, gcLo}, // HIRAGANA LETTER SMALL WA + {0x308F, 0x3094, prID, gcLo}, // [6] HIRAGANA LETTER WA..HIRAGANA LETTER VU + {0x3095, 0x3096, prCJ, gcLo}, // [2] HIRAGANA LETTER SMALL KA..HIRAGANA LETTER SMALL KE + {0x3099, 0x309A, prCM, gcMn}, // [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309B, 0x309C, prNS, gcSk}, // [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309D, 0x309E, prNS, gcLm}, // [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK + {0x309F, 0x309F, prID, gcLo}, // HIRAGANA DIGRAPH YORI + {0x30A0, 0x30A0, prNS, gcPd}, // KATAKANA-HIRAGANA DOUBLE HYPHEN + {0x30A1, 0x30A1, prCJ, gcLo}, // KATAKANA LETTER SMALL A + {0x30A2, 0x30A2, prID, gcLo}, // KATAKANA LETTER A + {0x30A3, 0x30A3, prCJ, gcLo}, // KATAKANA LETTER SMALL I + {0x30A4, 0x30A4, prID, gcLo}, // KATAKANA LETTER I + {0x30A5, 0x30A5, prCJ, gcLo}, // KATAKANA LETTER SMALL U + {0x30A6, 0x30A6, prID, gcLo}, // KATAKANA LETTER U + {0x30A7, 0x30A7, prCJ, gcLo}, // KATAKANA LETTER SMALL E + {0x30A8, 0x30A8, prID, gcLo}, // KATAKANA LETTER E + {0x30A9, 0x30A9, prCJ, gcLo}, // KATAKANA LETTER SMALL O + {0x30AA, 0x30C2, prID, gcLo}, // [25] KATAKANA LETTER O..KATAKANA LETTER DI + {0x30C3, 0x30C3, prCJ, gcLo}, // KATAKANA LETTER SMALL TU + {0x30C4, 0x30E2, prID, gcLo}, // [31] KATAKANA LETTER TU..KATAKANA LETTER MO + {0x30E3, 0x30E3, prCJ, gcLo}, // KATAKANA LETTER SMALL YA + {0x30E4, 0x30E4, prID, gcLo}, // KATAKANA LETTER YA + {0x30E5, 0x30E5, prCJ, gcLo}, // KATAKANA LETTER SMALL YU + {0x30E6, 0x30E6, prID, gcLo}, // KATAKANA LETTER YU + {0x30E7, 0x30E7, prCJ, gcLo}, // KATAKANA LETTER SMALL YO + {0x30E8, 0x30ED, prID, gcLo}, // [6] KATAKANA LETTER YO..KATAKANA LETTER RO + {0x30EE, 0x30EE, prCJ, gcLo}, // KATAKANA LETTER SMALL WA + {0x30EF, 0x30F4, prID, gcLo}, // [6] KATAKANA LETTER WA..KATAKANA LETTER VU + {0x30F5, 0x30F6, prCJ, gcLo}, // [2] KATAKANA LETTER SMALL KA..KATAKANA LETTER SMALL KE + {0x30F7, 0x30FA, prID, gcLo}, // [4] KATAKANA LETTER VA..KATAKANA LETTER VO + {0x30FB, 0x30FB, prNS, gcPo}, // KATAKANA MIDDLE DOT + {0x30FC, 0x30FC, prCJ, gcLm}, // KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0x30FD, 0x30FE, prNS, gcLm}, // [2] KATAKANA ITERATION MARK..KATAKANA VOICED ITERATION MARK + {0x30FF, 0x30FF, prID, gcLo}, // KATAKANA DIGRAPH KOTO + {0x3105, 0x312F, prID, gcLo}, // [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN + {0x3131, 0x318E, prID, gcLo}, // [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE + {0x3190, 0x3191, prID, gcSo}, // [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK + {0x3192, 0x3195, prID, gcNo}, // [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK + {0x3196, 0x319F, prID, gcSo}, // [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK + {0x31A0, 0x31BF, prID, gcLo}, // [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH + {0x31C0, 0x31E3, prID, gcSo}, // [36] CJK STROKE T..CJK STROKE Q + {0x31F0, 0x31FF, prCJ, gcLo}, // [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO + {0x3200, 0x321E, prID, gcSo}, // [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU + {0x3220, 0x3229, prID, gcNo}, // [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN + {0x322A, 0x3247, prID, gcSo}, // [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO + {0x3248, 0x324F, prAI, gcNo}, // [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE + {0x3250, 0x3250, prID, gcSo}, // PARTNERSHIP SIGN + {0x3251, 0x325F, prID, gcNo}, // [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE + {0x3260, 0x327F, prID, gcSo}, // [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL + {0x3280, 0x3289, prID, gcNo}, // [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN + {0x328A, 0x32B0, prID, gcSo}, // [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT + {0x32B1, 0x32BF, prID, gcNo}, // [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY + {0x32C0, 0x32FF, prID, gcSo}, // [64] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..SQUARE ERA NAME REIWA + {0x3300, 0x33FF, prID, gcSo}, // [256] SQUARE APAATO..SQUARE GAL + {0x3400, 0x4DBF, prID, gcLo}, // [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF + {0x4DC0, 0x4DFF, prAL, gcSo}, // [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION + {0x4E00, 0x9FFF, prID, gcLo}, // [20992] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFF + {0xA000, 0xA014, prID, gcLo}, // [21] YI SYLLABLE IT..YI SYLLABLE E + {0xA015, 0xA015, prNS, gcLm}, // YI SYLLABLE WU + {0xA016, 0xA48C, prID, gcLo}, // [1143] YI SYLLABLE BIT..YI SYLLABLE YYR + {0xA490, 0xA4C6, prID, gcSo}, // [55] YI RADICAL QOT..YI RADICAL KE + {0xA4D0, 0xA4F7, prAL, gcLo}, // [40] LISU LETTER BA..LISU LETTER OE + {0xA4F8, 0xA4FD, prAL, gcLm}, // [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU + {0xA4FE, 0xA4FF, prBA, gcPo}, // [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP + {0xA500, 0xA60B, prAL, gcLo}, // [268] VAI SYLLABLE EE..VAI SYLLABLE NG + {0xA60C, 0xA60C, prAL, gcLm}, // VAI SYLLABLE LENGTHENER + {0xA60D, 0xA60D, prBA, gcPo}, // VAI COMMA + {0xA60E, 0xA60E, prEX, gcPo}, // VAI FULL STOP + {0xA60F, 0xA60F, prBA, gcPo}, // VAI QUESTION MARK + {0xA610, 0xA61F, prAL, gcLo}, // [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG + {0xA620, 0xA629, prNU, gcNd}, // [10] VAI DIGIT ZERO..VAI DIGIT NINE + {0xA62A, 0xA62B, prAL, gcLo}, // [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO + {0xA640, 0xA66D, prAL, gcLC}, // [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O + {0xA66E, 0xA66E, prAL, gcLo}, // CYRILLIC LETTER MULTIOCULAR O + {0xA66F, 0xA66F, prCM, gcMn}, // COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prCM, gcMe}, // [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA673, 0xA673, prAL, gcPo}, // SLAVONIC ASTERISK + {0xA674, 0xA67D, prCM, gcMn}, // [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA67E, 0xA67E, prAL, gcPo}, // CYRILLIC KAVYKA + {0xA67F, 0xA67F, prAL, gcLm}, // CYRILLIC PAYEROK + {0xA680, 0xA69B, prAL, gcLC}, // [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O + {0xA69C, 0xA69D, prAL, gcLm}, // [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN + {0xA69E, 0xA69F, prCM, gcMn}, // [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6A0, 0xA6E5, prAL, gcLo}, // [70] BAMUM LETTER A..BAMUM LETTER KI + {0xA6E6, 0xA6EF, prAL, gcNl}, // [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM + {0xA6F0, 0xA6F1, prCM, gcMn}, // [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA6F2, 0xA6F2, prAL, gcPo}, // BAMUM NJAEMLI + {0xA6F3, 0xA6F7, prBA, gcPo}, // [5] BAMUM FULL STOP..BAMUM QUESTION MARK + {0xA700, 0xA716, prAL, gcSk}, // [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR + {0xA717, 0xA71F, prAL, gcLm}, // [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK + {0xA720, 0xA721, prAL, gcSk}, // [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE + {0xA722, 0xA76F, prAL, gcLC}, // [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON + {0xA770, 0xA770, prAL, gcLm}, // MODIFIER LETTER US + {0xA771, 0xA787, prAL, gcLC}, // [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T + {0xA788, 0xA788, prAL, gcLm}, // MODIFIER LETTER LOW CIRCUMFLEX ACCENT + {0xA789, 0xA78A, prAL, gcSk}, // [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN + {0xA78B, 0xA78E, prAL, gcLC}, // [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT + {0xA78F, 0xA78F, prAL, gcLo}, // LATIN LETTER SINOLOGICAL DOT + {0xA790, 0xA7CA, prAL, gcLC}, // [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY + {0xA7D0, 0xA7D1, prAL, gcLC}, // [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G + {0xA7D3, 0xA7D3, prAL, gcLl}, // LATIN SMALL LETTER DOUBLE THORN + {0xA7D5, 0xA7D9, prAL, gcLC}, // [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S + {0xA7F2, 0xA7F4, prAL, gcLm}, // [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q + {0xA7F5, 0xA7F6, prAL, gcLC}, // [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H + {0xA7F7, 0xA7F7, prAL, gcLo}, // LATIN EPIGRAPHIC LETTER SIDEWAYS I + {0xA7F8, 0xA7F9, prAL, gcLm}, // [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE + {0xA7FA, 0xA7FA, prAL, gcLl}, // LATIN LETTER SMALL CAPITAL TURNED M + {0xA7FB, 0xA7FF, prAL, gcLo}, // [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M + {0xA800, 0xA801, prAL, gcLo}, // [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I + {0xA802, 0xA802, prCM, gcMn}, // SYLOTI NAGRI SIGN DVISVARA + {0xA803, 0xA805, prAL, gcLo}, // [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O + {0xA806, 0xA806, prCM, gcMn}, // SYLOTI NAGRI SIGN HASANTA + {0xA807, 0xA80A, prAL, gcLo}, // [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO + {0xA80B, 0xA80B, prCM, gcMn}, // SYLOTI NAGRI SIGN ANUSVARA + {0xA80C, 0xA822, prAL, gcLo}, // [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO + {0xA823, 0xA824, prCM, gcMc}, // [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prCM, gcMn}, // [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prCM, gcMc}, // SYLOTI NAGRI VOWEL SIGN OO + {0xA828, 0xA82B, prAL, gcSo}, // [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4 + {0xA82C, 0xA82C, prCM, gcMn}, // SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA830, 0xA835, prAL, gcNo}, // [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS + {0xA836, 0xA837, prAL, gcSo}, // [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK + {0xA838, 0xA838, prPO, gcSc}, // NORTH INDIC RUPEE MARK + {0xA839, 0xA839, prAL, gcSo}, // NORTH INDIC QUANTITY MARK + {0xA840, 0xA873, prAL, gcLo}, // [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU + {0xA874, 0xA875, prBB, gcPo}, // [2] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA DOUBLE HEAD MARK + {0xA876, 0xA877, prEX, gcPo}, // [2] PHAGS-PA MARK SHAD..PHAGS-PA MARK DOUBLE SHAD + {0xA880, 0xA881, prCM, gcMc}, // [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA882, 0xA8B3, prAL, gcLo}, // [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA + {0xA8B4, 0xA8C3, prCM, gcMc}, // [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prCM, gcMn}, // [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8CE, 0xA8CF, prBA, gcPo}, // [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA + {0xA8D0, 0xA8D9, prNU, gcNd}, // [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE + {0xA8E0, 0xA8F1, prCM, gcMn}, // [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8F2, 0xA8F7, prAL, gcLo}, // [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA + {0xA8F8, 0xA8FA, prAL, gcPo}, // [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET + {0xA8FB, 0xA8FB, prAL, gcLo}, // DEVANAGARI HEADSTROKE + {0xA8FC, 0xA8FC, prBB, gcPo}, // DEVANAGARI SIGN SIDDHAM + {0xA8FD, 0xA8FE, prAL, gcLo}, // [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY + {0xA8FF, 0xA8FF, prCM, gcMn}, // DEVANAGARI VOWEL SIGN AY + {0xA900, 0xA909, prNU, gcNd}, // [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE + {0xA90A, 0xA925, prAL, gcLo}, // [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO + {0xA926, 0xA92D, prCM, gcMn}, // [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA92E, 0xA92F, prBA, gcPo}, // [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA + {0xA930, 0xA946, prAL, gcLo}, // [23] REJANG LETTER KA..REJANG LETTER A + {0xA947, 0xA951, prCM, gcMn}, // [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prCM, gcMc}, // [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA95F, 0xA95F, prAL, gcPo}, // REJANG SECTION MARK + {0xA960, 0xA97C, prJL, gcLo}, // [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prCM, gcMn}, // [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prCM, gcMc}, // JAVANESE SIGN WIGNYAN + {0xA984, 0xA9B2, prAL, gcLo}, // [47] JAVANESE LETTER A..JAVANESE LETTER HA + {0xA9B3, 0xA9B3, prCM, gcMn}, // JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prCM, gcMc}, // [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prCM, gcMn}, // [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prCM, gcMc}, // [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prCM, gcMn}, // [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prCM, gcMc}, // [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9C1, 0xA9C6, prAL, gcPo}, // [6] JAVANESE LEFT RERENGGAN..JAVANESE PADA WINDU + {0xA9C7, 0xA9C9, prBA, gcPo}, // [3] JAVANESE PADA PANGKAT..JAVANESE PADA LUNGSI + {0xA9CA, 0xA9CD, prAL, gcPo}, // [4] JAVANESE PADA ADEG..JAVANESE TURNED PADA PISELEH + {0xA9CF, 0xA9CF, prAL, gcLm}, // JAVANESE PANGRANGKEP + {0xA9D0, 0xA9D9, prNU, gcNd}, // [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE + {0xA9DE, 0xA9DF, prAL, gcPo}, // [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN + {0xA9E0, 0xA9E4, prSA, gcLo}, // [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA + {0xA9E5, 0xA9E5, prSA, gcMn}, // MYANMAR SIGN SHAN SAW + {0xA9E6, 0xA9E6, prSA, gcLm}, // MYANMAR MODIFIER LETTER SHAN REDUPLICATION + {0xA9E7, 0xA9EF, prSA, gcLo}, // [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA + {0xA9F0, 0xA9F9, prNU, gcNd}, // [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE + {0xA9FA, 0xA9FE, prSA, gcLo}, // [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA + {0xAA00, 0xAA28, prAL, gcLo}, // [41] CHAM LETTER A..CHAM LETTER HA + {0xAA29, 0xAA2E, prCM, gcMn}, // [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prCM, gcMc}, // [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prCM, gcMn}, // [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prCM, gcMc}, // [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prCM, gcMn}, // [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA40, 0xAA42, prAL, gcLo}, // [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG + {0xAA43, 0xAA43, prCM, gcMn}, // CHAM CONSONANT SIGN FINAL NG + {0xAA44, 0xAA4B, prAL, gcLo}, // [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS + {0xAA4C, 0xAA4C, prCM, gcMn}, // CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prCM, gcMc}, // CHAM CONSONANT SIGN FINAL H + {0xAA50, 0xAA59, prNU, gcNd}, // [10] CHAM DIGIT ZERO..CHAM DIGIT NINE + {0xAA5C, 0xAA5C, prAL, gcPo}, // CHAM PUNCTUATION SPIRAL + {0xAA5D, 0xAA5F, prBA, gcPo}, // [3] CHAM PUNCTUATION DANDA..CHAM PUNCTUATION TRIPLE DANDA + {0xAA60, 0xAA6F, prSA, gcLo}, // [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA + {0xAA70, 0xAA70, prSA, gcLm}, // MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION + {0xAA71, 0xAA76, prSA, gcLo}, // [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM + {0xAA77, 0xAA79, prSA, gcSo}, // [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO + {0xAA7A, 0xAA7A, prSA, gcLo}, // MYANMAR LETTER AITON RA + {0xAA7B, 0xAA7B, prSA, gcMc}, // MYANMAR SIGN PAO KAREN TONE + {0xAA7C, 0xAA7C, prSA, gcMn}, // MYANMAR SIGN TAI LAING TONE-2 + {0xAA7D, 0xAA7D, prSA, gcMc}, // MYANMAR SIGN TAI LAING TONE-5 + {0xAA7E, 0xAA7F, prSA, gcLo}, // [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA + {0xAA80, 0xAAAF, prSA, gcLo}, // [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O + {0xAAB0, 0xAAB0, prSA, gcMn}, // TAI VIET MAI KANG + {0xAAB1, 0xAAB1, prSA, gcLo}, // TAI VIET VOWEL AA + {0xAAB2, 0xAAB4, prSA, gcMn}, // [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB5, 0xAAB6, prSA, gcLo}, // [2] TAI VIET VOWEL E..TAI VIET VOWEL O + {0xAAB7, 0xAAB8, prSA, gcMn}, // [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAAB9, 0xAABD, prSA, gcLo}, // [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN + {0xAABE, 0xAABF, prSA, gcMn}, // [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC0, 0xAAC0, prSA, gcLo}, // TAI VIET TONE MAI NUENG + {0xAAC1, 0xAAC1, prSA, gcMn}, // TAI VIET TONE MAI THO + {0xAAC2, 0xAAC2, prSA, gcLo}, // TAI VIET TONE MAI SONG + {0xAADB, 0xAADC, prSA, gcLo}, // [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG + {0xAADD, 0xAADD, prSA, gcLm}, // TAI VIET SYMBOL SAM + {0xAADE, 0xAADF, prSA, gcPo}, // [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI + {0xAAE0, 0xAAEA, prAL, gcLo}, // [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA + {0xAAEB, 0xAAEB, prCM, gcMc}, // MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prCM, gcMn}, // [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF0, 0xAAF1, prBA, gcPo}, // [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM + {0xAAF2, 0xAAF2, prAL, gcLo}, // MEETEI MAYEK ANJI + {0xAAF3, 0xAAF4, prAL, gcLm}, // [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK + {0xAAF5, 0xAAF5, prCM, gcMc}, // MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prCM, gcMn}, // MEETEI MAYEK VIRAMA + {0xAB01, 0xAB06, prAL, gcLo}, // [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO + {0xAB09, 0xAB0E, prAL, gcLo}, // [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO + {0xAB11, 0xAB16, prAL, gcLo}, // [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO + {0xAB20, 0xAB26, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO + {0xAB28, 0xAB2E, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO + {0xAB30, 0xAB5A, prAL, gcLl}, // [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG + {0xAB5B, 0xAB5B, prAL, gcSk}, // MODIFIER BREVE WITH INVERTED BREVE + {0xAB5C, 0xAB5F, prAL, gcLm}, // [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK + {0xAB60, 0xAB68, prAL, gcLl}, // [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE + {0xAB69, 0xAB69, prAL, gcLm}, // MODIFIER LETTER SMALL TURNED W + {0xAB6A, 0xAB6B, prAL, gcSk}, // [2] MODIFIER LETTER LEFT TACK..MODIFIER LETTER RIGHT TACK + {0xAB70, 0xABBF, prAL, gcLl}, // [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA + {0xABC0, 0xABE2, prAL, gcLo}, // [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM + {0xABE3, 0xABE4, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prCM, gcMn}, // MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prCM, gcMn}, // MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEB, 0xABEB, prBA, gcPo}, // MEETEI MAYEK CHEIKHEI + {0xABEC, 0xABEC, prCM, gcMc}, // MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prCM, gcMn}, // MEETEI MAYEK APUN IYEK + {0xABF0, 0xABF9, prNU, gcNd}, // [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE + {0xAC00, 0xAC00, prH2, gcLo}, // HANGUL SYLLABLE GA + {0xAC01, 0xAC1B, prH3, gcLo}, // [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH + {0xAC1C, 0xAC1C, prH2, gcLo}, // HANGUL SYLLABLE GAE + {0xAC1D, 0xAC37, prH3, gcLo}, // [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH + {0xAC38, 0xAC38, prH2, gcLo}, // HANGUL SYLLABLE GYA + {0xAC39, 0xAC53, prH3, gcLo}, // [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH + {0xAC54, 0xAC54, prH2, gcLo}, // HANGUL SYLLABLE GYAE + {0xAC55, 0xAC6F, prH3, gcLo}, // [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH + {0xAC70, 0xAC70, prH2, gcLo}, // HANGUL SYLLABLE GEO + {0xAC71, 0xAC8B, prH3, gcLo}, // [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH + {0xAC8C, 0xAC8C, prH2, gcLo}, // HANGUL SYLLABLE GE + {0xAC8D, 0xACA7, prH3, gcLo}, // [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH + {0xACA8, 0xACA8, prH2, gcLo}, // HANGUL SYLLABLE GYEO + {0xACA9, 0xACC3, prH3, gcLo}, // [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH + {0xACC4, 0xACC4, prH2, gcLo}, // HANGUL SYLLABLE GYE + {0xACC5, 0xACDF, prH3, gcLo}, // [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH + {0xACE0, 0xACE0, prH2, gcLo}, // HANGUL SYLLABLE GO + {0xACE1, 0xACFB, prH3, gcLo}, // [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH + {0xACFC, 0xACFC, prH2, gcLo}, // HANGUL SYLLABLE GWA + {0xACFD, 0xAD17, prH3, gcLo}, // [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH + {0xAD18, 0xAD18, prH2, gcLo}, // HANGUL SYLLABLE GWAE + {0xAD19, 0xAD33, prH3, gcLo}, // [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH + {0xAD34, 0xAD34, prH2, gcLo}, // HANGUL SYLLABLE GOE + {0xAD35, 0xAD4F, prH3, gcLo}, // [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH + {0xAD50, 0xAD50, prH2, gcLo}, // HANGUL SYLLABLE GYO + {0xAD51, 0xAD6B, prH3, gcLo}, // [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH + {0xAD6C, 0xAD6C, prH2, gcLo}, // HANGUL SYLLABLE GU + {0xAD6D, 0xAD87, prH3, gcLo}, // [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH + {0xAD88, 0xAD88, prH2, gcLo}, // HANGUL SYLLABLE GWEO + {0xAD89, 0xADA3, prH3, gcLo}, // [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH + {0xADA4, 0xADA4, prH2, gcLo}, // HANGUL SYLLABLE GWE + {0xADA5, 0xADBF, prH3, gcLo}, // [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH + {0xADC0, 0xADC0, prH2, gcLo}, // HANGUL SYLLABLE GWI + {0xADC1, 0xADDB, prH3, gcLo}, // [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH + {0xADDC, 0xADDC, prH2, gcLo}, // HANGUL SYLLABLE GYU + {0xADDD, 0xADF7, prH3, gcLo}, // [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH + {0xADF8, 0xADF8, prH2, gcLo}, // HANGUL SYLLABLE GEU + {0xADF9, 0xAE13, prH3, gcLo}, // [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH + {0xAE14, 0xAE14, prH2, gcLo}, // HANGUL SYLLABLE GYI + {0xAE15, 0xAE2F, prH3, gcLo}, // [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH + {0xAE30, 0xAE30, prH2, gcLo}, // HANGUL SYLLABLE GI + {0xAE31, 0xAE4B, prH3, gcLo}, // [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH + {0xAE4C, 0xAE4C, prH2, gcLo}, // HANGUL SYLLABLE GGA + {0xAE4D, 0xAE67, prH3, gcLo}, // [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH + {0xAE68, 0xAE68, prH2, gcLo}, // HANGUL SYLLABLE GGAE + {0xAE69, 0xAE83, prH3, gcLo}, // [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH + {0xAE84, 0xAE84, prH2, gcLo}, // HANGUL SYLLABLE GGYA + {0xAE85, 0xAE9F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH + {0xAEA0, 0xAEA0, prH2, gcLo}, // HANGUL SYLLABLE GGYAE + {0xAEA1, 0xAEBB, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH + {0xAEBC, 0xAEBC, prH2, gcLo}, // HANGUL SYLLABLE GGEO + {0xAEBD, 0xAED7, prH3, gcLo}, // [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH + {0xAED8, 0xAED8, prH2, gcLo}, // HANGUL SYLLABLE GGE + {0xAED9, 0xAEF3, prH3, gcLo}, // [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH + {0xAEF4, 0xAEF4, prH2, gcLo}, // HANGUL SYLLABLE GGYEO + {0xAEF5, 0xAF0F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH + {0xAF10, 0xAF10, prH2, gcLo}, // HANGUL SYLLABLE GGYE + {0xAF11, 0xAF2B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH + {0xAF2C, 0xAF2C, prH2, gcLo}, // HANGUL SYLLABLE GGO + {0xAF2D, 0xAF47, prH3, gcLo}, // [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH + {0xAF48, 0xAF48, prH2, gcLo}, // HANGUL SYLLABLE GGWA + {0xAF49, 0xAF63, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH + {0xAF64, 0xAF64, prH2, gcLo}, // HANGUL SYLLABLE GGWAE + {0xAF65, 0xAF7F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH + {0xAF80, 0xAF80, prH2, gcLo}, // HANGUL SYLLABLE GGOE + {0xAF81, 0xAF9B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH + {0xAF9C, 0xAF9C, prH2, gcLo}, // HANGUL SYLLABLE GGYO + {0xAF9D, 0xAFB7, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH + {0xAFB8, 0xAFB8, prH2, gcLo}, // HANGUL SYLLABLE GGU + {0xAFB9, 0xAFD3, prH3, gcLo}, // [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH + {0xAFD4, 0xAFD4, prH2, gcLo}, // HANGUL SYLLABLE GGWEO + {0xAFD5, 0xAFEF, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH + {0xAFF0, 0xAFF0, prH2, gcLo}, // HANGUL SYLLABLE GGWE + {0xAFF1, 0xB00B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH + {0xB00C, 0xB00C, prH2, gcLo}, // HANGUL SYLLABLE GGWI + {0xB00D, 0xB027, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH + {0xB028, 0xB028, prH2, gcLo}, // HANGUL SYLLABLE GGYU + {0xB029, 0xB043, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH + {0xB044, 0xB044, prH2, gcLo}, // HANGUL SYLLABLE GGEU + {0xB045, 0xB05F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH + {0xB060, 0xB060, prH2, gcLo}, // HANGUL SYLLABLE GGYI + {0xB061, 0xB07B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH + {0xB07C, 0xB07C, prH2, gcLo}, // HANGUL SYLLABLE GGI + {0xB07D, 0xB097, prH3, gcLo}, // [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH + {0xB098, 0xB098, prH2, gcLo}, // HANGUL SYLLABLE NA + {0xB099, 0xB0B3, prH3, gcLo}, // [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH + {0xB0B4, 0xB0B4, prH2, gcLo}, // HANGUL SYLLABLE NAE + {0xB0B5, 0xB0CF, prH3, gcLo}, // [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH + {0xB0D0, 0xB0D0, prH2, gcLo}, // HANGUL SYLLABLE NYA + {0xB0D1, 0xB0EB, prH3, gcLo}, // [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH + {0xB0EC, 0xB0EC, prH2, gcLo}, // HANGUL SYLLABLE NYAE + {0xB0ED, 0xB107, prH3, gcLo}, // [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH + {0xB108, 0xB108, prH2, gcLo}, // HANGUL SYLLABLE NEO + {0xB109, 0xB123, prH3, gcLo}, // [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH + {0xB124, 0xB124, prH2, gcLo}, // HANGUL SYLLABLE NE + {0xB125, 0xB13F, prH3, gcLo}, // [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH + {0xB140, 0xB140, prH2, gcLo}, // HANGUL SYLLABLE NYEO + {0xB141, 0xB15B, prH3, gcLo}, // [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH + {0xB15C, 0xB15C, prH2, gcLo}, // HANGUL SYLLABLE NYE + {0xB15D, 0xB177, prH3, gcLo}, // [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH + {0xB178, 0xB178, prH2, gcLo}, // HANGUL SYLLABLE NO + {0xB179, 0xB193, prH3, gcLo}, // [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH + {0xB194, 0xB194, prH2, gcLo}, // HANGUL SYLLABLE NWA + {0xB195, 0xB1AF, prH3, gcLo}, // [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH + {0xB1B0, 0xB1B0, prH2, gcLo}, // HANGUL SYLLABLE NWAE + {0xB1B1, 0xB1CB, prH3, gcLo}, // [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH + {0xB1CC, 0xB1CC, prH2, gcLo}, // HANGUL SYLLABLE NOE + {0xB1CD, 0xB1E7, prH3, gcLo}, // [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH + {0xB1E8, 0xB1E8, prH2, gcLo}, // HANGUL SYLLABLE NYO + {0xB1E9, 0xB203, prH3, gcLo}, // [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH + {0xB204, 0xB204, prH2, gcLo}, // HANGUL SYLLABLE NU + {0xB205, 0xB21F, prH3, gcLo}, // [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH + {0xB220, 0xB220, prH2, gcLo}, // HANGUL SYLLABLE NWEO + {0xB221, 0xB23B, prH3, gcLo}, // [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH + {0xB23C, 0xB23C, prH2, gcLo}, // HANGUL SYLLABLE NWE + {0xB23D, 0xB257, prH3, gcLo}, // [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH + {0xB258, 0xB258, prH2, gcLo}, // HANGUL SYLLABLE NWI + {0xB259, 0xB273, prH3, gcLo}, // [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH + {0xB274, 0xB274, prH2, gcLo}, // HANGUL SYLLABLE NYU + {0xB275, 0xB28F, prH3, gcLo}, // [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH + {0xB290, 0xB290, prH2, gcLo}, // HANGUL SYLLABLE NEU + {0xB291, 0xB2AB, prH3, gcLo}, // [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH + {0xB2AC, 0xB2AC, prH2, gcLo}, // HANGUL SYLLABLE NYI + {0xB2AD, 0xB2C7, prH3, gcLo}, // [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH + {0xB2C8, 0xB2C8, prH2, gcLo}, // HANGUL SYLLABLE NI + {0xB2C9, 0xB2E3, prH3, gcLo}, // [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH + {0xB2E4, 0xB2E4, prH2, gcLo}, // HANGUL SYLLABLE DA + {0xB2E5, 0xB2FF, prH3, gcLo}, // [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH + {0xB300, 0xB300, prH2, gcLo}, // HANGUL SYLLABLE DAE + {0xB301, 0xB31B, prH3, gcLo}, // [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH + {0xB31C, 0xB31C, prH2, gcLo}, // HANGUL SYLLABLE DYA + {0xB31D, 0xB337, prH3, gcLo}, // [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH + {0xB338, 0xB338, prH2, gcLo}, // HANGUL SYLLABLE DYAE + {0xB339, 0xB353, prH3, gcLo}, // [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH + {0xB354, 0xB354, prH2, gcLo}, // HANGUL SYLLABLE DEO + {0xB355, 0xB36F, prH3, gcLo}, // [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH + {0xB370, 0xB370, prH2, gcLo}, // HANGUL SYLLABLE DE + {0xB371, 0xB38B, prH3, gcLo}, // [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH + {0xB38C, 0xB38C, prH2, gcLo}, // HANGUL SYLLABLE DYEO + {0xB38D, 0xB3A7, prH3, gcLo}, // [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH + {0xB3A8, 0xB3A8, prH2, gcLo}, // HANGUL SYLLABLE DYE + {0xB3A9, 0xB3C3, prH3, gcLo}, // [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH + {0xB3C4, 0xB3C4, prH2, gcLo}, // HANGUL SYLLABLE DO + {0xB3C5, 0xB3DF, prH3, gcLo}, // [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH + {0xB3E0, 0xB3E0, prH2, gcLo}, // HANGUL SYLLABLE DWA + {0xB3E1, 0xB3FB, prH3, gcLo}, // [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH + {0xB3FC, 0xB3FC, prH2, gcLo}, // HANGUL SYLLABLE DWAE + {0xB3FD, 0xB417, prH3, gcLo}, // [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH + {0xB418, 0xB418, prH2, gcLo}, // HANGUL SYLLABLE DOE + {0xB419, 0xB433, prH3, gcLo}, // [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH + {0xB434, 0xB434, prH2, gcLo}, // HANGUL SYLLABLE DYO + {0xB435, 0xB44F, prH3, gcLo}, // [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH + {0xB450, 0xB450, prH2, gcLo}, // HANGUL SYLLABLE DU + {0xB451, 0xB46B, prH3, gcLo}, // [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH + {0xB46C, 0xB46C, prH2, gcLo}, // HANGUL SYLLABLE DWEO + {0xB46D, 0xB487, prH3, gcLo}, // [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH + {0xB488, 0xB488, prH2, gcLo}, // HANGUL SYLLABLE DWE + {0xB489, 0xB4A3, prH3, gcLo}, // [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH + {0xB4A4, 0xB4A4, prH2, gcLo}, // HANGUL SYLLABLE DWI + {0xB4A5, 0xB4BF, prH3, gcLo}, // [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH + {0xB4C0, 0xB4C0, prH2, gcLo}, // HANGUL SYLLABLE DYU + {0xB4C1, 0xB4DB, prH3, gcLo}, // [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH + {0xB4DC, 0xB4DC, prH2, gcLo}, // HANGUL SYLLABLE DEU + {0xB4DD, 0xB4F7, prH3, gcLo}, // [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH + {0xB4F8, 0xB4F8, prH2, gcLo}, // HANGUL SYLLABLE DYI + {0xB4F9, 0xB513, prH3, gcLo}, // [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH + {0xB514, 0xB514, prH2, gcLo}, // HANGUL SYLLABLE DI + {0xB515, 0xB52F, prH3, gcLo}, // [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH + {0xB530, 0xB530, prH2, gcLo}, // HANGUL SYLLABLE DDA + {0xB531, 0xB54B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH + {0xB54C, 0xB54C, prH2, gcLo}, // HANGUL SYLLABLE DDAE + {0xB54D, 0xB567, prH3, gcLo}, // [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH + {0xB568, 0xB568, prH2, gcLo}, // HANGUL SYLLABLE DDYA + {0xB569, 0xB583, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH + {0xB584, 0xB584, prH2, gcLo}, // HANGUL SYLLABLE DDYAE + {0xB585, 0xB59F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH + {0xB5A0, 0xB5A0, prH2, gcLo}, // HANGUL SYLLABLE DDEO + {0xB5A1, 0xB5BB, prH3, gcLo}, // [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH + {0xB5BC, 0xB5BC, prH2, gcLo}, // HANGUL SYLLABLE DDE + {0xB5BD, 0xB5D7, prH3, gcLo}, // [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH + {0xB5D8, 0xB5D8, prH2, gcLo}, // HANGUL SYLLABLE DDYEO + {0xB5D9, 0xB5F3, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH + {0xB5F4, 0xB5F4, prH2, gcLo}, // HANGUL SYLLABLE DDYE + {0xB5F5, 0xB60F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH + {0xB610, 0xB610, prH2, gcLo}, // HANGUL SYLLABLE DDO + {0xB611, 0xB62B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH + {0xB62C, 0xB62C, prH2, gcLo}, // HANGUL SYLLABLE DDWA + {0xB62D, 0xB647, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH + {0xB648, 0xB648, prH2, gcLo}, // HANGUL SYLLABLE DDWAE + {0xB649, 0xB663, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH + {0xB664, 0xB664, prH2, gcLo}, // HANGUL SYLLABLE DDOE + {0xB665, 0xB67F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH + {0xB680, 0xB680, prH2, gcLo}, // HANGUL SYLLABLE DDYO + {0xB681, 0xB69B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH + {0xB69C, 0xB69C, prH2, gcLo}, // HANGUL SYLLABLE DDU + {0xB69D, 0xB6B7, prH3, gcLo}, // [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH + {0xB6B8, 0xB6B8, prH2, gcLo}, // HANGUL SYLLABLE DDWEO + {0xB6B9, 0xB6D3, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH + {0xB6D4, 0xB6D4, prH2, gcLo}, // HANGUL SYLLABLE DDWE + {0xB6D5, 0xB6EF, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH + {0xB6F0, 0xB6F0, prH2, gcLo}, // HANGUL SYLLABLE DDWI + {0xB6F1, 0xB70B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH + {0xB70C, 0xB70C, prH2, gcLo}, // HANGUL SYLLABLE DDYU + {0xB70D, 0xB727, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH + {0xB728, 0xB728, prH2, gcLo}, // HANGUL SYLLABLE DDEU + {0xB729, 0xB743, prH3, gcLo}, // [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH + {0xB744, 0xB744, prH2, gcLo}, // HANGUL SYLLABLE DDYI + {0xB745, 0xB75F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH + {0xB760, 0xB760, prH2, gcLo}, // HANGUL SYLLABLE DDI + {0xB761, 0xB77B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH + {0xB77C, 0xB77C, prH2, gcLo}, // HANGUL SYLLABLE RA + {0xB77D, 0xB797, prH3, gcLo}, // [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH + {0xB798, 0xB798, prH2, gcLo}, // HANGUL SYLLABLE RAE + {0xB799, 0xB7B3, prH3, gcLo}, // [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH + {0xB7B4, 0xB7B4, prH2, gcLo}, // HANGUL SYLLABLE RYA + {0xB7B5, 0xB7CF, prH3, gcLo}, // [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH + {0xB7D0, 0xB7D0, prH2, gcLo}, // HANGUL SYLLABLE RYAE + {0xB7D1, 0xB7EB, prH3, gcLo}, // [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH + {0xB7EC, 0xB7EC, prH2, gcLo}, // HANGUL SYLLABLE REO + {0xB7ED, 0xB807, prH3, gcLo}, // [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH + {0xB808, 0xB808, prH2, gcLo}, // HANGUL SYLLABLE RE + {0xB809, 0xB823, prH3, gcLo}, // [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH + {0xB824, 0xB824, prH2, gcLo}, // HANGUL SYLLABLE RYEO + {0xB825, 0xB83F, prH3, gcLo}, // [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH + {0xB840, 0xB840, prH2, gcLo}, // HANGUL SYLLABLE RYE + {0xB841, 0xB85B, prH3, gcLo}, // [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH + {0xB85C, 0xB85C, prH2, gcLo}, // HANGUL SYLLABLE RO + {0xB85D, 0xB877, prH3, gcLo}, // [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH + {0xB878, 0xB878, prH2, gcLo}, // HANGUL SYLLABLE RWA + {0xB879, 0xB893, prH3, gcLo}, // [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH + {0xB894, 0xB894, prH2, gcLo}, // HANGUL SYLLABLE RWAE + {0xB895, 0xB8AF, prH3, gcLo}, // [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH + {0xB8B0, 0xB8B0, prH2, gcLo}, // HANGUL SYLLABLE ROE + {0xB8B1, 0xB8CB, prH3, gcLo}, // [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH + {0xB8CC, 0xB8CC, prH2, gcLo}, // HANGUL SYLLABLE RYO + {0xB8CD, 0xB8E7, prH3, gcLo}, // [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH + {0xB8E8, 0xB8E8, prH2, gcLo}, // HANGUL SYLLABLE RU + {0xB8E9, 0xB903, prH3, gcLo}, // [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH + {0xB904, 0xB904, prH2, gcLo}, // HANGUL SYLLABLE RWEO + {0xB905, 0xB91F, prH3, gcLo}, // [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH + {0xB920, 0xB920, prH2, gcLo}, // HANGUL SYLLABLE RWE + {0xB921, 0xB93B, prH3, gcLo}, // [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH + {0xB93C, 0xB93C, prH2, gcLo}, // HANGUL SYLLABLE RWI + {0xB93D, 0xB957, prH3, gcLo}, // [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH + {0xB958, 0xB958, prH2, gcLo}, // HANGUL SYLLABLE RYU + {0xB959, 0xB973, prH3, gcLo}, // [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH + {0xB974, 0xB974, prH2, gcLo}, // HANGUL SYLLABLE REU + {0xB975, 0xB98F, prH3, gcLo}, // [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH + {0xB990, 0xB990, prH2, gcLo}, // HANGUL SYLLABLE RYI + {0xB991, 0xB9AB, prH3, gcLo}, // [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH + {0xB9AC, 0xB9AC, prH2, gcLo}, // HANGUL SYLLABLE RI + {0xB9AD, 0xB9C7, prH3, gcLo}, // [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH + {0xB9C8, 0xB9C8, prH2, gcLo}, // HANGUL SYLLABLE MA + {0xB9C9, 0xB9E3, prH3, gcLo}, // [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH + {0xB9E4, 0xB9E4, prH2, gcLo}, // HANGUL SYLLABLE MAE + {0xB9E5, 0xB9FF, prH3, gcLo}, // [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH + {0xBA00, 0xBA00, prH2, gcLo}, // HANGUL SYLLABLE MYA + {0xBA01, 0xBA1B, prH3, gcLo}, // [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH + {0xBA1C, 0xBA1C, prH2, gcLo}, // HANGUL SYLLABLE MYAE + {0xBA1D, 0xBA37, prH3, gcLo}, // [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH + {0xBA38, 0xBA38, prH2, gcLo}, // HANGUL SYLLABLE MEO + {0xBA39, 0xBA53, prH3, gcLo}, // [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH + {0xBA54, 0xBA54, prH2, gcLo}, // HANGUL SYLLABLE ME + {0xBA55, 0xBA6F, prH3, gcLo}, // [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH + {0xBA70, 0xBA70, prH2, gcLo}, // HANGUL SYLLABLE MYEO + {0xBA71, 0xBA8B, prH3, gcLo}, // [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH + {0xBA8C, 0xBA8C, prH2, gcLo}, // HANGUL SYLLABLE MYE + {0xBA8D, 0xBAA7, prH3, gcLo}, // [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH + {0xBAA8, 0xBAA8, prH2, gcLo}, // HANGUL SYLLABLE MO + {0xBAA9, 0xBAC3, prH3, gcLo}, // [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH + {0xBAC4, 0xBAC4, prH2, gcLo}, // HANGUL SYLLABLE MWA + {0xBAC5, 0xBADF, prH3, gcLo}, // [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH + {0xBAE0, 0xBAE0, prH2, gcLo}, // HANGUL SYLLABLE MWAE + {0xBAE1, 0xBAFB, prH3, gcLo}, // [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH + {0xBAFC, 0xBAFC, prH2, gcLo}, // HANGUL SYLLABLE MOE + {0xBAFD, 0xBB17, prH3, gcLo}, // [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH + {0xBB18, 0xBB18, prH2, gcLo}, // HANGUL SYLLABLE MYO + {0xBB19, 0xBB33, prH3, gcLo}, // [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH + {0xBB34, 0xBB34, prH2, gcLo}, // HANGUL SYLLABLE MU + {0xBB35, 0xBB4F, prH3, gcLo}, // [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH + {0xBB50, 0xBB50, prH2, gcLo}, // HANGUL SYLLABLE MWEO + {0xBB51, 0xBB6B, prH3, gcLo}, // [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH + {0xBB6C, 0xBB6C, prH2, gcLo}, // HANGUL SYLLABLE MWE + {0xBB6D, 0xBB87, prH3, gcLo}, // [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH + {0xBB88, 0xBB88, prH2, gcLo}, // HANGUL SYLLABLE MWI + {0xBB89, 0xBBA3, prH3, gcLo}, // [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH + {0xBBA4, 0xBBA4, prH2, gcLo}, // HANGUL SYLLABLE MYU + {0xBBA5, 0xBBBF, prH3, gcLo}, // [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH + {0xBBC0, 0xBBC0, prH2, gcLo}, // HANGUL SYLLABLE MEU + {0xBBC1, 0xBBDB, prH3, gcLo}, // [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH + {0xBBDC, 0xBBDC, prH2, gcLo}, // HANGUL SYLLABLE MYI + {0xBBDD, 0xBBF7, prH3, gcLo}, // [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH + {0xBBF8, 0xBBF8, prH2, gcLo}, // HANGUL SYLLABLE MI + {0xBBF9, 0xBC13, prH3, gcLo}, // [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH + {0xBC14, 0xBC14, prH2, gcLo}, // HANGUL SYLLABLE BA + {0xBC15, 0xBC2F, prH3, gcLo}, // [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH + {0xBC30, 0xBC30, prH2, gcLo}, // HANGUL SYLLABLE BAE + {0xBC31, 0xBC4B, prH3, gcLo}, // [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH + {0xBC4C, 0xBC4C, prH2, gcLo}, // HANGUL SYLLABLE BYA + {0xBC4D, 0xBC67, prH3, gcLo}, // [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH + {0xBC68, 0xBC68, prH2, gcLo}, // HANGUL SYLLABLE BYAE + {0xBC69, 0xBC83, prH3, gcLo}, // [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH + {0xBC84, 0xBC84, prH2, gcLo}, // HANGUL SYLLABLE BEO + {0xBC85, 0xBC9F, prH3, gcLo}, // [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH + {0xBCA0, 0xBCA0, prH2, gcLo}, // HANGUL SYLLABLE BE + {0xBCA1, 0xBCBB, prH3, gcLo}, // [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH + {0xBCBC, 0xBCBC, prH2, gcLo}, // HANGUL SYLLABLE BYEO + {0xBCBD, 0xBCD7, prH3, gcLo}, // [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH + {0xBCD8, 0xBCD8, prH2, gcLo}, // HANGUL SYLLABLE BYE + {0xBCD9, 0xBCF3, prH3, gcLo}, // [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH + {0xBCF4, 0xBCF4, prH2, gcLo}, // HANGUL SYLLABLE BO + {0xBCF5, 0xBD0F, prH3, gcLo}, // [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH + {0xBD10, 0xBD10, prH2, gcLo}, // HANGUL SYLLABLE BWA + {0xBD11, 0xBD2B, prH3, gcLo}, // [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH + {0xBD2C, 0xBD2C, prH2, gcLo}, // HANGUL SYLLABLE BWAE + {0xBD2D, 0xBD47, prH3, gcLo}, // [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH + {0xBD48, 0xBD48, prH2, gcLo}, // HANGUL SYLLABLE BOE + {0xBD49, 0xBD63, prH3, gcLo}, // [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH + {0xBD64, 0xBD64, prH2, gcLo}, // HANGUL SYLLABLE BYO + {0xBD65, 0xBD7F, prH3, gcLo}, // [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH + {0xBD80, 0xBD80, prH2, gcLo}, // HANGUL SYLLABLE BU + {0xBD81, 0xBD9B, prH3, gcLo}, // [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH + {0xBD9C, 0xBD9C, prH2, gcLo}, // HANGUL SYLLABLE BWEO + {0xBD9D, 0xBDB7, prH3, gcLo}, // [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH + {0xBDB8, 0xBDB8, prH2, gcLo}, // HANGUL SYLLABLE BWE + {0xBDB9, 0xBDD3, prH3, gcLo}, // [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH + {0xBDD4, 0xBDD4, prH2, gcLo}, // HANGUL SYLLABLE BWI + {0xBDD5, 0xBDEF, prH3, gcLo}, // [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH + {0xBDF0, 0xBDF0, prH2, gcLo}, // HANGUL SYLLABLE BYU + {0xBDF1, 0xBE0B, prH3, gcLo}, // [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH + {0xBE0C, 0xBE0C, prH2, gcLo}, // HANGUL SYLLABLE BEU + {0xBE0D, 0xBE27, prH3, gcLo}, // [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH + {0xBE28, 0xBE28, prH2, gcLo}, // HANGUL SYLLABLE BYI + {0xBE29, 0xBE43, prH3, gcLo}, // [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH + {0xBE44, 0xBE44, prH2, gcLo}, // HANGUL SYLLABLE BI + {0xBE45, 0xBE5F, prH3, gcLo}, // [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH + {0xBE60, 0xBE60, prH2, gcLo}, // HANGUL SYLLABLE BBA + {0xBE61, 0xBE7B, prH3, gcLo}, // [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH + {0xBE7C, 0xBE7C, prH2, gcLo}, // HANGUL SYLLABLE BBAE + {0xBE7D, 0xBE97, prH3, gcLo}, // [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH + {0xBE98, 0xBE98, prH2, gcLo}, // HANGUL SYLLABLE BBYA + {0xBE99, 0xBEB3, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH + {0xBEB4, 0xBEB4, prH2, gcLo}, // HANGUL SYLLABLE BBYAE + {0xBEB5, 0xBECF, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH + {0xBED0, 0xBED0, prH2, gcLo}, // HANGUL SYLLABLE BBEO + {0xBED1, 0xBEEB, prH3, gcLo}, // [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH + {0xBEEC, 0xBEEC, prH2, gcLo}, // HANGUL SYLLABLE BBE + {0xBEED, 0xBF07, prH3, gcLo}, // [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH + {0xBF08, 0xBF08, prH2, gcLo}, // HANGUL SYLLABLE BBYEO + {0xBF09, 0xBF23, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH + {0xBF24, 0xBF24, prH2, gcLo}, // HANGUL SYLLABLE BBYE + {0xBF25, 0xBF3F, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH + {0xBF40, 0xBF40, prH2, gcLo}, // HANGUL SYLLABLE BBO + {0xBF41, 0xBF5B, prH3, gcLo}, // [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH + {0xBF5C, 0xBF5C, prH2, gcLo}, // HANGUL SYLLABLE BBWA + {0xBF5D, 0xBF77, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH + {0xBF78, 0xBF78, prH2, gcLo}, // HANGUL SYLLABLE BBWAE + {0xBF79, 0xBF93, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH + {0xBF94, 0xBF94, prH2, gcLo}, // HANGUL SYLLABLE BBOE + {0xBF95, 0xBFAF, prH3, gcLo}, // [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH + {0xBFB0, 0xBFB0, prH2, gcLo}, // HANGUL SYLLABLE BBYO + {0xBFB1, 0xBFCB, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH + {0xBFCC, 0xBFCC, prH2, gcLo}, // HANGUL SYLLABLE BBU + {0xBFCD, 0xBFE7, prH3, gcLo}, // [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH + {0xBFE8, 0xBFE8, prH2, gcLo}, // HANGUL SYLLABLE BBWEO + {0xBFE9, 0xC003, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH + {0xC004, 0xC004, prH2, gcLo}, // HANGUL SYLLABLE BBWE + {0xC005, 0xC01F, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH + {0xC020, 0xC020, prH2, gcLo}, // HANGUL SYLLABLE BBWI + {0xC021, 0xC03B, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH + {0xC03C, 0xC03C, prH2, gcLo}, // HANGUL SYLLABLE BBYU + {0xC03D, 0xC057, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH + {0xC058, 0xC058, prH2, gcLo}, // HANGUL SYLLABLE BBEU + {0xC059, 0xC073, prH3, gcLo}, // [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH + {0xC074, 0xC074, prH2, gcLo}, // HANGUL SYLLABLE BBYI + {0xC075, 0xC08F, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH + {0xC090, 0xC090, prH2, gcLo}, // HANGUL SYLLABLE BBI + {0xC091, 0xC0AB, prH3, gcLo}, // [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH + {0xC0AC, 0xC0AC, prH2, gcLo}, // HANGUL SYLLABLE SA + {0xC0AD, 0xC0C7, prH3, gcLo}, // [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH + {0xC0C8, 0xC0C8, prH2, gcLo}, // HANGUL SYLLABLE SAE + {0xC0C9, 0xC0E3, prH3, gcLo}, // [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH + {0xC0E4, 0xC0E4, prH2, gcLo}, // HANGUL SYLLABLE SYA + {0xC0E5, 0xC0FF, prH3, gcLo}, // [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH + {0xC100, 0xC100, prH2, gcLo}, // HANGUL SYLLABLE SYAE + {0xC101, 0xC11B, prH3, gcLo}, // [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH + {0xC11C, 0xC11C, prH2, gcLo}, // HANGUL SYLLABLE SEO + {0xC11D, 0xC137, prH3, gcLo}, // [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH + {0xC138, 0xC138, prH2, gcLo}, // HANGUL SYLLABLE SE + {0xC139, 0xC153, prH3, gcLo}, // [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH + {0xC154, 0xC154, prH2, gcLo}, // HANGUL SYLLABLE SYEO + {0xC155, 0xC16F, prH3, gcLo}, // [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH + {0xC170, 0xC170, prH2, gcLo}, // HANGUL SYLLABLE SYE + {0xC171, 0xC18B, prH3, gcLo}, // [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH + {0xC18C, 0xC18C, prH2, gcLo}, // HANGUL SYLLABLE SO + {0xC18D, 0xC1A7, prH3, gcLo}, // [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH + {0xC1A8, 0xC1A8, prH2, gcLo}, // HANGUL SYLLABLE SWA + {0xC1A9, 0xC1C3, prH3, gcLo}, // [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH + {0xC1C4, 0xC1C4, prH2, gcLo}, // HANGUL SYLLABLE SWAE + {0xC1C5, 0xC1DF, prH3, gcLo}, // [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH + {0xC1E0, 0xC1E0, prH2, gcLo}, // HANGUL SYLLABLE SOE + {0xC1E1, 0xC1FB, prH3, gcLo}, // [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH + {0xC1FC, 0xC1FC, prH2, gcLo}, // HANGUL SYLLABLE SYO + {0xC1FD, 0xC217, prH3, gcLo}, // [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH + {0xC218, 0xC218, prH2, gcLo}, // HANGUL SYLLABLE SU + {0xC219, 0xC233, prH3, gcLo}, // [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH + {0xC234, 0xC234, prH2, gcLo}, // HANGUL SYLLABLE SWEO + {0xC235, 0xC24F, prH3, gcLo}, // [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH + {0xC250, 0xC250, prH2, gcLo}, // HANGUL SYLLABLE SWE + {0xC251, 0xC26B, prH3, gcLo}, // [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH + {0xC26C, 0xC26C, prH2, gcLo}, // HANGUL SYLLABLE SWI + {0xC26D, 0xC287, prH3, gcLo}, // [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH + {0xC288, 0xC288, prH2, gcLo}, // HANGUL SYLLABLE SYU + {0xC289, 0xC2A3, prH3, gcLo}, // [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH + {0xC2A4, 0xC2A4, prH2, gcLo}, // HANGUL SYLLABLE SEU + {0xC2A5, 0xC2BF, prH3, gcLo}, // [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH + {0xC2C0, 0xC2C0, prH2, gcLo}, // HANGUL SYLLABLE SYI + {0xC2C1, 0xC2DB, prH3, gcLo}, // [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH + {0xC2DC, 0xC2DC, prH2, gcLo}, // HANGUL SYLLABLE SI + {0xC2DD, 0xC2F7, prH3, gcLo}, // [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH + {0xC2F8, 0xC2F8, prH2, gcLo}, // HANGUL SYLLABLE SSA + {0xC2F9, 0xC313, prH3, gcLo}, // [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH + {0xC314, 0xC314, prH2, gcLo}, // HANGUL SYLLABLE SSAE + {0xC315, 0xC32F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH + {0xC330, 0xC330, prH2, gcLo}, // HANGUL SYLLABLE SSYA + {0xC331, 0xC34B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH + {0xC34C, 0xC34C, prH2, gcLo}, // HANGUL SYLLABLE SSYAE + {0xC34D, 0xC367, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH + {0xC368, 0xC368, prH2, gcLo}, // HANGUL SYLLABLE SSEO + {0xC369, 0xC383, prH3, gcLo}, // [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH + {0xC384, 0xC384, prH2, gcLo}, // HANGUL SYLLABLE SSE + {0xC385, 0xC39F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH + {0xC3A0, 0xC3A0, prH2, gcLo}, // HANGUL SYLLABLE SSYEO + {0xC3A1, 0xC3BB, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH + {0xC3BC, 0xC3BC, prH2, gcLo}, // HANGUL SYLLABLE SSYE + {0xC3BD, 0xC3D7, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH + {0xC3D8, 0xC3D8, prH2, gcLo}, // HANGUL SYLLABLE SSO + {0xC3D9, 0xC3F3, prH3, gcLo}, // [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH + {0xC3F4, 0xC3F4, prH2, gcLo}, // HANGUL SYLLABLE SSWA + {0xC3F5, 0xC40F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH + {0xC410, 0xC410, prH2, gcLo}, // HANGUL SYLLABLE SSWAE + {0xC411, 0xC42B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH + {0xC42C, 0xC42C, prH2, gcLo}, // HANGUL SYLLABLE SSOE + {0xC42D, 0xC447, prH3, gcLo}, // [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH + {0xC448, 0xC448, prH2, gcLo}, // HANGUL SYLLABLE SSYO + {0xC449, 0xC463, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH + {0xC464, 0xC464, prH2, gcLo}, // HANGUL SYLLABLE SSU + {0xC465, 0xC47F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH + {0xC480, 0xC480, prH2, gcLo}, // HANGUL SYLLABLE SSWEO + {0xC481, 0xC49B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH + {0xC49C, 0xC49C, prH2, gcLo}, // HANGUL SYLLABLE SSWE + {0xC49D, 0xC4B7, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH + {0xC4B8, 0xC4B8, prH2, gcLo}, // HANGUL SYLLABLE SSWI + {0xC4B9, 0xC4D3, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH + {0xC4D4, 0xC4D4, prH2, gcLo}, // HANGUL SYLLABLE SSYU + {0xC4D5, 0xC4EF, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH + {0xC4F0, 0xC4F0, prH2, gcLo}, // HANGUL SYLLABLE SSEU + {0xC4F1, 0xC50B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH + {0xC50C, 0xC50C, prH2, gcLo}, // HANGUL SYLLABLE SSYI + {0xC50D, 0xC527, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH + {0xC528, 0xC528, prH2, gcLo}, // HANGUL SYLLABLE SSI + {0xC529, 0xC543, prH3, gcLo}, // [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH + {0xC544, 0xC544, prH2, gcLo}, // HANGUL SYLLABLE A + {0xC545, 0xC55F, prH3, gcLo}, // [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH + {0xC560, 0xC560, prH2, gcLo}, // HANGUL SYLLABLE AE + {0xC561, 0xC57B, prH3, gcLo}, // [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH + {0xC57C, 0xC57C, prH2, gcLo}, // HANGUL SYLLABLE YA + {0xC57D, 0xC597, prH3, gcLo}, // [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH + {0xC598, 0xC598, prH2, gcLo}, // HANGUL SYLLABLE YAE + {0xC599, 0xC5B3, prH3, gcLo}, // [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH + {0xC5B4, 0xC5B4, prH2, gcLo}, // HANGUL SYLLABLE EO + {0xC5B5, 0xC5CF, prH3, gcLo}, // [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH + {0xC5D0, 0xC5D0, prH2, gcLo}, // HANGUL SYLLABLE E + {0xC5D1, 0xC5EB, prH3, gcLo}, // [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH + {0xC5EC, 0xC5EC, prH2, gcLo}, // HANGUL SYLLABLE YEO + {0xC5ED, 0xC607, prH3, gcLo}, // [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH + {0xC608, 0xC608, prH2, gcLo}, // HANGUL SYLLABLE YE + {0xC609, 0xC623, prH3, gcLo}, // [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH + {0xC624, 0xC624, prH2, gcLo}, // HANGUL SYLLABLE O + {0xC625, 0xC63F, prH3, gcLo}, // [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH + {0xC640, 0xC640, prH2, gcLo}, // HANGUL SYLLABLE WA + {0xC641, 0xC65B, prH3, gcLo}, // [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH + {0xC65C, 0xC65C, prH2, gcLo}, // HANGUL SYLLABLE WAE + {0xC65D, 0xC677, prH3, gcLo}, // [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH + {0xC678, 0xC678, prH2, gcLo}, // HANGUL SYLLABLE OE + {0xC679, 0xC693, prH3, gcLo}, // [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH + {0xC694, 0xC694, prH2, gcLo}, // HANGUL SYLLABLE YO + {0xC695, 0xC6AF, prH3, gcLo}, // [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH + {0xC6B0, 0xC6B0, prH2, gcLo}, // HANGUL SYLLABLE U + {0xC6B1, 0xC6CB, prH3, gcLo}, // [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH + {0xC6CC, 0xC6CC, prH2, gcLo}, // HANGUL SYLLABLE WEO + {0xC6CD, 0xC6E7, prH3, gcLo}, // [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH + {0xC6E8, 0xC6E8, prH2, gcLo}, // HANGUL SYLLABLE WE + {0xC6E9, 0xC703, prH3, gcLo}, // [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH + {0xC704, 0xC704, prH2, gcLo}, // HANGUL SYLLABLE WI + {0xC705, 0xC71F, prH3, gcLo}, // [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH + {0xC720, 0xC720, prH2, gcLo}, // HANGUL SYLLABLE YU + {0xC721, 0xC73B, prH3, gcLo}, // [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH + {0xC73C, 0xC73C, prH2, gcLo}, // HANGUL SYLLABLE EU + {0xC73D, 0xC757, prH3, gcLo}, // [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH + {0xC758, 0xC758, prH2, gcLo}, // HANGUL SYLLABLE YI + {0xC759, 0xC773, prH3, gcLo}, // [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH + {0xC774, 0xC774, prH2, gcLo}, // HANGUL SYLLABLE I + {0xC775, 0xC78F, prH3, gcLo}, // [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH + {0xC790, 0xC790, prH2, gcLo}, // HANGUL SYLLABLE JA + {0xC791, 0xC7AB, prH3, gcLo}, // [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH + {0xC7AC, 0xC7AC, prH2, gcLo}, // HANGUL SYLLABLE JAE + {0xC7AD, 0xC7C7, prH3, gcLo}, // [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH + {0xC7C8, 0xC7C8, prH2, gcLo}, // HANGUL SYLLABLE JYA + {0xC7C9, 0xC7E3, prH3, gcLo}, // [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH + {0xC7E4, 0xC7E4, prH2, gcLo}, // HANGUL SYLLABLE JYAE + {0xC7E5, 0xC7FF, prH3, gcLo}, // [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH + {0xC800, 0xC800, prH2, gcLo}, // HANGUL SYLLABLE JEO + {0xC801, 0xC81B, prH3, gcLo}, // [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH + {0xC81C, 0xC81C, prH2, gcLo}, // HANGUL SYLLABLE JE + {0xC81D, 0xC837, prH3, gcLo}, // [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH + {0xC838, 0xC838, prH2, gcLo}, // HANGUL SYLLABLE JYEO + {0xC839, 0xC853, prH3, gcLo}, // [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH + {0xC854, 0xC854, prH2, gcLo}, // HANGUL SYLLABLE JYE + {0xC855, 0xC86F, prH3, gcLo}, // [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH + {0xC870, 0xC870, prH2, gcLo}, // HANGUL SYLLABLE JO + {0xC871, 0xC88B, prH3, gcLo}, // [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH + {0xC88C, 0xC88C, prH2, gcLo}, // HANGUL SYLLABLE JWA + {0xC88D, 0xC8A7, prH3, gcLo}, // [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH + {0xC8A8, 0xC8A8, prH2, gcLo}, // HANGUL SYLLABLE JWAE + {0xC8A9, 0xC8C3, prH3, gcLo}, // [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH + {0xC8C4, 0xC8C4, prH2, gcLo}, // HANGUL SYLLABLE JOE + {0xC8C5, 0xC8DF, prH3, gcLo}, // [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH + {0xC8E0, 0xC8E0, prH2, gcLo}, // HANGUL SYLLABLE JYO + {0xC8E1, 0xC8FB, prH3, gcLo}, // [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH + {0xC8FC, 0xC8FC, prH2, gcLo}, // HANGUL SYLLABLE JU + {0xC8FD, 0xC917, prH3, gcLo}, // [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH + {0xC918, 0xC918, prH2, gcLo}, // HANGUL SYLLABLE JWEO + {0xC919, 0xC933, prH3, gcLo}, // [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH + {0xC934, 0xC934, prH2, gcLo}, // HANGUL SYLLABLE JWE + {0xC935, 0xC94F, prH3, gcLo}, // [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH + {0xC950, 0xC950, prH2, gcLo}, // HANGUL SYLLABLE JWI + {0xC951, 0xC96B, prH3, gcLo}, // [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH + {0xC96C, 0xC96C, prH2, gcLo}, // HANGUL SYLLABLE JYU + {0xC96D, 0xC987, prH3, gcLo}, // [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH + {0xC988, 0xC988, prH2, gcLo}, // HANGUL SYLLABLE JEU + {0xC989, 0xC9A3, prH3, gcLo}, // [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH + {0xC9A4, 0xC9A4, prH2, gcLo}, // HANGUL SYLLABLE JYI + {0xC9A5, 0xC9BF, prH3, gcLo}, // [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH + {0xC9C0, 0xC9C0, prH2, gcLo}, // HANGUL SYLLABLE JI + {0xC9C1, 0xC9DB, prH3, gcLo}, // [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH + {0xC9DC, 0xC9DC, prH2, gcLo}, // HANGUL SYLLABLE JJA + {0xC9DD, 0xC9F7, prH3, gcLo}, // [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH + {0xC9F8, 0xC9F8, prH2, gcLo}, // HANGUL SYLLABLE JJAE + {0xC9F9, 0xCA13, prH3, gcLo}, // [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH + {0xCA14, 0xCA14, prH2, gcLo}, // HANGUL SYLLABLE JJYA + {0xCA15, 0xCA2F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH + {0xCA30, 0xCA30, prH2, gcLo}, // HANGUL SYLLABLE JJYAE + {0xCA31, 0xCA4B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH + {0xCA4C, 0xCA4C, prH2, gcLo}, // HANGUL SYLLABLE JJEO + {0xCA4D, 0xCA67, prH3, gcLo}, // [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH + {0xCA68, 0xCA68, prH2, gcLo}, // HANGUL SYLLABLE JJE + {0xCA69, 0xCA83, prH3, gcLo}, // [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH + {0xCA84, 0xCA84, prH2, gcLo}, // HANGUL SYLLABLE JJYEO + {0xCA85, 0xCA9F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH + {0xCAA0, 0xCAA0, prH2, gcLo}, // HANGUL SYLLABLE JJYE + {0xCAA1, 0xCABB, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH + {0xCABC, 0xCABC, prH2, gcLo}, // HANGUL SYLLABLE JJO + {0xCABD, 0xCAD7, prH3, gcLo}, // [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH + {0xCAD8, 0xCAD8, prH2, gcLo}, // HANGUL SYLLABLE JJWA + {0xCAD9, 0xCAF3, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH + {0xCAF4, 0xCAF4, prH2, gcLo}, // HANGUL SYLLABLE JJWAE + {0xCAF5, 0xCB0F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH + {0xCB10, 0xCB10, prH2, gcLo}, // HANGUL SYLLABLE JJOE + {0xCB11, 0xCB2B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH + {0xCB2C, 0xCB2C, prH2, gcLo}, // HANGUL SYLLABLE JJYO + {0xCB2D, 0xCB47, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH + {0xCB48, 0xCB48, prH2, gcLo}, // HANGUL SYLLABLE JJU + {0xCB49, 0xCB63, prH3, gcLo}, // [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH + {0xCB64, 0xCB64, prH2, gcLo}, // HANGUL SYLLABLE JJWEO + {0xCB65, 0xCB7F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH + {0xCB80, 0xCB80, prH2, gcLo}, // HANGUL SYLLABLE JJWE + {0xCB81, 0xCB9B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH + {0xCB9C, 0xCB9C, prH2, gcLo}, // HANGUL SYLLABLE JJWI + {0xCB9D, 0xCBB7, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH + {0xCBB8, 0xCBB8, prH2, gcLo}, // HANGUL SYLLABLE JJYU + {0xCBB9, 0xCBD3, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH + {0xCBD4, 0xCBD4, prH2, gcLo}, // HANGUL SYLLABLE JJEU + {0xCBD5, 0xCBEF, prH3, gcLo}, // [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH + {0xCBF0, 0xCBF0, prH2, gcLo}, // HANGUL SYLLABLE JJYI + {0xCBF1, 0xCC0B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH + {0xCC0C, 0xCC0C, prH2, gcLo}, // HANGUL SYLLABLE JJI + {0xCC0D, 0xCC27, prH3, gcLo}, // [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH + {0xCC28, 0xCC28, prH2, gcLo}, // HANGUL SYLLABLE CA + {0xCC29, 0xCC43, prH3, gcLo}, // [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH + {0xCC44, 0xCC44, prH2, gcLo}, // HANGUL SYLLABLE CAE + {0xCC45, 0xCC5F, prH3, gcLo}, // [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH + {0xCC60, 0xCC60, prH2, gcLo}, // HANGUL SYLLABLE CYA + {0xCC61, 0xCC7B, prH3, gcLo}, // [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH + {0xCC7C, 0xCC7C, prH2, gcLo}, // HANGUL SYLLABLE CYAE + {0xCC7D, 0xCC97, prH3, gcLo}, // [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH + {0xCC98, 0xCC98, prH2, gcLo}, // HANGUL SYLLABLE CEO + {0xCC99, 0xCCB3, prH3, gcLo}, // [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH + {0xCCB4, 0xCCB4, prH2, gcLo}, // HANGUL SYLLABLE CE + {0xCCB5, 0xCCCF, prH3, gcLo}, // [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH + {0xCCD0, 0xCCD0, prH2, gcLo}, // HANGUL SYLLABLE CYEO + {0xCCD1, 0xCCEB, prH3, gcLo}, // [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH + {0xCCEC, 0xCCEC, prH2, gcLo}, // HANGUL SYLLABLE CYE + {0xCCED, 0xCD07, prH3, gcLo}, // [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH + {0xCD08, 0xCD08, prH2, gcLo}, // HANGUL SYLLABLE CO + {0xCD09, 0xCD23, prH3, gcLo}, // [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH + {0xCD24, 0xCD24, prH2, gcLo}, // HANGUL SYLLABLE CWA + {0xCD25, 0xCD3F, prH3, gcLo}, // [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH + {0xCD40, 0xCD40, prH2, gcLo}, // HANGUL SYLLABLE CWAE + {0xCD41, 0xCD5B, prH3, gcLo}, // [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH + {0xCD5C, 0xCD5C, prH2, gcLo}, // HANGUL SYLLABLE COE + {0xCD5D, 0xCD77, prH3, gcLo}, // [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH + {0xCD78, 0xCD78, prH2, gcLo}, // HANGUL SYLLABLE CYO + {0xCD79, 0xCD93, prH3, gcLo}, // [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH + {0xCD94, 0xCD94, prH2, gcLo}, // HANGUL SYLLABLE CU + {0xCD95, 0xCDAF, prH3, gcLo}, // [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH + {0xCDB0, 0xCDB0, prH2, gcLo}, // HANGUL SYLLABLE CWEO + {0xCDB1, 0xCDCB, prH3, gcLo}, // [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH + {0xCDCC, 0xCDCC, prH2, gcLo}, // HANGUL SYLLABLE CWE + {0xCDCD, 0xCDE7, prH3, gcLo}, // [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH + {0xCDE8, 0xCDE8, prH2, gcLo}, // HANGUL SYLLABLE CWI + {0xCDE9, 0xCE03, prH3, gcLo}, // [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH + {0xCE04, 0xCE04, prH2, gcLo}, // HANGUL SYLLABLE CYU + {0xCE05, 0xCE1F, prH3, gcLo}, // [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH + {0xCE20, 0xCE20, prH2, gcLo}, // HANGUL SYLLABLE CEU + {0xCE21, 0xCE3B, prH3, gcLo}, // [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH + {0xCE3C, 0xCE3C, prH2, gcLo}, // HANGUL SYLLABLE CYI + {0xCE3D, 0xCE57, prH3, gcLo}, // [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH + {0xCE58, 0xCE58, prH2, gcLo}, // HANGUL SYLLABLE CI + {0xCE59, 0xCE73, prH3, gcLo}, // [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH + {0xCE74, 0xCE74, prH2, gcLo}, // HANGUL SYLLABLE KA + {0xCE75, 0xCE8F, prH3, gcLo}, // [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH + {0xCE90, 0xCE90, prH2, gcLo}, // HANGUL SYLLABLE KAE + {0xCE91, 0xCEAB, prH3, gcLo}, // [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH + {0xCEAC, 0xCEAC, prH2, gcLo}, // HANGUL SYLLABLE KYA + {0xCEAD, 0xCEC7, prH3, gcLo}, // [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH + {0xCEC8, 0xCEC8, prH2, gcLo}, // HANGUL SYLLABLE KYAE + {0xCEC9, 0xCEE3, prH3, gcLo}, // [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH + {0xCEE4, 0xCEE4, prH2, gcLo}, // HANGUL SYLLABLE KEO + {0xCEE5, 0xCEFF, prH3, gcLo}, // [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH + {0xCF00, 0xCF00, prH2, gcLo}, // HANGUL SYLLABLE KE + {0xCF01, 0xCF1B, prH3, gcLo}, // [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH + {0xCF1C, 0xCF1C, prH2, gcLo}, // HANGUL SYLLABLE KYEO + {0xCF1D, 0xCF37, prH3, gcLo}, // [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH + {0xCF38, 0xCF38, prH2, gcLo}, // HANGUL SYLLABLE KYE + {0xCF39, 0xCF53, prH3, gcLo}, // [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH + {0xCF54, 0xCF54, prH2, gcLo}, // HANGUL SYLLABLE KO + {0xCF55, 0xCF6F, prH3, gcLo}, // [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH + {0xCF70, 0xCF70, prH2, gcLo}, // HANGUL SYLLABLE KWA + {0xCF71, 0xCF8B, prH3, gcLo}, // [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH + {0xCF8C, 0xCF8C, prH2, gcLo}, // HANGUL SYLLABLE KWAE + {0xCF8D, 0xCFA7, prH3, gcLo}, // [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH + {0xCFA8, 0xCFA8, prH2, gcLo}, // HANGUL SYLLABLE KOE + {0xCFA9, 0xCFC3, prH3, gcLo}, // [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH + {0xCFC4, 0xCFC4, prH2, gcLo}, // HANGUL SYLLABLE KYO + {0xCFC5, 0xCFDF, prH3, gcLo}, // [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH + {0xCFE0, 0xCFE0, prH2, gcLo}, // HANGUL SYLLABLE KU + {0xCFE1, 0xCFFB, prH3, gcLo}, // [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH + {0xCFFC, 0xCFFC, prH2, gcLo}, // HANGUL SYLLABLE KWEO + {0xCFFD, 0xD017, prH3, gcLo}, // [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH + {0xD018, 0xD018, prH2, gcLo}, // HANGUL SYLLABLE KWE + {0xD019, 0xD033, prH3, gcLo}, // [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH + {0xD034, 0xD034, prH2, gcLo}, // HANGUL SYLLABLE KWI + {0xD035, 0xD04F, prH3, gcLo}, // [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH + {0xD050, 0xD050, prH2, gcLo}, // HANGUL SYLLABLE KYU + {0xD051, 0xD06B, prH3, gcLo}, // [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH + {0xD06C, 0xD06C, prH2, gcLo}, // HANGUL SYLLABLE KEU + {0xD06D, 0xD087, prH3, gcLo}, // [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH + {0xD088, 0xD088, prH2, gcLo}, // HANGUL SYLLABLE KYI + {0xD089, 0xD0A3, prH3, gcLo}, // [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH + {0xD0A4, 0xD0A4, prH2, gcLo}, // HANGUL SYLLABLE KI + {0xD0A5, 0xD0BF, prH3, gcLo}, // [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH + {0xD0C0, 0xD0C0, prH2, gcLo}, // HANGUL SYLLABLE TA + {0xD0C1, 0xD0DB, prH3, gcLo}, // [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH + {0xD0DC, 0xD0DC, prH2, gcLo}, // HANGUL SYLLABLE TAE + {0xD0DD, 0xD0F7, prH3, gcLo}, // [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH + {0xD0F8, 0xD0F8, prH2, gcLo}, // HANGUL SYLLABLE TYA + {0xD0F9, 0xD113, prH3, gcLo}, // [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH + {0xD114, 0xD114, prH2, gcLo}, // HANGUL SYLLABLE TYAE + {0xD115, 0xD12F, prH3, gcLo}, // [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH + {0xD130, 0xD130, prH2, gcLo}, // HANGUL SYLLABLE TEO + {0xD131, 0xD14B, prH3, gcLo}, // [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH + {0xD14C, 0xD14C, prH2, gcLo}, // HANGUL SYLLABLE TE + {0xD14D, 0xD167, prH3, gcLo}, // [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH + {0xD168, 0xD168, prH2, gcLo}, // HANGUL SYLLABLE TYEO + {0xD169, 0xD183, prH3, gcLo}, // [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH + {0xD184, 0xD184, prH2, gcLo}, // HANGUL SYLLABLE TYE + {0xD185, 0xD19F, prH3, gcLo}, // [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH + {0xD1A0, 0xD1A0, prH2, gcLo}, // HANGUL SYLLABLE TO + {0xD1A1, 0xD1BB, prH3, gcLo}, // [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH + {0xD1BC, 0xD1BC, prH2, gcLo}, // HANGUL SYLLABLE TWA + {0xD1BD, 0xD1D7, prH3, gcLo}, // [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH + {0xD1D8, 0xD1D8, prH2, gcLo}, // HANGUL SYLLABLE TWAE + {0xD1D9, 0xD1F3, prH3, gcLo}, // [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH + {0xD1F4, 0xD1F4, prH2, gcLo}, // HANGUL SYLLABLE TOE + {0xD1F5, 0xD20F, prH3, gcLo}, // [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH + {0xD210, 0xD210, prH2, gcLo}, // HANGUL SYLLABLE TYO + {0xD211, 0xD22B, prH3, gcLo}, // [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH + {0xD22C, 0xD22C, prH2, gcLo}, // HANGUL SYLLABLE TU + {0xD22D, 0xD247, prH3, gcLo}, // [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH + {0xD248, 0xD248, prH2, gcLo}, // HANGUL SYLLABLE TWEO + {0xD249, 0xD263, prH3, gcLo}, // [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH + {0xD264, 0xD264, prH2, gcLo}, // HANGUL SYLLABLE TWE + {0xD265, 0xD27F, prH3, gcLo}, // [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH + {0xD280, 0xD280, prH2, gcLo}, // HANGUL SYLLABLE TWI + {0xD281, 0xD29B, prH3, gcLo}, // [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH + {0xD29C, 0xD29C, prH2, gcLo}, // HANGUL SYLLABLE TYU + {0xD29D, 0xD2B7, prH3, gcLo}, // [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH + {0xD2B8, 0xD2B8, prH2, gcLo}, // HANGUL SYLLABLE TEU + {0xD2B9, 0xD2D3, prH3, gcLo}, // [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH + {0xD2D4, 0xD2D4, prH2, gcLo}, // HANGUL SYLLABLE TYI + {0xD2D5, 0xD2EF, prH3, gcLo}, // [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH + {0xD2F0, 0xD2F0, prH2, gcLo}, // HANGUL SYLLABLE TI + {0xD2F1, 0xD30B, prH3, gcLo}, // [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH + {0xD30C, 0xD30C, prH2, gcLo}, // HANGUL SYLLABLE PA + {0xD30D, 0xD327, prH3, gcLo}, // [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH + {0xD328, 0xD328, prH2, gcLo}, // HANGUL SYLLABLE PAE + {0xD329, 0xD343, prH3, gcLo}, // [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH + {0xD344, 0xD344, prH2, gcLo}, // HANGUL SYLLABLE PYA + {0xD345, 0xD35F, prH3, gcLo}, // [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH + {0xD360, 0xD360, prH2, gcLo}, // HANGUL SYLLABLE PYAE + {0xD361, 0xD37B, prH3, gcLo}, // [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH + {0xD37C, 0xD37C, prH2, gcLo}, // HANGUL SYLLABLE PEO + {0xD37D, 0xD397, prH3, gcLo}, // [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH + {0xD398, 0xD398, prH2, gcLo}, // HANGUL SYLLABLE PE + {0xD399, 0xD3B3, prH3, gcLo}, // [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH + {0xD3B4, 0xD3B4, prH2, gcLo}, // HANGUL SYLLABLE PYEO + {0xD3B5, 0xD3CF, prH3, gcLo}, // [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH + {0xD3D0, 0xD3D0, prH2, gcLo}, // HANGUL SYLLABLE PYE + {0xD3D1, 0xD3EB, prH3, gcLo}, // [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH + {0xD3EC, 0xD3EC, prH2, gcLo}, // HANGUL SYLLABLE PO + {0xD3ED, 0xD407, prH3, gcLo}, // [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH + {0xD408, 0xD408, prH2, gcLo}, // HANGUL SYLLABLE PWA + {0xD409, 0xD423, prH3, gcLo}, // [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH + {0xD424, 0xD424, prH2, gcLo}, // HANGUL SYLLABLE PWAE + {0xD425, 0xD43F, prH3, gcLo}, // [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH + {0xD440, 0xD440, prH2, gcLo}, // HANGUL SYLLABLE POE + {0xD441, 0xD45B, prH3, gcLo}, // [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH + {0xD45C, 0xD45C, prH2, gcLo}, // HANGUL SYLLABLE PYO + {0xD45D, 0xD477, prH3, gcLo}, // [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH + {0xD478, 0xD478, prH2, gcLo}, // HANGUL SYLLABLE PU + {0xD479, 0xD493, prH3, gcLo}, // [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH + {0xD494, 0xD494, prH2, gcLo}, // HANGUL SYLLABLE PWEO + {0xD495, 0xD4AF, prH3, gcLo}, // [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH + {0xD4B0, 0xD4B0, prH2, gcLo}, // HANGUL SYLLABLE PWE + {0xD4B1, 0xD4CB, prH3, gcLo}, // [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH + {0xD4CC, 0xD4CC, prH2, gcLo}, // HANGUL SYLLABLE PWI + {0xD4CD, 0xD4E7, prH3, gcLo}, // [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH + {0xD4E8, 0xD4E8, prH2, gcLo}, // HANGUL SYLLABLE PYU + {0xD4E9, 0xD503, prH3, gcLo}, // [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH + {0xD504, 0xD504, prH2, gcLo}, // HANGUL SYLLABLE PEU + {0xD505, 0xD51F, prH3, gcLo}, // [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH + {0xD520, 0xD520, prH2, gcLo}, // HANGUL SYLLABLE PYI + {0xD521, 0xD53B, prH3, gcLo}, // [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH + {0xD53C, 0xD53C, prH2, gcLo}, // HANGUL SYLLABLE PI + {0xD53D, 0xD557, prH3, gcLo}, // [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH + {0xD558, 0xD558, prH2, gcLo}, // HANGUL SYLLABLE HA + {0xD559, 0xD573, prH3, gcLo}, // [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH + {0xD574, 0xD574, prH2, gcLo}, // HANGUL SYLLABLE HAE + {0xD575, 0xD58F, prH3, gcLo}, // [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH + {0xD590, 0xD590, prH2, gcLo}, // HANGUL SYLLABLE HYA + {0xD591, 0xD5AB, prH3, gcLo}, // [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH + {0xD5AC, 0xD5AC, prH2, gcLo}, // HANGUL SYLLABLE HYAE + {0xD5AD, 0xD5C7, prH3, gcLo}, // [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH + {0xD5C8, 0xD5C8, prH2, gcLo}, // HANGUL SYLLABLE HEO + {0xD5C9, 0xD5E3, prH3, gcLo}, // [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH + {0xD5E4, 0xD5E4, prH2, gcLo}, // HANGUL SYLLABLE HE + {0xD5E5, 0xD5FF, prH3, gcLo}, // [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH + {0xD600, 0xD600, prH2, gcLo}, // HANGUL SYLLABLE HYEO + {0xD601, 0xD61B, prH3, gcLo}, // [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH + {0xD61C, 0xD61C, prH2, gcLo}, // HANGUL SYLLABLE HYE + {0xD61D, 0xD637, prH3, gcLo}, // [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH + {0xD638, 0xD638, prH2, gcLo}, // HANGUL SYLLABLE HO + {0xD639, 0xD653, prH3, gcLo}, // [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH + {0xD654, 0xD654, prH2, gcLo}, // HANGUL SYLLABLE HWA + {0xD655, 0xD66F, prH3, gcLo}, // [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH + {0xD670, 0xD670, prH2, gcLo}, // HANGUL SYLLABLE HWAE + {0xD671, 0xD68B, prH3, gcLo}, // [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH + {0xD68C, 0xD68C, prH2, gcLo}, // HANGUL SYLLABLE HOE + {0xD68D, 0xD6A7, prH3, gcLo}, // [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH + {0xD6A8, 0xD6A8, prH2, gcLo}, // HANGUL SYLLABLE HYO + {0xD6A9, 0xD6C3, prH3, gcLo}, // [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH + {0xD6C4, 0xD6C4, prH2, gcLo}, // HANGUL SYLLABLE HU + {0xD6C5, 0xD6DF, prH3, gcLo}, // [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH + {0xD6E0, 0xD6E0, prH2, gcLo}, // HANGUL SYLLABLE HWEO + {0xD6E1, 0xD6FB, prH3, gcLo}, // [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH + {0xD6FC, 0xD6FC, prH2, gcLo}, // HANGUL SYLLABLE HWE + {0xD6FD, 0xD717, prH3, gcLo}, // [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH + {0xD718, 0xD718, prH2, gcLo}, // HANGUL SYLLABLE HWI + {0xD719, 0xD733, prH3, gcLo}, // [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH + {0xD734, 0xD734, prH2, gcLo}, // HANGUL SYLLABLE HYU + {0xD735, 0xD74F, prH3, gcLo}, // [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH + {0xD750, 0xD750, prH2, gcLo}, // HANGUL SYLLABLE HEU + {0xD751, 0xD76B, prH3, gcLo}, // [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH + {0xD76C, 0xD76C, prH2, gcLo}, // HANGUL SYLLABLE HYI + {0xD76D, 0xD787, prH3, gcLo}, // [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH + {0xD788, 0xD788, prH2, gcLo}, // HANGUL SYLLABLE HI + {0xD789, 0xD7A3, prH3, gcLo}, // [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prJV, gcLo}, // [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prJT, gcLo}, // [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xD800, 0xDB7F, prSG, gcCs}, // [896] .. + {0xDB80, 0xDBFF, prSG, gcCs}, // [128] .. + {0xDC00, 0xDFFF, prSG, gcCs}, // [1024] .. + {0xE000, 0xF8FF, prXX, gcCo}, // [6400] .. + {0xF900, 0xFA6D, prID, gcLo}, // [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D + {0xFA6E, 0xFA6F, prID, gcCn}, // [2] .. + {0xFA70, 0xFAD9, prID, gcLo}, // [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 + {0xFADA, 0xFAFF, prID, gcCn}, // [38] .. + {0xFB00, 0xFB06, prAL, gcLl}, // [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST + {0xFB13, 0xFB17, prAL, gcLl}, // [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH + {0xFB1D, 0xFB1D, prHL, gcLo}, // HEBREW LETTER YOD WITH HIRIQ + {0xFB1E, 0xFB1E, prCM, gcMn}, // HEBREW POINT JUDEO-SPANISH VARIKA + {0xFB1F, 0xFB28, prHL, gcLo}, // [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV + {0xFB29, 0xFB29, prAL, gcSm}, // HEBREW LETTER ALTERNATIVE PLUS SIGN + {0xFB2A, 0xFB36, prHL, gcLo}, // [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH + {0xFB38, 0xFB3C, prHL, gcLo}, // [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH + {0xFB3E, 0xFB3E, prHL, gcLo}, // HEBREW LETTER MEM WITH DAGESH + {0xFB40, 0xFB41, prHL, gcLo}, // [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH + {0xFB43, 0xFB44, prHL, gcLo}, // [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH + {0xFB46, 0xFB4F, prHL, gcLo}, // [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED + {0xFB50, 0xFBB1, prAL, gcLo}, // [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM + {0xFBB2, 0xFBC2, prAL, gcSk}, // [17] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL WASLA ABOVE + {0xFBD3, 0xFD3D, prAL, gcLo}, // [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM + {0xFD3E, 0xFD3E, prCL, gcPe}, // ORNATE LEFT PARENTHESIS + {0xFD3F, 0xFD3F, prOP, gcPs}, // ORNATE RIGHT PARENTHESIS + {0xFD40, 0xFD4F, prAL, gcSo}, // [16] ARABIC LIGATURE RAHIMAHU ALLAAH..ARABIC LIGATURE RAHIMAHUM ALLAAH + {0xFD50, 0xFD8F, prAL, gcLo}, // [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM + {0xFD92, 0xFDC7, prAL, gcLo}, // [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM + {0xFDCF, 0xFDCF, prAL, gcSo}, // ARABIC LIGATURE SALAAMUHU ALAYNAA + {0xFDF0, 0xFDFB, prAL, gcLo}, // [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU + {0xFDFC, 0xFDFC, prPO, gcSc}, // RIAL SIGN + {0xFDFD, 0xFDFF, prAL, gcSo}, // [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM..ARABIC LIGATURE AZZA WA JALL + {0xFE00, 0xFE0F, prCM, gcMn}, // [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE10, 0xFE10, prIS, gcPo}, // PRESENTATION FORM FOR VERTICAL COMMA + {0xFE11, 0xFE12, prCL, gcPo}, // [2] PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA..PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP + {0xFE13, 0xFE14, prIS, gcPo}, // [2] PRESENTATION FORM FOR VERTICAL COLON..PRESENTATION FORM FOR VERTICAL SEMICOLON + {0xFE15, 0xFE16, prEX, gcPo}, // [2] PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK..PRESENTATION FORM FOR VERTICAL QUESTION MARK + {0xFE17, 0xFE17, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET + {0xFE18, 0xFE18, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET + {0xFE19, 0xFE19, prIN, gcPo}, // PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS + {0xFE20, 0xFE2F, prCM, gcMn}, // [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFE30, 0xFE30, prID, gcPo}, // PRESENTATION FORM FOR VERTICAL TWO DOT LEADER + {0xFE31, 0xFE32, prID, gcPd}, // [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH + {0xFE33, 0xFE34, prID, gcPc}, // [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE + {0xFE35, 0xFE35, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS + {0xFE36, 0xFE36, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS + {0xFE37, 0xFE37, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET + {0xFE38, 0xFE38, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET + {0xFE39, 0xFE39, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET + {0xFE3A, 0xFE3A, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET + {0xFE3B, 0xFE3B, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET + {0xFE3C, 0xFE3C, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET + {0xFE3D, 0xFE3D, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET + {0xFE3E, 0xFE3E, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET + {0xFE3F, 0xFE3F, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET + {0xFE40, 0xFE40, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET + {0xFE41, 0xFE41, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET + {0xFE42, 0xFE42, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET + {0xFE43, 0xFE43, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET + {0xFE44, 0xFE44, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET + {0xFE45, 0xFE46, prID, gcPo}, // [2] SESAME DOT..WHITE SESAME DOT + {0xFE47, 0xFE47, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET + {0xFE48, 0xFE48, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET + {0xFE49, 0xFE4C, prID, gcPo}, // [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE + {0xFE4D, 0xFE4F, prID, gcPc}, // [3] DASHED LOW LINE..WAVY LOW LINE + {0xFE50, 0xFE50, prCL, gcPo}, // SMALL COMMA + {0xFE51, 0xFE51, prID, gcPo}, // SMALL IDEOGRAPHIC COMMA + {0xFE52, 0xFE52, prCL, gcPo}, // SMALL FULL STOP + {0xFE54, 0xFE55, prNS, gcPo}, // [2] SMALL SEMICOLON..SMALL COLON + {0xFE56, 0xFE57, prEX, gcPo}, // [2] SMALL QUESTION MARK..SMALL EXCLAMATION MARK + {0xFE58, 0xFE58, prID, gcPd}, // SMALL EM DASH + {0xFE59, 0xFE59, prOP, gcPs}, // SMALL LEFT PARENTHESIS + {0xFE5A, 0xFE5A, prCL, gcPe}, // SMALL RIGHT PARENTHESIS + {0xFE5B, 0xFE5B, prOP, gcPs}, // SMALL LEFT CURLY BRACKET + {0xFE5C, 0xFE5C, prCL, gcPe}, // SMALL RIGHT CURLY BRACKET + {0xFE5D, 0xFE5D, prOP, gcPs}, // SMALL LEFT TORTOISE SHELL BRACKET + {0xFE5E, 0xFE5E, prCL, gcPe}, // SMALL RIGHT TORTOISE SHELL BRACKET + {0xFE5F, 0xFE61, prID, gcPo}, // [3] SMALL NUMBER SIGN..SMALL ASTERISK + {0xFE62, 0xFE62, prID, gcSm}, // SMALL PLUS SIGN + {0xFE63, 0xFE63, prID, gcPd}, // SMALL HYPHEN-MINUS + {0xFE64, 0xFE66, prID, gcSm}, // [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN + {0xFE68, 0xFE68, prID, gcPo}, // SMALL REVERSE SOLIDUS + {0xFE69, 0xFE69, prPR, gcSc}, // SMALL DOLLAR SIGN + {0xFE6A, 0xFE6A, prPO, gcPo}, // SMALL PERCENT SIGN + {0xFE6B, 0xFE6B, prID, gcPo}, // SMALL COMMERCIAL AT + {0xFE70, 0xFE74, prAL, gcLo}, // [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM + {0xFE76, 0xFEFC, prAL, gcLo}, // [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM + {0xFEFF, 0xFEFF, prWJ, gcCf}, // ZERO WIDTH NO-BREAK SPACE + {0xFF01, 0xFF01, prEX, gcPo}, // FULLWIDTH EXCLAMATION MARK + {0xFF02, 0xFF03, prID, gcPo}, // [2] FULLWIDTH QUOTATION MARK..FULLWIDTH NUMBER SIGN + {0xFF04, 0xFF04, prPR, gcSc}, // FULLWIDTH DOLLAR SIGN + {0xFF05, 0xFF05, prPO, gcPo}, // FULLWIDTH PERCENT SIGN + {0xFF06, 0xFF07, prID, gcPo}, // [2] FULLWIDTH AMPERSAND..FULLWIDTH APOSTROPHE + {0xFF08, 0xFF08, prOP, gcPs}, // FULLWIDTH LEFT PARENTHESIS + {0xFF09, 0xFF09, prCL, gcPe}, // FULLWIDTH RIGHT PARENTHESIS + {0xFF0A, 0xFF0A, prID, gcPo}, // FULLWIDTH ASTERISK + {0xFF0B, 0xFF0B, prID, gcSm}, // FULLWIDTH PLUS SIGN + {0xFF0C, 0xFF0C, prCL, gcPo}, // FULLWIDTH COMMA + {0xFF0D, 0xFF0D, prID, gcPd}, // FULLWIDTH HYPHEN-MINUS + {0xFF0E, 0xFF0E, prCL, gcPo}, // FULLWIDTH FULL STOP + {0xFF0F, 0xFF0F, prID, gcPo}, // FULLWIDTH SOLIDUS + {0xFF10, 0xFF19, prID, gcNd}, // [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE + {0xFF1A, 0xFF1B, prNS, gcPo}, // [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON + {0xFF1C, 0xFF1E, prID, gcSm}, // [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN + {0xFF1F, 0xFF1F, prEX, gcPo}, // FULLWIDTH QUESTION MARK + {0xFF20, 0xFF20, prID, gcPo}, // FULLWIDTH COMMERCIAL AT + {0xFF21, 0xFF3A, prID, gcLu}, // [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z + {0xFF3B, 0xFF3B, prOP, gcPs}, // FULLWIDTH LEFT SQUARE BRACKET + {0xFF3C, 0xFF3C, prID, gcPo}, // FULLWIDTH REVERSE SOLIDUS + {0xFF3D, 0xFF3D, prCL, gcPe}, // FULLWIDTH RIGHT SQUARE BRACKET + {0xFF3E, 0xFF3E, prID, gcSk}, // FULLWIDTH CIRCUMFLEX ACCENT + {0xFF3F, 0xFF3F, prID, gcPc}, // FULLWIDTH LOW LINE + {0xFF40, 0xFF40, prID, gcSk}, // FULLWIDTH GRAVE ACCENT + {0xFF41, 0xFF5A, prID, gcLl}, // [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z + {0xFF5B, 0xFF5B, prOP, gcPs}, // FULLWIDTH LEFT CURLY BRACKET + {0xFF5C, 0xFF5C, prID, gcSm}, // FULLWIDTH VERTICAL LINE + {0xFF5D, 0xFF5D, prCL, gcPe}, // FULLWIDTH RIGHT CURLY BRACKET + {0xFF5E, 0xFF5E, prID, gcSm}, // FULLWIDTH TILDE + {0xFF5F, 0xFF5F, prOP, gcPs}, // FULLWIDTH LEFT WHITE PARENTHESIS + {0xFF60, 0xFF60, prCL, gcPe}, // FULLWIDTH RIGHT WHITE PARENTHESIS + {0xFF61, 0xFF61, prCL, gcPo}, // HALFWIDTH IDEOGRAPHIC FULL STOP + {0xFF62, 0xFF62, prOP, gcPs}, // HALFWIDTH LEFT CORNER BRACKET + {0xFF63, 0xFF63, prCL, gcPe}, // HALFWIDTH RIGHT CORNER BRACKET + {0xFF64, 0xFF64, prCL, gcPo}, // HALFWIDTH IDEOGRAPHIC COMMA + {0xFF65, 0xFF65, prNS, gcPo}, // HALFWIDTH KATAKANA MIDDLE DOT + {0xFF66, 0xFF66, prID, gcLo}, // HALFWIDTH KATAKANA LETTER WO + {0xFF67, 0xFF6F, prCJ, gcLo}, // [9] HALFWIDTH KATAKANA LETTER SMALL A..HALFWIDTH KATAKANA LETTER SMALL TU + {0xFF70, 0xFF70, prCJ, gcLm}, // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0xFF71, 0xFF9D, prID, gcLo}, // [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N + {0xFF9E, 0xFF9F, prNS, gcLm}, // [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFA0, 0xFFBE, prID, gcLo}, // [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH + {0xFFC2, 0xFFC7, prID, gcLo}, // [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E + {0xFFCA, 0xFFCF, prID, gcLo}, // [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE + {0xFFD2, 0xFFD7, prID, gcLo}, // [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU + {0xFFDA, 0xFFDC, prID, gcLo}, // [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I + {0xFFE0, 0xFFE0, prPO, gcSc}, // FULLWIDTH CENT SIGN + {0xFFE1, 0xFFE1, prPR, gcSc}, // FULLWIDTH POUND SIGN + {0xFFE2, 0xFFE2, prID, gcSm}, // FULLWIDTH NOT SIGN + {0xFFE3, 0xFFE3, prID, gcSk}, // FULLWIDTH MACRON + {0xFFE4, 0xFFE4, prID, gcSo}, // FULLWIDTH BROKEN BAR + {0xFFE5, 0xFFE6, prPR, gcSc}, // [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN + {0xFFE8, 0xFFE8, prAL, gcSo}, // HALFWIDTH FORMS LIGHT VERTICAL + {0xFFE9, 0xFFEC, prAL, gcSm}, // [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW + {0xFFED, 0xFFEE, prAL, gcSo}, // [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE + {0xFFF9, 0xFFFB, prCM, gcCf}, // [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0xFFFC, 0xFFFC, prCB, gcSo}, // OBJECT REPLACEMENT CHARACTER + {0xFFFD, 0xFFFD, prAI, gcSo}, // REPLACEMENT CHARACTER + {0x10000, 0x1000B, prAL, gcLo}, // [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE + {0x1000D, 0x10026, prAL, gcLo}, // [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO + {0x10028, 0x1003A, prAL, gcLo}, // [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO + {0x1003C, 0x1003D, prAL, gcLo}, // [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE + {0x1003F, 0x1004D, prAL, gcLo}, // [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO + {0x10050, 0x1005D, prAL, gcLo}, // [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 + {0x10080, 0x100FA, prAL, gcLo}, // [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 + {0x10100, 0x10102, prBA, gcPo}, // [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK + {0x10107, 0x10133, prAL, gcNo}, // [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND + {0x10137, 0x1013F, prAL, gcSo}, // [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT + {0x10140, 0x10174, prAL, gcNl}, // [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS + {0x10175, 0x10178, prAL, gcNo}, // [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN + {0x10179, 0x10189, prAL, gcSo}, // [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN + {0x1018A, 0x1018B, prAL, gcNo}, // [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN + {0x1018C, 0x1018E, prAL, gcSo}, // [3] GREEK SINUSOID SIGN..NOMISMA SIGN + {0x10190, 0x1019C, prAL, gcSo}, // [13] ROMAN SEXTANS SIGN..ASCIA SYMBOL + {0x101A0, 0x101A0, prAL, gcSo}, // GREEK SYMBOL TAU RHO + {0x101D0, 0x101FC, prAL, gcSo}, // [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND + {0x101FD, 0x101FD, prCM, gcMn}, // PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x10280, 0x1029C, prAL, gcLo}, // [29] LYCIAN LETTER A..LYCIAN LETTER X + {0x102A0, 0x102D0, prAL, gcLo}, // [49] CARIAN LETTER A..CARIAN LETTER UUU3 + {0x102E0, 0x102E0, prCM, gcMn}, // COPTIC EPACT THOUSANDS MARK + {0x102E1, 0x102FB, prAL, gcNo}, // [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED + {0x10300, 0x1031F, prAL, gcLo}, // [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS + {0x10320, 0x10323, prAL, gcNo}, // [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY + {0x1032D, 0x1032F, prAL, gcLo}, // [3] OLD ITALIC LETTER YE..OLD ITALIC LETTER SOUTHERN TSE + {0x10330, 0x10340, prAL, gcLo}, // [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA + {0x10341, 0x10341, prAL, gcNl}, // GOTHIC LETTER NINETY + {0x10342, 0x10349, prAL, gcLo}, // [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL + {0x1034A, 0x1034A, prAL, gcNl}, // GOTHIC LETTER NINE HUNDRED + {0x10350, 0x10375, prAL, gcLo}, // [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA + {0x10376, 0x1037A, prCM, gcMn}, // [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10380, 0x1039D, prAL, gcLo}, // [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU + {0x1039F, 0x1039F, prBA, gcPo}, // UGARITIC WORD DIVIDER + {0x103A0, 0x103C3, prAL, gcLo}, // [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA + {0x103C8, 0x103CF, prAL, gcLo}, // [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH + {0x103D0, 0x103D0, prBA, gcPo}, // OLD PERSIAN WORD DIVIDER + {0x103D1, 0x103D5, prAL, gcNl}, // [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED + {0x10400, 0x1044F, prAL, gcLC}, // [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW + {0x10450, 0x1047F, prAL, gcLo}, // [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW + {0x10480, 0x1049D, prAL, gcLo}, // [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO + {0x104A0, 0x104A9, prNU, gcNd}, // [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE + {0x104B0, 0x104D3, prAL, gcLu}, // [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA + {0x104D8, 0x104FB, prAL, gcLl}, // [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA + {0x10500, 0x10527, prAL, gcLo}, // [40] ELBASAN LETTER A..ELBASAN LETTER KHE + {0x10530, 0x10563, prAL, gcLo}, // [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW + {0x1056F, 0x1056F, prAL, gcPo}, // CAUCASIAN ALBANIAN CITATION MARK + {0x10570, 0x1057A, prAL, gcLu}, // [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA + {0x1057C, 0x1058A, prAL, gcLu}, // [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE + {0x1058C, 0x10592, prAL, gcLu}, // [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE + {0x10594, 0x10595, prAL, gcLu}, // [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE + {0x10597, 0x105A1, prAL, gcLl}, // [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA + {0x105A3, 0x105B1, prAL, gcLl}, // [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE + {0x105B3, 0x105B9, prAL, gcLl}, // [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE + {0x105BB, 0x105BC, prAL, gcLl}, // [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE + {0x10600, 0x10736, prAL, gcLo}, // [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 + {0x10740, 0x10755, prAL, gcLo}, // [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE + {0x10760, 0x10767, prAL, gcLo}, // [8] LINEAR A SIGN A800..LINEAR A SIGN A807 + {0x10780, 0x10785, prAL, gcLm}, // [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK + {0x10787, 0x107B0, prAL, gcLm}, // [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK + {0x107B2, 0x107BA, prAL, gcLm}, // [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL + {0x10800, 0x10805, prAL, gcLo}, // [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA + {0x10808, 0x10808, prAL, gcLo}, // CYPRIOT SYLLABLE JO + {0x1080A, 0x10835, prAL, gcLo}, // [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO + {0x10837, 0x10838, prAL, gcLo}, // [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE + {0x1083C, 0x1083C, prAL, gcLo}, // CYPRIOT SYLLABLE ZA + {0x1083F, 0x1083F, prAL, gcLo}, // CYPRIOT SYLLABLE ZO + {0x10840, 0x10855, prAL, gcLo}, // [22] IMPERIAL ARAMAIC LETTER ALEPH..IMPERIAL ARAMAIC LETTER TAW + {0x10857, 0x10857, prBA, gcPo}, // IMPERIAL ARAMAIC SECTION SIGN + {0x10858, 0x1085F, prAL, gcNo}, // [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND + {0x10860, 0x10876, prAL, gcLo}, // [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW + {0x10877, 0x10878, prAL, gcSo}, // [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON + {0x10879, 0x1087F, prAL, gcNo}, // [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY + {0x10880, 0x1089E, prAL, gcLo}, // [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW + {0x108A7, 0x108AF, prAL, gcNo}, // [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED + {0x108E0, 0x108F2, prAL, gcLo}, // [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH + {0x108F4, 0x108F5, prAL, gcLo}, // [2] HATRAN LETTER SHIN..HATRAN LETTER TAW + {0x108FB, 0x108FF, prAL, gcNo}, // [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED + {0x10900, 0x10915, prAL, gcLo}, // [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU + {0x10916, 0x1091B, prAL, gcNo}, // [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE + {0x1091F, 0x1091F, prBA, gcPo}, // PHOENICIAN WORD SEPARATOR + {0x10920, 0x10939, prAL, gcLo}, // [26] LYDIAN LETTER A..LYDIAN LETTER C + {0x1093F, 0x1093F, prAL, gcPo}, // LYDIAN TRIANGULAR MARK + {0x10980, 0x1099F, prAL, gcLo}, // [32] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2 + {0x109A0, 0x109B7, prAL, gcLo}, // [24] MEROITIC CURSIVE LETTER A..MEROITIC CURSIVE LETTER DA + {0x109BC, 0x109BD, prAL, gcNo}, // [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF + {0x109BE, 0x109BF, prAL, gcLo}, // [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN + {0x109C0, 0x109CF, prAL, gcNo}, // [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY + {0x109D2, 0x109FF, prAL, gcNo}, // [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS + {0x10A00, 0x10A00, prAL, gcLo}, // KHAROSHTHI LETTER A + {0x10A01, 0x10A03, prCM, gcMn}, // [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prCM, gcMn}, // [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prCM, gcMn}, // [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A10, 0x10A13, prAL, gcLo}, // [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA + {0x10A15, 0x10A17, prAL, gcLo}, // [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA + {0x10A19, 0x10A35, prAL, gcLo}, // [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA + {0x10A38, 0x10A3A, prCM, gcMn}, // [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prCM, gcMn}, // KHAROSHTHI VIRAMA + {0x10A40, 0x10A48, prAL, gcNo}, // [9] KHAROSHTHI DIGIT ONE..KHAROSHTHI FRACTION ONE HALF + {0x10A50, 0x10A57, prBA, gcPo}, // [8] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION DOUBLE DANDA + {0x10A58, 0x10A58, prAL, gcPo}, // KHAROSHTHI PUNCTUATION LINES + {0x10A60, 0x10A7C, prAL, gcLo}, // [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH + {0x10A7D, 0x10A7E, prAL, gcNo}, // [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY + {0x10A7F, 0x10A7F, prAL, gcPo}, // OLD SOUTH ARABIAN NUMERIC INDICATOR + {0x10A80, 0x10A9C, prAL, gcLo}, // [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH + {0x10A9D, 0x10A9F, prAL, gcNo}, // [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY + {0x10AC0, 0x10AC7, prAL, gcLo}, // [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW + {0x10AC8, 0x10AC8, prAL, gcSo}, // MANICHAEAN SIGN UD + {0x10AC9, 0x10AE4, prAL, gcLo}, // [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW + {0x10AE5, 0x10AE6, prCM, gcMn}, // [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10AEB, 0x10AEF, prAL, gcNo}, // [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED + {0x10AF0, 0x10AF5, prBA, gcPo}, // [6] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION TWO DOTS + {0x10AF6, 0x10AF6, prIN, gcPo}, // MANICHAEAN PUNCTUATION LINE FILLER + {0x10B00, 0x10B35, prAL, gcLo}, // [54] AVESTAN LETTER A..AVESTAN LETTER HE + {0x10B39, 0x10B3F, prBA, gcPo}, // [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION + {0x10B40, 0x10B55, prAL, gcLo}, // [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW + {0x10B58, 0x10B5F, prAL, gcNo}, // [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND + {0x10B60, 0x10B72, prAL, gcLo}, // [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW + {0x10B78, 0x10B7F, prAL, gcNo}, // [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND + {0x10B80, 0x10B91, prAL, gcLo}, // [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW + {0x10B99, 0x10B9C, prAL, gcPo}, // [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT + {0x10BA9, 0x10BAF, prAL, gcNo}, // [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED + {0x10C00, 0x10C48, prAL, gcLo}, // [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH + {0x10C80, 0x10CB2, prAL, gcLu}, // [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US + {0x10CC0, 0x10CF2, prAL, gcLl}, // [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US + {0x10CFA, 0x10CFF, prAL, gcNo}, // [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND + {0x10D00, 0x10D23, prAL, gcLo}, // [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA + {0x10D24, 0x10D27, prCM, gcMn}, // [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10D30, 0x10D39, prNU, gcNd}, // [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE + {0x10E60, 0x10E7E, prAL, gcNo}, // [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS + {0x10E80, 0x10EA9, prAL, gcLo}, // [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET + {0x10EAB, 0x10EAC, prCM, gcMn}, // [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EAD, 0x10EAD, prBA, gcPd}, // YEZIDI HYPHENATION MARK + {0x10EB0, 0x10EB1, prAL, gcLo}, // [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE + {0x10EFD, 0x10EFF, prCM, gcMn}, // [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F00, 0x10F1C, prAL, gcLo}, // [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL + {0x10F1D, 0x10F26, prAL, gcNo}, // [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF + {0x10F27, 0x10F27, prAL, gcLo}, // OLD SOGDIAN LIGATURE AYIN-DALETH + {0x10F30, 0x10F45, prAL, gcLo}, // [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN + {0x10F46, 0x10F50, prCM, gcMn}, // [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F51, 0x10F54, prAL, gcNo}, // [4] SOGDIAN NUMBER ONE..SOGDIAN NUMBER ONE HUNDRED + {0x10F55, 0x10F59, prAL, gcPo}, // [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT + {0x10F70, 0x10F81, prAL, gcLo}, // [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH + {0x10F82, 0x10F85, prCM, gcMn}, // [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x10F86, 0x10F89, prAL, gcPo}, // [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS + {0x10FB0, 0x10FC4, prAL, gcLo}, // [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW + {0x10FC5, 0x10FCB, prAL, gcNo}, // [7] CHORASMIAN NUMBER ONE..CHORASMIAN NUMBER ONE HUNDRED + {0x10FE0, 0x10FF6, prAL, gcLo}, // [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH + {0x11000, 0x11000, prCM, gcMc}, // BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prCM, gcMn}, // BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prCM, gcMc}, // BRAHMI SIGN VISARGA + {0x11003, 0x11037, prAL, gcLo}, // [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA + {0x11038, 0x11046, prCM, gcMn}, // [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11047, 0x11048, prBA, gcPo}, // [2] BRAHMI DANDA..BRAHMI DOUBLE DANDA + {0x11049, 0x1104D, prAL, gcPo}, // [5] BRAHMI PUNCTUATION DOT..BRAHMI PUNCTUATION LOTUS + {0x11052, 0x11065, prAL, gcNo}, // [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND + {0x11066, 0x1106F, prNU, gcNd}, // [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE + {0x11070, 0x11070, prCM, gcMn}, // BRAHMI SIGN OLD TAMIL VIRAMA + {0x11071, 0x11072, prAL, gcLo}, // [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O + {0x11073, 0x11074, prCM, gcMn}, // [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x11075, 0x11075, prAL, gcLo}, // BRAHMI LETTER OLD TAMIL LLA + {0x1107F, 0x1107F, prCM, gcMn}, // BRAHMI NUMBER JOINER + {0x11080, 0x11081, prCM, gcMn}, // [2] KAITHI SIGN CANDRABINDU..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prCM, gcMc}, // KAITHI SIGN VISARGA + {0x11083, 0x110AF, prAL, gcLo}, // [45] KAITHI LETTER A..KAITHI LETTER HA + {0x110B0, 0x110B2, prCM, gcMc}, // [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prCM, gcMn}, // [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prCM, gcMc}, // [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prCM, gcMn}, // [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BB, 0x110BC, prAL, gcPo}, // [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN + {0x110BD, 0x110BD, prAL, gcCf}, // KAITHI NUMBER SIGN + {0x110BE, 0x110C1, prBA, gcPo}, // [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA + {0x110C2, 0x110C2, prCM, gcMn}, // KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prAL, gcCf}, // KAITHI NUMBER SIGN ABOVE + {0x110D0, 0x110E8, prAL, gcLo}, // [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE + {0x110F0, 0x110F9, prNU, gcNd}, // [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE + {0x11100, 0x11102, prCM, gcMn}, // [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11103, 0x11126, prAL, gcLo}, // [36] CHAKMA LETTER AA..CHAKMA LETTER HAA + {0x11127, 0x1112B, prCM, gcMn}, // [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prCM, gcMc}, // CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prCM, gcMn}, // [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11136, 0x1113F, prNU, gcNd}, // [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE + {0x11140, 0x11143, prBA, gcPo}, // [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK + {0x11144, 0x11144, prAL, gcLo}, // CHAKMA LETTER LHAA + {0x11145, 0x11146, prCM, gcMc}, // [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11147, 0x11147, prAL, gcLo}, // CHAKMA LETTER VAA + {0x11150, 0x11172, prAL, gcLo}, // [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA + {0x11173, 0x11173, prCM, gcMn}, // MAHAJANI SIGN NUKTA + {0x11174, 0x11174, prAL, gcPo}, // MAHAJANI ABBREVIATION SIGN + {0x11175, 0x11175, prBB, gcPo}, // MAHAJANI SECTION MARK + {0x11176, 0x11176, prAL, gcLo}, // MAHAJANI LIGATURE SHRI + {0x11180, 0x11181, prCM, gcMn}, // [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prCM, gcMc}, // SHARADA SIGN VISARGA + {0x11183, 0x111B2, prAL, gcLo}, // [48] SHARADA LETTER A..SHARADA LETTER HA + {0x111B3, 0x111B5, prCM, gcMc}, // [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prCM, gcMn}, // [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prCM, gcMc}, // [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C1, 0x111C4, prAL, gcLo}, // [4] SHARADA SIGN AVAGRAHA..SHARADA OM + {0x111C5, 0x111C6, prBA, gcPo}, // [2] SHARADA DANDA..SHARADA DOUBLE DANDA + {0x111C7, 0x111C7, prAL, gcPo}, // SHARADA ABBREVIATION SIGN + {0x111C8, 0x111C8, prBA, gcPo}, // SHARADA SEPARATOR + {0x111C9, 0x111CC, prCM, gcMn}, // [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CD, 0x111CD, prAL, gcPo}, // SHARADA SUTRA MARK + {0x111CE, 0x111CE, prCM, gcMc}, // SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prCM, gcMn}, // SHARADA SIGN INVERTED CANDRABINDU + {0x111D0, 0x111D9, prNU, gcNd}, // [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE + {0x111DA, 0x111DA, prAL, gcLo}, // SHARADA EKAM + {0x111DB, 0x111DB, prBB, gcPo}, // SHARADA SIGN SIDDHAM + {0x111DC, 0x111DC, prAL, gcLo}, // SHARADA HEADSTROKE + {0x111DD, 0x111DF, prBA, gcPo}, // [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2 + {0x111E1, 0x111F4, prAL, gcNo}, // [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND + {0x11200, 0x11211, prAL, gcLo}, // [18] KHOJKI LETTER A..KHOJKI LETTER JJA + {0x11213, 0x1122B, prAL, gcLo}, // [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA + {0x1122C, 0x1122E, prCM, gcMc}, // [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prCM, gcMn}, // [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prCM, gcMc}, // [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prCM, gcMn}, // KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prCM, gcMc}, // KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prCM, gcMn}, // [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x11238, 0x11239, prBA, gcPo}, // [2] KHOJKI DANDA..KHOJKI DOUBLE DANDA + {0x1123A, 0x1123A, prAL, gcPo}, // KHOJKI WORD SEPARATOR + {0x1123B, 0x1123C, prBA, gcPo}, // [2] KHOJKI SECTION MARK..KHOJKI DOUBLE SECTION MARK + {0x1123D, 0x1123D, prAL, gcPo}, // KHOJKI ABBREVIATION SIGN + {0x1123E, 0x1123E, prCM, gcMn}, // KHOJKI SIGN SUKUN + {0x1123F, 0x11240, prAL, gcLo}, // [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I + {0x11241, 0x11241, prCM, gcMn}, // KHOJKI VOWEL SIGN VOCALIC R + {0x11280, 0x11286, prAL, gcLo}, // [7] MULTANI LETTER A..MULTANI LETTER GA + {0x11288, 0x11288, prAL, gcLo}, // MULTANI LETTER GHA + {0x1128A, 0x1128D, prAL, gcLo}, // [4] MULTANI LETTER CA..MULTANI LETTER JJA + {0x1128F, 0x1129D, prAL, gcLo}, // [15] MULTANI LETTER NYA..MULTANI LETTER BA + {0x1129F, 0x112A8, prAL, gcLo}, // [10] MULTANI LETTER BHA..MULTANI LETTER RHA + {0x112A9, 0x112A9, prBA, gcPo}, // MULTANI SECTION MARK + {0x112B0, 0x112DE, prAL, gcLo}, // [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA + {0x112DF, 0x112DF, prCM, gcMn}, // KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prCM, gcMc}, // [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prCM, gcMn}, // [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x112F0, 0x112F9, prNU, gcNd}, // [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE + {0x11300, 0x11301, prCM, gcMn}, // [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prCM, gcMc}, // [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x11305, 0x1130C, prAL, gcLo}, // [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L + {0x1130F, 0x11310, prAL, gcLo}, // [2] GRANTHA LETTER EE..GRANTHA LETTER AI + {0x11313, 0x11328, prAL, gcLo}, // [22] GRANTHA LETTER OO..GRANTHA LETTER NA + {0x1132A, 0x11330, prAL, gcLo}, // [7] GRANTHA LETTER PA..GRANTHA LETTER RA + {0x11332, 0x11333, prAL, gcLo}, // [2] GRANTHA LETTER LA..GRANTHA LETTER LLA + {0x11335, 0x11339, prAL, gcLo}, // [5] GRANTHA LETTER VA..GRANTHA LETTER HA + {0x1133B, 0x1133C, prCM, gcMn}, // [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133D, 0x1133D, prAL, gcLo}, // GRANTHA SIGN AVAGRAHA + {0x1133E, 0x1133F, prCM, gcMc}, // [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prCM, gcMn}, // GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prCM, gcMc}, // [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prCM, gcMc}, // [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prCM, gcMc}, // [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11350, 0x11350, prAL, gcLo}, // GRANTHA OM + {0x11357, 0x11357, prCM, gcMc}, // GRANTHA AU LENGTH MARK + {0x1135D, 0x11361, prAL, gcLo}, // [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL + {0x11362, 0x11363, prCM, gcMc}, // [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prCM, gcMn}, // [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prCM, gcMn}, // [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11400, 0x11434, prAL, gcLo}, // [53] NEWA LETTER A..NEWA LETTER HA + {0x11435, 0x11437, prCM, gcMc}, // [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prCM, gcMn}, // [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prCM, gcMc}, // [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prCM, gcMn}, // [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prCM, gcMc}, // NEWA SIGN VISARGA + {0x11446, 0x11446, prCM, gcMn}, // NEWA SIGN NUKTA + {0x11447, 0x1144A, prAL, gcLo}, // [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI + {0x1144B, 0x1144E, prBA, gcPo}, // [4] NEWA DANDA..NEWA GAP FILLER + {0x1144F, 0x1144F, prAL, gcPo}, // NEWA ABBREVIATION SIGN + {0x11450, 0x11459, prNU, gcNd}, // [10] NEWA DIGIT ZERO..NEWA DIGIT NINE + {0x1145A, 0x1145B, prBA, gcPo}, // [2] NEWA DOUBLE COMMA..NEWA PLACEHOLDER MARK + {0x1145D, 0x1145D, prAL, gcPo}, // NEWA INSERTION SIGN + {0x1145E, 0x1145E, prCM, gcMn}, // NEWA SANDHI MARK + {0x1145F, 0x11461, prAL, gcLo}, // [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA + {0x11480, 0x114AF, prAL, gcLo}, // [48] TIRHUTA ANJI..TIRHUTA LETTER HA + {0x114B0, 0x114B2, prCM, gcMc}, // [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prCM, gcMn}, // [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prCM, gcMc}, // TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prCM, gcMn}, // TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BE, prCM, gcMc}, // [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prCM, gcMn}, // [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prCM, gcMc}, // TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prCM, gcMn}, // [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x114C4, 0x114C5, prAL, gcLo}, // [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG + {0x114C6, 0x114C6, prAL, gcPo}, // TIRHUTA ABBREVIATION SIGN + {0x114C7, 0x114C7, prAL, gcLo}, // TIRHUTA OM + {0x114D0, 0x114D9, prNU, gcNd}, // [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE + {0x11580, 0x115AE, prAL, gcLo}, // [47] SIDDHAM LETTER A..SIDDHAM LETTER HA + {0x115AF, 0x115B1, prCM, gcMc}, // [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prCM, gcMn}, // [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prCM, gcMc}, // [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prCM, gcMn}, // [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prCM, gcMc}, // SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prCM, gcMn}, // [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115C1, 0x115C1, prBB, gcPo}, // SIDDHAM SIGN SIDDHAM + {0x115C2, 0x115C3, prBA, gcPo}, // [2] SIDDHAM DANDA..SIDDHAM DOUBLE DANDA + {0x115C4, 0x115C5, prEX, gcPo}, // [2] SIDDHAM SEPARATOR DOT..SIDDHAM SEPARATOR BAR + {0x115C6, 0x115C8, prAL, gcPo}, // [3] SIDDHAM REPETITION MARK-1..SIDDHAM REPETITION MARK-3 + {0x115C9, 0x115D7, prBA, gcPo}, // [15] SIDDHAM END OF TEXT MARK..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES + {0x115D8, 0x115DB, prAL, gcLo}, // [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U + {0x115DC, 0x115DD, prCM, gcMn}, // [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11600, 0x1162F, prAL, gcLo}, // [48] MODI LETTER A..MODI LETTER LLA + {0x11630, 0x11632, prCM, gcMc}, // [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prCM, gcMn}, // [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prCM, gcMc}, // [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prCM, gcMn}, // MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prCM, gcMc}, // MODI SIGN VISARGA + {0x1163F, 0x11640, prCM, gcMn}, // [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x11641, 0x11642, prBA, gcPo}, // [2] MODI DANDA..MODI DOUBLE DANDA + {0x11643, 0x11643, prAL, gcPo}, // MODI ABBREVIATION SIGN + {0x11644, 0x11644, prAL, gcLo}, // MODI SIGN HUVA + {0x11650, 0x11659, prNU, gcNd}, // [10] MODI DIGIT ZERO..MODI DIGIT NINE + {0x11660, 0x1166C, prBB, gcPo}, // [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT + {0x11680, 0x116AA, prAL, gcLo}, // [43] TAKRI LETTER A..TAKRI LETTER RRA + {0x116AB, 0x116AB, prCM, gcMn}, // TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prCM, gcMc}, // TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prCM, gcMn}, // TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prCM, gcMc}, // [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prCM, gcMn}, // [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prCM, gcMc}, // TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prCM, gcMn}, // TAKRI SIGN NUKTA + {0x116B8, 0x116B8, prAL, gcLo}, // TAKRI LETTER ARCHAIC KHA + {0x116B9, 0x116B9, prAL, gcPo}, // TAKRI ABBREVIATION SIGN + {0x116C0, 0x116C9, prNU, gcNd}, // [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE + {0x11700, 0x1171A, prSA, gcLo}, // [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA + {0x1171D, 0x1171F, prSA, gcMn}, // [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11720, 0x11721, prSA, gcMc}, // [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA + {0x11722, 0x11725, prSA, gcMn}, // [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prSA, gcMc}, // AHOM VOWEL SIGN E + {0x11727, 0x1172B, prSA, gcMn}, // [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x11730, 0x11739, prNU, gcNd}, // [10] AHOM DIGIT ZERO..AHOM DIGIT NINE + {0x1173A, 0x1173B, prSA, gcNo}, // [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY + {0x1173C, 0x1173E, prBA, gcPo}, // [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI + {0x1173F, 0x1173F, prSA, gcSo}, // AHOM SYMBOL VI + {0x11740, 0x11746, prSA, gcLo}, // [7] AHOM LETTER CA..AHOM LETTER LLA + {0x11800, 0x1182B, prAL, gcLo}, // [44] DOGRA LETTER A..DOGRA LETTER RRA + {0x1182C, 0x1182E, prCM, gcMc}, // [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prCM, gcMn}, // [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prCM, gcMc}, // DOGRA SIGN VISARGA + {0x11839, 0x1183A, prCM, gcMn}, // [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x1183B, 0x1183B, prAL, gcPo}, // DOGRA ABBREVIATION SIGN + {0x118A0, 0x118DF, prAL, gcLC}, // [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO + {0x118E0, 0x118E9, prNU, gcNd}, // [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE + {0x118EA, 0x118F2, prAL, gcNo}, // [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY + {0x118FF, 0x118FF, prAL, gcLo}, // WARANG CITI OM + {0x11900, 0x11906, prAL, gcLo}, // [7] DIVES AKURU LETTER A..DIVES AKURU LETTER E + {0x11909, 0x11909, prAL, gcLo}, // DIVES AKURU LETTER O + {0x1190C, 0x11913, prAL, gcLo}, // [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA + {0x11915, 0x11916, prAL, gcLo}, // [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA + {0x11918, 0x1192F, prAL, gcLo}, // [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA + {0x11930, 0x11935, prCM, gcMc}, // [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prCM, gcMc}, // [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prCM, gcMn}, // [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prCM, gcMc}, // DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prCM, gcMn}, // DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prAL, gcLo}, // DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prCM, gcMc}, // DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prAL, gcLo}, // DIVES AKURU INITIAL RA + {0x11942, 0x11942, prCM, gcMc}, // DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prCM, gcMn}, // DIVES AKURU SIGN NUKTA + {0x11944, 0x11946, prBA, gcPo}, // [3] DIVES AKURU DOUBLE DANDA..DIVES AKURU END OF TEXT MARK + {0x11950, 0x11959, prNU, gcNd}, // [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE + {0x119A0, 0x119A7, prAL, gcLo}, // [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR + {0x119AA, 0x119D0, prAL, gcLo}, // [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA + {0x119D1, 0x119D3, prCM, gcMc}, // [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prCM, gcMn}, // [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prCM, gcMn}, // [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prCM, gcMc}, // [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prCM, gcMn}, // NANDINAGARI SIGN VIRAMA + {0x119E1, 0x119E1, prAL, gcLo}, // NANDINAGARI SIGN AVAGRAHA + {0x119E2, 0x119E2, prBB, gcPo}, // NANDINAGARI SIGN SIDDHAM + {0x119E3, 0x119E3, prAL, gcLo}, // NANDINAGARI HEADSTROKE + {0x119E4, 0x119E4, prCM, gcMc}, // NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A00, 0x11A00, prAL, gcLo}, // ZANABAZAR SQUARE LETTER A + {0x11A01, 0x11A0A, prCM, gcMn}, // [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A0B, 0x11A32, prAL, gcLo}, // [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA + {0x11A33, 0x11A38, prCM, gcMn}, // [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prCM, gcMc}, // ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prAL, gcLo}, // ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prCM, gcMn}, // [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A3F, 0x11A3F, prBB, gcPo}, // ZANABAZAR SQUARE INITIAL HEAD MARK + {0x11A40, 0x11A40, prAL, gcPo}, // ZANABAZAR SQUARE CLOSING HEAD MARK + {0x11A41, 0x11A44, prBA, gcPo}, // [4] ZANABAZAR SQUARE MARK TSHEG..ZANABAZAR SQUARE MARK LONG TSHEG + {0x11A45, 0x11A45, prBB, gcPo}, // ZANABAZAR SQUARE INITIAL DOUBLE-LINED HEAD MARK + {0x11A46, 0x11A46, prAL, gcPo}, // ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK + {0x11A47, 0x11A47, prCM, gcMn}, // ZANABAZAR SQUARE SUBJOINER + {0x11A50, 0x11A50, prAL, gcLo}, // SOYOMBO LETTER A + {0x11A51, 0x11A56, prCM, gcMn}, // [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prCM, gcMc}, // [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prCM, gcMn}, // [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A5C, 0x11A89, prAL, gcLo}, // [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prCM, gcMn}, // [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prCM, gcMc}, // SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prCM, gcMn}, // [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11A9A, 0x11A9C, prBA, gcPo}, // [3] SOYOMBO MARK TSHEG..SOYOMBO MARK DOUBLE SHAD + {0x11A9D, 0x11A9D, prAL, gcLo}, // SOYOMBO MARK PLUTA + {0x11A9E, 0x11AA0, prBB, gcPo}, // [3] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO HEAD MARK WITH MOON AND SUN + {0x11AA1, 0x11AA2, prBA, gcPo}, // [2] SOYOMBO TERMINAL MARK-1..SOYOMBO TERMINAL MARK-2 + {0x11AB0, 0x11ABF, prAL, gcLo}, // [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA + {0x11AC0, 0x11AF8, prAL, gcLo}, // [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL + {0x11B00, 0x11B09, prBB, gcPo}, // [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU + {0x11C00, 0x11C08, prAL, gcLo}, // [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L + {0x11C0A, 0x11C2E, prAL, gcLo}, // [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA + {0x11C2F, 0x11C2F, prCM, gcMc}, // BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prCM, gcMn}, // [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prCM, gcMn}, // [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prCM, gcMc}, // BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prCM, gcMn}, // BHAIKSUKI SIGN VIRAMA + {0x11C40, 0x11C40, prAL, gcLo}, // BHAIKSUKI SIGN AVAGRAHA + {0x11C41, 0x11C45, prBA, gcPo}, // [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2 + {0x11C50, 0x11C59, prNU, gcNd}, // [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE + {0x11C5A, 0x11C6C, prAL, gcNo}, // [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK + {0x11C70, 0x11C70, prBB, gcPo}, // MARCHEN HEAD MARK + {0x11C71, 0x11C71, prEX, gcPo}, // MARCHEN MARK SHAD + {0x11C72, 0x11C8F, prAL, gcLo}, // [30] MARCHEN LETTER KA..MARCHEN LETTER A + {0x11C92, 0x11CA7, prCM, gcMn}, // [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prCM, gcMc}, // MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prCM, gcMn}, // [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prCM, gcMc}, // MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prCM, gcMn}, // [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prCM, gcMc}, // MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prCM, gcMn}, // [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D00, 0x11D06, prAL, gcLo}, // [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E + {0x11D08, 0x11D09, prAL, gcLo}, // [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O + {0x11D0B, 0x11D30, prAL, gcLo}, // [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA + {0x11D31, 0x11D36, prCM, gcMn}, // [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prCM, gcMn}, // MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prCM, gcMn}, // [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prCM, gcMn}, // [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prAL, gcLo}, // MASARAM GONDI REPHA + {0x11D47, 0x11D47, prCM, gcMn}, // MASARAM GONDI RA-KARA + {0x11D50, 0x11D59, prNU, gcNd}, // [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE + {0x11D60, 0x11D65, prAL, gcLo}, // [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU + {0x11D67, 0x11D68, prAL, gcLo}, // [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI + {0x11D6A, 0x11D89, prAL, gcLo}, // [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA + {0x11D8A, 0x11D8E, prCM, gcMc}, // [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prCM, gcMn}, // [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prCM, gcMc}, // [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prCM, gcMn}, // GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prCM, gcMc}, // GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prCM, gcMn}, // GUNJALA GONDI VIRAMA + {0x11D98, 0x11D98, prAL, gcLo}, // GUNJALA GONDI OM + {0x11DA0, 0x11DA9, prNU, gcNd}, // [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE + {0x11EE0, 0x11EF2, prAL, gcLo}, // [19] MAKASAR LETTER KA..MAKASAR ANGKA + {0x11EF3, 0x11EF4, prCM, gcMn}, // [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prCM, gcMc}, // [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11EF7, 0x11EF8, prAL, gcPo}, // [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION + {0x11F00, 0x11F01, prCM, gcMn}, // [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prAL, gcLo}, // KAWI SIGN REPHA + {0x11F03, 0x11F03, prCM, gcMc}, // KAWI SIGN VISARGA + {0x11F04, 0x11F10, prAL, gcLo}, // [13] KAWI LETTER A..KAWI LETTER O + {0x11F12, 0x11F33, prAL, gcLo}, // [34] KAWI LETTER KA..KAWI LETTER JNYA + {0x11F34, 0x11F35, prCM, gcMc}, // [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prCM, gcMn}, // [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prCM, gcMc}, // [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prCM, gcMn}, // KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prCM, gcMc}, // KAWI SIGN KILLER + {0x11F42, 0x11F42, prCM, gcMn}, // KAWI CONJOINER + {0x11F43, 0x11F44, prBA, gcPo}, // [2] KAWI DANDA..KAWI DOUBLE DANDA + {0x11F45, 0x11F4F, prID, gcPo}, // [11] KAWI PUNCTUATION SECTION MARKER..KAWI PUNCTUATION CLOSING SPIRAL + {0x11F50, 0x11F59, prNU, gcNd}, // [10] KAWI DIGIT ZERO..KAWI DIGIT NINE + {0x11FB0, 0x11FB0, prAL, gcLo}, // LISU LETTER YHA + {0x11FC0, 0x11FD4, prAL, gcNo}, // [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH + {0x11FD5, 0x11FDC, prAL, gcSo}, // [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI + {0x11FDD, 0x11FE0, prPO, gcSc}, // [4] TAMIL SIGN KAACU..TAMIL SIGN VARAAKAN + {0x11FE1, 0x11FF1, prAL, gcSo}, // [17] TAMIL SIGN PAARAM..TAMIL SIGN VAKAIYARAA + {0x11FFF, 0x11FFF, prBA, gcPo}, // TAMIL PUNCTUATION END OF TEXT + {0x12000, 0x12399, prAL, gcLo}, // [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U + {0x12400, 0x1246E, prAL, gcNl}, // [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM + {0x12470, 0x12474, prBA, gcPo}, // [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON + {0x12480, 0x12543, prAL, gcLo}, // [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU + {0x12F90, 0x12FF0, prAL, gcLo}, // [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 + {0x12FF1, 0x12FF2, prAL, gcPo}, // [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302 + {0x13000, 0x13257, prAL, gcLo}, // [600] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH O006 + {0x13258, 0x1325A, prOP, gcLo}, // [3] EGYPTIAN HIEROGLYPH O006A..EGYPTIAN HIEROGLYPH O006C + {0x1325B, 0x1325D, prCL, gcLo}, // [3] EGYPTIAN HIEROGLYPH O006D..EGYPTIAN HIEROGLYPH O006F + {0x1325E, 0x13281, prAL, gcLo}, // [36] EGYPTIAN HIEROGLYPH O007..EGYPTIAN HIEROGLYPH O033 + {0x13282, 0x13282, prCL, gcLo}, // EGYPTIAN HIEROGLYPH O033A + {0x13283, 0x13285, prAL, gcLo}, // [3] EGYPTIAN HIEROGLYPH O034..EGYPTIAN HIEROGLYPH O036 + {0x13286, 0x13286, prOP, gcLo}, // EGYPTIAN HIEROGLYPH O036A + {0x13287, 0x13287, prCL, gcLo}, // EGYPTIAN HIEROGLYPH O036B + {0x13288, 0x13288, prOP, gcLo}, // EGYPTIAN HIEROGLYPH O036C + {0x13289, 0x13289, prCL, gcLo}, // EGYPTIAN HIEROGLYPH O036D + {0x1328A, 0x13378, prAL, gcLo}, // [239] EGYPTIAN HIEROGLYPH O037..EGYPTIAN HIEROGLYPH V011 + {0x13379, 0x13379, prOP, gcLo}, // EGYPTIAN HIEROGLYPH V011A + {0x1337A, 0x1337B, prCL, gcLo}, // [2] EGYPTIAN HIEROGLYPH V011B..EGYPTIAN HIEROGLYPH V011C + {0x1337C, 0x1342F, prAL, gcLo}, // [180] EGYPTIAN HIEROGLYPH V012..EGYPTIAN HIEROGLYPH V011D + {0x13430, 0x13436, prGL, gcCf}, // [7] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH OVERLAY MIDDLE + {0x13437, 0x13437, prOP, gcCf}, // EGYPTIAN HIEROGLYPH BEGIN SEGMENT + {0x13438, 0x13438, prCL, gcCf}, // EGYPTIAN HIEROGLYPH END SEGMENT + {0x13439, 0x1343B, prGL, gcCf}, // [3] EGYPTIAN HIEROGLYPH INSERT AT MIDDLE..EGYPTIAN HIEROGLYPH INSERT AT BOTTOM + {0x1343C, 0x1343C, prOP, gcCf}, // EGYPTIAN HIEROGLYPH BEGIN ENCLOSURE + {0x1343D, 0x1343D, prCL, gcCf}, // EGYPTIAN HIEROGLYPH END ENCLOSURE + {0x1343E, 0x1343E, prOP, gcCf}, // EGYPTIAN HIEROGLYPH BEGIN WALLED ENCLOSURE + {0x1343F, 0x1343F, prCL, gcCf}, // EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prCM, gcMn}, // EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13441, 0x13446, prAL, gcLo}, // [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN + {0x13447, 0x13455, prCM, gcMn}, // [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x14400, 0x145CD, prAL, gcLo}, // [462] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A409 + {0x145CE, 0x145CE, prOP, gcLo}, // ANATOLIAN HIEROGLYPH A410 BEGIN LOGOGRAM MARK + {0x145CF, 0x145CF, prCL, gcLo}, // ANATOLIAN HIEROGLYPH A410A END LOGOGRAM MARK + {0x145D0, 0x14646, prAL, gcLo}, // [119] ANATOLIAN HIEROGLYPH A411..ANATOLIAN HIEROGLYPH A530 + {0x16800, 0x16A38, prAL, gcLo}, // [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ + {0x16A40, 0x16A5E, prAL, gcLo}, // [31] MRO LETTER TA..MRO LETTER TEK + {0x16A60, 0x16A69, prNU, gcNd}, // [10] MRO DIGIT ZERO..MRO DIGIT NINE + {0x16A6E, 0x16A6F, prBA, gcPo}, // [2] MRO DANDA..MRO DOUBLE DANDA + {0x16A70, 0x16ABE, prAL, gcLo}, // [79] TANGSA LETTER OZ..TANGSA LETTER ZA + {0x16AC0, 0x16AC9, prNU, gcNd}, // [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE + {0x16AD0, 0x16AED, prAL, gcLo}, // [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I + {0x16AF0, 0x16AF4, prCM, gcMn}, // [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16AF5, 0x16AF5, prBA, gcPo}, // BASSA VAH FULL STOP + {0x16B00, 0x16B2F, prAL, gcLo}, // [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU + {0x16B30, 0x16B36, prCM, gcMn}, // [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16B37, 0x16B39, prBA, gcPo}, // [3] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN CIM CHEEM + {0x16B3A, 0x16B3B, prAL, gcPo}, // [2] PAHAWH HMONG SIGN VOS THIAB..PAHAWH HMONG SIGN VOS FEEM + {0x16B3C, 0x16B3F, prAL, gcSo}, // [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB + {0x16B40, 0x16B43, prAL, gcLm}, // [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM + {0x16B44, 0x16B44, prBA, gcPo}, // PAHAWH HMONG SIGN XAUS + {0x16B45, 0x16B45, prAL, gcSo}, // PAHAWH HMONG SIGN CIM TSOV ROG + {0x16B50, 0x16B59, prNU, gcNd}, // [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE + {0x16B5B, 0x16B61, prAL, gcNo}, // [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS + {0x16B63, 0x16B77, prAL, gcLo}, // [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS + {0x16B7D, 0x16B8F, prAL, gcLo}, // [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ + {0x16E40, 0x16E7F, prAL, gcLC}, // [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y + {0x16E80, 0x16E96, prAL, gcNo}, // [23] MEDEFAIDRIN DIGIT ZERO..MEDEFAIDRIN DIGIT THREE ALTERNATE FORM + {0x16E97, 0x16E98, prBA, gcPo}, // [2] MEDEFAIDRIN COMMA..MEDEFAIDRIN FULL STOP + {0x16E99, 0x16E9A, prAL, gcPo}, // [2] MEDEFAIDRIN SYMBOL AIVA..MEDEFAIDRIN EXCLAMATION OH + {0x16F00, 0x16F4A, prAL, gcLo}, // [75] MIAO LETTER PA..MIAO LETTER RTE + {0x16F4F, 0x16F4F, prCM, gcMn}, // MIAO SIGN CONSONANT MODIFIER BAR + {0x16F50, 0x16F50, prAL, gcLo}, // MIAO LETTER NASALIZATION + {0x16F51, 0x16F87, prCM, gcMc}, // [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prCM, gcMn}, // [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16F93, 0x16F9F, prAL, gcLm}, // [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 + {0x16FE0, 0x16FE1, prNS, gcLm}, // [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK + {0x16FE2, 0x16FE2, prNS, gcPo}, // OLD CHINESE HOOK MARK + {0x16FE3, 0x16FE3, prNS, gcLm}, // OLD CHINESE ITERATION MARK + {0x16FE4, 0x16FE4, prGL, gcMn}, // KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prCM, gcMc}, // [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x17000, 0x187F7, prID, gcLo}, // [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 + {0x18800, 0x18AFF, prID, gcLo}, // [768] TANGUT COMPONENT-001..TANGUT COMPONENT-768 + {0x18B00, 0x18CD5, prAL, gcLo}, // [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5 + {0x18D00, 0x18D08, prID, gcLo}, // [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 + {0x1AFF0, 0x1AFF3, prAL, gcLm}, // [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 + {0x1AFF5, 0x1AFFB, prAL, gcLm}, // [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 + {0x1AFFD, 0x1AFFE, prAL, gcLm}, // [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 + {0x1B000, 0x1B0FF, prID, gcLo}, // [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2 + {0x1B100, 0x1B122, prID, gcLo}, // [35] HENTAIGANA LETTER RE-3..KATAKANA LETTER ARCHAIC WU + {0x1B132, 0x1B132, prCJ, gcLo}, // HIRAGANA LETTER SMALL KO + {0x1B150, 0x1B152, prCJ, gcLo}, // [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO + {0x1B155, 0x1B155, prCJ, gcLo}, // KATAKANA LETTER SMALL KO + {0x1B164, 0x1B167, prCJ, gcLo}, // [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N + {0x1B170, 0x1B2FB, prID, gcLo}, // [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB + {0x1BC00, 0x1BC6A, prAL, gcLo}, // [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M + {0x1BC70, 0x1BC7C, prAL, gcLo}, // [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK + {0x1BC80, 0x1BC88, prAL, gcLo}, // [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL + {0x1BC90, 0x1BC99, prAL, gcLo}, // [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW + {0x1BC9C, 0x1BC9C, prAL, gcSo}, // DUPLOYAN SIGN O WITH CROSS + {0x1BC9D, 0x1BC9E, prCM, gcMn}, // [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BC9F, 0x1BC9F, prBA, gcPo}, // DUPLOYAN PUNCTUATION CHINOOK FULL STOP + {0x1BCA0, 0x1BCA3, prCM, gcCf}, // [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prCM, gcMn}, // [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prCM, gcMn}, // [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1CF50, 0x1CFC3, prAL, gcSo}, // [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK + {0x1D000, 0x1D0F5, prAL, gcSo}, // [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO + {0x1D100, 0x1D126, prAL, gcSo}, // [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2 + {0x1D129, 0x1D164, prAL, gcSo}, // [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE + {0x1D165, 0x1D166, prCM, gcMc}, // [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prCM, gcMn}, // [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16A, 0x1D16C, prAL, gcSo}, // [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3 + {0x1D16D, 0x1D172, prCM, gcMc}, // [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prCM, gcCf}, // [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prCM, gcMn}, // [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D183, 0x1D184, prAL, gcSo}, // [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN + {0x1D185, 0x1D18B, prCM, gcMn}, // [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D18C, 0x1D1A9, prAL, gcSo}, // [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH + {0x1D1AA, 0x1D1AD, prCM, gcMn}, // [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D1AE, 0x1D1EA, prAL, gcSo}, // [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON + {0x1D200, 0x1D241, prAL, gcSo}, // [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54 + {0x1D242, 0x1D244, prCM, gcMn}, // [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1D245, 0x1D245, prAL, gcSo}, // GREEK MUSICAL LEIMMA + {0x1D2C0, 0x1D2D3, prAL, gcNo}, // [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN + {0x1D2E0, 0x1D2F3, prAL, gcNo}, // [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN + {0x1D300, 0x1D356, prAL, gcSo}, // [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING + {0x1D360, 0x1D378, prAL, gcNo}, // [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE + {0x1D400, 0x1D454, prAL, gcLC}, // [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G + {0x1D456, 0x1D49C, prAL, gcLC}, // [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A + {0x1D49E, 0x1D49F, prAL, gcLu}, // [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D + {0x1D4A2, 0x1D4A2, prAL, gcLu}, // MATHEMATICAL SCRIPT CAPITAL G + {0x1D4A5, 0x1D4A6, prAL, gcLu}, // [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K + {0x1D4A9, 0x1D4AC, prAL, gcLu}, // [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q + {0x1D4AE, 0x1D4B9, prAL, gcLC}, // [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D + {0x1D4BB, 0x1D4BB, prAL, gcLl}, // MATHEMATICAL SCRIPT SMALL F + {0x1D4BD, 0x1D4C3, prAL, gcLl}, // [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N + {0x1D4C5, 0x1D505, prAL, gcLC}, // [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B + {0x1D507, 0x1D50A, prAL, gcLu}, // [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G + {0x1D50D, 0x1D514, prAL, gcLu}, // [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q + {0x1D516, 0x1D51C, prAL, gcLu}, // [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y + {0x1D51E, 0x1D539, prAL, gcLC}, // [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B + {0x1D53B, 0x1D53E, prAL, gcLu}, // [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G + {0x1D540, 0x1D544, prAL, gcLu}, // [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M + {0x1D546, 0x1D546, prAL, gcLu}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL O + {0x1D54A, 0x1D550, prAL, gcLu}, // [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + {0x1D552, 0x1D6A5, prAL, gcLC}, // [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J + {0x1D6A8, 0x1D6C0, prAL, gcLu}, // [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA + {0x1D6C1, 0x1D6C1, prAL, gcSm}, // MATHEMATICAL BOLD NABLA + {0x1D6C2, 0x1D6DA, prAL, gcLl}, // [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA + {0x1D6DB, 0x1D6DB, prAL, gcSm}, // MATHEMATICAL BOLD PARTIAL DIFFERENTIAL + {0x1D6DC, 0x1D6FA, prAL, gcLC}, // [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA + {0x1D6FB, 0x1D6FB, prAL, gcSm}, // MATHEMATICAL ITALIC NABLA + {0x1D6FC, 0x1D714, prAL, gcLl}, // [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA + {0x1D715, 0x1D715, prAL, gcSm}, // MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL + {0x1D716, 0x1D734, prAL, gcLC}, // [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA + {0x1D735, 0x1D735, prAL, gcSm}, // MATHEMATICAL BOLD ITALIC NABLA + {0x1D736, 0x1D74E, prAL, gcLl}, // [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA + {0x1D74F, 0x1D74F, prAL, gcSm}, // MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL + {0x1D750, 0x1D76E, prAL, gcLC}, // [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA + {0x1D76F, 0x1D76F, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD NABLA + {0x1D770, 0x1D788, prAL, gcLl}, // [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA + {0x1D789, 0x1D789, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL + {0x1D78A, 0x1D7A8, prAL, gcLC}, // [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA + {0x1D7A9, 0x1D7A9, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA + {0x1D7AA, 0x1D7C2, prAL, gcLl}, // [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA + {0x1D7C3, 0x1D7C3, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL + {0x1D7C4, 0x1D7CB, prAL, gcLC}, // [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA + {0x1D7CE, 0x1D7FF, prNU, gcNd}, // [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + {0x1D800, 0x1D9FF, prAL, gcSo}, // [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD + {0x1DA00, 0x1DA36, prCM, gcMn}, // [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA37, 0x1DA3A, prAL, gcSo}, // [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE + {0x1DA3B, 0x1DA6C, prCM, gcMn}, // [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA6D, 0x1DA74, prAL, gcSo}, // [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING + {0x1DA75, 0x1DA75, prCM, gcMn}, // SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA76, 0x1DA83, prAL, gcSo}, // [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH + {0x1DA84, 0x1DA84, prCM, gcMn}, // SIGNWRITING LOCATION HEAD NECK + {0x1DA85, 0x1DA86, prAL, gcSo}, // [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS + {0x1DA87, 0x1DA8A, prBA, gcPo}, // [4] SIGNWRITING COMMA..SIGNWRITING COLON + {0x1DA8B, 0x1DA8B, prAL, gcPo}, // SIGNWRITING PARENTHESIS + {0x1DA9B, 0x1DA9F, prCM, gcMn}, // [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prCM, gcMn}, // [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1DF00, 0x1DF09, prAL, gcLl}, // [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK + {0x1DF0A, 0x1DF0A, prAL, gcLo}, // LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK + {0x1DF0B, 0x1DF1E, prAL, gcLl}, // [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL + {0x1DF25, 0x1DF2A, prAL, gcLl}, // [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK + {0x1E000, 0x1E006, prCM, gcMn}, // [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prCM, gcMn}, // [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prCM, gcMn}, // [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prCM, gcMn}, // [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prCM, gcMn}, // [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E030, 0x1E06D, prAL, gcLm}, // [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE + {0x1E08F, 0x1E08F, prCM, gcMn}, // COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E100, 0x1E12C, prAL, gcLo}, // [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W + {0x1E130, 0x1E136, prCM, gcMn}, // [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E137, 0x1E13D, prAL, gcLm}, // [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER + {0x1E140, 0x1E149, prNU, gcNd}, // [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE + {0x1E14E, 0x1E14E, prAL, gcLo}, // NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ + {0x1E14F, 0x1E14F, prAL, gcSo}, // NYIAKENG PUACHUE HMONG CIRCLED CA + {0x1E290, 0x1E2AD, prAL, gcLo}, // [30] TOTO LETTER PA..TOTO LETTER A + {0x1E2AE, 0x1E2AE, prCM, gcMn}, // TOTO SIGN RISING TONE + {0x1E2C0, 0x1E2EB, prAL, gcLo}, // [44] WANCHO LETTER AA..WANCHO LETTER YIH + {0x1E2EC, 0x1E2EF, prCM, gcMn}, // [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E2F0, 0x1E2F9, prNU, gcNd}, // [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE + {0x1E2FF, 0x1E2FF, prPR, gcSc}, // WANCHO NGUN SIGN + {0x1E4D0, 0x1E4EA, prAL, gcLo}, // [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL + {0x1E4EB, 0x1E4EB, prAL, gcLm}, // NAG MUNDARI SIGN OJOD + {0x1E4EC, 0x1E4EF, prCM, gcMn}, // [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E4F0, 0x1E4F9, prNU, gcNd}, // [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE + {0x1E7E0, 0x1E7E6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO + {0x1E7E8, 0x1E7EB, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE + {0x1E7ED, 0x1E7EE, prAL, gcLo}, // [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE + {0x1E7F0, 0x1E7FE, prAL, gcLo}, // [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE + {0x1E800, 0x1E8C4, prAL, gcLo}, // [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON + {0x1E8C7, 0x1E8CF, prAL, gcNo}, // [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE + {0x1E8D0, 0x1E8D6, prCM, gcMn}, // [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E900, 0x1E943, prAL, gcLC}, // [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA + {0x1E944, 0x1E94A, prCM, gcMn}, // [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1E94B, 0x1E94B, prAL, gcLm}, // ADLAM NASALIZATION MARK + {0x1E950, 0x1E959, prNU, gcNd}, // [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE + {0x1E95E, 0x1E95F, prOP, gcPo}, // [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK + {0x1EC71, 0x1ECAB, prAL, gcNo}, // [59] INDIC SIYAQ NUMBER ONE..INDIC SIYAQ NUMBER PREFIXED NINE + {0x1ECAC, 0x1ECAC, prPO, gcSo}, // INDIC SIYAQ PLACEHOLDER + {0x1ECAD, 0x1ECAF, prAL, gcNo}, // [3] INDIC SIYAQ FRACTION ONE QUARTER..INDIC SIYAQ FRACTION THREE QUARTERS + {0x1ECB0, 0x1ECB0, prPO, gcSc}, // INDIC SIYAQ RUPEE MARK + {0x1ECB1, 0x1ECB4, prAL, gcNo}, // [4] INDIC SIYAQ NUMBER ALTERNATE ONE..INDIC SIYAQ ALTERNATE LAKH MARK + {0x1ED01, 0x1ED2D, prAL, gcNo}, // [45] OTTOMAN SIYAQ NUMBER ONE..OTTOMAN SIYAQ NUMBER NINETY THOUSAND + {0x1ED2E, 0x1ED2E, prAL, gcSo}, // OTTOMAN SIYAQ MARRATAN + {0x1ED2F, 0x1ED3D, prAL, gcNo}, // [15] OTTOMAN SIYAQ ALTERNATE NUMBER TWO..OTTOMAN SIYAQ FRACTION ONE SIXTH + {0x1EE00, 0x1EE03, prAL, gcLo}, // [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL + {0x1EE05, 0x1EE1F, prAL, gcLo}, // [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF + {0x1EE21, 0x1EE22, prAL, gcLo}, // [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM + {0x1EE24, 0x1EE24, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL HEH + {0x1EE27, 0x1EE27, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL HAH + {0x1EE29, 0x1EE32, prAL, gcLo}, // [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF + {0x1EE34, 0x1EE37, prAL, gcLo}, // [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH + {0x1EE39, 0x1EE39, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL DAD + {0x1EE3B, 0x1EE3B, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL GHAIN + {0x1EE42, 0x1EE42, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED JEEM + {0x1EE47, 0x1EE47, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED HAH + {0x1EE49, 0x1EE49, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED YEH + {0x1EE4B, 0x1EE4B, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED LAM + {0x1EE4D, 0x1EE4F, prAL, gcLo}, // [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN + {0x1EE51, 0x1EE52, prAL, gcLo}, // [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF + {0x1EE54, 0x1EE54, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED SHEEN + {0x1EE57, 0x1EE57, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED KHAH + {0x1EE59, 0x1EE59, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED DAD + {0x1EE5B, 0x1EE5B, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED GHAIN + {0x1EE5D, 0x1EE5D, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED DOTLESS NOON + {0x1EE5F, 0x1EE5F, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED DOTLESS QAF + {0x1EE61, 0x1EE62, prAL, gcLo}, // [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM + {0x1EE64, 0x1EE64, prAL, gcLo}, // ARABIC MATHEMATICAL STRETCHED HEH + {0x1EE67, 0x1EE6A, prAL, gcLo}, // [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF + {0x1EE6C, 0x1EE72, prAL, gcLo}, // [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF + {0x1EE74, 0x1EE77, prAL, gcLo}, // [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH + {0x1EE79, 0x1EE7C, prAL, gcLo}, // [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH + {0x1EE7E, 0x1EE7E, prAL, gcLo}, // ARABIC MATHEMATICAL STRETCHED DOTLESS FEH + {0x1EE80, 0x1EE89, prAL, gcLo}, // [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH + {0x1EE8B, 0x1EE9B, prAL, gcLo}, // [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN + {0x1EEA1, 0x1EEA3, prAL, gcLo}, // [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL + {0x1EEA5, 0x1EEA9, prAL, gcLo}, // [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH + {0x1EEAB, 0x1EEBB, prAL, gcLo}, // [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN + {0x1EEF0, 0x1EEF1, prAL, gcSm}, // [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL + {0x1F000, 0x1F02B, prID, gcSo}, // [44] MAHJONG TILE EAST WIND..MAHJONG TILE BACK + {0x1F02C, 0x1F02F, prID, gcCn}, // [4] .. + {0x1F030, 0x1F093, prID, gcSo}, // [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06 + {0x1F094, 0x1F09F, prID, gcCn}, // [12] .. + {0x1F0A0, 0x1F0AE, prID, gcSo}, // [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES + {0x1F0AF, 0x1F0B0, prID, gcCn}, // [2] .. + {0x1F0B1, 0x1F0BF, prID, gcSo}, // [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER + {0x1F0C0, 0x1F0C0, prID, gcCn}, // + {0x1F0C1, 0x1F0CF, prID, gcSo}, // [15] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD BLACK JOKER + {0x1F0D0, 0x1F0D0, prID, gcCn}, // + {0x1F0D1, 0x1F0F5, prID, gcSo}, // [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21 + {0x1F0F6, 0x1F0FF, prID, gcCn}, // [10] .. + {0x1F100, 0x1F10C, prAI, gcNo}, // [13] DIGIT ZERO FULL STOP..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO + {0x1F10D, 0x1F10F, prID, gcSo}, // [3] CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH + {0x1F110, 0x1F12D, prAI, gcSo}, // [30] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED CD + {0x1F12E, 0x1F12F, prAL, gcSo}, // [2] CIRCLED WZ..COPYLEFT SYMBOL + {0x1F130, 0x1F169, prAI, gcSo}, // [58] SQUARED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z + {0x1F16A, 0x1F16C, prAL, gcSo}, // [3] RAISED MC SIGN..RAISED MR SIGN + {0x1F16D, 0x1F16F, prID, gcSo}, // [3] CIRCLED CC..CIRCLED HUMAN FIGURE + {0x1F170, 0x1F1AC, prAI, gcSo}, // [61] NEGATIVE SQUARED LATIN CAPITAL LETTER A..SQUARED VOD + {0x1F1AD, 0x1F1AD, prID, gcSo}, // MASK WORK SYMBOL + {0x1F1AE, 0x1F1E5, prID, gcCn}, // [56] .. + {0x1F1E6, 0x1F1FF, prRI, gcSo}, // [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z + {0x1F200, 0x1F202, prID, gcSo}, // [3] SQUARE HIRAGANA HOKA..SQUARED KATAKANA SA + {0x1F203, 0x1F20F, prID, gcCn}, // [13] .. + {0x1F210, 0x1F23B, prID, gcSo}, // [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D + {0x1F23C, 0x1F23F, prID, gcCn}, // [4] .. + {0x1F240, 0x1F248, prID, gcSo}, // [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 + {0x1F249, 0x1F24F, prID, gcCn}, // [7] .. + {0x1F250, 0x1F251, prID, gcSo}, // [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT + {0x1F252, 0x1F25F, prID, gcCn}, // [14] .. + {0x1F260, 0x1F265, prID, gcSo}, // [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI + {0x1F266, 0x1F2FF, prID, gcCn}, // [154] .. + {0x1F300, 0x1F384, prID, gcSo}, // [133] CYCLONE..CHRISTMAS TREE + {0x1F385, 0x1F385, prEB, gcSo}, // FATHER CHRISTMAS + {0x1F386, 0x1F39B, prID, gcSo}, // [22] FIREWORKS..CONTROL KNOBS + {0x1F39C, 0x1F39D, prAL, gcSo}, // [2] BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES + {0x1F39E, 0x1F3B4, prID, gcSo}, // [23] FILM FRAMES..FLOWER PLAYING CARDS + {0x1F3B5, 0x1F3B6, prAL, gcSo}, // [2] MUSICAL NOTE..MULTIPLE MUSICAL NOTES + {0x1F3B7, 0x1F3BB, prID, gcSo}, // [5] SAXOPHONE..VIOLIN + {0x1F3BC, 0x1F3BC, prAL, gcSo}, // MUSICAL SCORE + {0x1F3BD, 0x1F3C1, prID, gcSo}, // [5] RUNNING SHIRT WITH SASH..CHEQUERED FLAG + {0x1F3C2, 0x1F3C4, prEB, gcSo}, // [3] SNOWBOARDER..SURFER + {0x1F3C5, 0x1F3C6, prID, gcSo}, // [2] SPORTS MEDAL..TROPHY + {0x1F3C7, 0x1F3C7, prEB, gcSo}, // HORSE RACING + {0x1F3C8, 0x1F3C9, prID, gcSo}, // [2] AMERICAN FOOTBALL..RUGBY FOOTBALL + {0x1F3CA, 0x1F3CC, prEB, gcSo}, // [3] SWIMMER..GOLFER + {0x1F3CD, 0x1F3FA, prID, gcSo}, // [46] RACING MOTORCYCLE..AMPHORA + {0x1F3FB, 0x1F3FF, prEM, gcSk}, // [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + {0x1F400, 0x1F441, prID, gcSo}, // [66] RAT..EYE + {0x1F442, 0x1F443, prEB, gcSo}, // [2] EAR..NOSE + {0x1F444, 0x1F445, prID, gcSo}, // [2] MOUTH..TONGUE + {0x1F446, 0x1F450, prEB, gcSo}, // [11] WHITE UP POINTING BACKHAND INDEX..OPEN HANDS SIGN + {0x1F451, 0x1F465, prID, gcSo}, // [21] CROWN..BUSTS IN SILHOUETTE + {0x1F466, 0x1F478, prEB, gcSo}, // [19] BOY..PRINCESS + {0x1F479, 0x1F47B, prID, gcSo}, // [3] JAPANESE OGRE..GHOST + {0x1F47C, 0x1F47C, prEB, gcSo}, // BABY ANGEL + {0x1F47D, 0x1F480, prID, gcSo}, // [4] EXTRATERRESTRIAL ALIEN..SKULL + {0x1F481, 0x1F483, prEB, gcSo}, // [3] INFORMATION DESK PERSON..DANCER + {0x1F484, 0x1F484, prID, gcSo}, // LIPSTICK + {0x1F485, 0x1F487, prEB, gcSo}, // [3] NAIL POLISH..HAIRCUT + {0x1F488, 0x1F48E, prID, gcSo}, // [7] BARBER POLE..GEM STONE + {0x1F48F, 0x1F48F, prEB, gcSo}, // KISS + {0x1F490, 0x1F490, prID, gcSo}, // BOUQUET + {0x1F491, 0x1F491, prEB, gcSo}, // COUPLE WITH HEART + {0x1F492, 0x1F49F, prID, gcSo}, // [14] WEDDING..HEART DECORATION + {0x1F4A0, 0x1F4A0, prAL, gcSo}, // DIAMOND SHAPE WITH A DOT INSIDE + {0x1F4A1, 0x1F4A1, prID, gcSo}, // ELECTRIC LIGHT BULB + {0x1F4A2, 0x1F4A2, prAL, gcSo}, // ANGER SYMBOL + {0x1F4A3, 0x1F4A3, prID, gcSo}, // BOMB + {0x1F4A4, 0x1F4A4, prAL, gcSo}, // SLEEPING SYMBOL + {0x1F4A5, 0x1F4A9, prID, gcSo}, // [5] COLLISION SYMBOL..PILE OF POO + {0x1F4AA, 0x1F4AA, prEB, gcSo}, // FLEXED BICEPS + {0x1F4AB, 0x1F4AE, prID, gcSo}, // [4] DIZZY SYMBOL..WHITE FLOWER + {0x1F4AF, 0x1F4AF, prAL, gcSo}, // HUNDRED POINTS SYMBOL + {0x1F4B0, 0x1F4B0, prID, gcSo}, // MONEY BAG + {0x1F4B1, 0x1F4B2, prAL, gcSo}, // [2] CURRENCY EXCHANGE..HEAVY DOLLAR SIGN + {0x1F4B3, 0x1F4FF, prID, gcSo}, // [77] CREDIT CARD..PRAYER BEADS + {0x1F500, 0x1F506, prAL, gcSo}, // [7] TWISTED RIGHTWARDS ARROWS..HIGH BRIGHTNESS SYMBOL + {0x1F507, 0x1F516, prID, gcSo}, // [16] SPEAKER WITH CANCELLATION STROKE..BOOKMARK + {0x1F517, 0x1F524, prAL, gcSo}, // [14] LINK SYMBOL..INPUT SYMBOL FOR LATIN LETTERS + {0x1F525, 0x1F531, prID, gcSo}, // [13] FIRE..TRIDENT EMBLEM + {0x1F532, 0x1F549, prAL, gcSo}, // [24] BLACK SQUARE BUTTON..OM SYMBOL + {0x1F54A, 0x1F573, prID, gcSo}, // [42] DOVE OF PEACE..HOLE + {0x1F574, 0x1F575, prEB, gcSo}, // [2] MAN IN BUSINESS SUIT LEVITATING..SLEUTH OR SPY + {0x1F576, 0x1F579, prID, gcSo}, // [4] DARK SUNGLASSES..JOYSTICK + {0x1F57A, 0x1F57A, prEB, gcSo}, // MAN DANCING + {0x1F57B, 0x1F58F, prID, gcSo}, // [21] LEFT HAND TELEPHONE RECEIVER..TURNED OK HAND SIGN + {0x1F590, 0x1F590, prEB, gcSo}, // RAISED HAND WITH FINGERS SPLAYED + {0x1F591, 0x1F594, prID, gcSo}, // [4] REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND + {0x1F595, 0x1F596, prEB, gcSo}, // [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS + {0x1F597, 0x1F5D3, prID, gcSo}, // [61] WHITE DOWN POINTING LEFT HAND INDEX..SPIRAL CALENDAR PAD + {0x1F5D4, 0x1F5DB, prAL, gcSo}, // [8] DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL + {0x1F5DC, 0x1F5F3, prID, gcSo}, // [24] COMPRESSION..BALLOT BOX WITH BALLOT + {0x1F5F4, 0x1F5F9, prAL, gcSo}, // [6] BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK + {0x1F5FA, 0x1F5FF, prID, gcSo}, // [6] WORLD MAP..MOYAI + {0x1F600, 0x1F644, prID, gcSo}, // [69] GRINNING FACE..FACE WITH ROLLING EYES + {0x1F645, 0x1F647, prEB, gcSo}, // [3] FACE WITH NO GOOD GESTURE..PERSON BOWING DEEPLY + {0x1F648, 0x1F64A, prID, gcSo}, // [3] SEE-NO-EVIL MONKEY..SPEAK-NO-EVIL MONKEY + {0x1F64B, 0x1F64F, prEB, gcSo}, // [5] HAPPY PERSON RAISING ONE HAND..PERSON WITH FOLDED HANDS + {0x1F650, 0x1F675, prAL, gcSo}, // [38] NORTH WEST POINTING LEAF..SWASH AMPERSAND ORNAMENT + {0x1F676, 0x1F678, prQU, gcSo}, // [3] SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT..SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT + {0x1F679, 0x1F67B, prNS, gcSo}, // [3] HEAVY INTERROBANG ORNAMENT..HEAVY SANS-SERIF INTERROBANG ORNAMENT + {0x1F67C, 0x1F67F, prAL, gcSo}, // [4] VERY HEAVY SOLIDUS..REVERSE CHECKER BOARD + {0x1F680, 0x1F6A2, prID, gcSo}, // [35] ROCKET..SHIP + {0x1F6A3, 0x1F6A3, prEB, gcSo}, // ROWBOAT + {0x1F6A4, 0x1F6B3, prID, gcSo}, // [16] SPEEDBOAT..NO BICYCLES + {0x1F6B4, 0x1F6B6, prEB, gcSo}, // [3] BICYCLIST..PEDESTRIAN + {0x1F6B7, 0x1F6BF, prID, gcSo}, // [9] NO PEDESTRIANS..SHOWER + {0x1F6C0, 0x1F6C0, prEB, gcSo}, // BATH + {0x1F6C1, 0x1F6CB, prID, gcSo}, // [11] BATHTUB..COUCH AND LAMP + {0x1F6CC, 0x1F6CC, prEB, gcSo}, // SLEEPING ACCOMMODATION + {0x1F6CD, 0x1F6D7, prID, gcSo}, // [11] SHOPPING BAGS..ELEVATOR + {0x1F6D8, 0x1F6DB, prID, gcCn}, // [4] .. + {0x1F6DC, 0x1F6EC, prID, gcSo}, // [17] WIRELESS..AIRPLANE ARRIVING + {0x1F6ED, 0x1F6EF, prID, gcCn}, // [3] .. + {0x1F6F0, 0x1F6FC, prID, gcSo}, // [13] SATELLITE..ROLLER SKATE + {0x1F6FD, 0x1F6FF, prID, gcCn}, // [3] .. + {0x1F700, 0x1F773, prAL, gcSo}, // [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE + {0x1F774, 0x1F776, prID, gcSo}, // [3] LOT OF FORTUNE..LUNAR ECLIPSE + {0x1F777, 0x1F77A, prID, gcCn}, // [4] .. + {0x1F77B, 0x1F77F, prID, gcSo}, // [5] HAUMEA..ORCUS + {0x1F780, 0x1F7D4, prAL, gcSo}, // [85] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..HEAVY TWELVE POINTED PINWHEEL STAR + {0x1F7D5, 0x1F7D9, prID, gcSo}, // [5] CIRCLED TRIANGLE..NINE POINTED WHITE STAR + {0x1F7DA, 0x1F7DF, prID, gcCn}, // [6] .. + {0x1F7E0, 0x1F7EB, prID, gcSo}, // [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE + {0x1F7EC, 0x1F7EF, prID, gcCn}, // [4] .. + {0x1F7F0, 0x1F7F0, prID, gcSo}, // HEAVY EQUALS SIGN + {0x1F7F1, 0x1F7FF, prID, gcCn}, // [15] .. + {0x1F800, 0x1F80B, prAL, gcSo}, // [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD + {0x1F80C, 0x1F80F, prID, gcCn}, // [4] .. + {0x1F810, 0x1F847, prAL, gcSo}, // [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW + {0x1F848, 0x1F84F, prID, gcCn}, // [8] .. + {0x1F850, 0x1F859, prAL, gcSo}, // [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW + {0x1F85A, 0x1F85F, prID, gcCn}, // [6] .. + {0x1F860, 0x1F887, prAL, gcSo}, // [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW + {0x1F888, 0x1F88F, prID, gcCn}, // [8] .. + {0x1F890, 0x1F8AD, prAL, gcSo}, // [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS + {0x1F8AE, 0x1F8AF, prID, gcCn}, // [2] .. + {0x1F8B0, 0x1F8B1, prID, gcSo}, // [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST + {0x1F8B2, 0x1F8FF, prID, gcCn}, // [78] .. + {0x1F900, 0x1F90B, prAL, gcSo}, // [12] CIRCLED CROSS FORMEE WITH FOUR DOTS..DOWNWARD FACING NOTCHED HOOK WITH DOT + {0x1F90C, 0x1F90C, prEB, gcSo}, // PINCHED FINGERS + {0x1F90D, 0x1F90E, prID, gcSo}, // [2] WHITE HEART..BROWN HEART + {0x1F90F, 0x1F90F, prEB, gcSo}, // PINCHING HAND + {0x1F910, 0x1F917, prID, gcSo}, // [8] ZIPPER-MOUTH FACE..HUGGING FACE + {0x1F918, 0x1F91F, prEB, gcSo}, // [8] SIGN OF THE HORNS..I LOVE YOU HAND SIGN + {0x1F920, 0x1F925, prID, gcSo}, // [6] FACE WITH COWBOY HAT..LYING FACE + {0x1F926, 0x1F926, prEB, gcSo}, // FACE PALM + {0x1F927, 0x1F92F, prID, gcSo}, // [9] SNEEZING FACE..SHOCKED FACE WITH EXPLODING HEAD + {0x1F930, 0x1F939, prEB, gcSo}, // [10] PREGNANT WOMAN..JUGGLING + {0x1F93A, 0x1F93B, prID, gcSo}, // [2] FENCER..MODERN PENTATHLON + {0x1F93C, 0x1F93E, prEB, gcSo}, // [3] WRESTLERS..HANDBALL + {0x1F93F, 0x1F976, prID, gcSo}, // [56] DIVING MASK..FREEZING FACE + {0x1F977, 0x1F977, prEB, gcSo}, // NINJA + {0x1F978, 0x1F9B4, prID, gcSo}, // [61] DISGUISED FACE..BONE + {0x1F9B5, 0x1F9B6, prEB, gcSo}, // [2] LEG..FOOT + {0x1F9B7, 0x1F9B7, prID, gcSo}, // TOOTH + {0x1F9B8, 0x1F9B9, prEB, gcSo}, // [2] SUPERHERO..SUPERVILLAIN + {0x1F9BA, 0x1F9BA, prID, gcSo}, // SAFETY VEST + {0x1F9BB, 0x1F9BB, prEB, gcSo}, // EAR WITH HEARING AID + {0x1F9BC, 0x1F9CC, prID, gcSo}, // [17] MOTORIZED WHEELCHAIR..TROLL + {0x1F9CD, 0x1F9CF, prEB, gcSo}, // [3] STANDING PERSON..DEAF PERSON + {0x1F9D0, 0x1F9D0, prID, gcSo}, // FACE WITH MONOCLE + {0x1F9D1, 0x1F9DD, prEB, gcSo}, // [13] ADULT..ELF + {0x1F9DE, 0x1F9FF, prID, gcSo}, // [34] GENIE..NAZAR AMULET + {0x1FA00, 0x1FA53, prAL, gcSo}, // [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP + {0x1FA54, 0x1FA5F, prID, gcCn}, // [12] .. + {0x1FA60, 0x1FA6D, prID, gcSo}, // [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER + {0x1FA6E, 0x1FA6F, prID, gcCn}, // [2] .. + {0x1FA70, 0x1FA7C, prID, gcSo}, // [13] BALLET SHOES..CRUTCH + {0x1FA7D, 0x1FA7F, prID, gcCn}, // [3] .. + {0x1FA80, 0x1FA88, prID, gcSo}, // [9] YO-YO..FLUTE + {0x1FA89, 0x1FA8F, prID, gcCn}, // [7] .. + {0x1FA90, 0x1FABD, prID, gcSo}, // [46] RINGED PLANET..WING + {0x1FABE, 0x1FABE, prID, gcCn}, // + {0x1FABF, 0x1FAC2, prID, gcSo}, // [4] GOOSE..PEOPLE HUGGING + {0x1FAC3, 0x1FAC5, prEB, gcSo}, // [3] PREGNANT MAN..PERSON WITH CROWN + {0x1FAC6, 0x1FACD, prID, gcCn}, // [8] .. + {0x1FACE, 0x1FADB, prID, gcSo}, // [14] MOOSE..PEA POD + {0x1FADC, 0x1FADF, prID, gcCn}, // [4] .. + {0x1FAE0, 0x1FAE8, prID, gcSo}, // [9] MELTING FACE..SHAKING FACE + {0x1FAE9, 0x1FAEF, prID, gcCn}, // [7] .. + {0x1FAF0, 0x1FAF8, prEB, gcSo}, // [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND + {0x1FAF9, 0x1FAFF, prID, gcCn}, // [7] .. + {0x1FB00, 0x1FB92, prAL, gcSo}, // [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK + {0x1FB94, 0x1FBCA, prAL, gcSo}, // [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON + {0x1FBF0, 0x1FBF9, prNU, gcNd}, // [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE + {0x1FC00, 0x1FFFD, prID, gcCn}, // [1022] .. + {0x20000, 0x2A6DF, prID, gcLo}, // [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF + {0x2A6E0, 0x2A6FF, prID, gcCn}, // [32] .. + {0x2A700, 0x2B739, prID, gcLo}, // [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739 + {0x2B73A, 0x2B73F, prID, gcCn}, // [6] .. + {0x2B740, 0x2B81D, prID, gcLo}, // [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D + {0x2B81E, 0x2B81F, prID, gcCn}, // [2] .. + {0x2B820, 0x2CEA1, prID, gcLo}, // [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 + {0x2CEA2, 0x2CEAF, prID, gcCn}, // [14] .. + {0x2CEB0, 0x2EBE0, prID, gcLo}, // [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 + {0x2EBE1, 0x2F7FF, prID, gcCn}, // [3103] .. + {0x2F800, 0x2FA1D, prID, gcLo}, // [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + {0x2FA1E, 0x2FA1F, prID, gcCn}, // [2] .. + {0x2FA20, 0x2FFFD, prID, gcCn}, // [1502] .. + {0x30000, 0x3134A, prID, gcLo}, // [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A + {0x3134B, 0x3134F, prID, gcCn}, // [5] .. + {0x31350, 0x323AF, prID, gcLo}, // [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF + {0x323B0, 0x3FFFD, prID, gcCn}, // [56398] .. + {0xE0001, 0xE0001, prCM, gcCf}, // LANGUAGE TAG + {0xE0020, 0xE007F, prCM, gcCf}, // [96] TAG SPACE..CANCEL TAG + {0xE0100, 0xE01EF, prCM, gcMn}, // [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + {0xF0000, 0xFFFFD, prXX, gcCo}, // [65534] .. + {0x100000, 0x10FFFD, prXX, gcCo}, // [65534] .. +} diff --git a/vendor/github.com/rivo/uniseg/linerules.go b/vendor/github.com/rivo/uniseg/linerules.go new file mode 100644 index 000000000..7708ae0fb --- /dev/null +++ b/vendor/github.com/rivo/uniseg/linerules.go @@ -0,0 +1,626 @@ +package uniseg + +import "unicode/utf8" + +// The states of the line break parser. +const ( + lbAny = iota + lbBK + lbCR + lbLF + lbNL + lbSP + lbZW + lbWJ + lbGL + lbBA + lbHY + lbCL + lbCP + lbEX + lbIS + lbSY + lbOP + lbQU + lbQUSP + lbNS + lbCLCPSP + lbB2 + lbB2SP + lbCB + lbBB + lbLB21a + lbHL + lbAL + lbNU + lbPR + lbEB + lbIDEM + lbNUNU + lbNUSY + lbNUIS + lbNUCL + lbNUCP + lbPO + lbJL + lbJV + lbJT + lbH2 + lbH3 + lbOddRI + lbEvenRI + lbExtPicCn + lbZWJBit = 64 + lbCPeaFWHBit = 128 +) + +// These constants define whether a given text may be broken into the next line. +// If the break is optional (LineCanBreak), you may choose to break or not based +// on your own criteria, for example, if the text has reached the available +// width. +const ( + LineDontBreak = iota // You may not break the line here. + LineCanBreak // You may or may not break the line here. + LineMustBreak // You must break the line here. +) + +// lbTransitions implements the line break parser's state transitions. It's +// anologous to [grTransitions], see comments there for details. +// +// Unicode version 15.0.0. +func lbTransitions(state, prop int) (newState, lineBreak, rule int) { + switch uint64(state) | uint64(prop)<<32 { + // LB4. + case lbBK | prAny<<32: + return lbAny, LineMustBreak, 40 + + // LB5. + case lbCR | prLF<<32: + return lbLF, LineDontBreak, 50 + case lbCR | prAny<<32: + return lbAny, LineMustBreak, 50 + case lbLF | prAny<<32: + return lbAny, LineMustBreak, 50 + case lbNL | prAny<<32: + return lbAny, LineMustBreak, 50 + + // LB6. + case lbAny | prBK<<32: + return lbBK, LineDontBreak, 60 + case lbAny | prCR<<32: + return lbCR, LineDontBreak, 60 + case lbAny | prLF<<32: + return lbLF, LineDontBreak, 60 + case lbAny | prNL<<32: + return lbNL, LineDontBreak, 60 + + // LB7. + case lbAny | prSP<<32: + return lbSP, LineDontBreak, 70 + case lbAny | prZW<<32: + return lbZW, LineDontBreak, 70 + + // LB8. + case lbZW | prSP<<32: + return lbZW, LineDontBreak, 70 + case lbZW | prAny<<32: + return lbAny, LineCanBreak, 80 + + // LB11. + case lbAny | prWJ<<32: + return lbWJ, LineDontBreak, 110 + case lbWJ | prAny<<32: + return lbAny, LineDontBreak, 110 + + // LB12. + case lbAny | prGL<<32: + return lbGL, LineCanBreak, 310 + case lbGL | prAny<<32: + return lbAny, LineDontBreak, 120 + + // LB13 (simple transitions). + case lbAny | prCL<<32: + return lbCL, LineCanBreak, 310 + case lbAny | prCP<<32: + return lbCP, LineCanBreak, 310 + case lbAny | prEX<<32: + return lbEX, LineDontBreak, 130 + case lbAny | prIS<<32: + return lbIS, LineCanBreak, 310 + case lbAny | prSY<<32: + return lbSY, LineCanBreak, 310 + + // LB14. + case lbAny | prOP<<32: + return lbOP, LineCanBreak, 310 + case lbOP | prSP<<32: + return lbOP, LineDontBreak, 70 + case lbOP | prAny<<32: + return lbAny, LineDontBreak, 140 + + // LB15. + case lbQU | prSP<<32: + return lbQUSP, LineDontBreak, 70 + case lbQU | prOP<<32: + return lbOP, LineDontBreak, 150 + case lbQUSP | prOP<<32: + return lbOP, LineDontBreak, 150 + + // LB16. + case lbCL | prSP<<32: + return lbCLCPSP, LineDontBreak, 70 + case lbNUCL | prSP<<32: + return lbCLCPSP, LineDontBreak, 70 + case lbCP | prSP<<32: + return lbCLCPSP, LineDontBreak, 70 + case lbNUCP | prSP<<32: + return lbCLCPSP, LineDontBreak, 70 + case lbCL | prNS<<32: + return lbNS, LineDontBreak, 160 + case lbNUCL | prNS<<32: + return lbNS, LineDontBreak, 160 + case lbCP | prNS<<32: + return lbNS, LineDontBreak, 160 + case lbNUCP | prNS<<32: + return lbNS, LineDontBreak, 160 + case lbCLCPSP | prNS<<32: + return lbNS, LineDontBreak, 160 + + // LB17. + case lbAny | prB2<<32: + return lbB2, LineCanBreak, 310 + case lbB2 | prSP<<32: + return lbB2SP, LineDontBreak, 70 + case lbB2 | prB2<<32: + return lbB2, LineDontBreak, 170 + case lbB2SP | prB2<<32: + return lbB2, LineDontBreak, 170 + + // LB18. + case lbSP | prAny<<32: + return lbAny, LineCanBreak, 180 + case lbQUSP | prAny<<32: + return lbAny, LineCanBreak, 180 + case lbCLCPSP | prAny<<32: + return lbAny, LineCanBreak, 180 + case lbB2SP | prAny<<32: + return lbAny, LineCanBreak, 180 + + // LB19. + case lbAny | prQU<<32: + return lbQU, LineDontBreak, 190 + case lbQU | prAny<<32: + return lbAny, LineDontBreak, 190 + + // LB20. + case lbAny | prCB<<32: + return lbCB, LineCanBreak, 200 + case lbCB | prAny<<32: + return lbAny, LineCanBreak, 200 + + // LB21. + case lbAny | prBA<<32: + return lbBA, LineDontBreak, 210 + case lbAny | prHY<<32: + return lbHY, LineDontBreak, 210 + case lbAny | prNS<<32: + return lbNS, LineDontBreak, 210 + case lbAny | prBB<<32: + return lbBB, LineCanBreak, 310 + case lbBB | prAny<<32: + return lbAny, LineDontBreak, 210 + + // LB21a. + case lbAny | prHL<<32: + return lbHL, LineCanBreak, 310 + case lbHL | prHY<<32: + return lbLB21a, LineDontBreak, 210 + case lbHL | prBA<<32: + return lbLB21a, LineDontBreak, 210 + case lbLB21a | prAny<<32: + return lbAny, LineDontBreak, 211 + + // LB21b. + case lbSY | prHL<<32: + return lbHL, LineDontBreak, 212 + case lbNUSY | prHL<<32: + return lbHL, LineDontBreak, 212 + + // LB22. + case lbAny | prIN<<32: + return lbAny, LineDontBreak, 220 + + // LB23. + case lbAny | prAL<<32: + return lbAL, LineCanBreak, 310 + case lbAny | prNU<<32: + return lbNU, LineCanBreak, 310 + case lbAL | prNU<<32: + return lbNU, LineDontBreak, 230 + case lbHL | prNU<<32: + return lbNU, LineDontBreak, 230 + case lbNU | prAL<<32: + return lbAL, LineDontBreak, 230 + case lbNU | prHL<<32: + return lbHL, LineDontBreak, 230 + case lbNUNU | prAL<<32: + return lbAL, LineDontBreak, 230 + case lbNUNU | prHL<<32: + return lbHL, LineDontBreak, 230 + + // LB23a. + case lbAny | prPR<<32: + return lbPR, LineCanBreak, 310 + case lbAny | prID<<32: + return lbIDEM, LineCanBreak, 310 + case lbAny | prEB<<32: + return lbEB, LineCanBreak, 310 + case lbAny | prEM<<32: + return lbIDEM, LineCanBreak, 310 + case lbPR | prID<<32: + return lbIDEM, LineDontBreak, 231 + case lbPR | prEB<<32: + return lbEB, LineDontBreak, 231 + case lbPR | prEM<<32: + return lbIDEM, LineDontBreak, 231 + case lbIDEM | prPO<<32: + return lbPO, LineDontBreak, 231 + case lbEB | prPO<<32: + return lbPO, LineDontBreak, 231 + + // LB24. + case lbAny | prPO<<32: + return lbPO, LineCanBreak, 310 + case lbPR | prAL<<32: + return lbAL, LineDontBreak, 240 + case lbPR | prHL<<32: + return lbHL, LineDontBreak, 240 + case lbPO | prAL<<32: + return lbAL, LineDontBreak, 240 + case lbPO | prHL<<32: + return lbHL, LineDontBreak, 240 + case lbAL | prPR<<32: + return lbPR, LineDontBreak, 240 + case lbAL | prPO<<32: + return lbPO, LineDontBreak, 240 + case lbHL | prPR<<32: + return lbPR, LineDontBreak, 240 + case lbHL | prPO<<32: + return lbPO, LineDontBreak, 240 + + // LB25 (simple transitions). + case lbPR | prNU<<32: + return lbNU, LineDontBreak, 250 + case lbPO | prNU<<32: + return lbNU, LineDontBreak, 250 + case lbOP | prNU<<32: + return lbNU, LineDontBreak, 250 + case lbHY | prNU<<32: + return lbNU, LineDontBreak, 250 + case lbNU | prNU<<32: + return lbNUNU, LineDontBreak, 250 + case lbNU | prSY<<32: + return lbNUSY, LineDontBreak, 250 + case lbNU | prIS<<32: + return lbNUIS, LineDontBreak, 250 + case lbNUNU | prNU<<32: + return lbNUNU, LineDontBreak, 250 + case lbNUNU | prSY<<32: + return lbNUSY, LineDontBreak, 250 + case lbNUNU | prIS<<32: + return lbNUIS, LineDontBreak, 250 + case lbNUSY | prNU<<32: + return lbNUNU, LineDontBreak, 250 + case lbNUSY | prSY<<32: + return lbNUSY, LineDontBreak, 250 + case lbNUSY | prIS<<32: + return lbNUIS, LineDontBreak, 250 + case lbNUIS | prNU<<32: + return lbNUNU, LineDontBreak, 250 + case lbNUIS | prSY<<32: + return lbNUSY, LineDontBreak, 250 + case lbNUIS | prIS<<32: + return lbNUIS, LineDontBreak, 250 + case lbNU | prCL<<32: + return lbNUCL, LineDontBreak, 250 + case lbNU | prCP<<32: + return lbNUCP, LineDontBreak, 250 + case lbNUNU | prCL<<32: + return lbNUCL, LineDontBreak, 250 + case lbNUNU | prCP<<32: + return lbNUCP, LineDontBreak, 250 + case lbNUSY | prCL<<32: + return lbNUCL, LineDontBreak, 250 + case lbNUSY | prCP<<32: + return lbNUCP, LineDontBreak, 250 + case lbNUIS | prCL<<32: + return lbNUCL, LineDontBreak, 250 + case lbNUIS | prCP<<32: + return lbNUCP, LineDontBreak, 250 + case lbNU | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUNU | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUSY | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUIS | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUCL | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNUCP | prPO<<32: + return lbPO, LineDontBreak, 250 + case lbNU | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUNU | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUSY | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUIS | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUCL | prPR<<32: + return lbPR, LineDontBreak, 250 + case lbNUCP | prPR<<32: + return lbPR, LineDontBreak, 250 + + // LB26. + case lbAny | prJL<<32: + return lbJL, LineCanBreak, 310 + case lbAny | prJV<<32: + return lbJV, LineCanBreak, 310 + case lbAny | prJT<<32: + return lbJT, LineCanBreak, 310 + case lbAny | prH2<<32: + return lbH2, LineCanBreak, 310 + case lbAny | prH3<<32: + return lbH3, LineCanBreak, 310 + case lbJL | prJL<<32: + return lbJL, LineDontBreak, 260 + case lbJL | prJV<<32: + return lbJV, LineDontBreak, 260 + case lbJL | prH2<<32: + return lbH2, LineDontBreak, 260 + case lbJL | prH3<<32: + return lbH3, LineDontBreak, 260 + case lbJV | prJV<<32: + return lbJV, LineDontBreak, 260 + case lbJV | prJT<<32: + return lbJT, LineDontBreak, 260 + case lbH2 | prJV<<32: + return lbJV, LineDontBreak, 260 + case lbH2 | prJT<<32: + return lbJT, LineDontBreak, 260 + case lbJT | prJT<<32: + return lbJT, LineDontBreak, 260 + case lbH3 | prJT<<32: + return lbJT, LineDontBreak, 260 + + // LB27. + case lbJL | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbJV | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbJT | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbH2 | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbH3 | prPO<<32: + return lbPO, LineDontBreak, 270 + case lbPR | prJL<<32: + return lbJL, LineDontBreak, 270 + case lbPR | prJV<<32: + return lbJV, LineDontBreak, 270 + case lbPR | prJT<<32: + return lbJT, LineDontBreak, 270 + case lbPR | prH2<<32: + return lbH2, LineDontBreak, 270 + case lbPR | prH3<<32: + return lbH3, LineDontBreak, 270 + + // LB28. + case lbAL | prAL<<32: + return lbAL, LineDontBreak, 280 + case lbAL | prHL<<32: + return lbHL, LineDontBreak, 280 + case lbHL | prAL<<32: + return lbAL, LineDontBreak, 280 + case lbHL | prHL<<32: + return lbHL, LineDontBreak, 280 + + // LB29. + case lbIS | prAL<<32: + return lbAL, LineDontBreak, 290 + case lbIS | prHL<<32: + return lbHL, LineDontBreak, 290 + case lbNUIS | prAL<<32: + return lbAL, LineDontBreak, 290 + case lbNUIS | prHL<<32: + return lbHL, LineDontBreak, 290 + + default: + return -1, -1, -1 + } +} + +// transitionLineBreakState determines the new state of the line break parser +// given the current state and the next code point. It also returns the type of +// line break: LineDontBreak, LineCanBreak, or LineMustBreak. If more than one +// code point is needed to determine the new state, the byte slice or the string +// starting after rune "r" can be used (whichever is not nil or empty) for +// further lookups. +func transitionLineBreakState(state int, r rune, b []byte, str string) (newState int, lineBreak int) { + // Determine the property of the next character. + nextProperty, generalCategory := propertyLineBreak(r) + + // Prepare. + var forceNoBreak, isCPeaFWH bool + if state >= 0 && state&lbCPeaFWHBit != 0 { + isCPeaFWH = true // LB30: CP but ea is not F, W, or H. + state = state &^ lbCPeaFWHBit + } + if state >= 0 && state&lbZWJBit != 0 { + state = state &^ lbZWJBit // Extract zero-width joiner bit. + forceNoBreak = true // LB8a. + } + + defer func() { + // Transition into LB30. + if newState == lbCP || newState == lbNUCP { + ea := propertyEastAsianWidth(r) + if ea != prF && ea != prW && ea != prH { + newState |= lbCPeaFWHBit + } + } + + // Override break. + if forceNoBreak { + lineBreak = LineDontBreak + } + }() + + // LB1. + if nextProperty == prAI || nextProperty == prSG || nextProperty == prXX { + nextProperty = prAL + } else if nextProperty == prSA { + if generalCategory == gcMn || generalCategory == gcMc { + nextProperty = prCM + } else { + nextProperty = prAL + } + } else if nextProperty == prCJ { + nextProperty = prNS + } + + // Combining marks. + if nextProperty == prZWJ || nextProperty == prCM { + var bit int + if nextProperty == prZWJ { + bit = lbZWJBit + } + mustBreakState := state < 0 || state == lbBK || state == lbCR || state == lbLF || state == lbNL + if !mustBreakState && state != lbSP && state != lbZW && state != lbQUSP && state != lbCLCPSP && state != lbB2SP { + // LB9. + return state | bit, LineDontBreak + } else { + // LB10. + if mustBreakState { + return lbAL | bit, LineMustBreak + } + return lbAL | bit, LineCanBreak + } + } + + // Find the applicable transition in the table. + var rule int + newState, lineBreak, rule = lbTransitions(state, nextProperty) + if newState < 0 { + // No specific transition found. Try the less specific ones. + anyPropProp, anyPropLineBreak, anyPropRule := lbTransitions(state, prAny) + anyStateProp, anyStateLineBreak, anyStateRule := lbTransitions(lbAny, nextProperty) + if anyPropProp >= 0 && anyStateProp >= 0 { + // Both apply. We'll use a mix (see comments for grTransitions). + newState, lineBreak, rule = anyStateProp, anyStateLineBreak, anyStateRule + if anyPropRule < anyStateRule { + lineBreak, rule = anyPropLineBreak, anyPropRule + } + } else if anyPropProp >= 0 { + // We only have a specific state. + newState, lineBreak, rule = anyPropProp, anyPropLineBreak, anyPropRule + // This branch will probably never be reached because okAnyState will + // always be true given the current transition map. But we keep it here + // for future modifications to the transition map where this may not be + // true anymore. + } else if anyStateProp >= 0 { + // We only have a specific property. + newState, lineBreak, rule = anyStateProp, anyStateLineBreak, anyStateRule + } else { + // No known transition. LB31: ALL ÷ ALL. + newState, lineBreak, rule = lbAny, LineCanBreak, 310 + } + } + + // LB12a. + if rule > 121 && + nextProperty == prGL && + (state != lbSP && state != lbBA && state != lbHY && state != lbLB21a && state != lbQUSP && state != lbCLCPSP && state != lbB2SP) { + return lbGL, LineDontBreak + } + + // LB13. + if rule > 130 && state != lbNU && state != lbNUNU { + switch nextProperty { + case prCL: + return lbCL, LineDontBreak + case prCP: + return lbCP, LineDontBreak + case prIS: + return lbIS, LineDontBreak + case prSY: + return lbSY, LineDontBreak + } + } + + // LB25 (look ahead). + if rule > 250 && + (state == lbPR || state == lbPO) && + nextProperty == prOP || nextProperty == prHY { + var r rune + if b != nil { // Byte slice version. + r, _ = utf8.DecodeRune(b) + } else { // String version. + r, _ = utf8.DecodeRuneInString(str) + } + if r != utf8.RuneError { + pr, _ := propertyLineBreak(r) + if pr == prNU { + return lbNU, LineDontBreak + } + } + } + + // LB30 (part one). + if rule > 300 { + if (state == lbAL || state == lbHL || state == lbNU || state == lbNUNU) && nextProperty == prOP { + ea := propertyEastAsianWidth(r) + if ea != prF && ea != prW && ea != prH { + return lbOP, LineDontBreak + } + } else if isCPeaFWH { + switch nextProperty { + case prAL: + return lbAL, LineDontBreak + case prHL: + return lbHL, LineDontBreak + case prNU: + return lbNU, LineDontBreak + } + } + } + + // LB30a. + if newState == lbAny && nextProperty == prRI { + if state != lbOddRI && state != lbEvenRI { // Includes state == -1. + // Transition into the first RI. + return lbOddRI, lineBreak + } + if state == lbOddRI { + // Don't break pairs of Regional Indicators. + return lbEvenRI, LineDontBreak + } + return lbOddRI, lineBreak + } + + // LB30b. + if rule > 302 { + if nextProperty == prEM { + if state == lbEB || state == lbExtPicCn { + return prAny, LineDontBreak + } + } + graphemeProperty := propertyGraphemes(r) + if graphemeProperty == prExtendedPictographic && generalCategory == gcCn { + return lbExtPicCn, LineCanBreak + } + } + + return +} diff --git a/vendor/github.com/rivo/uniseg/properties.go b/vendor/github.com/rivo/uniseg/properties.go new file mode 100644 index 000000000..6290e6810 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/properties.go @@ -0,0 +1,208 @@ +package uniseg + +// The Unicode properties as used in the various parsers. Only the ones needed +// in the context of this package are included. +const ( + prXX = 0 // Same as prAny. + prAny = iota // prAny must be 0. + prPrepend // Grapheme properties must come first, to reduce the number of bits stored in the state vector. + prCR + prLF + prControl + prExtend + prRegionalIndicator + prSpacingMark + prL + prV + prT + prLV + prLVT + prZWJ + prExtendedPictographic + prNewline + prWSegSpace + prDoubleQuote + prSingleQuote + prMidNumLet + prNumeric + prMidLetter + prMidNum + prExtendNumLet + prALetter + prFormat + prHebrewLetter + prKatakana + prSp + prSTerm + prClose + prSContinue + prATerm + prUpper + prLower + prSep + prOLetter + prCM + prBA + prBK + prSP + prEX + prQU + prAL + prPR + prPO + prOP + prCP + prIS + prHY + prSY + prNU + prCL + prNL + prGL + prAI + prBB + prHL + prSA + prJL + prJV + prJT + prNS + prZW + prB2 + prIN + prWJ + prID + prEB + prCJ + prH2 + prH3 + prSG + prCB + prRI + prEM + prN + prNa + prA + prW + prH + prF + prEmojiPresentation +) + +// Unicode General Categories. Only the ones needed in the context of this +// package are included. +const ( + gcNone = iota // gcNone must be 0. + gcCc + gcZs + gcPo + gcSc + gcPs + gcPe + gcSm + gcPd + gcNd + gcLu + gcSk + gcPc + gcLl + gcSo + gcLo + gcPi + gcCf + gcNo + gcPf + gcLC + gcLm + gcMn + gcMe + gcMc + gcNl + gcZl + gcZp + gcCn + gcCs + gcCo +) + +// Special code points. +const ( + vs15 = 0xfe0e // Variation Selector-15 (text presentation) + vs16 = 0xfe0f // Variation Selector-16 (emoji presentation) +) + +// propertySearch performs a binary search on a property slice and returns the +// entry whose range (start = first array element, end = second array element) +// includes r, or an array of 0's if no such entry was found. +func propertySearch[E interface{ [3]int | [4]int }](dictionary []E, r rune) (result E) { + // Run a binary search. + from := 0 + to := len(dictionary) + for to > from { + middle := (from + to) / 2 + cpRange := dictionary[middle] + if int(r) < cpRange[0] { + to = middle + continue + } + if int(r) > cpRange[1] { + from = middle + 1 + continue + } + return cpRange + } + return +} + +// property returns the Unicode property value (see constants above) of the +// given code point. +func property(dictionary [][3]int, r rune) int { + return propertySearch(dictionary, r)[2] +} + +// propertyLineBreak returns the Unicode property value and General Category +// (see constants above) of the given code point, as listed in the line break +// code points table, while fast tracking ASCII digits and letters. +func propertyLineBreak(r rune) (property, generalCategory int) { + if r >= 'a' && r <= 'z' { + return prAL, gcLl + } + if r >= 'A' && r <= 'Z' { + return prAL, gcLu + } + if r >= '0' && r <= '9' { + return prNU, gcNd + } + entry := propertySearch(lineBreakCodePoints, r) + return entry[2], entry[3] +} + +// propertyGraphemes returns the Unicode grapheme cluster property value of the +// given code point while fast tracking ASCII characters. +func propertyGraphemes(r rune) int { + if r >= 0x20 && r <= 0x7e { + return prAny + } + if r == 0x0a { + return prLF + } + if r == 0x0d { + return prCR + } + if r >= 0 && r <= 0x1f || r == 0x7f { + return prControl + } + return property(graphemeCodePoints, r) +} + +// propertyEastAsianWidth returns the Unicode East Asian Width property value of +// the given code point while fast tracking ASCII characters. +func propertyEastAsianWidth(r rune) int { + if r >= 0x20 && r <= 0x7e { + return prNa + } + if r >= 0 && r <= 0x1f || r == 0x7f { + return prN + } + return property(eastAsianWidth, r) +} diff --git a/vendor/github.com/rivo/uniseg/sentence.go b/vendor/github.com/rivo/uniseg/sentence.go new file mode 100644 index 000000000..adc2a3577 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/sentence.go @@ -0,0 +1,90 @@ +package uniseg + +import "unicode/utf8" + +// FirstSentence returns the first sentence found in the given byte slice +// according to the rules of [Unicode Standard Annex #29, Sentence Boundaries]. +// This function can be called continuously to extract all sentences from a byte +// slice, as illustrated in the example below. +// +// If you don't know the current state, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified sentence. If the length of the "rest" +// slice is 0, the entire byte slice "b" has been processed. The "sentence" byte +// slice is the sub-slice of the input slice containing the identified sentence. +// +// Given an empty byte slice "b", the function returns nil values. +// +// [Unicode Standard Annex #29, Sentence Boundaries]: http://unicode.org/reports/tr29/#Sentence_Boundaries +func FirstSentence(b []byte, state int) (sentence, rest []byte, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + return b, nil, sbAny + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionSentenceBreakState(state, r, b[length:], "") + } + + // Transition until we find a boundary. + var boundary bool + for { + r, l := utf8.DecodeRune(b[length:]) + state, boundary = transitionSentenceBreakState(state, r, b[length+l:], "") + + if boundary { + return b[:length], b[length:], state + } + + length += l + if len(b) <= length { + return b, nil, sbAny + } + } +} + +// FirstSentenceInString is like [FirstSentence] but its input and outputs are +// strings. +func FirstSentenceInString(str string, state int) (sentence, rest string, newState int) { + // An empty byte slice returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + return str, "", sbAny + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionSentenceBreakState(state, r, nil, str[length:]) + } + + // Transition until we find a boundary. + var boundary bool + for { + r, l := utf8.DecodeRuneInString(str[length:]) + state, boundary = transitionSentenceBreakState(state, r, nil, str[length+l:]) + + if boundary { + return str[:length], str[length:], state + } + + length += l + if len(str) <= length { + return str, "", sbAny + } + } +} diff --git a/vendor/github.com/rivo/uniseg/sentenceproperties.go b/vendor/github.com/rivo/uniseg/sentenceproperties.go new file mode 100644 index 000000000..67717ec1f --- /dev/null +++ b/vendor/github.com/rivo/uniseg/sentenceproperties.go @@ -0,0 +1,2845 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// sentenceBreakCodePoints are taken from +// https://www.unicode.org/Public/15.0.0/ucd/auxiliary/SentenceBreakProperty.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var sentenceBreakCodePoints = [][3]int{ + {0x0009, 0x0009, prSp}, // Cc + {0x000A, 0x000A, prLF}, // Cc + {0x000B, 0x000C, prSp}, // Cc [2] .. + {0x000D, 0x000D, prCR}, // Cc + {0x0020, 0x0020, prSp}, // Zs SPACE + {0x0021, 0x0021, prSTerm}, // Po EXCLAMATION MARK + {0x0022, 0x0022, prClose}, // Po QUOTATION MARK + {0x0027, 0x0027, prClose}, // Po APOSTROPHE + {0x0028, 0x0028, prClose}, // Ps LEFT PARENTHESIS + {0x0029, 0x0029, prClose}, // Pe RIGHT PARENTHESIS + {0x002C, 0x002C, prSContinue}, // Po COMMA + {0x002D, 0x002D, prSContinue}, // Pd HYPHEN-MINUS + {0x002E, 0x002E, prATerm}, // Po FULL STOP + {0x0030, 0x0039, prNumeric}, // Nd [10] DIGIT ZERO..DIGIT NINE + {0x003A, 0x003A, prSContinue}, // Po COLON + {0x003F, 0x003F, prSTerm}, // Po QUESTION MARK + {0x0041, 0x005A, prUpper}, // L& [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z + {0x005B, 0x005B, prClose}, // Ps LEFT SQUARE BRACKET + {0x005D, 0x005D, prClose}, // Pe RIGHT SQUARE BRACKET + {0x0061, 0x007A, prLower}, // L& [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z + {0x007B, 0x007B, prClose}, // Ps LEFT CURLY BRACKET + {0x007D, 0x007D, prClose}, // Pe RIGHT CURLY BRACKET + {0x0085, 0x0085, prSep}, // Cc + {0x00A0, 0x00A0, prSp}, // Zs NO-BREAK SPACE + {0x00AA, 0x00AA, prLower}, // Lo FEMININE ORDINAL INDICATOR + {0x00AB, 0x00AB, prClose}, // Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00AD, 0x00AD, prFormat}, // Cf SOFT HYPHEN + {0x00B5, 0x00B5, prLower}, // L& MICRO SIGN + {0x00BA, 0x00BA, prLower}, // Lo MASCULINE ORDINAL INDICATOR + {0x00BB, 0x00BB, prClose}, // Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + {0x00C0, 0x00D6, prUpper}, // L& [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS + {0x00D8, 0x00DE, prUpper}, // L& [7] LATIN CAPITAL LETTER O WITH STROKE..LATIN CAPITAL LETTER THORN + {0x00DF, 0x00F6, prLower}, // L& [24] LATIN SMALL LETTER SHARP S..LATIN SMALL LETTER O WITH DIAERESIS + {0x00F8, 0x00FF, prLower}, // L& [8] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS + {0x0100, 0x0100, prUpper}, // L& LATIN CAPITAL LETTER A WITH MACRON + {0x0101, 0x0101, prLower}, // L& LATIN SMALL LETTER A WITH MACRON + {0x0102, 0x0102, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE + {0x0103, 0x0103, prLower}, // L& LATIN SMALL LETTER A WITH BREVE + {0x0104, 0x0104, prUpper}, // L& LATIN CAPITAL LETTER A WITH OGONEK + {0x0105, 0x0105, prLower}, // L& LATIN SMALL LETTER A WITH OGONEK + {0x0106, 0x0106, prUpper}, // L& LATIN CAPITAL LETTER C WITH ACUTE + {0x0107, 0x0107, prLower}, // L& LATIN SMALL LETTER C WITH ACUTE + {0x0108, 0x0108, prUpper}, // L& LATIN CAPITAL LETTER C WITH CIRCUMFLEX + {0x0109, 0x0109, prLower}, // L& LATIN SMALL LETTER C WITH CIRCUMFLEX + {0x010A, 0x010A, prUpper}, // L& LATIN CAPITAL LETTER C WITH DOT ABOVE + {0x010B, 0x010B, prLower}, // L& LATIN SMALL LETTER C WITH DOT ABOVE + {0x010C, 0x010C, prUpper}, // L& LATIN CAPITAL LETTER C WITH CARON + {0x010D, 0x010D, prLower}, // L& LATIN SMALL LETTER C WITH CARON + {0x010E, 0x010E, prUpper}, // L& LATIN CAPITAL LETTER D WITH CARON + {0x010F, 0x010F, prLower}, // L& LATIN SMALL LETTER D WITH CARON + {0x0110, 0x0110, prUpper}, // L& LATIN CAPITAL LETTER D WITH STROKE + {0x0111, 0x0111, prLower}, // L& LATIN SMALL LETTER D WITH STROKE + {0x0112, 0x0112, prUpper}, // L& LATIN CAPITAL LETTER E WITH MACRON + {0x0113, 0x0113, prLower}, // L& LATIN SMALL LETTER E WITH MACRON + {0x0114, 0x0114, prUpper}, // L& LATIN CAPITAL LETTER E WITH BREVE + {0x0115, 0x0115, prLower}, // L& LATIN SMALL LETTER E WITH BREVE + {0x0116, 0x0116, prUpper}, // L& LATIN CAPITAL LETTER E WITH DOT ABOVE + {0x0117, 0x0117, prLower}, // L& LATIN SMALL LETTER E WITH DOT ABOVE + {0x0118, 0x0118, prUpper}, // L& LATIN CAPITAL LETTER E WITH OGONEK + {0x0119, 0x0119, prLower}, // L& LATIN SMALL LETTER E WITH OGONEK + {0x011A, 0x011A, prUpper}, // L& LATIN CAPITAL LETTER E WITH CARON + {0x011B, 0x011B, prLower}, // L& LATIN SMALL LETTER E WITH CARON + {0x011C, 0x011C, prUpper}, // L& LATIN CAPITAL LETTER G WITH CIRCUMFLEX + {0x011D, 0x011D, prLower}, // L& LATIN SMALL LETTER G WITH CIRCUMFLEX + {0x011E, 0x011E, prUpper}, // L& LATIN CAPITAL LETTER G WITH BREVE + {0x011F, 0x011F, prLower}, // L& LATIN SMALL LETTER G WITH BREVE + {0x0120, 0x0120, prUpper}, // L& LATIN CAPITAL LETTER G WITH DOT ABOVE + {0x0121, 0x0121, prLower}, // L& LATIN SMALL LETTER G WITH DOT ABOVE + {0x0122, 0x0122, prUpper}, // L& LATIN CAPITAL LETTER G WITH CEDILLA + {0x0123, 0x0123, prLower}, // L& LATIN SMALL LETTER G WITH CEDILLA + {0x0124, 0x0124, prUpper}, // L& LATIN CAPITAL LETTER H WITH CIRCUMFLEX + {0x0125, 0x0125, prLower}, // L& LATIN SMALL LETTER H WITH CIRCUMFLEX + {0x0126, 0x0126, prUpper}, // L& LATIN CAPITAL LETTER H WITH STROKE + {0x0127, 0x0127, prLower}, // L& LATIN SMALL LETTER H WITH STROKE + {0x0128, 0x0128, prUpper}, // L& LATIN CAPITAL LETTER I WITH TILDE + {0x0129, 0x0129, prLower}, // L& LATIN SMALL LETTER I WITH TILDE + {0x012A, 0x012A, prUpper}, // L& LATIN CAPITAL LETTER I WITH MACRON + {0x012B, 0x012B, prLower}, // L& LATIN SMALL LETTER I WITH MACRON + {0x012C, 0x012C, prUpper}, // L& LATIN CAPITAL LETTER I WITH BREVE + {0x012D, 0x012D, prLower}, // L& LATIN SMALL LETTER I WITH BREVE + {0x012E, 0x012E, prUpper}, // L& LATIN CAPITAL LETTER I WITH OGONEK + {0x012F, 0x012F, prLower}, // L& LATIN SMALL LETTER I WITH OGONEK + {0x0130, 0x0130, prUpper}, // L& LATIN CAPITAL LETTER I WITH DOT ABOVE + {0x0131, 0x0131, prLower}, // L& LATIN SMALL LETTER DOTLESS I + {0x0132, 0x0132, prUpper}, // L& LATIN CAPITAL LIGATURE IJ + {0x0133, 0x0133, prLower}, // L& LATIN SMALL LIGATURE IJ + {0x0134, 0x0134, prUpper}, // L& LATIN CAPITAL LETTER J WITH CIRCUMFLEX + {0x0135, 0x0135, prLower}, // L& LATIN SMALL LETTER J WITH CIRCUMFLEX + {0x0136, 0x0136, prUpper}, // L& LATIN CAPITAL LETTER K WITH CEDILLA + {0x0137, 0x0138, prLower}, // L& [2] LATIN SMALL LETTER K WITH CEDILLA..LATIN SMALL LETTER KRA + {0x0139, 0x0139, prUpper}, // L& LATIN CAPITAL LETTER L WITH ACUTE + {0x013A, 0x013A, prLower}, // L& LATIN SMALL LETTER L WITH ACUTE + {0x013B, 0x013B, prUpper}, // L& LATIN CAPITAL LETTER L WITH CEDILLA + {0x013C, 0x013C, prLower}, // L& LATIN SMALL LETTER L WITH CEDILLA + {0x013D, 0x013D, prUpper}, // L& LATIN CAPITAL LETTER L WITH CARON + {0x013E, 0x013E, prLower}, // L& LATIN SMALL LETTER L WITH CARON + {0x013F, 0x013F, prUpper}, // L& LATIN CAPITAL LETTER L WITH MIDDLE DOT + {0x0140, 0x0140, prLower}, // L& LATIN SMALL LETTER L WITH MIDDLE DOT + {0x0141, 0x0141, prUpper}, // L& LATIN CAPITAL LETTER L WITH STROKE + {0x0142, 0x0142, prLower}, // L& LATIN SMALL LETTER L WITH STROKE + {0x0143, 0x0143, prUpper}, // L& LATIN CAPITAL LETTER N WITH ACUTE + {0x0144, 0x0144, prLower}, // L& LATIN SMALL LETTER N WITH ACUTE + {0x0145, 0x0145, prUpper}, // L& LATIN CAPITAL LETTER N WITH CEDILLA + {0x0146, 0x0146, prLower}, // L& LATIN SMALL LETTER N WITH CEDILLA + {0x0147, 0x0147, prUpper}, // L& LATIN CAPITAL LETTER N WITH CARON + {0x0148, 0x0149, prLower}, // L& [2] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER N PRECEDED BY APOSTROPHE + {0x014A, 0x014A, prUpper}, // L& LATIN CAPITAL LETTER ENG + {0x014B, 0x014B, prLower}, // L& LATIN SMALL LETTER ENG + {0x014C, 0x014C, prUpper}, // L& LATIN CAPITAL LETTER O WITH MACRON + {0x014D, 0x014D, prLower}, // L& LATIN SMALL LETTER O WITH MACRON + {0x014E, 0x014E, prUpper}, // L& LATIN CAPITAL LETTER O WITH BREVE + {0x014F, 0x014F, prLower}, // L& LATIN SMALL LETTER O WITH BREVE + {0x0150, 0x0150, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + {0x0151, 0x0151, prLower}, // L& LATIN SMALL LETTER O WITH DOUBLE ACUTE + {0x0152, 0x0152, prUpper}, // L& LATIN CAPITAL LIGATURE OE + {0x0153, 0x0153, prLower}, // L& LATIN SMALL LIGATURE OE + {0x0154, 0x0154, prUpper}, // L& LATIN CAPITAL LETTER R WITH ACUTE + {0x0155, 0x0155, prLower}, // L& LATIN SMALL LETTER R WITH ACUTE + {0x0156, 0x0156, prUpper}, // L& LATIN CAPITAL LETTER R WITH CEDILLA + {0x0157, 0x0157, prLower}, // L& LATIN SMALL LETTER R WITH CEDILLA + {0x0158, 0x0158, prUpper}, // L& LATIN CAPITAL LETTER R WITH CARON + {0x0159, 0x0159, prLower}, // L& LATIN SMALL LETTER R WITH CARON + {0x015A, 0x015A, prUpper}, // L& LATIN CAPITAL LETTER S WITH ACUTE + {0x015B, 0x015B, prLower}, // L& LATIN SMALL LETTER S WITH ACUTE + {0x015C, 0x015C, prUpper}, // L& LATIN CAPITAL LETTER S WITH CIRCUMFLEX + {0x015D, 0x015D, prLower}, // L& LATIN SMALL LETTER S WITH CIRCUMFLEX + {0x015E, 0x015E, prUpper}, // L& LATIN CAPITAL LETTER S WITH CEDILLA + {0x015F, 0x015F, prLower}, // L& LATIN SMALL LETTER S WITH CEDILLA + {0x0160, 0x0160, prUpper}, // L& LATIN CAPITAL LETTER S WITH CARON + {0x0161, 0x0161, prLower}, // L& LATIN SMALL LETTER S WITH CARON + {0x0162, 0x0162, prUpper}, // L& LATIN CAPITAL LETTER T WITH CEDILLA + {0x0163, 0x0163, prLower}, // L& LATIN SMALL LETTER T WITH CEDILLA + {0x0164, 0x0164, prUpper}, // L& LATIN CAPITAL LETTER T WITH CARON + {0x0165, 0x0165, prLower}, // L& LATIN SMALL LETTER T WITH CARON + {0x0166, 0x0166, prUpper}, // L& LATIN CAPITAL LETTER T WITH STROKE + {0x0167, 0x0167, prLower}, // L& LATIN SMALL LETTER T WITH STROKE + {0x0168, 0x0168, prUpper}, // L& LATIN CAPITAL LETTER U WITH TILDE + {0x0169, 0x0169, prLower}, // L& LATIN SMALL LETTER U WITH TILDE + {0x016A, 0x016A, prUpper}, // L& LATIN CAPITAL LETTER U WITH MACRON + {0x016B, 0x016B, prLower}, // L& LATIN SMALL LETTER U WITH MACRON + {0x016C, 0x016C, prUpper}, // L& LATIN CAPITAL LETTER U WITH BREVE + {0x016D, 0x016D, prLower}, // L& LATIN SMALL LETTER U WITH BREVE + {0x016E, 0x016E, prUpper}, // L& LATIN CAPITAL LETTER U WITH RING ABOVE + {0x016F, 0x016F, prLower}, // L& LATIN SMALL LETTER U WITH RING ABOVE + {0x0170, 0x0170, prUpper}, // L& LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + {0x0171, 0x0171, prLower}, // L& LATIN SMALL LETTER U WITH DOUBLE ACUTE + {0x0172, 0x0172, prUpper}, // L& LATIN CAPITAL LETTER U WITH OGONEK + {0x0173, 0x0173, prLower}, // L& LATIN SMALL LETTER U WITH OGONEK + {0x0174, 0x0174, prUpper}, // L& LATIN CAPITAL LETTER W WITH CIRCUMFLEX + {0x0175, 0x0175, prLower}, // L& LATIN SMALL LETTER W WITH CIRCUMFLEX + {0x0176, 0x0176, prUpper}, // L& LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + {0x0177, 0x0177, prLower}, // L& LATIN SMALL LETTER Y WITH CIRCUMFLEX + {0x0178, 0x0179, prUpper}, // L& [2] LATIN CAPITAL LETTER Y WITH DIAERESIS..LATIN CAPITAL LETTER Z WITH ACUTE + {0x017A, 0x017A, prLower}, // L& LATIN SMALL LETTER Z WITH ACUTE + {0x017B, 0x017B, prUpper}, // L& LATIN CAPITAL LETTER Z WITH DOT ABOVE + {0x017C, 0x017C, prLower}, // L& LATIN SMALL LETTER Z WITH DOT ABOVE + {0x017D, 0x017D, prUpper}, // L& LATIN CAPITAL LETTER Z WITH CARON + {0x017E, 0x0180, prLower}, // L& [3] LATIN SMALL LETTER Z WITH CARON..LATIN SMALL LETTER B WITH STROKE + {0x0181, 0x0182, prUpper}, // L& [2] LATIN CAPITAL LETTER B WITH HOOK..LATIN CAPITAL LETTER B WITH TOPBAR + {0x0183, 0x0183, prLower}, // L& LATIN SMALL LETTER B WITH TOPBAR + {0x0184, 0x0184, prUpper}, // L& LATIN CAPITAL LETTER TONE SIX + {0x0185, 0x0185, prLower}, // L& LATIN SMALL LETTER TONE SIX + {0x0186, 0x0187, prUpper}, // L& [2] LATIN CAPITAL LETTER OPEN O..LATIN CAPITAL LETTER C WITH HOOK + {0x0188, 0x0188, prLower}, // L& LATIN SMALL LETTER C WITH HOOK + {0x0189, 0x018B, prUpper}, // L& [3] LATIN CAPITAL LETTER AFRICAN D..LATIN CAPITAL LETTER D WITH TOPBAR + {0x018C, 0x018D, prLower}, // L& [2] LATIN SMALL LETTER D WITH TOPBAR..LATIN SMALL LETTER TURNED DELTA + {0x018E, 0x0191, prUpper}, // L& [4] LATIN CAPITAL LETTER REVERSED E..LATIN CAPITAL LETTER F WITH HOOK + {0x0192, 0x0192, prLower}, // L& LATIN SMALL LETTER F WITH HOOK + {0x0193, 0x0194, prUpper}, // L& [2] LATIN CAPITAL LETTER G WITH HOOK..LATIN CAPITAL LETTER GAMMA + {0x0195, 0x0195, prLower}, // L& LATIN SMALL LETTER HV + {0x0196, 0x0198, prUpper}, // L& [3] LATIN CAPITAL LETTER IOTA..LATIN CAPITAL LETTER K WITH HOOK + {0x0199, 0x019B, prLower}, // L& [3] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE + {0x019C, 0x019D, prUpper}, // L& [2] LATIN CAPITAL LETTER TURNED M..LATIN CAPITAL LETTER N WITH LEFT HOOK + {0x019E, 0x019E, prLower}, // L& LATIN SMALL LETTER N WITH LONG RIGHT LEG + {0x019F, 0x01A0, prUpper}, // L& [2] LATIN CAPITAL LETTER O WITH MIDDLE TILDE..LATIN CAPITAL LETTER O WITH HORN + {0x01A1, 0x01A1, prLower}, // L& LATIN SMALL LETTER O WITH HORN + {0x01A2, 0x01A2, prUpper}, // L& LATIN CAPITAL LETTER OI + {0x01A3, 0x01A3, prLower}, // L& LATIN SMALL LETTER OI + {0x01A4, 0x01A4, prUpper}, // L& LATIN CAPITAL LETTER P WITH HOOK + {0x01A5, 0x01A5, prLower}, // L& LATIN SMALL LETTER P WITH HOOK + {0x01A6, 0x01A7, prUpper}, // L& [2] LATIN LETTER YR..LATIN CAPITAL LETTER TONE TWO + {0x01A8, 0x01A8, prLower}, // L& LATIN SMALL LETTER TONE TWO + {0x01A9, 0x01A9, prUpper}, // L& LATIN CAPITAL LETTER ESH + {0x01AA, 0x01AB, prLower}, // L& [2] LATIN LETTER REVERSED ESH LOOP..LATIN SMALL LETTER T WITH PALATAL HOOK + {0x01AC, 0x01AC, prUpper}, // L& LATIN CAPITAL LETTER T WITH HOOK + {0x01AD, 0x01AD, prLower}, // L& LATIN SMALL LETTER T WITH HOOK + {0x01AE, 0x01AF, prUpper}, // L& [2] LATIN CAPITAL LETTER T WITH RETROFLEX HOOK..LATIN CAPITAL LETTER U WITH HORN + {0x01B0, 0x01B0, prLower}, // L& LATIN SMALL LETTER U WITH HORN + {0x01B1, 0x01B3, prUpper}, // L& [3] LATIN CAPITAL LETTER UPSILON..LATIN CAPITAL LETTER Y WITH HOOK + {0x01B4, 0x01B4, prLower}, // L& LATIN SMALL LETTER Y WITH HOOK + {0x01B5, 0x01B5, prUpper}, // L& LATIN CAPITAL LETTER Z WITH STROKE + {0x01B6, 0x01B6, prLower}, // L& LATIN SMALL LETTER Z WITH STROKE + {0x01B7, 0x01B8, prUpper}, // L& [2] LATIN CAPITAL LETTER EZH..LATIN CAPITAL LETTER EZH REVERSED + {0x01B9, 0x01BA, prLower}, // L& [2] LATIN SMALL LETTER EZH REVERSED..LATIN SMALL LETTER EZH WITH TAIL + {0x01BB, 0x01BB, prOLetter}, // Lo LATIN LETTER TWO WITH STROKE + {0x01BC, 0x01BC, prUpper}, // L& LATIN CAPITAL LETTER TONE FIVE + {0x01BD, 0x01BF, prLower}, // L& [3] LATIN SMALL LETTER TONE FIVE..LATIN LETTER WYNN + {0x01C0, 0x01C3, prOLetter}, // Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK + {0x01C4, 0x01C5, prUpper}, // L& [2] LATIN CAPITAL LETTER DZ WITH CARON..LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON + {0x01C6, 0x01C6, prLower}, // L& LATIN SMALL LETTER DZ WITH CARON + {0x01C7, 0x01C8, prUpper}, // L& [2] LATIN CAPITAL LETTER LJ..LATIN CAPITAL LETTER L WITH SMALL LETTER J + {0x01C9, 0x01C9, prLower}, // L& LATIN SMALL LETTER LJ + {0x01CA, 0x01CB, prUpper}, // L& [2] LATIN CAPITAL LETTER NJ..LATIN CAPITAL LETTER N WITH SMALL LETTER J + {0x01CC, 0x01CC, prLower}, // L& LATIN SMALL LETTER NJ + {0x01CD, 0x01CD, prUpper}, // L& LATIN CAPITAL LETTER A WITH CARON + {0x01CE, 0x01CE, prLower}, // L& LATIN SMALL LETTER A WITH CARON + {0x01CF, 0x01CF, prUpper}, // L& LATIN CAPITAL LETTER I WITH CARON + {0x01D0, 0x01D0, prLower}, // L& LATIN SMALL LETTER I WITH CARON + {0x01D1, 0x01D1, prUpper}, // L& LATIN CAPITAL LETTER O WITH CARON + {0x01D2, 0x01D2, prLower}, // L& LATIN SMALL LETTER O WITH CARON + {0x01D3, 0x01D3, prUpper}, // L& LATIN CAPITAL LETTER U WITH CARON + {0x01D4, 0x01D4, prLower}, // L& LATIN SMALL LETTER U WITH CARON + {0x01D5, 0x01D5, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON + {0x01D6, 0x01D6, prLower}, // L& LATIN SMALL LETTER U WITH DIAERESIS AND MACRON + {0x01D7, 0x01D7, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE + {0x01D8, 0x01D8, prLower}, // L& LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE + {0x01D9, 0x01D9, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON + {0x01DA, 0x01DA, prLower}, // L& LATIN SMALL LETTER U WITH DIAERESIS AND CARON + {0x01DB, 0x01DB, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE + {0x01DC, 0x01DD, prLower}, // L& [2] LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE..LATIN SMALL LETTER TURNED E + {0x01DE, 0x01DE, prUpper}, // L& LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON + {0x01DF, 0x01DF, prLower}, // L& LATIN SMALL LETTER A WITH DIAERESIS AND MACRON + {0x01E0, 0x01E0, prUpper}, // L& LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON + {0x01E1, 0x01E1, prLower}, // L& LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON + {0x01E2, 0x01E2, prUpper}, // L& LATIN CAPITAL LETTER AE WITH MACRON + {0x01E3, 0x01E3, prLower}, // L& LATIN SMALL LETTER AE WITH MACRON + {0x01E4, 0x01E4, prUpper}, // L& LATIN CAPITAL LETTER G WITH STROKE + {0x01E5, 0x01E5, prLower}, // L& LATIN SMALL LETTER G WITH STROKE + {0x01E6, 0x01E6, prUpper}, // L& LATIN CAPITAL LETTER G WITH CARON + {0x01E7, 0x01E7, prLower}, // L& LATIN SMALL LETTER G WITH CARON + {0x01E8, 0x01E8, prUpper}, // L& LATIN CAPITAL LETTER K WITH CARON + {0x01E9, 0x01E9, prLower}, // L& LATIN SMALL LETTER K WITH CARON + {0x01EA, 0x01EA, prUpper}, // L& LATIN CAPITAL LETTER O WITH OGONEK + {0x01EB, 0x01EB, prLower}, // L& LATIN SMALL LETTER O WITH OGONEK + {0x01EC, 0x01EC, prUpper}, // L& LATIN CAPITAL LETTER O WITH OGONEK AND MACRON + {0x01ED, 0x01ED, prLower}, // L& LATIN SMALL LETTER O WITH OGONEK AND MACRON + {0x01EE, 0x01EE, prUpper}, // L& LATIN CAPITAL LETTER EZH WITH CARON + {0x01EF, 0x01F0, prLower}, // L& [2] LATIN SMALL LETTER EZH WITH CARON..LATIN SMALL LETTER J WITH CARON + {0x01F1, 0x01F2, prUpper}, // L& [2] LATIN CAPITAL LETTER DZ..LATIN CAPITAL LETTER D WITH SMALL LETTER Z + {0x01F3, 0x01F3, prLower}, // L& LATIN SMALL LETTER DZ + {0x01F4, 0x01F4, prUpper}, // L& LATIN CAPITAL LETTER G WITH ACUTE + {0x01F5, 0x01F5, prLower}, // L& LATIN SMALL LETTER G WITH ACUTE + {0x01F6, 0x01F8, prUpper}, // L& [3] LATIN CAPITAL LETTER HWAIR..LATIN CAPITAL LETTER N WITH GRAVE + {0x01F9, 0x01F9, prLower}, // L& LATIN SMALL LETTER N WITH GRAVE + {0x01FA, 0x01FA, prUpper}, // L& LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE + {0x01FB, 0x01FB, prLower}, // L& LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE + {0x01FC, 0x01FC, prUpper}, // L& LATIN CAPITAL LETTER AE WITH ACUTE + {0x01FD, 0x01FD, prLower}, // L& LATIN SMALL LETTER AE WITH ACUTE + {0x01FE, 0x01FE, prUpper}, // L& LATIN CAPITAL LETTER O WITH STROKE AND ACUTE + {0x01FF, 0x01FF, prLower}, // L& LATIN SMALL LETTER O WITH STROKE AND ACUTE + {0x0200, 0x0200, prUpper}, // L& LATIN CAPITAL LETTER A WITH DOUBLE GRAVE + {0x0201, 0x0201, prLower}, // L& LATIN SMALL LETTER A WITH DOUBLE GRAVE + {0x0202, 0x0202, prUpper}, // L& LATIN CAPITAL LETTER A WITH INVERTED BREVE + {0x0203, 0x0203, prLower}, // L& LATIN SMALL LETTER A WITH INVERTED BREVE + {0x0204, 0x0204, prUpper}, // L& LATIN CAPITAL LETTER E WITH DOUBLE GRAVE + {0x0205, 0x0205, prLower}, // L& LATIN SMALL LETTER E WITH DOUBLE GRAVE + {0x0206, 0x0206, prUpper}, // L& LATIN CAPITAL LETTER E WITH INVERTED BREVE + {0x0207, 0x0207, prLower}, // L& LATIN SMALL LETTER E WITH INVERTED BREVE + {0x0208, 0x0208, prUpper}, // L& LATIN CAPITAL LETTER I WITH DOUBLE GRAVE + {0x0209, 0x0209, prLower}, // L& LATIN SMALL LETTER I WITH DOUBLE GRAVE + {0x020A, 0x020A, prUpper}, // L& LATIN CAPITAL LETTER I WITH INVERTED BREVE + {0x020B, 0x020B, prLower}, // L& LATIN SMALL LETTER I WITH INVERTED BREVE + {0x020C, 0x020C, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOUBLE GRAVE + {0x020D, 0x020D, prLower}, // L& LATIN SMALL LETTER O WITH DOUBLE GRAVE + {0x020E, 0x020E, prUpper}, // L& LATIN CAPITAL LETTER O WITH INVERTED BREVE + {0x020F, 0x020F, prLower}, // L& LATIN SMALL LETTER O WITH INVERTED BREVE + {0x0210, 0x0210, prUpper}, // L& LATIN CAPITAL LETTER R WITH DOUBLE GRAVE + {0x0211, 0x0211, prLower}, // L& LATIN SMALL LETTER R WITH DOUBLE GRAVE + {0x0212, 0x0212, prUpper}, // L& LATIN CAPITAL LETTER R WITH INVERTED BREVE + {0x0213, 0x0213, prLower}, // L& LATIN SMALL LETTER R WITH INVERTED BREVE + {0x0214, 0x0214, prUpper}, // L& LATIN CAPITAL LETTER U WITH DOUBLE GRAVE + {0x0215, 0x0215, prLower}, // L& LATIN SMALL LETTER U WITH DOUBLE GRAVE + {0x0216, 0x0216, prUpper}, // L& LATIN CAPITAL LETTER U WITH INVERTED BREVE + {0x0217, 0x0217, prLower}, // L& LATIN SMALL LETTER U WITH INVERTED BREVE + {0x0218, 0x0218, prUpper}, // L& LATIN CAPITAL LETTER S WITH COMMA BELOW + {0x0219, 0x0219, prLower}, // L& LATIN SMALL LETTER S WITH COMMA BELOW + {0x021A, 0x021A, prUpper}, // L& LATIN CAPITAL LETTER T WITH COMMA BELOW + {0x021B, 0x021B, prLower}, // L& LATIN SMALL LETTER T WITH COMMA BELOW + {0x021C, 0x021C, prUpper}, // L& LATIN CAPITAL LETTER YOGH + {0x021D, 0x021D, prLower}, // L& LATIN SMALL LETTER YOGH + {0x021E, 0x021E, prUpper}, // L& LATIN CAPITAL LETTER H WITH CARON + {0x021F, 0x021F, prLower}, // L& LATIN SMALL LETTER H WITH CARON + {0x0220, 0x0220, prUpper}, // L& LATIN CAPITAL LETTER N WITH LONG RIGHT LEG + {0x0221, 0x0221, prLower}, // L& LATIN SMALL LETTER D WITH CURL + {0x0222, 0x0222, prUpper}, // L& LATIN CAPITAL LETTER OU + {0x0223, 0x0223, prLower}, // L& LATIN SMALL LETTER OU + {0x0224, 0x0224, prUpper}, // L& LATIN CAPITAL LETTER Z WITH HOOK + {0x0225, 0x0225, prLower}, // L& LATIN SMALL LETTER Z WITH HOOK + {0x0226, 0x0226, prUpper}, // L& LATIN CAPITAL LETTER A WITH DOT ABOVE + {0x0227, 0x0227, prLower}, // L& LATIN SMALL LETTER A WITH DOT ABOVE + {0x0228, 0x0228, prUpper}, // L& LATIN CAPITAL LETTER E WITH CEDILLA + {0x0229, 0x0229, prLower}, // L& LATIN SMALL LETTER E WITH CEDILLA + {0x022A, 0x022A, prUpper}, // L& LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON + {0x022B, 0x022B, prLower}, // L& LATIN SMALL LETTER O WITH DIAERESIS AND MACRON + {0x022C, 0x022C, prUpper}, // L& LATIN CAPITAL LETTER O WITH TILDE AND MACRON + {0x022D, 0x022D, prLower}, // L& LATIN SMALL LETTER O WITH TILDE AND MACRON + {0x022E, 0x022E, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOT ABOVE + {0x022F, 0x022F, prLower}, // L& LATIN SMALL LETTER O WITH DOT ABOVE + {0x0230, 0x0230, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON + {0x0231, 0x0231, prLower}, // L& LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON + {0x0232, 0x0232, prUpper}, // L& LATIN CAPITAL LETTER Y WITH MACRON + {0x0233, 0x0239, prLower}, // L& [7] LATIN SMALL LETTER Y WITH MACRON..LATIN SMALL LETTER QP DIGRAPH + {0x023A, 0x023B, prUpper}, // L& [2] LATIN CAPITAL LETTER A WITH STROKE..LATIN CAPITAL LETTER C WITH STROKE + {0x023C, 0x023C, prLower}, // L& LATIN SMALL LETTER C WITH STROKE + {0x023D, 0x023E, prUpper}, // L& [2] LATIN CAPITAL LETTER L WITH BAR..LATIN CAPITAL LETTER T WITH DIAGONAL STROKE + {0x023F, 0x0240, prLower}, // L& [2] LATIN SMALL LETTER S WITH SWASH TAIL..LATIN SMALL LETTER Z WITH SWASH TAIL + {0x0241, 0x0241, prUpper}, // L& LATIN CAPITAL LETTER GLOTTAL STOP + {0x0242, 0x0242, prLower}, // L& LATIN SMALL LETTER GLOTTAL STOP + {0x0243, 0x0246, prUpper}, // L& [4] LATIN CAPITAL LETTER B WITH STROKE..LATIN CAPITAL LETTER E WITH STROKE + {0x0247, 0x0247, prLower}, // L& LATIN SMALL LETTER E WITH STROKE + {0x0248, 0x0248, prUpper}, // L& LATIN CAPITAL LETTER J WITH STROKE + {0x0249, 0x0249, prLower}, // L& LATIN SMALL LETTER J WITH STROKE + {0x024A, 0x024A, prUpper}, // L& LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL + {0x024B, 0x024B, prLower}, // L& LATIN SMALL LETTER Q WITH HOOK TAIL + {0x024C, 0x024C, prUpper}, // L& LATIN CAPITAL LETTER R WITH STROKE + {0x024D, 0x024D, prLower}, // L& LATIN SMALL LETTER R WITH STROKE + {0x024E, 0x024E, prUpper}, // L& LATIN CAPITAL LETTER Y WITH STROKE + {0x024F, 0x0293, prLower}, // L& [69] LATIN SMALL LETTER Y WITH STROKE..LATIN SMALL LETTER EZH WITH CURL + {0x0294, 0x0294, prOLetter}, // Lo LATIN LETTER GLOTTAL STOP + {0x0295, 0x02AF, prLower}, // L& [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL + {0x02B0, 0x02B8, prLower}, // Lm [9] MODIFIER LETTER SMALL H..MODIFIER LETTER SMALL Y + {0x02B9, 0x02BF, prOLetter}, // Lm [7] MODIFIER LETTER PRIME..MODIFIER LETTER LEFT HALF RING + {0x02C0, 0x02C1, prLower}, // Lm [2] MODIFIER LETTER GLOTTAL STOP..MODIFIER LETTER REVERSED GLOTTAL STOP + {0x02C6, 0x02D1, prOLetter}, // Lm [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON + {0x02E0, 0x02E4, prLower}, // Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP + {0x02EC, 0x02EC, prOLetter}, // Lm MODIFIER LETTER VOICING + {0x02EE, 0x02EE, prOLetter}, // Lm MODIFIER LETTER DOUBLE APOSTROPHE + {0x0300, 0x036F, prExtend}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X + {0x0370, 0x0370, prUpper}, // L& GREEK CAPITAL LETTER HETA + {0x0371, 0x0371, prLower}, // L& GREEK SMALL LETTER HETA + {0x0372, 0x0372, prUpper}, // L& GREEK CAPITAL LETTER ARCHAIC SAMPI + {0x0373, 0x0373, prLower}, // L& GREEK SMALL LETTER ARCHAIC SAMPI + {0x0374, 0x0374, prOLetter}, // Lm GREEK NUMERAL SIGN + {0x0376, 0x0376, prUpper}, // L& GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA + {0x0377, 0x0377, prLower}, // L& GREEK SMALL LETTER PAMPHYLIAN DIGAMMA + {0x037A, 0x037A, prLower}, // Lm GREEK YPOGEGRAMMENI + {0x037B, 0x037D, prLower}, // L& [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x037F, 0x037F, prUpper}, // L& GREEK CAPITAL LETTER YOT + {0x0386, 0x0386, prUpper}, // L& GREEK CAPITAL LETTER ALPHA WITH TONOS + {0x0388, 0x038A, prUpper}, // L& [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS + {0x038C, 0x038C, prUpper}, // L& GREEK CAPITAL LETTER OMICRON WITH TONOS + {0x038E, 0x038F, prUpper}, // L& [2] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER OMEGA WITH TONOS + {0x0390, 0x0390, prLower}, // L& GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + {0x0391, 0x03A1, prUpper}, // L& [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO + {0x03A3, 0x03AB, prUpper}, // L& [9] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + {0x03AC, 0x03CE, prLower}, // L& [35] GREEK SMALL LETTER ALPHA WITH TONOS..GREEK SMALL LETTER OMEGA WITH TONOS + {0x03CF, 0x03CF, prUpper}, // L& GREEK CAPITAL KAI SYMBOL + {0x03D0, 0x03D1, prLower}, // L& [2] GREEK BETA SYMBOL..GREEK THETA SYMBOL + {0x03D2, 0x03D4, prUpper}, // L& [3] GREEK UPSILON WITH HOOK SYMBOL..GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL + {0x03D5, 0x03D7, prLower}, // L& [3] GREEK PHI SYMBOL..GREEK KAI SYMBOL + {0x03D8, 0x03D8, prUpper}, // L& GREEK LETTER ARCHAIC KOPPA + {0x03D9, 0x03D9, prLower}, // L& GREEK SMALL LETTER ARCHAIC KOPPA + {0x03DA, 0x03DA, prUpper}, // L& GREEK LETTER STIGMA + {0x03DB, 0x03DB, prLower}, // L& GREEK SMALL LETTER STIGMA + {0x03DC, 0x03DC, prUpper}, // L& GREEK LETTER DIGAMMA + {0x03DD, 0x03DD, prLower}, // L& GREEK SMALL LETTER DIGAMMA + {0x03DE, 0x03DE, prUpper}, // L& GREEK LETTER KOPPA + {0x03DF, 0x03DF, prLower}, // L& GREEK SMALL LETTER KOPPA + {0x03E0, 0x03E0, prUpper}, // L& GREEK LETTER SAMPI + {0x03E1, 0x03E1, prLower}, // L& GREEK SMALL LETTER SAMPI + {0x03E2, 0x03E2, prUpper}, // L& COPTIC CAPITAL LETTER SHEI + {0x03E3, 0x03E3, prLower}, // L& COPTIC SMALL LETTER SHEI + {0x03E4, 0x03E4, prUpper}, // L& COPTIC CAPITAL LETTER FEI + {0x03E5, 0x03E5, prLower}, // L& COPTIC SMALL LETTER FEI + {0x03E6, 0x03E6, prUpper}, // L& COPTIC CAPITAL LETTER KHEI + {0x03E7, 0x03E7, prLower}, // L& COPTIC SMALL LETTER KHEI + {0x03E8, 0x03E8, prUpper}, // L& COPTIC CAPITAL LETTER HORI + {0x03E9, 0x03E9, prLower}, // L& COPTIC SMALL LETTER HORI + {0x03EA, 0x03EA, prUpper}, // L& COPTIC CAPITAL LETTER GANGIA + {0x03EB, 0x03EB, prLower}, // L& COPTIC SMALL LETTER GANGIA + {0x03EC, 0x03EC, prUpper}, // L& COPTIC CAPITAL LETTER SHIMA + {0x03ED, 0x03ED, prLower}, // L& COPTIC SMALL LETTER SHIMA + {0x03EE, 0x03EE, prUpper}, // L& COPTIC CAPITAL LETTER DEI + {0x03EF, 0x03F3, prLower}, // L& [5] COPTIC SMALL LETTER DEI..GREEK LETTER YOT + {0x03F4, 0x03F4, prUpper}, // L& GREEK CAPITAL THETA SYMBOL + {0x03F5, 0x03F5, prLower}, // L& GREEK LUNATE EPSILON SYMBOL + {0x03F7, 0x03F7, prUpper}, // L& GREEK CAPITAL LETTER SHO + {0x03F8, 0x03F8, prLower}, // L& GREEK SMALL LETTER SHO + {0x03F9, 0x03FA, prUpper}, // L& [2] GREEK CAPITAL LUNATE SIGMA SYMBOL..GREEK CAPITAL LETTER SAN + {0x03FB, 0x03FC, prLower}, // L& [2] GREEK SMALL LETTER SAN..GREEK RHO WITH STROKE SYMBOL + {0x03FD, 0x042F, prUpper}, // L& [51] GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL..CYRILLIC CAPITAL LETTER YA + {0x0430, 0x045F, prLower}, // L& [48] CYRILLIC SMALL LETTER A..CYRILLIC SMALL LETTER DZHE + {0x0460, 0x0460, prUpper}, // L& CYRILLIC CAPITAL LETTER OMEGA + {0x0461, 0x0461, prLower}, // L& CYRILLIC SMALL LETTER OMEGA + {0x0462, 0x0462, prUpper}, // L& CYRILLIC CAPITAL LETTER YAT + {0x0463, 0x0463, prLower}, // L& CYRILLIC SMALL LETTER YAT + {0x0464, 0x0464, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED E + {0x0465, 0x0465, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED E + {0x0466, 0x0466, prUpper}, // L& CYRILLIC CAPITAL LETTER LITTLE YUS + {0x0467, 0x0467, prLower}, // L& CYRILLIC SMALL LETTER LITTLE YUS + {0x0468, 0x0468, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS + {0x0469, 0x0469, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS + {0x046A, 0x046A, prUpper}, // L& CYRILLIC CAPITAL LETTER BIG YUS + {0x046B, 0x046B, prLower}, // L& CYRILLIC SMALL LETTER BIG YUS + {0x046C, 0x046C, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS + {0x046D, 0x046D, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED BIG YUS + {0x046E, 0x046E, prUpper}, // L& CYRILLIC CAPITAL LETTER KSI + {0x046F, 0x046F, prLower}, // L& CYRILLIC SMALL LETTER KSI + {0x0470, 0x0470, prUpper}, // L& CYRILLIC CAPITAL LETTER PSI + {0x0471, 0x0471, prLower}, // L& CYRILLIC SMALL LETTER PSI + {0x0472, 0x0472, prUpper}, // L& CYRILLIC CAPITAL LETTER FITA + {0x0473, 0x0473, prLower}, // L& CYRILLIC SMALL LETTER FITA + {0x0474, 0x0474, prUpper}, // L& CYRILLIC CAPITAL LETTER IZHITSA + {0x0475, 0x0475, prLower}, // L& CYRILLIC SMALL LETTER IZHITSA + {0x0476, 0x0476, prUpper}, // L& CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + {0x0477, 0x0477, prLower}, // L& CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + {0x0478, 0x0478, prUpper}, // L& CYRILLIC CAPITAL LETTER UK + {0x0479, 0x0479, prLower}, // L& CYRILLIC SMALL LETTER UK + {0x047A, 0x047A, prUpper}, // L& CYRILLIC CAPITAL LETTER ROUND OMEGA + {0x047B, 0x047B, prLower}, // L& CYRILLIC SMALL LETTER ROUND OMEGA + {0x047C, 0x047C, prUpper}, // L& CYRILLIC CAPITAL LETTER OMEGA WITH TITLO + {0x047D, 0x047D, prLower}, // L& CYRILLIC SMALL LETTER OMEGA WITH TITLO + {0x047E, 0x047E, prUpper}, // L& CYRILLIC CAPITAL LETTER OT + {0x047F, 0x047F, prLower}, // L& CYRILLIC SMALL LETTER OT + {0x0480, 0x0480, prUpper}, // L& CYRILLIC CAPITAL LETTER KOPPA + {0x0481, 0x0481, prLower}, // L& CYRILLIC SMALL LETTER KOPPA + {0x0483, 0x0487, prExtend}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prExtend}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x048A, 0x048A, prUpper}, // L& CYRILLIC CAPITAL LETTER SHORT I WITH TAIL + {0x048B, 0x048B, prLower}, // L& CYRILLIC SMALL LETTER SHORT I WITH TAIL + {0x048C, 0x048C, prUpper}, // L& CYRILLIC CAPITAL LETTER SEMISOFT SIGN + {0x048D, 0x048D, prLower}, // L& CYRILLIC SMALL LETTER SEMISOFT SIGN + {0x048E, 0x048E, prUpper}, // L& CYRILLIC CAPITAL LETTER ER WITH TICK + {0x048F, 0x048F, prLower}, // L& CYRILLIC SMALL LETTER ER WITH TICK + {0x0490, 0x0490, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH UPTURN + {0x0491, 0x0491, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH UPTURN + {0x0492, 0x0492, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH STROKE + {0x0493, 0x0493, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH STROKE + {0x0494, 0x0494, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK + {0x0495, 0x0495, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK + {0x0496, 0x0496, prUpper}, // L& CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER + {0x0497, 0x0497, prLower}, // L& CYRILLIC SMALL LETTER ZHE WITH DESCENDER + {0x0498, 0x0498, prUpper}, // L& CYRILLIC CAPITAL LETTER ZE WITH DESCENDER + {0x0499, 0x0499, prLower}, // L& CYRILLIC SMALL LETTER ZE WITH DESCENDER + {0x049A, 0x049A, prUpper}, // L& CYRILLIC CAPITAL LETTER KA WITH DESCENDER + {0x049B, 0x049B, prLower}, // L& CYRILLIC SMALL LETTER KA WITH DESCENDER + {0x049C, 0x049C, prUpper}, // L& CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE + {0x049D, 0x049D, prLower}, // L& CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE + {0x049E, 0x049E, prUpper}, // L& CYRILLIC CAPITAL LETTER KA WITH STROKE + {0x049F, 0x049F, prLower}, // L& CYRILLIC SMALL LETTER KA WITH STROKE + {0x04A0, 0x04A0, prUpper}, // L& CYRILLIC CAPITAL LETTER BASHKIR KA + {0x04A1, 0x04A1, prLower}, // L& CYRILLIC SMALL LETTER BASHKIR KA + {0x04A2, 0x04A2, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH DESCENDER + {0x04A3, 0x04A3, prLower}, // L& CYRILLIC SMALL LETTER EN WITH DESCENDER + {0x04A4, 0x04A4, prUpper}, // L& CYRILLIC CAPITAL LIGATURE EN GHE + {0x04A5, 0x04A5, prLower}, // L& CYRILLIC SMALL LIGATURE EN GHE + {0x04A6, 0x04A6, prUpper}, // L& CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK + {0x04A7, 0x04A7, prLower}, // L& CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK + {0x04A8, 0x04A8, prUpper}, // L& CYRILLIC CAPITAL LETTER ABKHASIAN HA + {0x04A9, 0x04A9, prLower}, // L& CYRILLIC SMALL LETTER ABKHASIAN HA + {0x04AA, 0x04AA, prUpper}, // L& CYRILLIC CAPITAL LETTER ES WITH DESCENDER + {0x04AB, 0x04AB, prLower}, // L& CYRILLIC SMALL LETTER ES WITH DESCENDER + {0x04AC, 0x04AC, prUpper}, // L& CYRILLIC CAPITAL LETTER TE WITH DESCENDER + {0x04AD, 0x04AD, prLower}, // L& CYRILLIC SMALL LETTER TE WITH DESCENDER + {0x04AE, 0x04AE, prUpper}, // L& CYRILLIC CAPITAL LETTER STRAIGHT U + {0x04AF, 0x04AF, prLower}, // L& CYRILLIC SMALL LETTER STRAIGHT U + {0x04B0, 0x04B0, prUpper}, // L& CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE + {0x04B1, 0x04B1, prLower}, // L& CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE + {0x04B2, 0x04B2, prUpper}, // L& CYRILLIC CAPITAL LETTER HA WITH DESCENDER + {0x04B3, 0x04B3, prLower}, // L& CYRILLIC SMALL LETTER HA WITH DESCENDER + {0x04B4, 0x04B4, prUpper}, // L& CYRILLIC CAPITAL LIGATURE TE TSE + {0x04B5, 0x04B5, prLower}, // L& CYRILLIC SMALL LIGATURE TE TSE + {0x04B6, 0x04B6, prUpper}, // L& CYRILLIC CAPITAL LETTER CHE WITH DESCENDER + {0x04B7, 0x04B7, prLower}, // L& CYRILLIC SMALL LETTER CHE WITH DESCENDER + {0x04B8, 0x04B8, prUpper}, // L& CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE + {0x04B9, 0x04B9, prLower}, // L& CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE + {0x04BA, 0x04BA, prUpper}, // L& CYRILLIC CAPITAL LETTER SHHA + {0x04BB, 0x04BB, prLower}, // L& CYRILLIC SMALL LETTER SHHA + {0x04BC, 0x04BC, prUpper}, // L& CYRILLIC CAPITAL LETTER ABKHASIAN CHE + {0x04BD, 0x04BD, prLower}, // L& CYRILLIC SMALL LETTER ABKHASIAN CHE + {0x04BE, 0x04BE, prUpper}, // L& CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER + {0x04BF, 0x04BF, prLower}, // L& CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER + {0x04C0, 0x04C1, prUpper}, // L& [2] CYRILLIC LETTER PALOCHKA..CYRILLIC CAPITAL LETTER ZHE WITH BREVE + {0x04C2, 0x04C2, prLower}, // L& CYRILLIC SMALL LETTER ZHE WITH BREVE + {0x04C3, 0x04C3, prUpper}, // L& CYRILLIC CAPITAL LETTER KA WITH HOOK + {0x04C4, 0x04C4, prLower}, // L& CYRILLIC SMALL LETTER KA WITH HOOK + {0x04C5, 0x04C5, prUpper}, // L& CYRILLIC CAPITAL LETTER EL WITH TAIL + {0x04C6, 0x04C6, prLower}, // L& CYRILLIC SMALL LETTER EL WITH TAIL + {0x04C7, 0x04C7, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH HOOK + {0x04C8, 0x04C8, prLower}, // L& CYRILLIC SMALL LETTER EN WITH HOOK + {0x04C9, 0x04C9, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH TAIL + {0x04CA, 0x04CA, prLower}, // L& CYRILLIC SMALL LETTER EN WITH TAIL + {0x04CB, 0x04CB, prUpper}, // L& CYRILLIC CAPITAL LETTER KHAKASSIAN CHE + {0x04CC, 0x04CC, prLower}, // L& CYRILLIC SMALL LETTER KHAKASSIAN CHE + {0x04CD, 0x04CD, prUpper}, // L& CYRILLIC CAPITAL LETTER EM WITH TAIL + {0x04CE, 0x04CF, prLower}, // L& [2] CYRILLIC SMALL LETTER EM WITH TAIL..CYRILLIC SMALL LETTER PALOCHKA + {0x04D0, 0x04D0, prUpper}, // L& CYRILLIC CAPITAL LETTER A WITH BREVE + {0x04D1, 0x04D1, prLower}, // L& CYRILLIC SMALL LETTER A WITH BREVE + {0x04D2, 0x04D2, prUpper}, // L& CYRILLIC CAPITAL LETTER A WITH DIAERESIS + {0x04D3, 0x04D3, prLower}, // L& CYRILLIC SMALL LETTER A WITH DIAERESIS + {0x04D4, 0x04D4, prUpper}, // L& CYRILLIC CAPITAL LIGATURE A IE + {0x04D5, 0x04D5, prLower}, // L& CYRILLIC SMALL LIGATURE A IE + {0x04D6, 0x04D6, prUpper}, // L& CYRILLIC CAPITAL LETTER IE WITH BREVE + {0x04D7, 0x04D7, prLower}, // L& CYRILLIC SMALL LETTER IE WITH BREVE + {0x04D8, 0x04D8, prUpper}, // L& CYRILLIC CAPITAL LETTER SCHWA + {0x04D9, 0x04D9, prLower}, // L& CYRILLIC SMALL LETTER SCHWA + {0x04DA, 0x04DA, prUpper}, // L& CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS + {0x04DB, 0x04DB, prLower}, // L& CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS + {0x04DC, 0x04DC, prUpper}, // L& CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS + {0x04DD, 0x04DD, prLower}, // L& CYRILLIC SMALL LETTER ZHE WITH DIAERESIS + {0x04DE, 0x04DE, prUpper}, // L& CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS + {0x04DF, 0x04DF, prLower}, // L& CYRILLIC SMALL LETTER ZE WITH DIAERESIS + {0x04E0, 0x04E0, prUpper}, // L& CYRILLIC CAPITAL LETTER ABKHASIAN DZE + {0x04E1, 0x04E1, prLower}, // L& CYRILLIC SMALL LETTER ABKHASIAN DZE + {0x04E2, 0x04E2, prUpper}, // L& CYRILLIC CAPITAL LETTER I WITH MACRON + {0x04E3, 0x04E3, prLower}, // L& CYRILLIC SMALL LETTER I WITH MACRON + {0x04E4, 0x04E4, prUpper}, // L& CYRILLIC CAPITAL LETTER I WITH DIAERESIS + {0x04E5, 0x04E5, prLower}, // L& CYRILLIC SMALL LETTER I WITH DIAERESIS + {0x04E6, 0x04E6, prUpper}, // L& CYRILLIC CAPITAL LETTER O WITH DIAERESIS + {0x04E7, 0x04E7, prLower}, // L& CYRILLIC SMALL LETTER O WITH DIAERESIS + {0x04E8, 0x04E8, prUpper}, // L& CYRILLIC CAPITAL LETTER BARRED O + {0x04E9, 0x04E9, prLower}, // L& CYRILLIC SMALL LETTER BARRED O + {0x04EA, 0x04EA, prUpper}, // L& CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS + {0x04EB, 0x04EB, prLower}, // L& CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS + {0x04EC, 0x04EC, prUpper}, // L& CYRILLIC CAPITAL LETTER E WITH DIAERESIS + {0x04ED, 0x04ED, prLower}, // L& CYRILLIC SMALL LETTER E WITH DIAERESIS + {0x04EE, 0x04EE, prUpper}, // L& CYRILLIC CAPITAL LETTER U WITH MACRON + {0x04EF, 0x04EF, prLower}, // L& CYRILLIC SMALL LETTER U WITH MACRON + {0x04F0, 0x04F0, prUpper}, // L& CYRILLIC CAPITAL LETTER U WITH DIAERESIS + {0x04F1, 0x04F1, prLower}, // L& CYRILLIC SMALL LETTER U WITH DIAERESIS + {0x04F2, 0x04F2, prUpper}, // L& CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE + {0x04F3, 0x04F3, prLower}, // L& CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE + {0x04F4, 0x04F4, prUpper}, // L& CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS + {0x04F5, 0x04F5, prLower}, // L& CYRILLIC SMALL LETTER CHE WITH DIAERESIS + {0x04F6, 0x04F6, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH DESCENDER + {0x04F7, 0x04F7, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH DESCENDER + {0x04F8, 0x04F8, prUpper}, // L& CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS + {0x04F9, 0x04F9, prLower}, // L& CYRILLIC SMALL LETTER YERU WITH DIAERESIS + {0x04FA, 0x04FA, prUpper}, // L& CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK + {0x04FB, 0x04FB, prLower}, // L& CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK + {0x04FC, 0x04FC, prUpper}, // L& CYRILLIC CAPITAL LETTER HA WITH HOOK + {0x04FD, 0x04FD, prLower}, // L& CYRILLIC SMALL LETTER HA WITH HOOK + {0x04FE, 0x04FE, prUpper}, // L& CYRILLIC CAPITAL LETTER HA WITH STROKE + {0x04FF, 0x04FF, prLower}, // L& CYRILLIC SMALL LETTER HA WITH STROKE + {0x0500, 0x0500, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI DE + {0x0501, 0x0501, prLower}, // L& CYRILLIC SMALL LETTER KOMI DE + {0x0502, 0x0502, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI DJE + {0x0503, 0x0503, prLower}, // L& CYRILLIC SMALL LETTER KOMI DJE + {0x0504, 0x0504, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI ZJE + {0x0505, 0x0505, prLower}, // L& CYRILLIC SMALL LETTER KOMI ZJE + {0x0506, 0x0506, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI DZJE + {0x0507, 0x0507, prLower}, // L& CYRILLIC SMALL LETTER KOMI DZJE + {0x0508, 0x0508, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI LJE + {0x0509, 0x0509, prLower}, // L& CYRILLIC SMALL LETTER KOMI LJE + {0x050A, 0x050A, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI NJE + {0x050B, 0x050B, prLower}, // L& CYRILLIC SMALL LETTER KOMI NJE + {0x050C, 0x050C, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI SJE + {0x050D, 0x050D, prLower}, // L& CYRILLIC SMALL LETTER KOMI SJE + {0x050E, 0x050E, prUpper}, // L& CYRILLIC CAPITAL LETTER KOMI TJE + {0x050F, 0x050F, prLower}, // L& CYRILLIC SMALL LETTER KOMI TJE + {0x0510, 0x0510, prUpper}, // L& CYRILLIC CAPITAL LETTER REVERSED ZE + {0x0511, 0x0511, prLower}, // L& CYRILLIC SMALL LETTER REVERSED ZE + {0x0512, 0x0512, prUpper}, // L& CYRILLIC CAPITAL LETTER EL WITH HOOK + {0x0513, 0x0513, prLower}, // L& CYRILLIC SMALL LETTER EL WITH HOOK + {0x0514, 0x0514, prUpper}, // L& CYRILLIC CAPITAL LETTER LHA + {0x0515, 0x0515, prLower}, // L& CYRILLIC SMALL LETTER LHA + {0x0516, 0x0516, prUpper}, // L& CYRILLIC CAPITAL LETTER RHA + {0x0517, 0x0517, prLower}, // L& CYRILLIC SMALL LETTER RHA + {0x0518, 0x0518, prUpper}, // L& CYRILLIC CAPITAL LETTER YAE + {0x0519, 0x0519, prLower}, // L& CYRILLIC SMALL LETTER YAE + {0x051A, 0x051A, prUpper}, // L& CYRILLIC CAPITAL LETTER QA + {0x051B, 0x051B, prLower}, // L& CYRILLIC SMALL LETTER QA + {0x051C, 0x051C, prUpper}, // L& CYRILLIC CAPITAL LETTER WE + {0x051D, 0x051D, prLower}, // L& CYRILLIC SMALL LETTER WE + {0x051E, 0x051E, prUpper}, // L& CYRILLIC CAPITAL LETTER ALEUT KA + {0x051F, 0x051F, prLower}, // L& CYRILLIC SMALL LETTER ALEUT KA + {0x0520, 0x0520, prUpper}, // L& CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK + {0x0521, 0x0521, prLower}, // L& CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK + {0x0522, 0x0522, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK + {0x0523, 0x0523, prLower}, // L& CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK + {0x0524, 0x0524, prUpper}, // L& CYRILLIC CAPITAL LETTER PE WITH DESCENDER + {0x0525, 0x0525, prLower}, // L& CYRILLIC SMALL LETTER PE WITH DESCENDER + {0x0526, 0x0526, prUpper}, // L& CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER + {0x0527, 0x0527, prLower}, // L& CYRILLIC SMALL LETTER SHHA WITH DESCENDER + {0x0528, 0x0528, prUpper}, // L& CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK + {0x0529, 0x0529, prLower}, // L& CYRILLIC SMALL LETTER EN WITH LEFT HOOK + {0x052A, 0x052A, prUpper}, // L& CYRILLIC CAPITAL LETTER DZZHE + {0x052B, 0x052B, prLower}, // L& CYRILLIC SMALL LETTER DZZHE + {0x052C, 0x052C, prUpper}, // L& CYRILLIC CAPITAL LETTER DCHE + {0x052D, 0x052D, prLower}, // L& CYRILLIC SMALL LETTER DCHE + {0x052E, 0x052E, prUpper}, // L& CYRILLIC CAPITAL LETTER EL WITH DESCENDER + {0x052F, 0x052F, prLower}, // L& CYRILLIC SMALL LETTER EL WITH DESCENDER + {0x0531, 0x0556, prUpper}, // L& [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH + {0x0559, 0x0559, prOLetter}, // Lm ARMENIAN MODIFIER LETTER LEFT HALF RING + {0x055D, 0x055D, prSContinue}, // Po ARMENIAN COMMA + {0x0560, 0x0588, prLower}, // L& [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE + {0x0589, 0x0589, prSTerm}, // Po ARMENIAN FULL STOP + {0x0591, 0x05BD, prExtend}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BF, 0x05BF, prExtend}, // Mn HEBREW POINT RAFE + {0x05C1, 0x05C2, prExtend}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C4, 0x05C5, prExtend}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C7, 0x05C7, prExtend}, // Mn HEBREW POINT QAMATS QATAN + {0x05D0, 0x05EA, prOLetter}, // Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV + {0x05EF, 0x05F2, prOLetter}, // Lo [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD + {0x05F3, 0x05F3, prOLetter}, // Po HEBREW PUNCTUATION GERESH + {0x0600, 0x0605, prFormat}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x060C, 0x060D, prSContinue}, // Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR + {0x0610, 0x061A, prExtend}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061C, 0x061C, prFormat}, // Cf ARABIC LETTER MARK + {0x061D, 0x061F, prSTerm}, // Po [3] ARABIC END OF TEXT MARK..ARABIC QUESTION MARK + {0x0620, 0x063F, prOLetter}, // Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE + {0x0640, 0x0640, prOLetter}, // Lm ARABIC TATWEEL + {0x0641, 0x064A, prOLetter}, // Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH + {0x064B, 0x065F, prExtend}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0660, 0x0669, prNumeric}, // Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE + {0x066B, 0x066C, prNumeric}, // Po [2] ARABIC DECIMAL SEPARATOR..ARABIC THOUSANDS SEPARATOR + {0x066E, 0x066F, prOLetter}, // Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF + {0x0670, 0x0670, prExtend}, // Mn ARABIC LETTER SUPERSCRIPT ALEF + {0x0671, 0x06D3, prOLetter}, // Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE + {0x06D4, 0x06D4, prSTerm}, // Po ARABIC FULL STOP + {0x06D5, 0x06D5, prOLetter}, // Lo ARABIC LETTER AE + {0x06D6, 0x06DC, prExtend}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prFormat}, // Cf ARABIC END OF AYAH + {0x06DF, 0x06E4, prExtend}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E5, 0x06E6, prOLetter}, // Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH + {0x06E7, 0x06E8, prExtend}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06EA, 0x06ED, prExtend}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x06EE, 0x06EF, prOLetter}, // Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V + {0x06F0, 0x06F9, prNumeric}, // Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE + {0x06FA, 0x06FC, prOLetter}, // Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW + {0x06FF, 0x06FF, prOLetter}, // Lo ARABIC LETTER HEH WITH INVERTED V + {0x0700, 0x0702, prSTerm}, // Po [3] SYRIAC END OF PARAGRAPH..SYRIAC SUBLINEAR FULL STOP + {0x070F, 0x070F, prFormat}, // Cf SYRIAC ABBREVIATION MARK + {0x0710, 0x0710, prOLetter}, // Lo SYRIAC LETTER ALAPH + {0x0711, 0x0711, prExtend}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0712, 0x072F, prOLetter}, // Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH + {0x0730, 0x074A, prExtend}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x074D, 0x07A5, prOLetter}, // Lo [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU + {0x07A6, 0x07B0, prExtend}, // Mn [11] THAANA ABAFILI..THAANA SUKUN + {0x07B1, 0x07B1, prOLetter}, // Lo THAANA LETTER NAA + {0x07C0, 0x07C9, prNumeric}, // Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE + {0x07CA, 0x07EA, prOLetter}, // Lo [33] NKO LETTER A..NKO LETTER JONA RA + {0x07EB, 0x07F3, prExtend}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07F4, 0x07F5, prOLetter}, // Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE + {0x07F8, 0x07F8, prSContinue}, // Po NKO COMMA + {0x07F9, 0x07F9, prSTerm}, // Po NKO EXCLAMATION MARK + {0x07FA, 0x07FA, prOLetter}, // Lm NKO LAJANYALAN + {0x07FD, 0x07FD, prExtend}, // Mn NKO DANTAYALAN + {0x0800, 0x0815, prOLetter}, // Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF + {0x0816, 0x0819, prExtend}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081A, 0x081A, prOLetter}, // Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT + {0x081B, 0x0823, prExtend}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0824, 0x0824, prOLetter}, // Lm SAMARITAN MODIFIER LETTER SHORT A + {0x0825, 0x0827, prExtend}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0828, 0x0828, prOLetter}, // Lm SAMARITAN MODIFIER LETTER I + {0x0829, 0x082D, prExtend}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0837, 0x0837, prSTerm}, // Po SAMARITAN PUNCTUATION MELODIC QITSA + {0x0839, 0x0839, prSTerm}, // Po SAMARITAN PUNCTUATION QITSA + {0x083D, 0x083E, prSTerm}, // Po [2] SAMARITAN PUNCTUATION SOF MASHFAAT..SAMARITAN PUNCTUATION ANNAAU + {0x0840, 0x0858, prOLetter}, // Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN + {0x0859, 0x085B, prExtend}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x0860, 0x086A, prOLetter}, // Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA + {0x0870, 0x0887, prOLetter}, // Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT + {0x0889, 0x088E, prOLetter}, // Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL + {0x0890, 0x0891, prFormat}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prExtend}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08A0, 0x08C8, prOLetter}, // Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF + {0x08C9, 0x08C9, prOLetter}, // Lm ARABIC SMALL FARSI YEH + {0x08CA, 0x08E1, prExtend}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prFormat}, // Cf ARABIC DISPUTED END OF AYAH + {0x08E3, 0x0902, prExtend}, // Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prExtend}, // Mc DEVANAGARI SIGN VISARGA + {0x0904, 0x0939, prOLetter}, // Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA + {0x093A, 0x093A, prExtend}, // Mn DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prExtend}, // Mc DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prExtend}, // Mn DEVANAGARI SIGN NUKTA + {0x093D, 0x093D, prOLetter}, // Lo DEVANAGARI SIGN AVAGRAHA + {0x093E, 0x0940, prExtend}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prExtend}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prExtend}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prExtend}, // Mn DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prExtend}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0950, 0x0950, prOLetter}, // Lo DEVANAGARI OM + {0x0951, 0x0957, prExtend}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0958, 0x0961, prOLetter}, // Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL + {0x0962, 0x0963, prExtend}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0964, 0x0965, prSTerm}, // Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA + {0x0966, 0x096F, prNumeric}, // Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE + {0x0971, 0x0971, prOLetter}, // Lm DEVANAGARI SIGN HIGH SPACING DOT + {0x0972, 0x0980, prOLetter}, // Lo [15] DEVANAGARI LETTER CANDRA A..BENGALI ANJI + {0x0981, 0x0981, prExtend}, // Mn BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prExtend}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x0985, 0x098C, prOLetter}, // Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L + {0x098F, 0x0990, prOLetter}, // Lo [2] BENGALI LETTER E..BENGALI LETTER AI + {0x0993, 0x09A8, prOLetter}, // Lo [22] BENGALI LETTER O..BENGALI LETTER NA + {0x09AA, 0x09B0, prOLetter}, // Lo [7] BENGALI LETTER PA..BENGALI LETTER RA + {0x09B2, 0x09B2, prOLetter}, // Lo BENGALI LETTER LA + {0x09B6, 0x09B9, prOLetter}, // Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA + {0x09BC, 0x09BC, prExtend}, // Mn BENGALI SIGN NUKTA + {0x09BD, 0x09BD, prOLetter}, // Lo BENGALI SIGN AVAGRAHA + {0x09BE, 0x09C0, prExtend}, // Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prExtend}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prExtend}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prExtend}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prExtend}, // Mn BENGALI SIGN VIRAMA + {0x09CE, 0x09CE, prOLetter}, // Lo BENGALI LETTER KHANDA TA + {0x09D7, 0x09D7, prExtend}, // Mc BENGALI AU LENGTH MARK + {0x09DC, 0x09DD, prOLetter}, // Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA + {0x09DF, 0x09E1, prOLetter}, // Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL + {0x09E2, 0x09E3, prExtend}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09E6, 0x09EF, prNumeric}, // Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE + {0x09F0, 0x09F1, prOLetter}, // Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL + {0x09FC, 0x09FC, prOLetter}, // Lo BENGALI LETTER VEDIC ANUSVARA + {0x09FE, 0x09FE, prExtend}, // Mn BENGALI SANDHI MARK + {0x0A01, 0x0A02, prExtend}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prExtend}, // Mc GURMUKHI SIGN VISARGA + {0x0A05, 0x0A0A, prOLetter}, // Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU + {0x0A0F, 0x0A10, prOLetter}, // Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI + {0x0A13, 0x0A28, prOLetter}, // Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA + {0x0A2A, 0x0A30, prOLetter}, // Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA + {0x0A32, 0x0A33, prOLetter}, // Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA + {0x0A35, 0x0A36, prOLetter}, // Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA + {0x0A38, 0x0A39, prOLetter}, // Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA + {0x0A3C, 0x0A3C, prExtend}, // Mn GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prExtend}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prExtend}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prExtend}, // Mn GURMUKHI SIGN UDAAT + {0x0A59, 0x0A5C, prOLetter}, // Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA + {0x0A5E, 0x0A5E, prOLetter}, // Lo GURMUKHI LETTER FA + {0x0A66, 0x0A6F, prNumeric}, // Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE + {0x0A70, 0x0A71, prExtend}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A72, 0x0A74, prOLetter}, // Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR + {0x0A75, 0x0A75, prExtend}, // Mn GURMUKHI SIGN YAKASH + {0x0A81, 0x0A82, prExtend}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prExtend}, // Mc GUJARATI SIGN VISARGA + {0x0A85, 0x0A8D, prOLetter}, // Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E + {0x0A8F, 0x0A91, prOLetter}, // Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O + {0x0A93, 0x0AA8, prOLetter}, // Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA + {0x0AAA, 0x0AB0, prOLetter}, // Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA + {0x0AB2, 0x0AB3, prOLetter}, // Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA + {0x0AB5, 0x0AB9, prOLetter}, // Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA + {0x0ABC, 0x0ABC, prExtend}, // Mn GUJARATI SIGN NUKTA + {0x0ABD, 0x0ABD, prOLetter}, // Lo GUJARATI SIGN AVAGRAHA + {0x0ABE, 0x0AC0, prExtend}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prExtend}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prExtend}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prExtend}, // Mc GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prExtend}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prExtend}, // Mn GUJARATI SIGN VIRAMA + {0x0AD0, 0x0AD0, prOLetter}, // Lo GUJARATI OM + {0x0AE0, 0x0AE1, prOLetter}, // Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL + {0x0AE2, 0x0AE3, prExtend}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AE6, 0x0AEF, prNumeric}, // Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE + {0x0AF9, 0x0AF9, prOLetter}, // Lo GUJARATI LETTER ZHA + {0x0AFA, 0x0AFF, prExtend}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prExtend}, // Mn ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prExtend}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B05, 0x0B0C, prOLetter}, // Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L + {0x0B0F, 0x0B10, prOLetter}, // Lo [2] ORIYA LETTER E..ORIYA LETTER AI + {0x0B13, 0x0B28, prOLetter}, // Lo [22] ORIYA LETTER O..ORIYA LETTER NA + {0x0B2A, 0x0B30, prOLetter}, // Lo [7] ORIYA LETTER PA..ORIYA LETTER RA + {0x0B32, 0x0B33, prOLetter}, // Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA + {0x0B35, 0x0B39, prOLetter}, // Lo [5] ORIYA LETTER VA..ORIYA LETTER HA + {0x0B3C, 0x0B3C, prExtend}, // Mn ORIYA SIGN NUKTA + {0x0B3D, 0x0B3D, prOLetter}, // Lo ORIYA SIGN AVAGRAHA + {0x0B3E, 0x0B3E, prExtend}, // Mc ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prExtend}, // Mn ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prExtend}, // Mc ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prExtend}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prExtend}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prExtend}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prExtend}, // Mn ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prExtend}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prExtend}, // Mc ORIYA AU LENGTH MARK + {0x0B5C, 0x0B5D, prOLetter}, // Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA + {0x0B5F, 0x0B61, prOLetter}, // Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL + {0x0B62, 0x0B63, prExtend}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B66, 0x0B6F, prNumeric}, // Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE + {0x0B71, 0x0B71, prOLetter}, // Lo ORIYA LETTER WA + {0x0B82, 0x0B82, prExtend}, // Mn TAMIL SIGN ANUSVARA + {0x0B83, 0x0B83, prOLetter}, // Lo TAMIL SIGN VISARGA + {0x0B85, 0x0B8A, prOLetter}, // Lo [6] TAMIL LETTER A..TAMIL LETTER UU + {0x0B8E, 0x0B90, prOLetter}, // Lo [3] TAMIL LETTER E..TAMIL LETTER AI + {0x0B92, 0x0B95, prOLetter}, // Lo [4] TAMIL LETTER O..TAMIL LETTER KA + {0x0B99, 0x0B9A, prOLetter}, // Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA + {0x0B9C, 0x0B9C, prOLetter}, // Lo TAMIL LETTER JA + {0x0B9E, 0x0B9F, prOLetter}, // Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA + {0x0BA3, 0x0BA4, prOLetter}, // Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA + {0x0BA8, 0x0BAA, prOLetter}, // Lo [3] TAMIL LETTER NA..TAMIL LETTER PA + {0x0BAE, 0x0BB9, prOLetter}, // Lo [12] TAMIL LETTER MA..TAMIL LETTER HA + {0x0BBE, 0x0BBF, prExtend}, // Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prExtend}, // Mn TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prExtend}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prExtend}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prExtend}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prExtend}, // Mn TAMIL SIGN VIRAMA + {0x0BD0, 0x0BD0, prOLetter}, // Lo TAMIL OM + {0x0BD7, 0x0BD7, prExtend}, // Mc TAMIL AU LENGTH MARK + {0x0BE6, 0x0BEF, prNumeric}, // Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE + {0x0C00, 0x0C00, prExtend}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prExtend}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prExtend}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C05, 0x0C0C, prOLetter}, // Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L + {0x0C0E, 0x0C10, prOLetter}, // Lo [3] TELUGU LETTER E..TELUGU LETTER AI + {0x0C12, 0x0C28, prOLetter}, // Lo [23] TELUGU LETTER O..TELUGU LETTER NA + {0x0C2A, 0x0C39, prOLetter}, // Lo [16] TELUGU LETTER PA..TELUGU LETTER HA + {0x0C3C, 0x0C3C, prExtend}, // Mn TELUGU SIGN NUKTA + {0x0C3D, 0x0C3D, prOLetter}, // Lo TELUGU SIGN AVAGRAHA + {0x0C3E, 0x0C40, prExtend}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prExtend}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prExtend}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prExtend}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prExtend}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C58, 0x0C5A, prOLetter}, // Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA + {0x0C5D, 0x0C5D, prOLetter}, // Lo TELUGU LETTER NAKAARA POLLU + {0x0C60, 0x0C61, prOLetter}, // Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL + {0x0C62, 0x0C63, prExtend}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C66, 0x0C6F, prNumeric}, // Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE + {0x0C80, 0x0C80, prOLetter}, // Lo KANNADA SIGN SPACING CANDRABINDU + {0x0C81, 0x0C81, prExtend}, // Mn KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prExtend}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0C85, 0x0C8C, prOLetter}, // Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L + {0x0C8E, 0x0C90, prOLetter}, // Lo [3] KANNADA LETTER E..KANNADA LETTER AI + {0x0C92, 0x0CA8, prOLetter}, // Lo [23] KANNADA LETTER O..KANNADA LETTER NA + {0x0CAA, 0x0CB3, prOLetter}, // Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA + {0x0CB5, 0x0CB9, prOLetter}, // Lo [5] KANNADA LETTER VA..KANNADA LETTER HA + {0x0CBC, 0x0CBC, prExtend}, // Mn KANNADA SIGN NUKTA + {0x0CBD, 0x0CBD, prOLetter}, // Lo KANNADA SIGN AVAGRAHA + {0x0CBE, 0x0CBE, prExtend}, // Mc KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prExtend}, // Mn KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC4, prExtend}, // Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prExtend}, // Mn KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prExtend}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prExtend}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prExtend}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prExtend}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CDD, 0x0CDE, prOLetter}, // Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA + {0x0CE0, 0x0CE1, prOLetter}, // Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL + {0x0CE2, 0x0CE3, prExtend}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CE6, 0x0CEF, prNumeric}, // Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE + {0x0CF1, 0x0CF2, prOLetter}, // Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA + {0x0CF3, 0x0CF3, prExtend}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prExtend}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prExtend}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D04, 0x0D0C, prOLetter}, // Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L + {0x0D0E, 0x0D10, prOLetter}, // Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI + {0x0D12, 0x0D3A, prOLetter}, // Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA + {0x0D3B, 0x0D3C, prExtend}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3D, 0x0D3D, prOLetter}, // Lo MALAYALAM SIGN AVAGRAHA + {0x0D3E, 0x0D40, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prExtend}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prExtend}, // Mn MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prOLetter}, // Lo MALAYALAM LETTER DOT REPH + {0x0D54, 0x0D56, prOLetter}, // Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL + {0x0D57, 0x0D57, prExtend}, // Mc MALAYALAM AU LENGTH MARK + {0x0D5F, 0x0D61, prOLetter}, // Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL + {0x0D62, 0x0D63, prExtend}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D66, 0x0D6F, prNumeric}, // Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE + {0x0D7A, 0x0D7F, prOLetter}, // Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K + {0x0D81, 0x0D81, prExtend}, // Mn SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prExtend}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0D85, 0x0D96, prOLetter}, // Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA + {0x0D9A, 0x0DB1, prOLetter}, // Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA + {0x0DB3, 0x0DBB, prOLetter}, // Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA + {0x0DBD, 0x0DBD, prOLetter}, // Lo SINHALA LETTER DANTAJA LAYANNA + {0x0DC0, 0x0DC6, prOLetter}, // Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA + {0x0DCA, 0x0DCA, prExtend}, // Mn SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DD1, prExtend}, // Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prExtend}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prExtend}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDF, prExtend}, // Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA + {0x0DE6, 0x0DEF, prNumeric}, // Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE + {0x0DF2, 0x0DF3, prExtend}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0E01, 0x0E30, prOLetter}, // Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A + {0x0E31, 0x0E31, prExtend}, // Mn THAI CHARACTER MAI HAN-AKAT + {0x0E32, 0x0E33, prOLetter}, // Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM + {0x0E34, 0x0E3A, prExtend}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E40, 0x0E45, prOLetter}, // Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO + {0x0E46, 0x0E46, prOLetter}, // Lm THAI CHARACTER MAIYAMOK + {0x0E47, 0x0E4E, prExtend}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0E50, 0x0E59, prNumeric}, // Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE + {0x0E81, 0x0E82, prOLetter}, // Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG + {0x0E84, 0x0E84, prOLetter}, // Lo LAO LETTER KHO TAM + {0x0E86, 0x0E8A, prOLetter}, // Lo [5] LAO LETTER PALI GHA..LAO LETTER SO TAM + {0x0E8C, 0x0EA3, prOLetter}, // Lo [24] LAO LETTER PALI JHA..LAO LETTER LO LING + {0x0EA5, 0x0EA5, prOLetter}, // Lo LAO LETTER LO LOOT + {0x0EA7, 0x0EB0, prOLetter}, // Lo [10] LAO LETTER WO..LAO VOWEL SIGN A + {0x0EB1, 0x0EB1, prExtend}, // Mn LAO VOWEL SIGN MAI KAN + {0x0EB2, 0x0EB3, prOLetter}, // Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM + {0x0EB4, 0x0EBC, prExtend}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EBD, 0x0EBD, prOLetter}, // Lo LAO SEMIVOWEL SIGN NYO + {0x0EC0, 0x0EC4, prOLetter}, // Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI + {0x0EC6, 0x0EC6, prOLetter}, // Lm LAO KO LA + {0x0EC8, 0x0ECE, prExtend}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0ED0, 0x0ED9, prNumeric}, // Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE + {0x0EDC, 0x0EDF, prOLetter}, // Lo [4] LAO HO NO..LAO LETTER KHMU NYO + {0x0F00, 0x0F00, prOLetter}, // Lo TIBETAN SYLLABLE OM + {0x0F18, 0x0F19, prExtend}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F20, 0x0F29, prNumeric}, // Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE + {0x0F35, 0x0F35, prExtend}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F37, 0x0F37, prExtend}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F39, 0x0F39, prExtend}, // Mn TIBETAN MARK TSA -PHRU + {0x0F3A, 0x0F3A, prClose}, // Ps TIBETAN MARK GUG RTAGS GYON + {0x0F3B, 0x0F3B, prClose}, // Pe TIBETAN MARK GUG RTAGS GYAS + {0x0F3C, 0x0F3C, prClose}, // Ps TIBETAN MARK ANG KHANG GYON + {0x0F3D, 0x0F3D, prClose}, // Pe TIBETAN MARK ANG KHANG GYAS + {0x0F3E, 0x0F3F, prExtend}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F40, 0x0F47, prOLetter}, // Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA + {0x0F49, 0x0F6C, prOLetter}, // Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA + {0x0F71, 0x0F7E, prExtend}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prExtend}, // Mc TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prExtend}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F86, 0x0F87, prExtend}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F88, 0x0F8C, prOLetter}, // Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN + {0x0F8D, 0x0F97, prExtend}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prExtend}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FC6, 0x0FC6, prExtend}, // Mn TIBETAN SYMBOL PADMA GDAN + {0x1000, 0x102A, prOLetter}, // Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU + {0x102B, 0x102C, prExtend}, // Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA + {0x102D, 0x1030, prExtend}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prExtend}, // Mc MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prExtend}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1038, 0x1038, prExtend}, // Mc MYANMAR SIGN VISARGA + {0x1039, 0x103A, prExtend}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prExtend}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prExtend}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x103F, 0x103F, prOLetter}, // Lo MYANMAR LETTER GREAT SA + {0x1040, 0x1049, prNumeric}, // Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE + {0x104A, 0x104B, prSTerm}, // Po [2] MYANMAR SIGN LITTLE SECTION..MYANMAR SIGN SECTION + {0x1050, 0x1055, prOLetter}, // Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL + {0x1056, 0x1057, prExtend}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prExtend}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105A, 0x105D, prOLetter}, // Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE + {0x105E, 0x1060, prExtend}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1061, 0x1061, prOLetter}, // Lo MYANMAR LETTER SGAW KAREN SHA + {0x1062, 0x1064, prExtend}, // Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO + {0x1065, 0x1066, prOLetter}, // Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA + {0x1067, 0x106D, prExtend}, // Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 + {0x106E, 0x1070, prOLetter}, // Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA + {0x1071, 0x1074, prExtend}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1075, 0x1081, prOLetter}, // Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA + {0x1082, 0x1082, prExtend}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1083, 0x1084, prExtend}, // Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prExtend}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x1087, 0x108C, prExtend}, // Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 + {0x108D, 0x108D, prExtend}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x108E, 0x108E, prOLetter}, // Lo MYANMAR LETTER RUMAI PALAUNG FA + {0x108F, 0x108F, prExtend}, // Mc MYANMAR SIGN RUMAI PALAUNG TONE-5 + {0x1090, 0x1099, prNumeric}, // Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE + {0x109A, 0x109C, prExtend}, // Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A + {0x109D, 0x109D, prExtend}, // Mn MYANMAR VOWEL SIGN AITON AI + {0x10A0, 0x10C5, prUpper}, // L& [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE + {0x10C7, 0x10C7, prUpper}, // L& GEORGIAN CAPITAL LETTER YN + {0x10CD, 0x10CD, prUpper}, // L& GEORGIAN CAPITAL LETTER AEN + {0x10D0, 0x10FA, prOLetter}, // L& [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN + {0x10FC, 0x10FC, prLower}, // Lm MODIFIER LETTER GEORGIAN NAR + {0x10FD, 0x10FF, prOLetter}, // L& [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN + {0x1100, 0x1248, prOLetter}, // Lo [329] HANGUL CHOSEONG KIYEOK..ETHIOPIC SYLLABLE QWA + {0x124A, 0x124D, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE + {0x1250, 0x1256, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO + {0x1258, 0x1258, prOLetter}, // Lo ETHIOPIC SYLLABLE QHWA + {0x125A, 0x125D, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE + {0x1260, 0x1288, prOLetter}, // Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA + {0x128A, 0x128D, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE + {0x1290, 0x12B0, prOLetter}, // Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA + {0x12B2, 0x12B5, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE + {0x12B8, 0x12BE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO + {0x12C0, 0x12C0, prOLetter}, // Lo ETHIOPIC SYLLABLE KXWA + {0x12C2, 0x12C5, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE + {0x12C8, 0x12D6, prOLetter}, // Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O + {0x12D8, 0x1310, prOLetter}, // Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA + {0x1312, 0x1315, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE + {0x1318, 0x135A, prOLetter}, // Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA + {0x135D, 0x135F, prExtend}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1362, 0x1362, prSTerm}, // Po ETHIOPIC FULL STOP + {0x1367, 0x1368, prSTerm}, // Po [2] ETHIOPIC QUESTION MARK..ETHIOPIC PARAGRAPH SEPARATOR + {0x1380, 0x138F, prOLetter}, // Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE + {0x13A0, 0x13F5, prUpper}, // L& [86] CHEROKEE LETTER A..CHEROKEE LETTER MV + {0x13F8, 0x13FD, prLower}, // L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV + {0x1401, 0x166C, prOLetter}, // Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA + {0x166E, 0x166E, prSTerm}, // Po CANADIAN SYLLABICS FULL STOP + {0x166F, 0x167F, prOLetter}, // Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W + {0x1680, 0x1680, prSp}, // Zs OGHAM SPACE MARK + {0x1681, 0x169A, prOLetter}, // Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH + {0x169B, 0x169B, prClose}, // Ps OGHAM FEATHER MARK + {0x169C, 0x169C, prClose}, // Pe OGHAM REVERSED FEATHER MARK + {0x16A0, 0x16EA, prOLetter}, // Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X + {0x16EE, 0x16F0, prOLetter}, // Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL + {0x16F1, 0x16F8, prOLetter}, // Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC + {0x1700, 0x1711, prOLetter}, // Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA + {0x1712, 0x1714, prExtend}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prExtend}, // Mc TAGALOG SIGN PAMUDPOD + {0x171F, 0x1731, prOLetter}, // Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA + {0x1732, 0x1733, prExtend}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prExtend}, // Mc HANUNOO SIGN PAMUDPOD + {0x1735, 0x1736, prSTerm}, // Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION + {0x1740, 0x1751, prOLetter}, // Lo [18] BUHID LETTER A..BUHID LETTER HA + {0x1752, 0x1753, prExtend}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1760, 0x176C, prOLetter}, // Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA + {0x176E, 0x1770, prOLetter}, // Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA + {0x1772, 0x1773, prExtend}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x1780, 0x17B3, prOLetter}, // Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU + {0x17B4, 0x17B5, prExtend}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prExtend}, // Mc KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prExtend}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prExtend}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prExtend}, // Mn KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prExtend}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prExtend}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17D7, 0x17D7, prOLetter}, // Lm KHMER SIGN LEK TOO + {0x17DC, 0x17DC, prOLetter}, // Lo KHMER SIGN AVAKRAHASANYA + {0x17DD, 0x17DD, prExtend}, // Mn KHMER SIGN ATTHACAN + {0x17E0, 0x17E9, prNumeric}, // Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE + {0x1802, 0x1802, prSContinue}, // Po MONGOLIAN COMMA + {0x1803, 0x1803, prSTerm}, // Po MONGOLIAN FULL STOP + {0x1808, 0x1808, prSContinue}, // Po MONGOLIAN MANCHU COMMA + {0x1809, 0x1809, prSTerm}, // Po MONGOLIAN MANCHU FULL STOP + {0x180B, 0x180D, prExtend}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prFormat}, // Cf MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prExtend}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1810, 0x1819, prNumeric}, // Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE + {0x1820, 0x1842, prOLetter}, // Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI + {0x1843, 0x1843, prOLetter}, // Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN + {0x1844, 0x1878, prOLetter}, // Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS + {0x1880, 0x1884, prOLetter}, // Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA + {0x1885, 0x1886, prExtend}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x1887, 0x18A8, prOLetter}, // Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA + {0x18A9, 0x18A9, prExtend}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA + {0x18AA, 0x18AA, prOLetter}, // Lo MONGOLIAN LETTER MANCHU ALI GALI LHA + {0x18B0, 0x18F5, prOLetter}, // Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S + {0x1900, 0x191E, prOLetter}, // Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA + {0x1920, 0x1922, prExtend}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prExtend}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prExtend}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prExtend}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prExtend}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prExtend}, // Mn LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prExtend}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prExtend}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1944, 0x1945, prSTerm}, // Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK + {0x1946, 0x194F, prNumeric}, // Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE + {0x1950, 0x196D, prOLetter}, // Lo [30] TAI LE LETTER KA..TAI LE LETTER AI + {0x1970, 0x1974, prOLetter}, // Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 + {0x1980, 0x19AB, prOLetter}, // Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA + {0x19B0, 0x19C9, prOLetter}, // Lo [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2 + {0x19D0, 0x19D9, prNumeric}, // Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE + {0x1A00, 0x1A16, prOLetter}, // Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA + {0x1A17, 0x1A18, prExtend}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prExtend}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prExtend}, // Mn BUGINESE VOWEL SIGN AE + {0x1A20, 0x1A54, prOLetter}, // Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA + {0x1A55, 0x1A55, prExtend}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prExtend}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prExtend}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prExtend}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prExtend}, // Mn TAI THAM SIGN SAKOT + {0x1A61, 0x1A61, prExtend}, // Mc TAI THAM VOWEL SIGN A + {0x1A62, 0x1A62, prExtend}, // Mn TAI THAM VOWEL SIGN MAI SAT + {0x1A63, 0x1A64, prExtend}, // Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA + {0x1A65, 0x1A6C, prExtend}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prExtend}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prExtend}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prExtend}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1A80, 0x1A89, prNumeric}, // Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE + {0x1A90, 0x1A99, prNumeric}, // Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE + {0x1AA7, 0x1AA7, prOLetter}, // Lm TAI THAM SIGN MAI YAMOK + {0x1AA8, 0x1AAB, prSTerm}, // Po [4] TAI THAM SIGN KAAN..TAI THAM SIGN SATKAANKUU + {0x1AB0, 0x1ABD, prExtend}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prExtend}, // Me COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prExtend}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prExtend}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prExtend}, // Mc BALINESE SIGN BISAH + {0x1B05, 0x1B33, prOLetter}, // Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA + {0x1B34, 0x1B34, prExtend}, // Mn BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prExtend}, // Mc BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prExtend}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prExtend}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prExtend}, // Mn BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prExtend}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prExtend}, // Mn BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prExtend}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B45, 0x1B4C, prOLetter}, // Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA + {0x1B50, 0x1B59, prNumeric}, // Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE + {0x1B5A, 0x1B5B, prSTerm}, // Po [2] BALINESE PANTI..BALINESE PAMADA + {0x1B5E, 0x1B5F, prSTerm}, // Po [2] BALINESE CARIK SIKI..BALINESE CARIK PAREREN + {0x1B6B, 0x1B73, prExtend}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B7D, 0x1B7E, prSTerm}, // Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG + {0x1B80, 0x1B81, prExtend}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prExtend}, // Mc SUNDANESE SIGN PANGWISAD + {0x1B83, 0x1BA0, prOLetter}, // Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA + {0x1BA1, 0x1BA1, prExtend}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prExtend}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prExtend}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prExtend}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prExtend}, // Mc SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prExtend}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BAE, 0x1BAF, prOLetter}, // Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA + {0x1BB0, 0x1BB9, prNumeric}, // Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE + {0x1BBA, 0x1BE5, prOLetter}, // Lo [44] SUNDANESE AVAGRAHA..BATAK LETTER U + {0x1BE6, 0x1BE6, prExtend}, // Mn BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prExtend}, // Mc BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prExtend}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prExtend}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prExtend}, // Mn BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prExtend}, // Mc BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prExtend}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prExtend}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1C00, 0x1C23, prOLetter}, // Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A + {0x1C24, 0x1C2B, prExtend}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prExtend}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prExtend}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prExtend}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1C3B, 0x1C3C, prSTerm}, // Po [2] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION NYET THYOOM TA-ROL + {0x1C40, 0x1C49, prNumeric}, // Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE + {0x1C4D, 0x1C4F, prOLetter}, // Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA + {0x1C50, 0x1C59, prNumeric}, // Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE + {0x1C5A, 0x1C77, prOLetter}, // Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH + {0x1C78, 0x1C7D, prOLetter}, // Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD + {0x1C7E, 0x1C7F, prSTerm}, // Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD + {0x1C80, 0x1C88, prLower}, // L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK + {0x1C90, 0x1CBA, prOLetter}, // L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN + {0x1CBD, 0x1CBF, prOLetter}, // L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN + {0x1CD0, 0x1CD2, prExtend}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD4, 0x1CE0, prExtend}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prExtend}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prExtend}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CE9, 0x1CEC, prOLetter}, // Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL + {0x1CED, 0x1CED, prExtend}, // Mn VEDIC SIGN TIRYAK + {0x1CEE, 0x1CF3, prOLetter}, // Lo [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA + {0x1CF4, 0x1CF4, prExtend}, // Mn VEDIC TONE CANDRA ABOVE + {0x1CF5, 0x1CF6, prOLetter}, // Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA + {0x1CF7, 0x1CF7, prExtend}, // Mc VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prExtend}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1CFA, 0x1CFA, prOLetter}, // Lo VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA + {0x1D00, 0x1D2B, prLower}, // L& [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL + {0x1D2C, 0x1D6A, prLower}, // Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI + {0x1D6B, 0x1D77, prLower}, // L& [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G + {0x1D78, 0x1D78, prLower}, // Lm MODIFIER LETTER CYRILLIC EN + {0x1D79, 0x1D9A, prLower}, // L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK + {0x1D9B, 0x1DBF, prLower}, // Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA + {0x1DC0, 0x1DFF, prExtend}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x1E00, 0x1E00, prUpper}, // L& LATIN CAPITAL LETTER A WITH RING BELOW + {0x1E01, 0x1E01, prLower}, // L& LATIN SMALL LETTER A WITH RING BELOW + {0x1E02, 0x1E02, prUpper}, // L& LATIN CAPITAL LETTER B WITH DOT ABOVE + {0x1E03, 0x1E03, prLower}, // L& LATIN SMALL LETTER B WITH DOT ABOVE + {0x1E04, 0x1E04, prUpper}, // L& LATIN CAPITAL LETTER B WITH DOT BELOW + {0x1E05, 0x1E05, prLower}, // L& LATIN SMALL LETTER B WITH DOT BELOW + {0x1E06, 0x1E06, prUpper}, // L& LATIN CAPITAL LETTER B WITH LINE BELOW + {0x1E07, 0x1E07, prLower}, // L& LATIN SMALL LETTER B WITH LINE BELOW + {0x1E08, 0x1E08, prUpper}, // L& LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE + {0x1E09, 0x1E09, prLower}, // L& LATIN SMALL LETTER C WITH CEDILLA AND ACUTE + {0x1E0A, 0x1E0A, prUpper}, // L& LATIN CAPITAL LETTER D WITH DOT ABOVE + {0x1E0B, 0x1E0B, prLower}, // L& LATIN SMALL LETTER D WITH DOT ABOVE + {0x1E0C, 0x1E0C, prUpper}, // L& LATIN CAPITAL LETTER D WITH DOT BELOW + {0x1E0D, 0x1E0D, prLower}, // L& LATIN SMALL LETTER D WITH DOT BELOW + {0x1E0E, 0x1E0E, prUpper}, // L& LATIN CAPITAL LETTER D WITH LINE BELOW + {0x1E0F, 0x1E0F, prLower}, // L& LATIN SMALL LETTER D WITH LINE BELOW + {0x1E10, 0x1E10, prUpper}, // L& LATIN CAPITAL LETTER D WITH CEDILLA + {0x1E11, 0x1E11, prLower}, // L& LATIN SMALL LETTER D WITH CEDILLA + {0x1E12, 0x1E12, prUpper}, // L& LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW + {0x1E13, 0x1E13, prLower}, // L& LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW + {0x1E14, 0x1E14, prUpper}, // L& LATIN CAPITAL LETTER E WITH MACRON AND GRAVE + {0x1E15, 0x1E15, prLower}, // L& LATIN SMALL LETTER E WITH MACRON AND GRAVE + {0x1E16, 0x1E16, prUpper}, // L& LATIN CAPITAL LETTER E WITH MACRON AND ACUTE + {0x1E17, 0x1E17, prLower}, // L& LATIN SMALL LETTER E WITH MACRON AND ACUTE + {0x1E18, 0x1E18, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW + {0x1E19, 0x1E19, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW + {0x1E1A, 0x1E1A, prUpper}, // L& LATIN CAPITAL LETTER E WITH TILDE BELOW + {0x1E1B, 0x1E1B, prLower}, // L& LATIN SMALL LETTER E WITH TILDE BELOW + {0x1E1C, 0x1E1C, prUpper}, // L& LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE + {0x1E1D, 0x1E1D, prLower}, // L& LATIN SMALL LETTER E WITH CEDILLA AND BREVE + {0x1E1E, 0x1E1E, prUpper}, // L& LATIN CAPITAL LETTER F WITH DOT ABOVE + {0x1E1F, 0x1E1F, prLower}, // L& LATIN SMALL LETTER F WITH DOT ABOVE + {0x1E20, 0x1E20, prUpper}, // L& LATIN CAPITAL LETTER G WITH MACRON + {0x1E21, 0x1E21, prLower}, // L& LATIN SMALL LETTER G WITH MACRON + {0x1E22, 0x1E22, prUpper}, // L& LATIN CAPITAL LETTER H WITH DOT ABOVE + {0x1E23, 0x1E23, prLower}, // L& LATIN SMALL LETTER H WITH DOT ABOVE + {0x1E24, 0x1E24, prUpper}, // L& LATIN CAPITAL LETTER H WITH DOT BELOW + {0x1E25, 0x1E25, prLower}, // L& LATIN SMALL LETTER H WITH DOT BELOW + {0x1E26, 0x1E26, prUpper}, // L& LATIN CAPITAL LETTER H WITH DIAERESIS + {0x1E27, 0x1E27, prLower}, // L& LATIN SMALL LETTER H WITH DIAERESIS + {0x1E28, 0x1E28, prUpper}, // L& LATIN CAPITAL LETTER H WITH CEDILLA + {0x1E29, 0x1E29, prLower}, // L& LATIN SMALL LETTER H WITH CEDILLA + {0x1E2A, 0x1E2A, prUpper}, // L& LATIN CAPITAL LETTER H WITH BREVE BELOW + {0x1E2B, 0x1E2B, prLower}, // L& LATIN SMALL LETTER H WITH BREVE BELOW + {0x1E2C, 0x1E2C, prUpper}, // L& LATIN CAPITAL LETTER I WITH TILDE BELOW + {0x1E2D, 0x1E2D, prLower}, // L& LATIN SMALL LETTER I WITH TILDE BELOW + {0x1E2E, 0x1E2E, prUpper}, // L& LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE + {0x1E2F, 0x1E2F, prLower}, // L& LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE + {0x1E30, 0x1E30, prUpper}, // L& LATIN CAPITAL LETTER K WITH ACUTE + {0x1E31, 0x1E31, prLower}, // L& LATIN SMALL LETTER K WITH ACUTE + {0x1E32, 0x1E32, prUpper}, // L& LATIN CAPITAL LETTER K WITH DOT BELOW + {0x1E33, 0x1E33, prLower}, // L& LATIN SMALL LETTER K WITH DOT BELOW + {0x1E34, 0x1E34, prUpper}, // L& LATIN CAPITAL LETTER K WITH LINE BELOW + {0x1E35, 0x1E35, prLower}, // L& LATIN SMALL LETTER K WITH LINE BELOW + {0x1E36, 0x1E36, prUpper}, // L& LATIN CAPITAL LETTER L WITH DOT BELOW + {0x1E37, 0x1E37, prLower}, // L& LATIN SMALL LETTER L WITH DOT BELOW + {0x1E38, 0x1E38, prUpper}, // L& LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON + {0x1E39, 0x1E39, prLower}, // L& LATIN SMALL LETTER L WITH DOT BELOW AND MACRON + {0x1E3A, 0x1E3A, prUpper}, // L& LATIN CAPITAL LETTER L WITH LINE BELOW + {0x1E3B, 0x1E3B, prLower}, // L& LATIN SMALL LETTER L WITH LINE BELOW + {0x1E3C, 0x1E3C, prUpper}, // L& LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW + {0x1E3D, 0x1E3D, prLower}, // L& LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW + {0x1E3E, 0x1E3E, prUpper}, // L& LATIN CAPITAL LETTER M WITH ACUTE + {0x1E3F, 0x1E3F, prLower}, // L& LATIN SMALL LETTER M WITH ACUTE + {0x1E40, 0x1E40, prUpper}, // L& LATIN CAPITAL LETTER M WITH DOT ABOVE + {0x1E41, 0x1E41, prLower}, // L& LATIN SMALL LETTER M WITH DOT ABOVE + {0x1E42, 0x1E42, prUpper}, // L& LATIN CAPITAL LETTER M WITH DOT BELOW + {0x1E43, 0x1E43, prLower}, // L& LATIN SMALL LETTER M WITH DOT BELOW + {0x1E44, 0x1E44, prUpper}, // L& LATIN CAPITAL LETTER N WITH DOT ABOVE + {0x1E45, 0x1E45, prLower}, // L& LATIN SMALL LETTER N WITH DOT ABOVE + {0x1E46, 0x1E46, prUpper}, // L& LATIN CAPITAL LETTER N WITH DOT BELOW + {0x1E47, 0x1E47, prLower}, // L& LATIN SMALL LETTER N WITH DOT BELOW + {0x1E48, 0x1E48, prUpper}, // L& LATIN CAPITAL LETTER N WITH LINE BELOW + {0x1E49, 0x1E49, prLower}, // L& LATIN SMALL LETTER N WITH LINE BELOW + {0x1E4A, 0x1E4A, prUpper}, // L& LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW + {0x1E4B, 0x1E4B, prLower}, // L& LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW + {0x1E4C, 0x1E4C, prUpper}, // L& LATIN CAPITAL LETTER O WITH TILDE AND ACUTE + {0x1E4D, 0x1E4D, prLower}, // L& LATIN SMALL LETTER O WITH TILDE AND ACUTE + {0x1E4E, 0x1E4E, prUpper}, // L& LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS + {0x1E4F, 0x1E4F, prLower}, // L& LATIN SMALL LETTER O WITH TILDE AND DIAERESIS + {0x1E50, 0x1E50, prUpper}, // L& LATIN CAPITAL LETTER O WITH MACRON AND GRAVE + {0x1E51, 0x1E51, prLower}, // L& LATIN SMALL LETTER O WITH MACRON AND GRAVE + {0x1E52, 0x1E52, prUpper}, // L& LATIN CAPITAL LETTER O WITH MACRON AND ACUTE + {0x1E53, 0x1E53, prLower}, // L& LATIN SMALL LETTER O WITH MACRON AND ACUTE + {0x1E54, 0x1E54, prUpper}, // L& LATIN CAPITAL LETTER P WITH ACUTE + {0x1E55, 0x1E55, prLower}, // L& LATIN SMALL LETTER P WITH ACUTE + {0x1E56, 0x1E56, prUpper}, // L& LATIN CAPITAL LETTER P WITH DOT ABOVE + {0x1E57, 0x1E57, prLower}, // L& LATIN SMALL LETTER P WITH DOT ABOVE + {0x1E58, 0x1E58, prUpper}, // L& LATIN CAPITAL LETTER R WITH DOT ABOVE + {0x1E59, 0x1E59, prLower}, // L& LATIN SMALL LETTER R WITH DOT ABOVE + {0x1E5A, 0x1E5A, prUpper}, // L& LATIN CAPITAL LETTER R WITH DOT BELOW + {0x1E5B, 0x1E5B, prLower}, // L& LATIN SMALL LETTER R WITH DOT BELOW + {0x1E5C, 0x1E5C, prUpper}, // L& LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON + {0x1E5D, 0x1E5D, prLower}, // L& LATIN SMALL LETTER R WITH DOT BELOW AND MACRON + {0x1E5E, 0x1E5E, prUpper}, // L& LATIN CAPITAL LETTER R WITH LINE BELOW + {0x1E5F, 0x1E5F, prLower}, // L& LATIN SMALL LETTER R WITH LINE BELOW + {0x1E60, 0x1E60, prUpper}, // L& LATIN CAPITAL LETTER S WITH DOT ABOVE + {0x1E61, 0x1E61, prLower}, // L& LATIN SMALL LETTER S WITH DOT ABOVE + {0x1E62, 0x1E62, prUpper}, // L& LATIN CAPITAL LETTER S WITH DOT BELOW + {0x1E63, 0x1E63, prLower}, // L& LATIN SMALL LETTER S WITH DOT BELOW + {0x1E64, 0x1E64, prUpper}, // L& LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE + {0x1E65, 0x1E65, prLower}, // L& LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE + {0x1E66, 0x1E66, prUpper}, // L& LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE + {0x1E67, 0x1E67, prLower}, // L& LATIN SMALL LETTER S WITH CARON AND DOT ABOVE + {0x1E68, 0x1E68, prUpper}, // L& LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE + {0x1E69, 0x1E69, prLower}, // L& LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE + {0x1E6A, 0x1E6A, prUpper}, // L& LATIN CAPITAL LETTER T WITH DOT ABOVE + {0x1E6B, 0x1E6B, prLower}, // L& LATIN SMALL LETTER T WITH DOT ABOVE + {0x1E6C, 0x1E6C, prUpper}, // L& LATIN CAPITAL LETTER T WITH DOT BELOW + {0x1E6D, 0x1E6D, prLower}, // L& LATIN SMALL LETTER T WITH DOT BELOW + {0x1E6E, 0x1E6E, prUpper}, // L& LATIN CAPITAL LETTER T WITH LINE BELOW + {0x1E6F, 0x1E6F, prLower}, // L& LATIN SMALL LETTER T WITH LINE BELOW + {0x1E70, 0x1E70, prUpper}, // L& LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW + {0x1E71, 0x1E71, prLower}, // L& LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW + {0x1E72, 0x1E72, prUpper}, // L& LATIN CAPITAL LETTER U WITH DIAERESIS BELOW + {0x1E73, 0x1E73, prLower}, // L& LATIN SMALL LETTER U WITH DIAERESIS BELOW + {0x1E74, 0x1E74, prUpper}, // L& LATIN CAPITAL LETTER U WITH TILDE BELOW + {0x1E75, 0x1E75, prLower}, // L& LATIN SMALL LETTER U WITH TILDE BELOW + {0x1E76, 0x1E76, prUpper}, // L& LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW + {0x1E77, 0x1E77, prLower}, // L& LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW + {0x1E78, 0x1E78, prUpper}, // L& LATIN CAPITAL LETTER U WITH TILDE AND ACUTE + {0x1E79, 0x1E79, prLower}, // L& LATIN SMALL LETTER U WITH TILDE AND ACUTE + {0x1E7A, 0x1E7A, prUpper}, // L& LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS + {0x1E7B, 0x1E7B, prLower}, // L& LATIN SMALL LETTER U WITH MACRON AND DIAERESIS + {0x1E7C, 0x1E7C, prUpper}, // L& LATIN CAPITAL LETTER V WITH TILDE + {0x1E7D, 0x1E7D, prLower}, // L& LATIN SMALL LETTER V WITH TILDE + {0x1E7E, 0x1E7E, prUpper}, // L& LATIN CAPITAL LETTER V WITH DOT BELOW + {0x1E7F, 0x1E7F, prLower}, // L& LATIN SMALL LETTER V WITH DOT BELOW + {0x1E80, 0x1E80, prUpper}, // L& LATIN CAPITAL LETTER W WITH GRAVE + {0x1E81, 0x1E81, prLower}, // L& LATIN SMALL LETTER W WITH GRAVE + {0x1E82, 0x1E82, prUpper}, // L& LATIN CAPITAL LETTER W WITH ACUTE + {0x1E83, 0x1E83, prLower}, // L& LATIN SMALL LETTER W WITH ACUTE + {0x1E84, 0x1E84, prUpper}, // L& LATIN CAPITAL LETTER W WITH DIAERESIS + {0x1E85, 0x1E85, prLower}, // L& LATIN SMALL LETTER W WITH DIAERESIS + {0x1E86, 0x1E86, prUpper}, // L& LATIN CAPITAL LETTER W WITH DOT ABOVE + {0x1E87, 0x1E87, prLower}, // L& LATIN SMALL LETTER W WITH DOT ABOVE + {0x1E88, 0x1E88, prUpper}, // L& LATIN CAPITAL LETTER W WITH DOT BELOW + {0x1E89, 0x1E89, prLower}, // L& LATIN SMALL LETTER W WITH DOT BELOW + {0x1E8A, 0x1E8A, prUpper}, // L& LATIN CAPITAL LETTER X WITH DOT ABOVE + {0x1E8B, 0x1E8B, prLower}, // L& LATIN SMALL LETTER X WITH DOT ABOVE + {0x1E8C, 0x1E8C, prUpper}, // L& LATIN CAPITAL LETTER X WITH DIAERESIS + {0x1E8D, 0x1E8D, prLower}, // L& LATIN SMALL LETTER X WITH DIAERESIS + {0x1E8E, 0x1E8E, prUpper}, // L& LATIN CAPITAL LETTER Y WITH DOT ABOVE + {0x1E8F, 0x1E8F, prLower}, // L& LATIN SMALL LETTER Y WITH DOT ABOVE + {0x1E90, 0x1E90, prUpper}, // L& LATIN CAPITAL LETTER Z WITH CIRCUMFLEX + {0x1E91, 0x1E91, prLower}, // L& LATIN SMALL LETTER Z WITH CIRCUMFLEX + {0x1E92, 0x1E92, prUpper}, // L& LATIN CAPITAL LETTER Z WITH DOT BELOW + {0x1E93, 0x1E93, prLower}, // L& LATIN SMALL LETTER Z WITH DOT BELOW + {0x1E94, 0x1E94, prUpper}, // L& LATIN CAPITAL LETTER Z WITH LINE BELOW + {0x1E95, 0x1E9D, prLower}, // L& [9] LATIN SMALL LETTER Z WITH LINE BELOW..LATIN SMALL LETTER LONG S WITH HIGH STROKE + {0x1E9E, 0x1E9E, prUpper}, // L& LATIN CAPITAL LETTER SHARP S + {0x1E9F, 0x1E9F, prLower}, // L& LATIN SMALL LETTER DELTA + {0x1EA0, 0x1EA0, prUpper}, // L& LATIN CAPITAL LETTER A WITH DOT BELOW + {0x1EA1, 0x1EA1, prLower}, // L& LATIN SMALL LETTER A WITH DOT BELOW + {0x1EA2, 0x1EA2, prUpper}, // L& LATIN CAPITAL LETTER A WITH HOOK ABOVE + {0x1EA3, 0x1EA3, prLower}, // L& LATIN SMALL LETTER A WITH HOOK ABOVE + {0x1EA4, 0x1EA4, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE + {0x1EA5, 0x1EA5, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE + {0x1EA6, 0x1EA6, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE + {0x1EA7, 0x1EA7, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE + {0x1EA8, 0x1EA8, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE + {0x1EA9, 0x1EA9, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE + {0x1EAA, 0x1EAA, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE + {0x1EAB, 0x1EAB, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE + {0x1EAC, 0x1EAC, prUpper}, // L& LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW + {0x1EAD, 0x1EAD, prLower}, // L& LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW + {0x1EAE, 0x1EAE, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND ACUTE + {0x1EAF, 0x1EAF, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND ACUTE + {0x1EB0, 0x1EB0, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND GRAVE + {0x1EB1, 0x1EB1, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND GRAVE + {0x1EB2, 0x1EB2, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE + {0x1EB3, 0x1EB3, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE + {0x1EB4, 0x1EB4, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND TILDE + {0x1EB5, 0x1EB5, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND TILDE + {0x1EB6, 0x1EB6, prUpper}, // L& LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW + {0x1EB7, 0x1EB7, prLower}, // L& LATIN SMALL LETTER A WITH BREVE AND DOT BELOW + {0x1EB8, 0x1EB8, prUpper}, // L& LATIN CAPITAL LETTER E WITH DOT BELOW + {0x1EB9, 0x1EB9, prLower}, // L& LATIN SMALL LETTER E WITH DOT BELOW + {0x1EBA, 0x1EBA, prUpper}, // L& LATIN CAPITAL LETTER E WITH HOOK ABOVE + {0x1EBB, 0x1EBB, prLower}, // L& LATIN SMALL LETTER E WITH HOOK ABOVE + {0x1EBC, 0x1EBC, prUpper}, // L& LATIN CAPITAL LETTER E WITH TILDE + {0x1EBD, 0x1EBD, prLower}, // L& LATIN SMALL LETTER E WITH TILDE + {0x1EBE, 0x1EBE, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE + {0x1EBF, 0x1EBF, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE + {0x1EC0, 0x1EC0, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE + {0x1EC1, 0x1EC1, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE + {0x1EC2, 0x1EC2, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE + {0x1EC3, 0x1EC3, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE + {0x1EC4, 0x1EC4, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE + {0x1EC5, 0x1EC5, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE + {0x1EC6, 0x1EC6, prUpper}, // L& LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW + {0x1EC7, 0x1EC7, prLower}, // L& LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW + {0x1EC8, 0x1EC8, prUpper}, // L& LATIN CAPITAL LETTER I WITH HOOK ABOVE + {0x1EC9, 0x1EC9, prLower}, // L& LATIN SMALL LETTER I WITH HOOK ABOVE + {0x1ECA, 0x1ECA, prUpper}, // L& LATIN CAPITAL LETTER I WITH DOT BELOW + {0x1ECB, 0x1ECB, prLower}, // L& LATIN SMALL LETTER I WITH DOT BELOW + {0x1ECC, 0x1ECC, prUpper}, // L& LATIN CAPITAL LETTER O WITH DOT BELOW + {0x1ECD, 0x1ECD, prLower}, // L& LATIN SMALL LETTER O WITH DOT BELOW + {0x1ECE, 0x1ECE, prUpper}, // L& LATIN CAPITAL LETTER O WITH HOOK ABOVE + {0x1ECF, 0x1ECF, prLower}, // L& LATIN SMALL LETTER O WITH HOOK ABOVE + {0x1ED0, 0x1ED0, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE + {0x1ED1, 0x1ED1, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE + {0x1ED2, 0x1ED2, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE + {0x1ED3, 0x1ED3, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE + {0x1ED4, 0x1ED4, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE + {0x1ED5, 0x1ED5, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE + {0x1ED6, 0x1ED6, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE + {0x1ED7, 0x1ED7, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE + {0x1ED8, 0x1ED8, prUpper}, // L& LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW + {0x1ED9, 0x1ED9, prLower}, // L& LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW + {0x1EDA, 0x1EDA, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND ACUTE + {0x1EDB, 0x1EDB, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND ACUTE + {0x1EDC, 0x1EDC, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND GRAVE + {0x1EDD, 0x1EDD, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND GRAVE + {0x1EDE, 0x1EDE, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE + {0x1EDF, 0x1EDF, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE + {0x1EE0, 0x1EE0, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND TILDE + {0x1EE1, 0x1EE1, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND TILDE + {0x1EE2, 0x1EE2, prUpper}, // L& LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW + {0x1EE3, 0x1EE3, prLower}, // L& LATIN SMALL LETTER O WITH HORN AND DOT BELOW + {0x1EE4, 0x1EE4, prUpper}, // L& LATIN CAPITAL LETTER U WITH DOT BELOW + {0x1EE5, 0x1EE5, prLower}, // L& LATIN SMALL LETTER U WITH DOT BELOW + {0x1EE6, 0x1EE6, prUpper}, // L& LATIN CAPITAL LETTER U WITH HOOK ABOVE + {0x1EE7, 0x1EE7, prLower}, // L& LATIN SMALL LETTER U WITH HOOK ABOVE + {0x1EE8, 0x1EE8, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND ACUTE + {0x1EE9, 0x1EE9, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND ACUTE + {0x1EEA, 0x1EEA, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND GRAVE + {0x1EEB, 0x1EEB, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND GRAVE + {0x1EEC, 0x1EEC, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE + {0x1EED, 0x1EED, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE + {0x1EEE, 0x1EEE, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND TILDE + {0x1EEF, 0x1EEF, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND TILDE + {0x1EF0, 0x1EF0, prUpper}, // L& LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW + {0x1EF1, 0x1EF1, prLower}, // L& LATIN SMALL LETTER U WITH HORN AND DOT BELOW + {0x1EF2, 0x1EF2, prUpper}, // L& LATIN CAPITAL LETTER Y WITH GRAVE + {0x1EF3, 0x1EF3, prLower}, // L& LATIN SMALL LETTER Y WITH GRAVE + {0x1EF4, 0x1EF4, prUpper}, // L& LATIN CAPITAL LETTER Y WITH DOT BELOW + {0x1EF5, 0x1EF5, prLower}, // L& LATIN SMALL LETTER Y WITH DOT BELOW + {0x1EF6, 0x1EF6, prUpper}, // L& LATIN CAPITAL LETTER Y WITH HOOK ABOVE + {0x1EF7, 0x1EF7, prLower}, // L& LATIN SMALL LETTER Y WITH HOOK ABOVE + {0x1EF8, 0x1EF8, prUpper}, // L& LATIN CAPITAL LETTER Y WITH TILDE + {0x1EF9, 0x1EF9, prLower}, // L& LATIN SMALL LETTER Y WITH TILDE + {0x1EFA, 0x1EFA, prUpper}, // L& LATIN CAPITAL LETTER MIDDLE-WELSH LL + {0x1EFB, 0x1EFB, prLower}, // L& LATIN SMALL LETTER MIDDLE-WELSH LL + {0x1EFC, 0x1EFC, prUpper}, // L& LATIN CAPITAL LETTER MIDDLE-WELSH V + {0x1EFD, 0x1EFD, prLower}, // L& LATIN SMALL LETTER MIDDLE-WELSH V + {0x1EFE, 0x1EFE, prUpper}, // L& LATIN CAPITAL LETTER Y WITH LOOP + {0x1EFF, 0x1F07, prLower}, // L& [9] LATIN SMALL LETTER Y WITH LOOP..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI + {0x1F08, 0x1F0F, prUpper}, // L& [8] GREEK CAPITAL LETTER ALPHA WITH PSILI..GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI + {0x1F10, 0x1F15, prLower}, // L& [6] GREEK SMALL LETTER EPSILON WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA + {0x1F18, 0x1F1D, prUpper}, // L& [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA + {0x1F20, 0x1F27, prLower}, // L& [8] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI + {0x1F28, 0x1F2F, prUpper}, // L& [8] GREEK CAPITAL LETTER ETA WITH PSILI..GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI + {0x1F30, 0x1F37, prLower}, // L& [8] GREEK SMALL LETTER IOTA WITH PSILI..GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI + {0x1F38, 0x1F3F, prUpper}, // L& [8] GREEK CAPITAL LETTER IOTA WITH PSILI..GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI + {0x1F40, 0x1F45, prLower}, // L& [6] GREEK SMALL LETTER OMICRON WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA + {0x1F48, 0x1F4D, prUpper}, // L& [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA + {0x1F50, 0x1F57, prLower}, // L& [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F59, 0x1F59, prUpper}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA + {0x1F5B, 0x1F5B, prUpper}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA + {0x1F5D, 0x1F5D, prUpper}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA + {0x1F5F, 0x1F5F, prUpper}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F60, 0x1F67, prLower}, // L& [8] GREEK SMALL LETTER OMEGA WITH PSILI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI + {0x1F68, 0x1F6F, prUpper}, // L& [8] GREEK CAPITAL LETTER OMEGA WITH PSILI..GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI + {0x1F70, 0x1F7D, prLower}, // L& [14] GREEK SMALL LETTER ALPHA WITH VARIA..GREEK SMALL LETTER OMEGA WITH OXIA + {0x1F80, 0x1F87, prLower}, // L& [8] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI + {0x1F88, 0x1F8F, prUpper}, // L& [8] GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI + {0x1F90, 0x1F97, prLower}, // L& [8] GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI + {0x1F98, 0x1F9F, prUpper}, // L& [8] GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI + {0x1FA0, 0x1FA7, prLower}, // L& [8] GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI + {0x1FA8, 0x1FAF, prUpper}, // L& [8] GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI + {0x1FB0, 0x1FB4, prLower}, // L& [5] GREEK SMALL LETTER ALPHA WITH VRACHY..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI + {0x1FB6, 0x1FB7, prLower}, // L& [2] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI + {0x1FB8, 0x1FBC, prUpper}, // L& [5] GREEK CAPITAL LETTER ALPHA WITH VRACHY..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI + {0x1FBE, 0x1FBE, prLower}, // L& GREEK PROSGEGRAMMENI + {0x1FC2, 0x1FC4, prLower}, // L& [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI + {0x1FC6, 0x1FC7, prLower}, // L& [2] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI + {0x1FC8, 0x1FCC, prUpper}, // L& [5] GREEK CAPITAL LETTER EPSILON WITH VARIA..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI + {0x1FD0, 0x1FD3, prLower}, // L& [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + {0x1FD6, 0x1FD7, prLower}, // L& [2] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI + {0x1FD8, 0x1FDB, prUpper}, // L& [4] GREEK CAPITAL LETTER IOTA WITH VRACHY..GREEK CAPITAL LETTER IOTA WITH OXIA + {0x1FE0, 0x1FE7, prLower}, // L& [8] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI + {0x1FE8, 0x1FEC, prUpper}, // L& [5] GREEK CAPITAL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA + {0x1FF2, 0x1FF4, prLower}, // L& [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI + {0x1FF6, 0x1FF7, prLower}, // L& [2] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI + {0x1FF8, 0x1FFC, prUpper}, // L& [5] GREEK CAPITAL LETTER OMICRON WITH VARIA..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + {0x2000, 0x200A, prSp}, // Zs [11] EN QUAD..HAIR SPACE + {0x200B, 0x200B, prFormat}, // Cf ZERO WIDTH SPACE + {0x200C, 0x200D, prExtend}, // Cf [2] ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER + {0x200E, 0x200F, prFormat}, // Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK + {0x2013, 0x2014, prSContinue}, // Pd [2] EN DASH..EM DASH + {0x2018, 0x2018, prClose}, // Pi LEFT SINGLE QUOTATION MARK + {0x2019, 0x2019, prClose}, // Pf RIGHT SINGLE QUOTATION MARK + {0x201A, 0x201A, prClose}, // Ps SINGLE LOW-9 QUOTATION MARK + {0x201B, 0x201C, prClose}, // Pi [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK + {0x201D, 0x201D, prClose}, // Pf RIGHT DOUBLE QUOTATION MARK + {0x201E, 0x201E, prClose}, // Ps DOUBLE LOW-9 QUOTATION MARK + {0x201F, 0x201F, prClose}, // Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK + {0x2024, 0x2024, prATerm}, // Po ONE DOT LEADER + {0x2028, 0x2028, prSep}, // Zl LINE SEPARATOR + {0x2029, 0x2029, prSep}, // Zp PARAGRAPH SEPARATOR + {0x202A, 0x202E, prFormat}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x202F, 0x202F, prSp}, // Zs NARROW NO-BREAK SPACE + {0x2039, 0x2039, prClose}, // Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK + {0x203A, 0x203A, prClose}, // Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + {0x203C, 0x203D, prSTerm}, // Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG + {0x2045, 0x2045, prClose}, // Ps LEFT SQUARE BRACKET WITH QUILL + {0x2046, 0x2046, prClose}, // Pe RIGHT SQUARE BRACKET WITH QUILL + {0x2047, 0x2049, prSTerm}, // Po [3] DOUBLE QUESTION MARK..EXCLAMATION QUESTION MARK + {0x205F, 0x205F, prSp}, // Zs MEDIUM MATHEMATICAL SPACE + {0x2060, 0x2064, prFormat}, // Cf [5] WORD JOINER..INVISIBLE PLUS + {0x2066, 0x206F, prFormat}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x2071, 0x2071, prLower}, // Lm SUPERSCRIPT LATIN SMALL LETTER I + {0x207D, 0x207D, prClose}, // Ps SUPERSCRIPT LEFT PARENTHESIS + {0x207E, 0x207E, prClose}, // Pe SUPERSCRIPT RIGHT PARENTHESIS + {0x207F, 0x207F, prLower}, // Lm SUPERSCRIPT LATIN SMALL LETTER N + {0x208D, 0x208D, prClose}, // Ps SUBSCRIPT LEFT PARENTHESIS + {0x208E, 0x208E, prClose}, // Pe SUBSCRIPT RIGHT PARENTHESIS + {0x2090, 0x209C, prLower}, // Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T + {0x20D0, 0x20DC, prExtend}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prExtend}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prExtend}, // Mn COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prExtend}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prExtend}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2102, 0x2102, prUpper}, // L& DOUBLE-STRUCK CAPITAL C + {0x2107, 0x2107, prUpper}, // L& EULER CONSTANT + {0x210A, 0x210A, prLower}, // L& SCRIPT SMALL G + {0x210B, 0x210D, prUpper}, // L& [3] SCRIPT CAPITAL H..DOUBLE-STRUCK CAPITAL H + {0x210E, 0x210F, prLower}, // L& [2] PLANCK CONSTANT..PLANCK CONSTANT OVER TWO PI + {0x2110, 0x2112, prUpper}, // L& [3] SCRIPT CAPITAL I..SCRIPT CAPITAL L + {0x2113, 0x2113, prLower}, // L& SCRIPT SMALL L + {0x2115, 0x2115, prUpper}, // L& DOUBLE-STRUCK CAPITAL N + {0x2119, 0x211D, prUpper}, // L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R + {0x2124, 0x2124, prUpper}, // L& DOUBLE-STRUCK CAPITAL Z + {0x2126, 0x2126, prUpper}, // L& OHM SIGN + {0x2128, 0x2128, prUpper}, // L& BLACK-LETTER CAPITAL Z + {0x212A, 0x212D, prUpper}, // L& [4] KELVIN SIGN..BLACK-LETTER CAPITAL C + {0x212F, 0x212F, prLower}, // L& SCRIPT SMALL E + {0x2130, 0x2133, prUpper}, // L& [4] SCRIPT CAPITAL E..SCRIPT CAPITAL M + {0x2134, 0x2134, prLower}, // L& SCRIPT SMALL O + {0x2135, 0x2138, prOLetter}, // Lo [4] ALEF SYMBOL..DALET SYMBOL + {0x2139, 0x2139, prLower}, // L& INFORMATION SOURCE + {0x213C, 0x213D, prLower}, // L& [2] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK SMALL GAMMA + {0x213E, 0x213F, prUpper}, // L& [2] DOUBLE-STRUCK CAPITAL GAMMA..DOUBLE-STRUCK CAPITAL PI + {0x2145, 0x2145, prUpper}, // L& DOUBLE-STRUCK ITALIC CAPITAL D + {0x2146, 0x2149, prLower}, // L& [4] DOUBLE-STRUCK ITALIC SMALL D..DOUBLE-STRUCK ITALIC SMALL J + {0x214E, 0x214E, prLower}, // L& TURNED SMALL F + {0x2160, 0x216F, prUpper}, // Nl [16] ROMAN NUMERAL ONE..ROMAN NUMERAL ONE THOUSAND + {0x2170, 0x217F, prLower}, // Nl [16] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND + {0x2180, 0x2182, prOLetter}, // Nl [3] ROMAN NUMERAL ONE THOUSAND C D..ROMAN NUMERAL TEN THOUSAND + {0x2183, 0x2183, prUpper}, // L& ROMAN NUMERAL REVERSED ONE HUNDRED + {0x2184, 0x2184, prLower}, // L& LATIN SMALL LETTER REVERSED C + {0x2185, 0x2188, prOLetter}, // Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND + {0x2308, 0x2308, prClose}, // Ps LEFT CEILING + {0x2309, 0x2309, prClose}, // Pe RIGHT CEILING + {0x230A, 0x230A, prClose}, // Ps LEFT FLOOR + {0x230B, 0x230B, prClose}, // Pe RIGHT FLOOR + {0x2329, 0x2329, prClose}, // Ps LEFT-POINTING ANGLE BRACKET + {0x232A, 0x232A, prClose}, // Pe RIGHT-POINTING ANGLE BRACKET + {0x24B6, 0x24CF, prUpper}, // So [26] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN CAPITAL LETTER Z + {0x24D0, 0x24E9, prLower}, // So [26] CIRCLED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z + {0x275B, 0x2760, prClose}, // So [6] HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT..HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT + {0x2768, 0x2768, prClose}, // Ps MEDIUM LEFT PARENTHESIS ORNAMENT + {0x2769, 0x2769, prClose}, // Pe MEDIUM RIGHT PARENTHESIS ORNAMENT + {0x276A, 0x276A, prClose}, // Ps MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT + {0x276B, 0x276B, prClose}, // Pe MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT + {0x276C, 0x276C, prClose}, // Ps MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x276D, 0x276D, prClose}, // Pe MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x276E, 0x276E, prClose}, // Ps HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x276F, 0x276F, prClose}, // Pe HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT + {0x2770, 0x2770, prClose}, // Ps HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT + {0x2771, 0x2771, prClose}, // Pe HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT + {0x2772, 0x2772, prClose}, // Ps LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + {0x2773, 0x2773, prClose}, // Pe LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + {0x2774, 0x2774, prClose}, // Ps MEDIUM LEFT CURLY BRACKET ORNAMENT + {0x2775, 0x2775, prClose}, // Pe MEDIUM RIGHT CURLY BRACKET ORNAMENT + {0x27C5, 0x27C5, prClose}, // Ps LEFT S-SHAPED BAG DELIMITER + {0x27C6, 0x27C6, prClose}, // Pe RIGHT S-SHAPED BAG DELIMITER + {0x27E6, 0x27E6, prClose}, // Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET + {0x27E7, 0x27E7, prClose}, // Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET + {0x27E8, 0x27E8, prClose}, // Ps MATHEMATICAL LEFT ANGLE BRACKET + {0x27E9, 0x27E9, prClose}, // Pe MATHEMATICAL RIGHT ANGLE BRACKET + {0x27EA, 0x27EA, prClose}, // Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + {0x27EB, 0x27EB, prClose}, // Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + {0x27EC, 0x27EC, prClose}, // Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + {0x27ED, 0x27ED, prClose}, // Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + {0x27EE, 0x27EE, prClose}, // Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS + {0x27EF, 0x27EF, prClose}, // Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS + {0x2983, 0x2983, prClose}, // Ps LEFT WHITE CURLY BRACKET + {0x2984, 0x2984, prClose}, // Pe RIGHT WHITE CURLY BRACKET + {0x2985, 0x2985, prClose}, // Ps LEFT WHITE PARENTHESIS + {0x2986, 0x2986, prClose}, // Pe RIGHT WHITE PARENTHESIS + {0x2987, 0x2987, prClose}, // Ps Z NOTATION LEFT IMAGE BRACKET + {0x2988, 0x2988, prClose}, // Pe Z NOTATION RIGHT IMAGE BRACKET + {0x2989, 0x2989, prClose}, // Ps Z NOTATION LEFT BINDING BRACKET + {0x298A, 0x298A, prClose}, // Pe Z NOTATION RIGHT BINDING BRACKET + {0x298B, 0x298B, prClose}, // Ps LEFT SQUARE BRACKET WITH UNDERBAR + {0x298C, 0x298C, prClose}, // Pe RIGHT SQUARE BRACKET WITH UNDERBAR + {0x298D, 0x298D, prClose}, // Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x298E, 0x298E, prClose}, // Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x298F, 0x298F, prClose}, // Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + {0x2990, 0x2990, prClose}, // Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + {0x2991, 0x2991, prClose}, // Ps LEFT ANGLE BRACKET WITH DOT + {0x2992, 0x2992, prClose}, // Pe RIGHT ANGLE BRACKET WITH DOT + {0x2993, 0x2993, prClose}, // Ps LEFT ARC LESS-THAN BRACKET + {0x2994, 0x2994, prClose}, // Pe RIGHT ARC GREATER-THAN BRACKET + {0x2995, 0x2995, prClose}, // Ps DOUBLE LEFT ARC GREATER-THAN BRACKET + {0x2996, 0x2996, prClose}, // Pe DOUBLE RIGHT ARC LESS-THAN BRACKET + {0x2997, 0x2997, prClose}, // Ps LEFT BLACK TORTOISE SHELL BRACKET + {0x2998, 0x2998, prClose}, // Pe RIGHT BLACK TORTOISE SHELL BRACKET + {0x29D8, 0x29D8, prClose}, // Ps LEFT WIGGLY FENCE + {0x29D9, 0x29D9, prClose}, // Pe RIGHT WIGGLY FENCE + {0x29DA, 0x29DA, prClose}, // Ps LEFT DOUBLE WIGGLY FENCE + {0x29DB, 0x29DB, prClose}, // Pe RIGHT DOUBLE WIGGLY FENCE + {0x29FC, 0x29FC, prClose}, // Ps LEFT-POINTING CURVED ANGLE BRACKET + {0x29FD, 0x29FD, prClose}, // Pe RIGHT-POINTING CURVED ANGLE BRACKET + {0x2C00, 0x2C2F, prUpper}, // L& [48] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI + {0x2C30, 0x2C5F, prLower}, // L& [48] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI + {0x2C60, 0x2C60, prUpper}, // L& LATIN CAPITAL LETTER L WITH DOUBLE BAR + {0x2C61, 0x2C61, prLower}, // L& LATIN SMALL LETTER L WITH DOUBLE BAR + {0x2C62, 0x2C64, prUpper}, // L& [3] LATIN CAPITAL LETTER L WITH MIDDLE TILDE..LATIN CAPITAL LETTER R WITH TAIL + {0x2C65, 0x2C66, prLower}, // L& [2] LATIN SMALL LETTER A WITH STROKE..LATIN SMALL LETTER T WITH DIAGONAL STROKE + {0x2C67, 0x2C67, prUpper}, // L& LATIN CAPITAL LETTER H WITH DESCENDER + {0x2C68, 0x2C68, prLower}, // L& LATIN SMALL LETTER H WITH DESCENDER + {0x2C69, 0x2C69, prUpper}, // L& LATIN CAPITAL LETTER K WITH DESCENDER + {0x2C6A, 0x2C6A, prLower}, // L& LATIN SMALL LETTER K WITH DESCENDER + {0x2C6B, 0x2C6B, prUpper}, // L& LATIN CAPITAL LETTER Z WITH DESCENDER + {0x2C6C, 0x2C6C, prLower}, // L& LATIN SMALL LETTER Z WITH DESCENDER + {0x2C6D, 0x2C70, prUpper}, // L& [4] LATIN CAPITAL LETTER ALPHA..LATIN CAPITAL LETTER TURNED ALPHA + {0x2C71, 0x2C71, prLower}, // L& LATIN SMALL LETTER V WITH RIGHT HOOK + {0x2C72, 0x2C72, prUpper}, // L& LATIN CAPITAL LETTER W WITH HOOK + {0x2C73, 0x2C74, prLower}, // L& [2] LATIN SMALL LETTER W WITH HOOK..LATIN SMALL LETTER V WITH CURL + {0x2C75, 0x2C75, prUpper}, // L& LATIN CAPITAL LETTER HALF H + {0x2C76, 0x2C7B, prLower}, // L& [6] LATIN SMALL LETTER HALF H..LATIN LETTER SMALL CAPITAL TURNED E + {0x2C7C, 0x2C7D, prLower}, // Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V + {0x2C7E, 0x2C80, prUpper}, // L& [3] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC CAPITAL LETTER ALFA + {0x2C81, 0x2C81, prLower}, // L& COPTIC SMALL LETTER ALFA + {0x2C82, 0x2C82, prUpper}, // L& COPTIC CAPITAL LETTER VIDA + {0x2C83, 0x2C83, prLower}, // L& COPTIC SMALL LETTER VIDA + {0x2C84, 0x2C84, prUpper}, // L& COPTIC CAPITAL LETTER GAMMA + {0x2C85, 0x2C85, prLower}, // L& COPTIC SMALL LETTER GAMMA + {0x2C86, 0x2C86, prUpper}, // L& COPTIC CAPITAL LETTER DALDA + {0x2C87, 0x2C87, prLower}, // L& COPTIC SMALL LETTER DALDA + {0x2C88, 0x2C88, prUpper}, // L& COPTIC CAPITAL LETTER EIE + {0x2C89, 0x2C89, prLower}, // L& COPTIC SMALL LETTER EIE + {0x2C8A, 0x2C8A, prUpper}, // L& COPTIC CAPITAL LETTER SOU + {0x2C8B, 0x2C8B, prLower}, // L& COPTIC SMALL LETTER SOU + {0x2C8C, 0x2C8C, prUpper}, // L& COPTIC CAPITAL LETTER ZATA + {0x2C8D, 0x2C8D, prLower}, // L& COPTIC SMALL LETTER ZATA + {0x2C8E, 0x2C8E, prUpper}, // L& COPTIC CAPITAL LETTER HATE + {0x2C8F, 0x2C8F, prLower}, // L& COPTIC SMALL LETTER HATE + {0x2C90, 0x2C90, prUpper}, // L& COPTIC CAPITAL LETTER THETHE + {0x2C91, 0x2C91, prLower}, // L& COPTIC SMALL LETTER THETHE + {0x2C92, 0x2C92, prUpper}, // L& COPTIC CAPITAL LETTER IAUDA + {0x2C93, 0x2C93, prLower}, // L& COPTIC SMALL LETTER IAUDA + {0x2C94, 0x2C94, prUpper}, // L& COPTIC CAPITAL LETTER KAPA + {0x2C95, 0x2C95, prLower}, // L& COPTIC SMALL LETTER KAPA + {0x2C96, 0x2C96, prUpper}, // L& COPTIC CAPITAL LETTER LAULA + {0x2C97, 0x2C97, prLower}, // L& COPTIC SMALL LETTER LAULA + {0x2C98, 0x2C98, prUpper}, // L& COPTIC CAPITAL LETTER MI + {0x2C99, 0x2C99, prLower}, // L& COPTIC SMALL LETTER MI + {0x2C9A, 0x2C9A, prUpper}, // L& COPTIC CAPITAL LETTER NI + {0x2C9B, 0x2C9B, prLower}, // L& COPTIC SMALL LETTER NI + {0x2C9C, 0x2C9C, prUpper}, // L& COPTIC CAPITAL LETTER KSI + {0x2C9D, 0x2C9D, prLower}, // L& COPTIC SMALL LETTER KSI + {0x2C9E, 0x2C9E, prUpper}, // L& COPTIC CAPITAL LETTER O + {0x2C9F, 0x2C9F, prLower}, // L& COPTIC SMALL LETTER O + {0x2CA0, 0x2CA0, prUpper}, // L& COPTIC CAPITAL LETTER PI + {0x2CA1, 0x2CA1, prLower}, // L& COPTIC SMALL LETTER PI + {0x2CA2, 0x2CA2, prUpper}, // L& COPTIC CAPITAL LETTER RO + {0x2CA3, 0x2CA3, prLower}, // L& COPTIC SMALL LETTER RO + {0x2CA4, 0x2CA4, prUpper}, // L& COPTIC CAPITAL LETTER SIMA + {0x2CA5, 0x2CA5, prLower}, // L& COPTIC SMALL LETTER SIMA + {0x2CA6, 0x2CA6, prUpper}, // L& COPTIC CAPITAL LETTER TAU + {0x2CA7, 0x2CA7, prLower}, // L& COPTIC SMALL LETTER TAU + {0x2CA8, 0x2CA8, prUpper}, // L& COPTIC CAPITAL LETTER UA + {0x2CA9, 0x2CA9, prLower}, // L& COPTIC SMALL LETTER UA + {0x2CAA, 0x2CAA, prUpper}, // L& COPTIC CAPITAL LETTER FI + {0x2CAB, 0x2CAB, prLower}, // L& COPTIC SMALL LETTER FI + {0x2CAC, 0x2CAC, prUpper}, // L& COPTIC CAPITAL LETTER KHI + {0x2CAD, 0x2CAD, prLower}, // L& COPTIC SMALL LETTER KHI + {0x2CAE, 0x2CAE, prUpper}, // L& COPTIC CAPITAL LETTER PSI + {0x2CAF, 0x2CAF, prLower}, // L& COPTIC SMALL LETTER PSI + {0x2CB0, 0x2CB0, prUpper}, // L& COPTIC CAPITAL LETTER OOU + {0x2CB1, 0x2CB1, prLower}, // L& COPTIC SMALL LETTER OOU + {0x2CB2, 0x2CB2, prUpper}, // L& COPTIC CAPITAL LETTER DIALECT-P ALEF + {0x2CB3, 0x2CB3, prLower}, // L& COPTIC SMALL LETTER DIALECT-P ALEF + {0x2CB4, 0x2CB4, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC AIN + {0x2CB5, 0x2CB5, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC AIN + {0x2CB6, 0x2CB6, prUpper}, // L& COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE + {0x2CB7, 0x2CB7, prLower}, // L& COPTIC SMALL LETTER CRYPTOGRAMMIC EIE + {0x2CB8, 0x2CB8, prUpper}, // L& COPTIC CAPITAL LETTER DIALECT-P KAPA + {0x2CB9, 0x2CB9, prLower}, // L& COPTIC SMALL LETTER DIALECT-P KAPA + {0x2CBA, 0x2CBA, prUpper}, // L& COPTIC CAPITAL LETTER DIALECT-P NI + {0x2CBB, 0x2CBB, prLower}, // L& COPTIC SMALL LETTER DIALECT-P NI + {0x2CBC, 0x2CBC, prUpper}, // L& COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI + {0x2CBD, 0x2CBD, prLower}, // L& COPTIC SMALL LETTER CRYPTOGRAMMIC NI + {0x2CBE, 0x2CBE, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC OOU + {0x2CBF, 0x2CBF, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC OOU + {0x2CC0, 0x2CC0, prUpper}, // L& COPTIC CAPITAL LETTER SAMPI + {0x2CC1, 0x2CC1, prLower}, // L& COPTIC SMALL LETTER SAMPI + {0x2CC2, 0x2CC2, prUpper}, // L& COPTIC CAPITAL LETTER CROSSED SHEI + {0x2CC3, 0x2CC3, prLower}, // L& COPTIC SMALL LETTER CROSSED SHEI + {0x2CC4, 0x2CC4, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC SHEI + {0x2CC5, 0x2CC5, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC SHEI + {0x2CC6, 0x2CC6, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC ESH + {0x2CC7, 0x2CC7, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC ESH + {0x2CC8, 0x2CC8, prUpper}, // L& COPTIC CAPITAL LETTER AKHMIMIC KHEI + {0x2CC9, 0x2CC9, prLower}, // L& COPTIC SMALL LETTER AKHMIMIC KHEI + {0x2CCA, 0x2CCA, prUpper}, // L& COPTIC CAPITAL LETTER DIALECT-P HORI + {0x2CCB, 0x2CCB, prLower}, // L& COPTIC SMALL LETTER DIALECT-P HORI + {0x2CCC, 0x2CCC, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC HORI + {0x2CCD, 0x2CCD, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC HORI + {0x2CCE, 0x2CCE, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC HA + {0x2CCF, 0x2CCF, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC HA + {0x2CD0, 0x2CD0, prUpper}, // L& COPTIC CAPITAL LETTER L-SHAPED HA + {0x2CD1, 0x2CD1, prLower}, // L& COPTIC SMALL LETTER L-SHAPED HA + {0x2CD2, 0x2CD2, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC HEI + {0x2CD3, 0x2CD3, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC HEI + {0x2CD4, 0x2CD4, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC HAT + {0x2CD5, 0x2CD5, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC HAT + {0x2CD6, 0x2CD6, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC GANGIA + {0x2CD7, 0x2CD7, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC GANGIA + {0x2CD8, 0x2CD8, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC DJA + {0x2CD9, 0x2CD9, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC DJA + {0x2CDA, 0x2CDA, prUpper}, // L& COPTIC CAPITAL LETTER OLD COPTIC SHIMA + {0x2CDB, 0x2CDB, prLower}, // L& COPTIC SMALL LETTER OLD COPTIC SHIMA + {0x2CDC, 0x2CDC, prUpper}, // L& COPTIC CAPITAL LETTER OLD NUBIAN SHIMA + {0x2CDD, 0x2CDD, prLower}, // L& COPTIC SMALL LETTER OLD NUBIAN SHIMA + {0x2CDE, 0x2CDE, prUpper}, // L& COPTIC CAPITAL LETTER OLD NUBIAN NGI + {0x2CDF, 0x2CDF, prLower}, // L& COPTIC SMALL LETTER OLD NUBIAN NGI + {0x2CE0, 0x2CE0, prUpper}, // L& COPTIC CAPITAL LETTER OLD NUBIAN NYI + {0x2CE1, 0x2CE1, prLower}, // L& COPTIC SMALL LETTER OLD NUBIAN NYI + {0x2CE2, 0x2CE2, prUpper}, // L& COPTIC CAPITAL LETTER OLD NUBIAN WAU + {0x2CE3, 0x2CE4, prLower}, // L& [2] COPTIC SMALL LETTER OLD NUBIAN WAU..COPTIC SYMBOL KAI + {0x2CEB, 0x2CEB, prUpper}, // L& COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI + {0x2CEC, 0x2CEC, prLower}, // L& COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI + {0x2CED, 0x2CED, prUpper}, // L& COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEE, 0x2CEE, prLower}, // L& COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEF, 0x2CF1, prExtend}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2CF2, 0x2CF2, prUpper}, // L& COPTIC CAPITAL LETTER BOHAIRIC KHEI + {0x2CF3, 0x2CF3, prLower}, // L& COPTIC SMALL LETTER BOHAIRIC KHEI + {0x2D00, 0x2D25, prLower}, // L& [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE + {0x2D27, 0x2D27, prLower}, // L& GEORGIAN SMALL LETTER YN + {0x2D2D, 0x2D2D, prLower}, // L& GEORGIAN SMALL LETTER AEN + {0x2D30, 0x2D67, prOLetter}, // Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO + {0x2D6F, 0x2D6F, prOLetter}, // Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK + {0x2D7F, 0x2D7F, prExtend}, // Mn TIFINAGH CONSONANT JOINER + {0x2D80, 0x2D96, prOLetter}, // Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE + {0x2DA0, 0x2DA6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO + {0x2DA8, 0x2DAE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO + {0x2DB0, 0x2DB6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO + {0x2DB8, 0x2DBE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO + {0x2DC0, 0x2DC6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO + {0x2DC8, 0x2DCE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO + {0x2DD0, 0x2DD6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO + {0x2DD8, 0x2DDE, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO + {0x2DE0, 0x2DFF, prExtend}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x2E00, 0x2E01, prClose}, // Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER + {0x2E02, 0x2E02, prClose}, // Pi LEFT SUBSTITUTION BRACKET + {0x2E03, 0x2E03, prClose}, // Pf RIGHT SUBSTITUTION BRACKET + {0x2E04, 0x2E04, prClose}, // Pi LEFT DOTTED SUBSTITUTION BRACKET + {0x2E05, 0x2E05, prClose}, // Pf RIGHT DOTTED SUBSTITUTION BRACKET + {0x2E06, 0x2E08, prClose}, // Po [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER + {0x2E09, 0x2E09, prClose}, // Pi LEFT TRANSPOSITION BRACKET + {0x2E0A, 0x2E0A, prClose}, // Pf RIGHT TRANSPOSITION BRACKET + {0x2E0B, 0x2E0B, prClose}, // Po RAISED SQUARE + {0x2E0C, 0x2E0C, prClose}, // Pi LEFT RAISED OMISSION BRACKET + {0x2E0D, 0x2E0D, prClose}, // Pf RIGHT RAISED OMISSION BRACKET + {0x2E1C, 0x2E1C, prClose}, // Pi LEFT LOW PARAPHRASE BRACKET + {0x2E1D, 0x2E1D, prClose}, // Pf RIGHT LOW PARAPHRASE BRACKET + {0x2E20, 0x2E20, prClose}, // Pi LEFT VERTICAL BAR WITH QUILL + {0x2E21, 0x2E21, prClose}, // Pf RIGHT VERTICAL BAR WITH QUILL + {0x2E22, 0x2E22, prClose}, // Ps TOP LEFT HALF BRACKET + {0x2E23, 0x2E23, prClose}, // Pe TOP RIGHT HALF BRACKET + {0x2E24, 0x2E24, prClose}, // Ps BOTTOM LEFT HALF BRACKET + {0x2E25, 0x2E25, prClose}, // Pe BOTTOM RIGHT HALF BRACKET + {0x2E26, 0x2E26, prClose}, // Ps LEFT SIDEWAYS U BRACKET + {0x2E27, 0x2E27, prClose}, // Pe RIGHT SIDEWAYS U BRACKET + {0x2E28, 0x2E28, prClose}, // Ps LEFT DOUBLE PARENTHESIS + {0x2E29, 0x2E29, prClose}, // Pe RIGHT DOUBLE PARENTHESIS + {0x2E2E, 0x2E2E, prSTerm}, // Po REVERSED QUESTION MARK + {0x2E2F, 0x2E2F, prOLetter}, // Lm VERTICAL TILDE + {0x2E3C, 0x2E3C, prSTerm}, // Po STENOGRAPHIC FULL STOP + {0x2E42, 0x2E42, prClose}, // Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK + {0x2E53, 0x2E54, prSTerm}, // Po [2] MEDIEVAL EXCLAMATION MARK..MEDIEVAL QUESTION MARK + {0x2E55, 0x2E55, prClose}, // Ps LEFT SQUARE BRACKET WITH STROKE + {0x2E56, 0x2E56, prClose}, // Pe RIGHT SQUARE BRACKET WITH STROKE + {0x2E57, 0x2E57, prClose}, // Ps LEFT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E58, 0x2E58, prClose}, // Pe RIGHT SQUARE BRACKET WITH DOUBLE STROKE + {0x2E59, 0x2E59, prClose}, // Ps TOP HALF LEFT PARENTHESIS + {0x2E5A, 0x2E5A, prClose}, // Pe TOP HALF RIGHT PARENTHESIS + {0x2E5B, 0x2E5B, prClose}, // Ps BOTTOM HALF LEFT PARENTHESIS + {0x2E5C, 0x2E5C, prClose}, // Pe BOTTOM HALF RIGHT PARENTHESIS + {0x3000, 0x3000, prSp}, // Zs IDEOGRAPHIC SPACE + {0x3001, 0x3001, prSContinue}, // Po IDEOGRAPHIC COMMA + {0x3002, 0x3002, prSTerm}, // Po IDEOGRAPHIC FULL STOP + {0x3005, 0x3005, prOLetter}, // Lm IDEOGRAPHIC ITERATION MARK + {0x3006, 0x3006, prOLetter}, // Lo IDEOGRAPHIC CLOSING MARK + {0x3007, 0x3007, prOLetter}, // Nl IDEOGRAPHIC NUMBER ZERO + {0x3008, 0x3008, prClose}, // Ps LEFT ANGLE BRACKET + {0x3009, 0x3009, prClose}, // Pe RIGHT ANGLE BRACKET + {0x300A, 0x300A, prClose}, // Ps LEFT DOUBLE ANGLE BRACKET + {0x300B, 0x300B, prClose}, // Pe RIGHT DOUBLE ANGLE BRACKET + {0x300C, 0x300C, prClose}, // Ps LEFT CORNER BRACKET + {0x300D, 0x300D, prClose}, // Pe RIGHT CORNER BRACKET + {0x300E, 0x300E, prClose}, // Ps LEFT WHITE CORNER BRACKET + {0x300F, 0x300F, prClose}, // Pe RIGHT WHITE CORNER BRACKET + {0x3010, 0x3010, prClose}, // Ps LEFT BLACK LENTICULAR BRACKET + {0x3011, 0x3011, prClose}, // Pe RIGHT BLACK LENTICULAR BRACKET + {0x3014, 0x3014, prClose}, // Ps LEFT TORTOISE SHELL BRACKET + {0x3015, 0x3015, prClose}, // Pe RIGHT TORTOISE SHELL BRACKET + {0x3016, 0x3016, prClose}, // Ps LEFT WHITE LENTICULAR BRACKET + {0x3017, 0x3017, prClose}, // Pe RIGHT WHITE LENTICULAR BRACKET + {0x3018, 0x3018, prClose}, // Ps LEFT WHITE TORTOISE SHELL BRACKET + {0x3019, 0x3019, prClose}, // Pe RIGHT WHITE TORTOISE SHELL BRACKET + {0x301A, 0x301A, prClose}, // Ps LEFT WHITE SQUARE BRACKET + {0x301B, 0x301B, prClose}, // Pe RIGHT WHITE SQUARE BRACKET + {0x301D, 0x301D, prClose}, // Ps REVERSED DOUBLE PRIME QUOTATION MARK + {0x301E, 0x301F, prClose}, // Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK + {0x3021, 0x3029, prOLetter}, // Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE + {0x302A, 0x302D, prExtend}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prExtend}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3031, 0x3035, prOLetter}, // Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF + {0x3038, 0x303A, prOLetter}, // Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY + {0x303B, 0x303B, prOLetter}, // Lm VERTICAL IDEOGRAPHIC ITERATION MARK + {0x303C, 0x303C, prOLetter}, // Lo MASU MARK + {0x3041, 0x3096, prOLetter}, // Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE + {0x3099, 0x309A, prExtend}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309D, 0x309E, prOLetter}, // Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK + {0x309F, 0x309F, prOLetter}, // Lo HIRAGANA DIGRAPH YORI + {0x30A1, 0x30FA, prOLetter}, // Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO + {0x30FC, 0x30FE, prOLetter}, // Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK + {0x30FF, 0x30FF, prOLetter}, // Lo KATAKANA DIGRAPH KOTO + {0x3105, 0x312F, prOLetter}, // Lo [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN + {0x3131, 0x318E, prOLetter}, // Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE + {0x31A0, 0x31BF, prOLetter}, // Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH + {0x31F0, 0x31FF, prOLetter}, // Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO + {0x3400, 0x4DBF, prOLetter}, // Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF + {0x4E00, 0xA014, prOLetter}, // Lo [21013] CJK UNIFIED IDEOGRAPH-4E00..YI SYLLABLE E + {0xA015, 0xA015, prOLetter}, // Lm YI SYLLABLE WU + {0xA016, 0xA48C, prOLetter}, // Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR + {0xA4D0, 0xA4F7, prOLetter}, // Lo [40] LISU LETTER BA..LISU LETTER OE + {0xA4F8, 0xA4FD, prOLetter}, // Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU + {0xA4FF, 0xA4FF, prSTerm}, // Po LISU PUNCTUATION FULL STOP + {0xA500, 0xA60B, prOLetter}, // Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG + {0xA60C, 0xA60C, prOLetter}, // Lm VAI SYLLABLE LENGTHENER + {0xA60E, 0xA60F, prSTerm}, // Po [2] VAI FULL STOP..VAI QUESTION MARK + {0xA610, 0xA61F, prOLetter}, // Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG + {0xA620, 0xA629, prNumeric}, // Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE + {0xA62A, 0xA62B, prOLetter}, // Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO + {0xA640, 0xA640, prUpper}, // L& CYRILLIC CAPITAL LETTER ZEMLYA + {0xA641, 0xA641, prLower}, // L& CYRILLIC SMALL LETTER ZEMLYA + {0xA642, 0xA642, prUpper}, // L& CYRILLIC CAPITAL LETTER DZELO + {0xA643, 0xA643, prLower}, // L& CYRILLIC SMALL LETTER DZELO + {0xA644, 0xA644, prUpper}, // L& CYRILLIC CAPITAL LETTER REVERSED DZE + {0xA645, 0xA645, prLower}, // L& CYRILLIC SMALL LETTER REVERSED DZE + {0xA646, 0xA646, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTA + {0xA647, 0xA647, prLower}, // L& CYRILLIC SMALL LETTER IOTA + {0xA648, 0xA648, prUpper}, // L& CYRILLIC CAPITAL LETTER DJERV + {0xA649, 0xA649, prLower}, // L& CYRILLIC SMALL LETTER DJERV + {0xA64A, 0xA64A, prUpper}, // L& CYRILLIC CAPITAL LETTER MONOGRAPH UK + {0xA64B, 0xA64B, prLower}, // L& CYRILLIC SMALL LETTER MONOGRAPH UK + {0xA64C, 0xA64C, prUpper}, // L& CYRILLIC CAPITAL LETTER BROAD OMEGA + {0xA64D, 0xA64D, prLower}, // L& CYRILLIC SMALL LETTER BROAD OMEGA + {0xA64E, 0xA64E, prUpper}, // L& CYRILLIC CAPITAL LETTER NEUTRAL YER + {0xA64F, 0xA64F, prLower}, // L& CYRILLIC SMALL LETTER NEUTRAL YER + {0xA650, 0xA650, prUpper}, // L& CYRILLIC CAPITAL LETTER YERU WITH BACK YER + {0xA651, 0xA651, prLower}, // L& CYRILLIC SMALL LETTER YERU WITH BACK YER + {0xA652, 0xA652, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED YAT + {0xA653, 0xA653, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED YAT + {0xA654, 0xA654, prUpper}, // L& CYRILLIC CAPITAL LETTER REVERSED YU + {0xA655, 0xA655, prLower}, // L& CYRILLIC SMALL LETTER REVERSED YU + {0xA656, 0xA656, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED A + {0xA657, 0xA657, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED A + {0xA658, 0xA658, prUpper}, // L& CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS + {0xA659, 0xA659, prLower}, // L& CYRILLIC SMALL LETTER CLOSED LITTLE YUS + {0xA65A, 0xA65A, prUpper}, // L& CYRILLIC CAPITAL LETTER BLENDED YUS + {0xA65B, 0xA65B, prLower}, // L& CYRILLIC SMALL LETTER BLENDED YUS + {0xA65C, 0xA65C, prUpper}, // L& CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS + {0xA65D, 0xA65D, prLower}, // L& CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS + {0xA65E, 0xA65E, prUpper}, // L& CYRILLIC CAPITAL LETTER YN + {0xA65F, 0xA65F, prLower}, // L& CYRILLIC SMALL LETTER YN + {0xA660, 0xA660, prUpper}, // L& CYRILLIC CAPITAL LETTER REVERSED TSE + {0xA661, 0xA661, prLower}, // L& CYRILLIC SMALL LETTER REVERSED TSE + {0xA662, 0xA662, prUpper}, // L& CYRILLIC CAPITAL LETTER SOFT DE + {0xA663, 0xA663, prLower}, // L& CYRILLIC SMALL LETTER SOFT DE + {0xA664, 0xA664, prUpper}, // L& CYRILLIC CAPITAL LETTER SOFT EL + {0xA665, 0xA665, prLower}, // L& CYRILLIC SMALL LETTER SOFT EL + {0xA666, 0xA666, prUpper}, // L& CYRILLIC CAPITAL LETTER SOFT EM + {0xA667, 0xA667, prLower}, // L& CYRILLIC SMALL LETTER SOFT EM + {0xA668, 0xA668, prUpper}, // L& CYRILLIC CAPITAL LETTER MONOCULAR O + {0xA669, 0xA669, prLower}, // L& CYRILLIC SMALL LETTER MONOCULAR O + {0xA66A, 0xA66A, prUpper}, // L& CYRILLIC CAPITAL LETTER BINOCULAR O + {0xA66B, 0xA66B, prLower}, // L& CYRILLIC SMALL LETTER BINOCULAR O + {0xA66C, 0xA66C, prUpper}, // L& CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O + {0xA66D, 0xA66D, prLower}, // L& CYRILLIC SMALL LETTER DOUBLE MONOCULAR O + {0xA66E, 0xA66E, prOLetter}, // Lo CYRILLIC LETTER MULTIOCULAR O + {0xA66F, 0xA66F, prExtend}, // Mn COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prExtend}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA674, 0xA67D, prExtend}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA67F, 0xA67F, prOLetter}, // Lm CYRILLIC PAYEROK + {0xA680, 0xA680, prUpper}, // L& CYRILLIC CAPITAL LETTER DWE + {0xA681, 0xA681, prLower}, // L& CYRILLIC SMALL LETTER DWE + {0xA682, 0xA682, prUpper}, // L& CYRILLIC CAPITAL LETTER DZWE + {0xA683, 0xA683, prLower}, // L& CYRILLIC SMALL LETTER DZWE + {0xA684, 0xA684, prUpper}, // L& CYRILLIC CAPITAL LETTER ZHWE + {0xA685, 0xA685, prLower}, // L& CYRILLIC SMALL LETTER ZHWE + {0xA686, 0xA686, prUpper}, // L& CYRILLIC CAPITAL LETTER CCHE + {0xA687, 0xA687, prLower}, // L& CYRILLIC SMALL LETTER CCHE + {0xA688, 0xA688, prUpper}, // L& CYRILLIC CAPITAL LETTER DZZE + {0xA689, 0xA689, prLower}, // L& CYRILLIC SMALL LETTER DZZE + {0xA68A, 0xA68A, prUpper}, // L& CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK + {0xA68B, 0xA68B, prLower}, // L& CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK + {0xA68C, 0xA68C, prUpper}, // L& CYRILLIC CAPITAL LETTER TWE + {0xA68D, 0xA68D, prLower}, // L& CYRILLIC SMALL LETTER TWE + {0xA68E, 0xA68E, prUpper}, // L& CYRILLIC CAPITAL LETTER TSWE + {0xA68F, 0xA68F, prLower}, // L& CYRILLIC SMALL LETTER TSWE + {0xA690, 0xA690, prUpper}, // L& CYRILLIC CAPITAL LETTER TSSE + {0xA691, 0xA691, prLower}, // L& CYRILLIC SMALL LETTER TSSE + {0xA692, 0xA692, prUpper}, // L& CYRILLIC CAPITAL LETTER TCHE + {0xA693, 0xA693, prLower}, // L& CYRILLIC SMALL LETTER TCHE + {0xA694, 0xA694, prUpper}, // L& CYRILLIC CAPITAL LETTER HWE + {0xA695, 0xA695, prLower}, // L& CYRILLIC SMALL LETTER HWE + {0xA696, 0xA696, prUpper}, // L& CYRILLIC CAPITAL LETTER SHWE + {0xA697, 0xA697, prLower}, // L& CYRILLIC SMALL LETTER SHWE + {0xA698, 0xA698, prUpper}, // L& CYRILLIC CAPITAL LETTER DOUBLE O + {0xA699, 0xA699, prLower}, // L& CYRILLIC SMALL LETTER DOUBLE O + {0xA69A, 0xA69A, prUpper}, // L& CYRILLIC CAPITAL LETTER CROSSED O + {0xA69B, 0xA69B, prLower}, // L& CYRILLIC SMALL LETTER CROSSED O + {0xA69C, 0xA69D, prLower}, // Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN + {0xA69E, 0xA69F, prExtend}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6A0, 0xA6E5, prOLetter}, // Lo [70] BAMUM LETTER A..BAMUM LETTER KI + {0xA6E6, 0xA6EF, prOLetter}, // Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM + {0xA6F0, 0xA6F1, prExtend}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA6F3, 0xA6F3, prSTerm}, // Po BAMUM FULL STOP + {0xA6F7, 0xA6F7, prSTerm}, // Po BAMUM QUESTION MARK + {0xA717, 0xA71F, prOLetter}, // Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK + {0xA722, 0xA722, prUpper}, // L& LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF + {0xA723, 0xA723, prLower}, // L& LATIN SMALL LETTER EGYPTOLOGICAL ALEF + {0xA724, 0xA724, prUpper}, // L& LATIN CAPITAL LETTER EGYPTOLOGICAL AIN + {0xA725, 0xA725, prLower}, // L& LATIN SMALL LETTER EGYPTOLOGICAL AIN + {0xA726, 0xA726, prUpper}, // L& LATIN CAPITAL LETTER HENG + {0xA727, 0xA727, prLower}, // L& LATIN SMALL LETTER HENG + {0xA728, 0xA728, prUpper}, // L& LATIN CAPITAL LETTER TZ + {0xA729, 0xA729, prLower}, // L& LATIN SMALL LETTER TZ + {0xA72A, 0xA72A, prUpper}, // L& LATIN CAPITAL LETTER TRESILLO + {0xA72B, 0xA72B, prLower}, // L& LATIN SMALL LETTER TRESILLO + {0xA72C, 0xA72C, prUpper}, // L& LATIN CAPITAL LETTER CUATRILLO + {0xA72D, 0xA72D, prLower}, // L& LATIN SMALL LETTER CUATRILLO + {0xA72E, 0xA72E, prUpper}, // L& LATIN CAPITAL LETTER CUATRILLO WITH COMMA + {0xA72F, 0xA731, prLower}, // L& [3] LATIN SMALL LETTER CUATRILLO WITH COMMA..LATIN LETTER SMALL CAPITAL S + {0xA732, 0xA732, prUpper}, // L& LATIN CAPITAL LETTER AA + {0xA733, 0xA733, prLower}, // L& LATIN SMALL LETTER AA + {0xA734, 0xA734, prUpper}, // L& LATIN CAPITAL LETTER AO + {0xA735, 0xA735, prLower}, // L& LATIN SMALL LETTER AO + {0xA736, 0xA736, prUpper}, // L& LATIN CAPITAL LETTER AU + {0xA737, 0xA737, prLower}, // L& LATIN SMALL LETTER AU + {0xA738, 0xA738, prUpper}, // L& LATIN CAPITAL LETTER AV + {0xA739, 0xA739, prLower}, // L& LATIN SMALL LETTER AV + {0xA73A, 0xA73A, prUpper}, // L& LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR + {0xA73B, 0xA73B, prLower}, // L& LATIN SMALL LETTER AV WITH HORIZONTAL BAR + {0xA73C, 0xA73C, prUpper}, // L& LATIN CAPITAL LETTER AY + {0xA73D, 0xA73D, prLower}, // L& LATIN SMALL LETTER AY + {0xA73E, 0xA73E, prUpper}, // L& LATIN CAPITAL LETTER REVERSED C WITH DOT + {0xA73F, 0xA73F, prLower}, // L& LATIN SMALL LETTER REVERSED C WITH DOT + {0xA740, 0xA740, prUpper}, // L& LATIN CAPITAL LETTER K WITH STROKE + {0xA741, 0xA741, prLower}, // L& LATIN SMALL LETTER K WITH STROKE + {0xA742, 0xA742, prUpper}, // L& LATIN CAPITAL LETTER K WITH DIAGONAL STROKE + {0xA743, 0xA743, prLower}, // L& LATIN SMALL LETTER K WITH DIAGONAL STROKE + {0xA744, 0xA744, prUpper}, // L& LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE + {0xA745, 0xA745, prLower}, // L& LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE + {0xA746, 0xA746, prUpper}, // L& LATIN CAPITAL LETTER BROKEN L + {0xA747, 0xA747, prLower}, // L& LATIN SMALL LETTER BROKEN L + {0xA748, 0xA748, prUpper}, // L& LATIN CAPITAL LETTER L WITH HIGH STROKE + {0xA749, 0xA749, prLower}, // L& LATIN SMALL LETTER L WITH HIGH STROKE + {0xA74A, 0xA74A, prUpper}, // L& LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY + {0xA74B, 0xA74B, prLower}, // L& LATIN SMALL LETTER O WITH LONG STROKE OVERLAY + {0xA74C, 0xA74C, prUpper}, // L& LATIN CAPITAL LETTER O WITH LOOP + {0xA74D, 0xA74D, prLower}, // L& LATIN SMALL LETTER O WITH LOOP + {0xA74E, 0xA74E, prUpper}, // L& LATIN CAPITAL LETTER OO + {0xA74F, 0xA74F, prLower}, // L& LATIN SMALL LETTER OO + {0xA750, 0xA750, prUpper}, // L& LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER + {0xA751, 0xA751, prLower}, // L& LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER + {0xA752, 0xA752, prUpper}, // L& LATIN CAPITAL LETTER P WITH FLOURISH + {0xA753, 0xA753, prLower}, // L& LATIN SMALL LETTER P WITH FLOURISH + {0xA754, 0xA754, prUpper}, // L& LATIN CAPITAL LETTER P WITH SQUIRREL TAIL + {0xA755, 0xA755, prLower}, // L& LATIN SMALL LETTER P WITH SQUIRREL TAIL + {0xA756, 0xA756, prUpper}, // L& LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER + {0xA757, 0xA757, prLower}, // L& LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER + {0xA758, 0xA758, prUpper}, // L& LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE + {0xA759, 0xA759, prLower}, // L& LATIN SMALL LETTER Q WITH DIAGONAL STROKE + {0xA75A, 0xA75A, prUpper}, // L& LATIN CAPITAL LETTER R ROTUNDA + {0xA75B, 0xA75B, prLower}, // L& LATIN SMALL LETTER R ROTUNDA + {0xA75C, 0xA75C, prUpper}, // L& LATIN CAPITAL LETTER RUM ROTUNDA + {0xA75D, 0xA75D, prLower}, // L& LATIN SMALL LETTER RUM ROTUNDA + {0xA75E, 0xA75E, prUpper}, // L& LATIN CAPITAL LETTER V WITH DIAGONAL STROKE + {0xA75F, 0xA75F, prLower}, // L& LATIN SMALL LETTER V WITH DIAGONAL STROKE + {0xA760, 0xA760, prUpper}, // L& LATIN CAPITAL LETTER VY + {0xA761, 0xA761, prLower}, // L& LATIN SMALL LETTER VY + {0xA762, 0xA762, prUpper}, // L& LATIN CAPITAL LETTER VISIGOTHIC Z + {0xA763, 0xA763, prLower}, // L& LATIN SMALL LETTER VISIGOTHIC Z + {0xA764, 0xA764, prUpper}, // L& LATIN CAPITAL LETTER THORN WITH STROKE + {0xA765, 0xA765, prLower}, // L& LATIN SMALL LETTER THORN WITH STROKE + {0xA766, 0xA766, prUpper}, // L& LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER + {0xA767, 0xA767, prLower}, // L& LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER + {0xA768, 0xA768, prUpper}, // L& LATIN CAPITAL LETTER VEND + {0xA769, 0xA769, prLower}, // L& LATIN SMALL LETTER VEND + {0xA76A, 0xA76A, prUpper}, // L& LATIN CAPITAL LETTER ET + {0xA76B, 0xA76B, prLower}, // L& LATIN SMALL LETTER ET + {0xA76C, 0xA76C, prUpper}, // L& LATIN CAPITAL LETTER IS + {0xA76D, 0xA76D, prLower}, // L& LATIN SMALL LETTER IS + {0xA76E, 0xA76E, prUpper}, // L& LATIN CAPITAL LETTER CON + {0xA76F, 0xA76F, prLower}, // L& LATIN SMALL LETTER CON + {0xA770, 0xA770, prLower}, // Lm MODIFIER LETTER US + {0xA771, 0xA778, prLower}, // L& [8] LATIN SMALL LETTER DUM..LATIN SMALL LETTER UM + {0xA779, 0xA779, prUpper}, // L& LATIN CAPITAL LETTER INSULAR D + {0xA77A, 0xA77A, prLower}, // L& LATIN SMALL LETTER INSULAR D + {0xA77B, 0xA77B, prUpper}, // L& LATIN CAPITAL LETTER INSULAR F + {0xA77C, 0xA77C, prLower}, // L& LATIN SMALL LETTER INSULAR F + {0xA77D, 0xA77E, prUpper}, // L& [2] LATIN CAPITAL LETTER INSULAR G..LATIN CAPITAL LETTER TURNED INSULAR G + {0xA77F, 0xA77F, prLower}, // L& LATIN SMALL LETTER TURNED INSULAR G + {0xA780, 0xA780, prUpper}, // L& LATIN CAPITAL LETTER TURNED L + {0xA781, 0xA781, prLower}, // L& LATIN SMALL LETTER TURNED L + {0xA782, 0xA782, prUpper}, // L& LATIN CAPITAL LETTER INSULAR R + {0xA783, 0xA783, prLower}, // L& LATIN SMALL LETTER INSULAR R + {0xA784, 0xA784, prUpper}, // L& LATIN CAPITAL LETTER INSULAR S + {0xA785, 0xA785, prLower}, // L& LATIN SMALL LETTER INSULAR S + {0xA786, 0xA786, prUpper}, // L& LATIN CAPITAL LETTER INSULAR T + {0xA787, 0xA787, prLower}, // L& LATIN SMALL LETTER INSULAR T + {0xA788, 0xA788, prOLetter}, // Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT + {0xA78B, 0xA78B, prUpper}, // L& LATIN CAPITAL LETTER SALTILLO + {0xA78C, 0xA78C, prLower}, // L& LATIN SMALL LETTER SALTILLO + {0xA78D, 0xA78D, prUpper}, // L& LATIN CAPITAL LETTER TURNED H + {0xA78E, 0xA78E, prLower}, // L& LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT + {0xA78F, 0xA78F, prOLetter}, // Lo LATIN LETTER SINOLOGICAL DOT + {0xA790, 0xA790, prUpper}, // L& LATIN CAPITAL LETTER N WITH DESCENDER + {0xA791, 0xA791, prLower}, // L& LATIN SMALL LETTER N WITH DESCENDER + {0xA792, 0xA792, prUpper}, // L& LATIN CAPITAL LETTER C WITH BAR + {0xA793, 0xA795, prLower}, // L& [3] LATIN SMALL LETTER C WITH BAR..LATIN SMALL LETTER H WITH PALATAL HOOK + {0xA796, 0xA796, prUpper}, // L& LATIN CAPITAL LETTER B WITH FLOURISH + {0xA797, 0xA797, prLower}, // L& LATIN SMALL LETTER B WITH FLOURISH + {0xA798, 0xA798, prUpper}, // L& LATIN CAPITAL LETTER F WITH STROKE + {0xA799, 0xA799, prLower}, // L& LATIN SMALL LETTER F WITH STROKE + {0xA79A, 0xA79A, prUpper}, // L& LATIN CAPITAL LETTER VOLAPUK AE + {0xA79B, 0xA79B, prLower}, // L& LATIN SMALL LETTER VOLAPUK AE + {0xA79C, 0xA79C, prUpper}, // L& LATIN CAPITAL LETTER VOLAPUK OE + {0xA79D, 0xA79D, prLower}, // L& LATIN SMALL LETTER VOLAPUK OE + {0xA79E, 0xA79E, prUpper}, // L& LATIN CAPITAL LETTER VOLAPUK UE + {0xA79F, 0xA79F, prLower}, // L& LATIN SMALL LETTER VOLAPUK UE + {0xA7A0, 0xA7A0, prUpper}, // L& LATIN CAPITAL LETTER G WITH OBLIQUE STROKE + {0xA7A1, 0xA7A1, prLower}, // L& LATIN SMALL LETTER G WITH OBLIQUE STROKE + {0xA7A2, 0xA7A2, prUpper}, // L& LATIN CAPITAL LETTER K WITH OBLIQUE STROKE + {0xA7A3, 0xA7A3, prLower}, // L& LATIN SMALL LETTER K WITH OBLIQUE STROKE + {0xA7A4, 0xA7A4, prUpper}, // L& LATIN CAPITAL LETTER N WITH OBLIQUE STROKE + {0xA7A5, 0xA7A5, prLower}, // L& LATIN SMALL LETTER N WITH OBLIQUE STROKE + {0xA7A6, 0xA7A6, prUpper}, // L& LATIN CAPITAL LETTER R WITH OBLIQUE STROKE + {0xA7A7, 0xA7A7, prLower}, // L& LATIN SMALL LETTER R WITH OBLIQUE STROKE + {0xA7A8, 0xA7A8, prUpper}, // L& LATIN CAPITAL LETTER S WITH OBLIQUE STROKE + {0xA7A9, 0xA7A9, prLower}, // L& LATIN SMALL LETTER S WITH OBLIQUE STROKE + {0xA7AA, 0xA7AE, prUpper}, // L& [5] LATIN CAPITAL LETTER H WITH HOOK..LATIN CAPITAL LETTER SMALL CAPITAL I + {0xA7AF, 0xA7AF, prLower}, // L& LATIN LETTER SMALL CAPITAL Q + {0xA7B0, 0xA7B4, prUpper}, // L& [5] LATIN CAPITAL LETTER TURNED K..LATIN CAPITAL LETTER BETA + {0xA7B5, 0xA7B5, prLower}, // L& LATIN SMALL LETTER BETA + {0xA7B6, 0xA7B6, prUpper}, // L& LATIN CAPITAL LETTER OMEGA + {0xA7B7, 0xA7B7, prLower}, // L& LATIN SMALL LETTER OMEGA + {0xA7B8, 0xA7B8, prUpper}, // L& LATIN CAPITAL LETTER U WITH STROKE + {0xA7B9, 0xA7B9, prLower}, // L& LATIN SMALL LETTER U WITH STROKE + {0xA7BA, 0xA7BA, prUpper}, // L& LATIN CAPITAL LETTER GLOTTAL A + {0xA7BB, 0xA7BB, prLower}, // L& LATIN SMALL LETTER GLOTTAL A + {0xA7BC, 0xA7BC, prUpper}, // L& LATIN CAPITAL LETTER GLOTTAL I + {0xA7BD, 0xA7BD, prLower}, // L& LATIN SMALL LETTER GLOTTAL I + {0xA7BE, 0xA7BE, prUpper}, // L& LATIN CAPITAL LETTER GLOTTAL U + {0xA7BF, 0xA7BF, prLower}, // L& LATIN SMALL LETTER GLOTTAL U + {0xA7C0, 0xA7C0, prUpper}, // L& LATIN CAPITAL LETTER OLD POLISH O + {0xA7C1, 0xA7C1, prLower}, // L& LATIN SMALL LETTER OLD POLISH O + {0xA7C2, 0xA7C2, prUpper}, // L& LATIN CAPITAL LETTER ANGLICANA W + {0xA7C3, 0xA7C3, prLower}, // L& LATIN SMALL LETTER ANGLICANA W + {0xA7C4, 0xA7C7, prUpper}, // L& [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY + {0xA7C8, 0xA7C8, prLower}, // L& LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY + {0xA7C9, 0xA7C9, prUpper}, // L& LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY + {0xA7CA, 0xA7CA, prLower}, // L& LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY + {0xA7D0, 0xA7D0, prUpper}, // L& LATIN CAPITAL LETTER CLOSED INSULAR G + {0xA7D1, 0xA7D1, prLower}, // L& LATIN SMALL LETTER CLOSED INSULAR G + {0xA7D3, 0xA7D3, prLower}, // L& LATIN SMALL LETTER DOUBLE THORN + {0xA7D5, 0xA7D5, prLower}, // L& LATIN SMALL LETTER DOUBLE WYNN + {0xA7D6, 0xA7D6, prUpper}, // L& LATIN CAPITAL LETTER MIDDLE SCOTS S + {0xA7D7, 0xA7D7, prLower}, // L& LATIN SMALL LETTER MIDDLE SCOTS S + {0xA7D8, 0xA7D8, prUpper}, // L& LATIN CAPITAL LETTER SIGMOID S + {0xA7D9, 0xA7D9, prLower}, // L& LATIN SMALL LETTER SIGMOID S + {0xA7F2, 0xA7F4, prLower}, // Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q + {0xA7F5, 0xA7F5, prUpper}, // L& LATIN CAPITAL LETTER REVERSED HALF H + {0xA7F6, 0xA7F6, prLower}, // L& LATIN SMALL LETTER REVERSED HALF H + {0xA7F7, 0xA7F7, prOLetter}, // Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I + {0xA7F8, 0xA7F9, prLower}, // Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE + {0xA7FA, 0xA7FA, prLower}, // L& LATIN LETTER SMALL CAPITAL TURNED M + {0xA7FB, 0xA801, prOLetter}, // Lo [7] LATIN EPIGRAPHIC LETTER REVERSED F..SYLOTI NAGRI LETTER I + {0xA802, 0xA802, prExtend}, // Mn SYLOTI NAGRI SIGN DVISVARA + {0xA803, 0xA805, prOLetter}, // Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O + {0xA806, 0xA806, prExtend}, // Mn SYLOTI NAGRI SIGN HASANTA + {0xA807, 0xA80A, prOLetter}, // Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO + {0xA80B, 0xA80B, prExtend}, // Mn SYLOTI NAGRI SIGN ANUSVARA + {0xA80C, 0xA822, prOLetter}, // Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO + {0xA823, 0xA824, prExtend}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prExtend}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prExtend}, // Mc SYLOTI NAGRI VOWEL SIGN OO + {0xA82C, 0xA82C, prExtend}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA840, 0xA873, prOLetter}, // Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU + {0xA876, 0xA877, prSTerm}, // Po [2] PHAGS-PA MARK SHAD..PHAGS-PA MARK DOUBLE SHAD + {0xA880, 0xA881, prExtend}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA882, 0xA8B3, prOLetter}, // Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA + {0xA8B4, 0xA8C3, prExtend}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prExtend}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8CE, 0xA8CF, prSTerm}, // Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA + {0xA8D0, 0xA8D9, prNumeric}, // Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE + {0xA8E0, 0xA8F1, prExtend}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8F2, 0xA8F7, prOLetter}, // Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA + {0xA8FB, 0xA8FB, prOLetter}, // Lo DEVANAGARI HEADSTROKE + {0xA8FD, 0xA8FE, prOLetter}, // Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY + {0xA8FF, 0xA8FF, prExtend}, // Mn DEVANAGARI VOWEL SIGN AY + {0xA900, 0xA909, prNumeric}, // Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE + {0xA90A, 0xA925, prOLetter}, // Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO + {0xA926, 0xA92D, prExtend}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA92F, 0xA92F, prSTerm}, // Po KAYAH LI SIGN SHYA + {0xA930, 0xA946, prOLetter}, // Lo [23] REJANG LETTER KA..REJANG LETTER A + {0xA947, 0xA951, prExtend}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prExtend}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA960, 0xA97C, prOLetter}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prExtend}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prExtend}, // Mc JAVANESE SIGN WIGNYAN + {0xA984, 0xA9B2, prOLetter}, // Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA + {0xA9B3, 0xA9B3, prExtend}, // Mn JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prExtend}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prExtend}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prExtend}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prExtend}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prExtend}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9C8, 0xA9C9, prSTerm}, // Po [2] JAVANESE PADA LINGSA..JAVANESE PADA LUNGSI + {0xA9CF, 0xA9CF, prOLetter}, // Lm JAVANESE PANGRANGKEP + {0xA9D0, 0xA9D9, prNumeric}, // Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE + {0xA9E0, 0xA9E4, prOLetter}, // Lo [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA + {0xA9E5, 0xA9E5, prExtend}, // Mn MYANMAR SIGN SHAN SAW + {0xA9E6, 0xA9E6, prOLetter}, // Lm MYANMAR MODIFIER LETTER SHAN REDUPLICATION + {0xA9E7, 0xA9EF, prOLetter}, // Lo [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA + {0xA9F0, 0xA9F9, prNumeric}, // Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE + {0xA9FA, 0xA9FE, prOLetter}, // Lo [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA + {0xAA00, 0xAA28, prOLetter}, // Lo [41] CHAM LETTER A..CHAM LETTER HA + {0xAA29, 0xAA2E, prExtend}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prExtend}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prExtend}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prExtend}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prExtend}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA40, 0xAA42, prOLetter}, // Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG + {0xAA43, 0xAA43, prExtend}, // Mn CHAM CONSONANT SIGN FINAL NG + {0xAA44, 0xAA4B, prOLetter}, // Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS + {0xAA4C, 0xAA4C, prExtend}, // Mn CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prExtend}, // Mc CHAM CONSONANT SIGN FINAL H + {0xAA50, 0xAA59, prNumeric}, // Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE + {0xAA5D, 0xAA5F, prSTerm}, // Po [3] CHAM PUNCTUATION DANDA..CHAM PUNCTUATION TRIPLE DANDA + {0xAA60, 0xAA6F, prOLetter}, // Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA + {0xAA70, 0xAA70, prOLetter}, // Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION + {0xAA71, 0xAA76, prOLetter}, // Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM + {0xAA7A, 0xAA7A, prOLetter}, // Lo MYANMAR LETTER AITON RA + {0xAA7B, 0xAA7B, prExtend}, // Mc MYANMAR SIGN PAO KAREN TONE + {0xAA7C, 0xAA7C, prExtend}, // Mn MYANMAR SIGN TAI LAING TONE-2 + {0xAA7D, 0xAA7D, prExtend}, // Mc MYANMAR SIGN TAI LAING TONE-5 + {0xAA7E, 0xAAAF, prOLetter}, // Lo [50] MYANMAR LETTER SHWE PALAUNG CHA..TAI VIET LETTER HIGH O + {0xAAB0, 0xAAB0, prExtend}, // Mn TAI VIET MAI KANG + {0xAAB1, 0xAAB1, prOLetter}, // Lo TAI VIET VOWEL AA + {0xAAB2, 0xAAB4, prExtend}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB5, 0xAAB6, prOLetter}, // Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O + {0xAAB7, 0xAAB8, prExtend}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAAB9, 0xAABD, prOLetter}, // Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN + {0xAABE, 0xAABF, prExtend}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC0, 0xAAC0, prOLetter}, // Lo TAI VIET TONE MAI NUENG + {0xAAC1, 0xAAC1, prExtend}, // Mn TAI VIET TONE MAI THO + {0xAAC2, 0xAAC2, prOLetter}, // Lo TAI VIET TONE MAI SONG + {0xAADB, 0xAADC, prOLetter}, // Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG + {0xAADD, 0xAADD, prOLetter}, // Lm TAI VIET SYMBOL SAM + {0xAAE0, 0xAAEA, prOLetter}, // Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA + {0xAAEB, 0xAAEB, prExtend}, // Mc MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prExtend}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF0, 0xAAF1, prSTerm}, // Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM + {0xAAF2, 0xAAF2, prOLetter}, // Lo MEETEI MAYEK ANJI + {0xAAF3, 0xAAF4, prOLetter}, // Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK + {0xAAF5, 0xAAF5, prExtend}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prExtend}, // Mn MEETEI MAYEK VIRAMA + {0xAB01, 0xAB06, prOLetter}, // Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO + {0xAB09, 0xAB0E, prOLetter}, // Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO + {0xAB11, 0xAB16, prOLetter}, // Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO + {0xAB20, 0xAB26, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO + {0xAB28, 0xAB2E, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO + {0xAB30, 0xAB5A, prLower}, // L& [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG + {0xAB5C, 0xAB5F, prLower}, // Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK + {0xAB60, 0xAB68, prLower}, // L& [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE + {0xAB69, 0xAB69, prLower}, // Lm MODIFIER LETTER SMALL TURNED W + {0xAB70, 0xABBF, prLower}, // L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA + {0xABC0, 0xABE2, prOLetter}, // Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM + {0xABE3, 0xABE4, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEB, 0xABEB, prSTerm}, // Po MEETEI MAYEK CHEIKHEI + {0xABEC, 0xABEC, prExtend}, // Mc MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prExtend}, // Mn MEETEI MAYEK APUN IYEK + {0xABF0, 0xABF9, prNumeric}, // Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE + {0xAC00, 0xD7A3, prOLetter}, // Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prOLetter}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prOLetter}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xF900, 0xFA6D, prOLetter}, // Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D + {0xFA70, 0xFAD9, prOLetter}, // Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 + {0xFB00, 0xFB06, prLower}, // L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST + {0xFB13, 0xFB17, prLower}, // L& [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH + {0xFB1D, 0xFB1D, prOLetter}, // Lo HEBREW LETTER YOD WITH HIRIQ + {0xFB1E, 0xFB1E, prExtend}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA + {0xFB1F, 0xFB28, prOLetter}, // Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV + {0xFB2A, 0xFB36, prOLetter}, // Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH + {0xFB38, 0xFB3C, prOLetter}, // Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH + {0xFB3E, 0xFB3E, prOLetter}, // Lo HEBREW LETTER MEM WITH DAGESH + {0xFB40, 0xFB41, prOLetter}, // Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH + {0xFB43, 0xFB44, prOLetter}, // Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH + {0xFB46, 0xFBB1, prOLetter}, // Lo [108] HEBREW LETTER TSADI WITH DAGESH..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM + {0xFBD3, 0xFD3D, prOLetter}, // Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM + {0xFD3E, 0xFD3E, prClose}, // Pe ORNATE LEFT PARENTHESIS + {0xFD3F, 0xFD3F, prClose}, // Ps ORNATE RIGHT PARENTHESIS + {0xFD50, 0xFD8F, prOLetter}, // Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM + {0xFD92, 0xFDC7, prOLetter}, // Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM + {0xFDF0, 0xFDFB, prOLetter}, // Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU + {0xFE00, 0xFE0F, prExtend}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE10, 0xFE11, prSContinue}, // Po [2] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA + {0xFE13, 0xFE13, prSContinue}, // Po PRESENTATION FORM FOR VERTICAL COLON + {0xFE17, 0xFE17, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET + {0xFE18, 0xFE18, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET + {0xFE20, 0xFE2F, prExtend}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFE31, 0xFE32, prSContinue}, // Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH + {0xFE35, 0xFE35, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS + {0xFE36, 0xFE36, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS + {0xFE37, 0xFE37, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET + {0xFE38, 0xFE38, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET + {0xFE39, 0xFE39, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET + {0xFE3A, 0xFE3A, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET + {0xFE3B, 0xFE3B, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET + {0xFE3C, 0xFE3C, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET + {0xFE3D, 0xFE3D, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET + {0xFE3E, 0xFE3E, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET + {0xFE3F, 0xFE3F, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET + {0xFE40, 0xFE40, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET + {0xFE41, 0xFE41, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET + {0xFE42, 0xFE42, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET + {0xFE43, 0xFE43, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET + {0xFE44, 0xFE44, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET + {0xFE47, 0xFE47, prClose}, // Ps PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET + {0xFE48, 0xFE48, prClose}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET + {0xFE50, 0xFE51, prSContinue}, // Po [2] SMALL COMMA..SMALL IDEOGRAPHIC COMMA + {0xFE52, 0xFE52, prATerm}, // Po SMALL FULL STOP + {0xFE55, 0xFE55, prSContinue}, // Po SMALL COLON + {0xFE56, 0xFE57, prSTerm}, // Po [2] SMALL QUESTION MARK..SMALL EXCLAMATION MARK + {0xFE58, 0xFE58, prSContinue}, // Pd SMALL EM DASH + {0xFE59, 0xFE59, prClose}, // Ps SMALL LEFT PARENTHESIS + {0xFE5A, 0xFE5A, prClose}, // Pe SMALL RIGHT PARENTHESIS + {0xFE5B, 0xFE5B, prClose}, // Ps SMALL LEFT CURLY BRACKET + {0xFE5C, 0xFE5C, prClose}, // Pe SMALL RIGHT CURLY BRACKET + {0xFE5D, 0xFE5D, prClose}, // Ps SMALL LEFT TORTOISE SHELL BRACKET + {0xFE5E, 0xFE5E, prClose}, // Pe SMALL RIGHT TORTOISE SHELL BRACKET + {0xFE63, 0xFE63, prSContinue}, // Pd SMALL HYPHEN-MINUS + {0xFE70, 0xFE74, prOLetter}, // Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM + {0xFE76, 0xFEFC, prOLetter}, // Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM + {0xFEFF, 0xFEFF, prFormat}, // Cf ZERO WIDTH NO-BREAK SPACE + {0xFF01, 0xFF01, prSTerm}, // Po FULLWIDTH EXCLAMATION MARK + {0xFF08, 0xFF08, prClose}, // Ps FULLWIDTH LEFT PARENTHESIS + {0xFF09, 0xFF09, prClose}, // Pe FULLWIDTH RIGHT PARENTHESIS + {0xFF0C, 0xFF0C, prSContinue}, // Po FULLWIDTH COMMA + {0xFF0D, 0xFF0D, prSContinue}, // Pd FULLWIDTH HYPHEN-MINUS + {0xFF0E, 0xFF0E, prATerm}, // Po FULLWIDTH FULL STOP + {0xFF10, 0xFF19, prNumeric}, // Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE + {0xFF1A, 0xFF1A, prSContinue}, // Po FULLWIDTH COLON + {0xFF1F, 0xFF1F, prSTerm}, // Po FULLWIDTH QUESTION MARK + {0xFF21, 0xFF3A, prUpper}, // L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z + {0xFF3B, 0xFF3B, prClose}, // Ps FULLWIDTH LEFT SQUARE BRACKET + {0xFF3D, 0xFF3D, prClose}, // Pe FULLWIDTH RIGHT SQUARE BRACKET + {0xFF41, 0xFF5A, prLower}, // L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z + {0xFF5B, 0xFF5B, prClose}, // Ps FULLWIDTH LEFT CURLY BRACKET + {0xFF5D, 0xFF5D, prClose}, // Pe FULLWIDTH RIGHT CURLY BRACKET + {0xFF5F, 0xFF5F, prClose}, // Ps FULLWIDTH LEFT WHITE PARENTHESIS + {0xFF60, 0xFF60, prClose}, // Pe FULLWIDTH RIGHT WHITE PARENTHESIS + {0xFF61, 0xFF61, prSTerm}, // Po HALFWIDTH IDEOGRAPHIC FULL STOP + {0xFF62, 0xFF62, prClose}, // Ps HALFWIDTH LEFT CORNER BRACKET + {0xFF63, 0xFF63, prClose}, // Pe HALFWIDTH RIGHT CORNER BRACKET + {0xFF64, 0xFF64, prSContinue}, // Po HALFWIDTH IDEOGRAPHIC COMMA + {0xFF66, 0xFF6F, prOLetter}, // Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU + {0xFF70, 0xFF70, prOLetter}, // Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0xFF71, 0xFF9D, prOLetter}, // Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N + {0xFF9E, 0xFF9F, prExtend}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFA0, 0xFFBE, prOLetter}, // Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH + {0xFFC2, 0xFFC7, prOLetter}, // Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E + {0xFFCA, 0xFFCF, prOLetter}, // Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE + {0xFFD2, 0xFFD7, prOLetter}, // Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU + {0xFFDA, 0xFFDC, prOLetter}, // Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I + {0xFFF9, 0xFFFB, prFormat}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0x10000, 0x1000B, prOLetter}, // Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE + {0x1000D, 0x10026, prOLetter}, // Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO + {0x10028, 0x1003A, prOLetter}, // Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO + {0x1003C, 0x1003D, prOLetter}, // Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE + {0x1003F, 0x1004D, prOLetter}, // Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO + {0x10050, 0x1005D, prOLetter}, // Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 + {0x10080, 0x100FA, prOLetter}, // Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 + {0x10140, 0x10174, prOLetter}, // Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS + {0x101FD, 0x101FD, prExtend}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x10280, 0x1029C, prOLetter}, // Lo [29] LYCIAN LETTER A..LYCIAN LETTER X + {0x102A0, 0x102D0, prOLetter}, // Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3 + {0x102E0, 0x102E0, prExtend}, // Mn COPTIC EPACT THOUSANDS MARK + {0x10300, 0x1031F, prOLetter}, // Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS + {0x1032D, 0x10340, prOLetter}, // Lo [20] OLD ITALIC LETTER YE..GOTHIC LETTER PAIRTHRA + {0x10341, 0x10341, prOLetter}, // Nl GOTHIC LETTER NINETY + {0x10342, 0x10349, prOLetter}, // Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL + {0x1034A, 0x1034A, prOLetter}, // Nl GOTHIC LETTER NINE HUNDRED + {0x10350, 0x10375, prOLetter}, // Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA + {0x10376, 0x1037A, prExtend}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10380, 0x1039D, prOLetter}, // Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU + {0x103A0, 0x103C3, prOLetter}, // Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA + {0x103C8, 0x103CF, prOLetter}, // Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH + {0x103D1, 0x103D5, prOLetter}, // Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED + {0x10400, 0x10427, prUpper}, // L& [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW + {0x10428, 0x1044F, prLower}, // L& [40] DESERET SMALL LETTER LONG I..DESERET SMALL LETTER EW + {0x10450, 0x1049D, prOLetter}, // Lo [78] SHAVIAN LETTER PEEP..OSMANYA LETTER OO + {0x104A0, 0x104A9, prNumeric}, // Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE + {0x104B0, 0x104D3, prUpper}, // L& [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA + {0x104D8, 0x104FB, prLower}, // L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA + {0x10500, 0x10527, prOLetter}, // Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE + {0x10530, 0x10563, prOLetter}, // Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW + {0x10570, 0x1057A, prUpper}, // L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA + {0x1057C, 0x1058A, prUpper}, // L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE + {0x1058C, 0x10592, prUpper}, // L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE + {0x10594, 0x10595, prUpper}, // L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE + {0x10597, 0x105A1, prLower}, // L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA + {0x105A3, 0x105B1, prLower}, // L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE + {0x105B3, 0x105B9, prLower}, // L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE + {0x105BB, 0x105BC, prLower}, // L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE + {0x10600, 0x10736, prOLetter}, // Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 + {0x10740, 0x10755, prOLetter}, // Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE + {0x10760, 0x10767, prOLetter}, // Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 + {0x10780, 0x10780, prLower}, // Lm MODIFIER LETTER SMALL CAPITAL AA + {0x10781, 0x10782, prOLetter}, // Lm [2] MODIFIER LETTER SUPERSCRIPT TRIANGULAR COLON..MODIFIER LETTER SUPERSCRIPT HALF TRIANGULAR COLON + {0x10783, 0x10785, prLower}, // Lm [3] MODIFIER LETTER SMALL AE..MODIFIER LETTER SMALL B WITH HOOK + {0x10787, 0x107B0, prLower}, // Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK + {0x107B2, 0x107BA, prLower}, // Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL + {0x10800, 0x10805, prOLetter}, // Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA + {0x10808, 0x10808, prOLetter}, // Lo CYPRIOT SYLLABLE JO + {0x1080A, 0x10835, prOLetter}, // Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO + {0x10837, 0x10838, prOLetter}, // Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE + {0x1083C, 0x1083C, prOLetter}, // Lo CYPRIOT SYLLABLE ZA + {0x1083F, 0x10855, prOLetter}, // Lo [23] CYPRIOT SYLLABLE ZO..IMPERIAL ARAMAIC LETTER TAW + {0x10860, 0x10876, prOLetter}, // Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW + {0x10880, 0x1089E, prOLetter}, // Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW + {0x108E0, 0x108F2, prOLetter}, // Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH + {0x108F4, 0x108F5, prOLetter}, // Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW + {0x10900, 0x10915, prOLetter}, // Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU + {0x10920, 0x10939, prOLetter}, // Lo [26] LYDIAN LETTER A..LYDIAN LETTER C + {0x10980, 0x109B7, prOLetter}, // Lo [56] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC CURSIVE LETTER DA + {0x109BE, 0x109BF, prOLetter}, // Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN + {0x10A00, 0x10A00, prOLetter}, // Lo KHAROSHTHI LETTER A + {0x10A01, 0x10A03, prExtend}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prExtend}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prExtend}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A10, 0x10A13, prOLetter}, // Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA + {0x10A15, 0x10A17, prOLetter}, // Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA + {0x10A19, 0x10A35, prOLetter}, // Lo [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA + {0x10A38, 0x10A3A, prExtend}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prExtend}, // Mn KHAROSHTHI VIRAMA + {0x10A56, 0x10A57, prSTerm}, // Po [2] KHAROSHTHI PUNCTUATION DANDA..KHAROSHTHI PUNCTUATION DOUBLE DANDA + {0x10A60, 0x10A7C, prOLetter}, // Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH + {0x10A80, 0x10A9C, prOLetter}, // Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH + {0x10AC0, 0x10AC7, prOLetter}, // Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW + {0x10AC9, 0x10AE4, prOLetter}, // Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW + {0x10AE5, 0x10AE6, prExtend}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10B00, 0x10B35, prOLetter}, // Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE + {0x10B40, 0x10B55, prOLetter}, // Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW + {0x10B60, 0x10B72, prOLetter}, // Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW + {0x10B80, 0x10B91, prOLetter}, // Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW + {0x10C00, 0x10C48, prOLetter}, // Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH + {0x10C80, 0x10CB2, prUpper}, // L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US + {0x10CC0, 0x10CF2, prLower}, // L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US + {0x10D00, 0x10D23, prOLetter}, // Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA + {0x10D24, 0x10D27, prExtend}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10D30, 0x10D39, prNumeric}, // Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE + {0x10E80, 0x10EA9, prOLetter}, // Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET + {0x10EAB, 0x10EAC, prExtend}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EB0, 0x10EB1, prOLetter}, // Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE + {0x10EFD, 0x10EFF, prExtend}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F00, 0x10F1C, prOLetter}, // Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL + {0x10F27, 0x10F27, prOLetter}, // Lo OLD SOGDIAN LIGATURE AYIN-DALETH + {0x10F30, 0x10F45, prOLetter}, // Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN + {0x10F46, 0x10F50, prExtend}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F55, 0x10F59, prSTerm}, // Po [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT + {0x10F70, 0x10F81, prOLetter}, // Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH + {0x10F82, 0x10F85, prExtend}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x10F86, 0x10F89, prSTerm}, // Po [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS + {0x10FB0, 0x10FC4, prOLetter}, // Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW + {0x10FE0, 0x10FF6, prOLetter}, // Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH + {0x11000, 0x11000, prExtend}, // Mc BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prExtend}, // Mn BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prExtend}, // Mc BRAHMI SIGN VISARGA + {0x11003, 0x11037, prOLetter}, // Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA + {0x11038, 0x11046, prExtend}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11047, 0x11048, prSTerm}, // Po [2] BRAHMI DANDA..BRAHMI DOUBLE DANDA + {0x11066, 0x1106F, prNumeric}, // Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE + {0x11070, 0x11070, prExtend}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA + {0x11071, 0x11072, prOLetter}, // Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O + {0x11073, 0x11074, prExtend}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x11075, 0x11075, prOLetter}, // Lo BRAHMI LETTER OLD TAMIL LLA + {0x1107F, 0x11081, prExtend}, // Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prExtend}, // Mc KAITHI SIGN VISARGA + {0x11083, 0x110AF, prOLetter}, // Lo [45] KAITHI LETTER A..KAITHI LETTER HA + {0x110B0, 0x110B2, prExtend}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prExtend}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prExtend}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prExtend}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BD, 0x110BD, prFormat}, // Cf KAITHI NUMBER SIGN + {0x110BE, 0x110C1, prSTerm}, // Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA + {0x110C2, 0x110C2, prExtend}, // Mn KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prFormat}, // Cf KAITHI NUMBER SIGN ABOVE + {0x110D0, 0x110E8, prOLetter}, // Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE + {0x110F0, 0x110F9, prNumeric}, // Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE + {0x11100, 0x11102, prExtend}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11103, 0x11126, prOLetter}, // Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA + {0x11127, 0x1112B, prExtend}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prExtend}, // Mc CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prExtend}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11136, 0x1113F, prNumeric}, // Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE + {0x11141, 0x11143, prSTerm}, // Po [3] CHAKMA DANDA..CHAKMA QUESTION MARK + {0x11144, 0x11144, prOLetter}, // Lo CHAKMA LETTER LHAA + {0x11145, 0x11146, prExtend}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11147, 0x11147, prOLetter}, // Lo CHAKMA LETTER VAA + {0x11150, 0x11172, prOLetter}, // Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA + {0x11173, 0x11173, prExtend}, // Mn MAHAJANI SIGN NUKTA + {0x11176, 0x11176, prOLetter}, // Lo MAHAJANI LIGATURE SHRI + {0x11180, 0x11181, prExtend}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prExtend}, // Mc SHARADA SIGN VISARGA + {0x11183, 0x111B2, prOLetter}, // Lo [48] SHARADA LETTER A..SHARADA LETTER HA + {0x111B3, 0x111B5, prExtend}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prExtend}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prExtend}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C1, 0x111C4, prOLetter}, // Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM + {0x111C5, 0x111C6, prSTerm}, // Po [2] SHARADA DANDA..SHARADA DOUBLE DANDA + {0x111C9, 0x111CC, prExtend}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CD, 0x111CD, prSTerm}, // Po SHARADA SUTRA MARK + {0x111CE, 0x111CE, prExtend}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prExtend}, // Mn SHARADA SIGN INVERTED CANDRABINDU + {0x111D0, 0x111D9, prNumeric}, // Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE + {0x111DA, 0x111DA, prOLetter}, // Lo SHARADA EKAM + {0x111DC, 0x111DC, prOLetter}, // Lo SHARADA HEADSTROKE + {0x111DE, 0x111DF, prSTerm}, // Po [2] SHARADA SECTION MARK-1..SHARADA SECTION MARK-2 + {0x11200, 0x11211, prOLetter}, // Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA + {0x11213, 0x1122B, prOLetter}, // Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA + {0x1122C, 0x1122E, prExtend}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prExtend}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prExtend}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prExtend}, // Mn KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prExtend}, // Mc KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prExtend}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x11238, 0x11239, prSTerm}, // Po [2] KHOJKI DANDA..KHOJKI DOUBLE DANDA + {0x1123B, 0x1123C, prSTerm}, // Po [2] KHOJKI SECTION MARK..KHOJKI DOUBLE SECTION MARK + {0x1123E, 0x1123E, prExtend}, // Mn KHOJKI SIGN SUKUN + {0x1123F, 0x11240, prOLetter}, // Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I + {0x11241, 0x11241, prExtend}, // Mn KHOJKI VOWEL SIGN VOCALIC R + {0x11280, 0x11286, prOLetter}, // Lo [7] MULTANI LETTER A..MULTANI LETTER GA + {0x11288, 0x11288, prOLetter}, // Lo MULTANI LETTER GHA + {0x1128A, 0x1128D, prOLetter}, // Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA + {0x1128F, 0x1129D, prOLetter}, // Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA + {0x1129F, 0x112A8, prOLetter}, // Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA + {0x112A9, 0x112A9, prSTerm}, // Po MULTANI SECTION MARK + {0x112B0, 0x112DE, prOLetter}, // Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA + {0x112DF, 0x112DF, prExtend}, // Mn KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prExtend}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prExtend}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x112F0, 0x112F9, prNumeric}, // Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE + {0x11300, 0x11301, prExtend}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prExtend}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x11305, 0x1130C, prOLetter}, // Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L + {0x1130F, 0x11310, prOLetter}, // Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI + {0x11313, 0x11328, prOLetter}, // Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA + {0x1132A, 0x11330, prOLetter}, // Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA + {0x11332, 0x11333, prOLetter}, // Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA + {0x11335, 0x11339, prOLetter}, // Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA + {0x1133B, 0x1133C, prExtend}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133D, 0x1133D, prOLetter}, // Lo GRANTHA SIGN AVAGRAHA + {0x1133E, 0x1133F, prExtend}, // Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prExtend}, // Mn GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prExtend}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prExtend}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prExtend}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11350, 0x11350, prOLetter}, // Lo GRANTHA OM + {0x11357, 0x11357, prExtend}, // Mc GRANTHA AU LENGTH MARK + {0x1135D, 0x11361, prOLetter}, // Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL + {0x11362, 0x11363, prExtend}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prExtend}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prExtend}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11400, 0x11434, prOLetter}, // Lo [53] NEWA LETTER A..NEWA LETTER HA + {0x11435, 0x11437, prExtend}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prExtend}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prExtend}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prExtend}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prExtend}, // Mc NEWA SIGN VISARGA + {0x11446, 0x11446, prExtend}, // Mn NEWA SIGN NUKTA + {0x11447, 0x1144A, prOLetter}, // Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI + {0x1144B, 0x1144C, prSTerm}, // Po [2] NEWA DANDA..NEWA DOUBLE DANDA + {0x11450, 0x11459, prNumeric}, // Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE + {0x1145E, 0x1145E, prExtend}, // Mn NEWA SANDHI MARK + {0x1145F, 0x11461, prOLetter}, // Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA + {0x11480, 0x114AF, prOLetter}, // Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA + {0x114B0, 0x114B2, prExtend}, // Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prExtend}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prExtend}, // Mc TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prExtend}, // Mn TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BE, prExtend}, // Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prExtend}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prExtend}, // Mc TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prExtend}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x114C4, 0x114C5, prOLetter}, // Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG + {0x114C7, 0x114C7, prOLetter}, // Lo TIRHUTA OM + {0x114D0, 0x114D9, prNumeric}, // Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE + {0x11580, 0x115AE, prOLetter}, // Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA + {0x115AF, 0x115B1, prExtend}, // Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prExtend}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prExtend}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prExtend}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prExtend}, // Mc SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prExtend}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115C2, 0x115C3, prSTerm}, // Po [2] SIDDHAM DANDA..SIDDHAM DOUBLE DANDA + {0x115C9, 0x115D7, prSTerm}, // Po [15] SIDDHAM END OF TEXT MARK..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES + {0x115D8, 0x115DB, prOLetter}, // Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U + {0x115DC, 0x115DD, prExtend}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11600, 0x1162F, prOLetter}, // Lo [48] MODI LETTER A..MODI LETTER LLA + {0x11630, 0x11632, prExtend}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prExtend}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prExtend}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prExtend}, // Mn MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prExtend}, // Mc MODI SIGN VISARGA + {0x1163F, 0x11640, prExtend}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x11641, 0x11642, prSTerm}, // Po [2] MODI DANDA..MODI DOUBLE DANDA + {0x11644, 0x11644, prOLetter}, // Lo MODI SIGN HUVA + {0x11650, 0x11659, prNumeric}, // Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE + {0x11680, 0x116AA, prOLetter}, // Lo [43] TAKRI LETTER A..TAKRI LETTER RRA + {0x116AB, 0x116AB, prExtend}, // Mn TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prExtend}, // Mc TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prExtend}, // Mn TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prExtend}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prExtend}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prExtend}, // Mc TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prExtend}, // Mn TAKRI SIGN NUKTA + {0x116B8, 0x116B8, prOLetter}, // Lo TAKRI LETTER ARCHAIC KHA + {0x116C0, 0x116C9, prNumeric}, // Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE + {0x11700, 0x1171A, prOLetter}, // Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA + {0x1171D, 0x1171F, prExtend}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11720, 0x11721, prExtend}, // Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA + {0x11722, 0x11725, prExtend}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prExtend}, // Mc AHOM VOWEL SIGN E + {0x11727, 0x1172B, prExtend}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x11730, 0x11739, prNumeric}, // Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE + {0x1173C, 0x1173E, prSTerm}, // Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI + {0x11740, 0x11746, prOLetter}, // Lo [7] AHOM LETTER CA..AHOM LETTER LLA + {0x11800, 0x1182B, prOLetter}, // Lo [44] DOGRA LETTER A..DOGRA LETTER RRA + {0x1182C, 0x1182E, prExtend}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prExtend}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prExtend}, // Mc DOGRA SIGN VISARGA + {0x11839, 0x1183A, prExtend}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x118A0, 0x118BF, prUpper}, // L& [32] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI CAPITAL LETTER VIYO + {0x118C0, 0x118DF, prLower}, // L& [32] WARANG CITI SMALL LETTER NGAA..WARANG CITI SMALL LETTER VIYO + {0x118E0, 0x118E9, prNumeric}, // Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE + {0x118FF, 0x11906, prOLetter}, // Lo [8] WARANG CITI OM..DIVES AKURU LETTER E + {0x11909, 0x11909, prOLetter}, // Lo DIVES AKURU LETTER O + {0x1190C, 0x11913, prOLetter}, // Lo [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA + {0x11915, 0x11916, prOLetter}, // Lo [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA + {0x11918, 0x1192F, prOLetter}, // Lo [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA + {0x11930, 0x11935, prExtend}, // Mc [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prExtend}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prExtend}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prExtend}, // Mc DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prExtend}, // Mn DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prOLetter}, // Lo DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prExtend}, // Mc DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prOLetter}, // Lo DIVES AKURU INITIAL RA + {0x11942, 0x11942, prExtend}, // Mc DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prExtend}, // Mn DIVES AKURU SIGN NUKTA + {0x11944, 0x11944, prSTerm}, // Po DIVES AKURU DOUBLE DANDA + {0x11946, 0x11946, prSTerm}, // Po DIVES AKURU END OF TEXT MARK + {0x11950, 0x11959, prNumeric}, // Nd [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE + {0x119A0, 0x119A7, prOLetter}, // Lo [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR + {0x119AA, 0x119D0, prOLetter}, // Lo [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA + {0x119D1, 0x119D3, prExtend}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prExtend}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prExtend}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prExtend}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prExtend}, // Mn NANDINAGARI SIGN VIRAMA + {0x119E1, 0x119E1, prOLetter}, // Lo NANDINAGARI SIGN AVAGRAHA + {0x119E3, 0x119E3, prOLetter}, // Lo NANDINAGARI HEADSTROKE + {0x119E4, 0x119E4, prExtend}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A00, 0x11A00, prOLetter}, // Lo ZANABAZAR SQUARE LETTER A + {0x11A01, 0x11A0A, prExtend}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A0B, 0x11A32, prOLetter}, // Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA + {0x11A33, 0x11A38, prExtend}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prExtend}, // Mc ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prOLetter}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prExtend}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A42, 0x11A43, prSTerm}, // Po [2] ZANABAZAR SQUARE MARK SHAD..ZANABAZAR SQUARE MARK DOUBLE SHAD + {0x11A47, 0x11A47, prExtend}, // Mn ZANABAZAR SQUARE SUBJOINER + {0x11A50, 0x11A50, prOLetter}, // Lo SOYOMBO LETTER A + {0x11A51, 0x11A56, prExtend}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prExtend}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prExtend}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A5C, 0x11A89, prOLetter}, // Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prExtend}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prExtend}, // Mc SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prExtend}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11A9B, 0x11A9C, prSTerm}, // Po [2] SOYOMBO MARK SHAD..SOYOMBO MARK DOUBLE SHAD + {0x11A9D, 0x11A9D, prOLetter}, // Lo SOYOMBO MARK PLUTA + {0x11AB0, 0x11AF8, prOLetter}, // Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL + {0x11C00, 0x11C08, prOLetter}, // Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L + {0x11C0A, 0x11C2E, prOLetter}, // Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA + {0x11C2F, 0x11C2F, prExtend}, // Mc BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prExtend}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prExtend}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prExtend}, // Mc BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prExtend}, // Mn BHAIKSUKI SIGN VIRAMA + {0x11C40, 0x11C40, prOLetter}, // Lo BHAIKSUKI SIGN AVAGRAHA + {0x11C41, 0x11C42, prSTerm}, // Po [2] BHAIKSUKI DANDA..BHAIKSUKI DOUBLE DANDA + {0x11C50, 0x11C59, prNumeric}, // Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE + {0x11C72, 0x11C8F, prOLetter}, // Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A + {0x11C92, 0x11CA7, prExtend}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prExtend}, // Mc MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prExtend}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prExtend}, // Mc MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prExtend}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prExtend}, // Mc MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prExtend}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D00, 0x11D06, prOLetter}, // Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E + {0x11D08, 0x11D09, prOLetter}, // Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O + {0x11D0B, 0x11D30, prOLetter}, // Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA + {0x11D31, 0x11D36, prExtend}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prExtend}, // Mn MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prExtend}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prExtend}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prOLetter}, // Lo MASARAM GONDI REPHA + {0x11D47, 0x11D47, prExtend}, // Mn MASARAM GONDI RA-KARA + {0x11D50, 0x11D59, prNumeric}, // Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE + {0x11D60, 0x11D65, prOLetter}, // Lo [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU + {0x11D67, 0x11D68, prOLetter}, // Lo [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI + {0x11D6A, 0x11D89, prOLetter}, // Lo [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA + {0x11D8A, 0x11D8E, prExtend}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prExtend}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prExtend}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prExtend}, // Mn GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prExtend}, // Mc GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prExtend}, // Mn GUNJALA GONDI VIRAMA + {0x11D98, 0x11D98, prOLetter}, // Lo GUNJALA GONDI OM + {0x11DA0, 0x11DA9, prNumeric}, // Nd [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE + {0x11EE0, 0x11EF2, prOLetter}, // Lo [19] MAKASAR LETTER KA..MAKASAR ANGKA + {0x11EF3, 0x11EF4, prExtend}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prExtend}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11EF7, 0x11EF8, prSTerm}, // Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION + {0x11F00, 0x11F01, prExtend}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prOLetter}, // Lo KAWI SIGN REPHA + {0x11F03, 0x11F03, prExtend}, // Mc KAWI SIGN VISARGA + {0x11F04, 0x11F10, prOLetter}, // Lo [13] KAWI LETTER A..KAWI LETTER O + {0x11F12, 0x11F33, prOLetter}, // Lo [34] KAWI LETTER KA..KAWI LETTER JNYA + {0x11F34, 0x11F35, prExtend}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prExtend}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prExtend}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prExtend}, // Mn KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prExtend}, // Mc KAWI SIGN KILLER + {0x11F42, 0x11F42, prExtend}, // Mn KAWI CONJOINER + {0x11F43, 0x11F44, prSTerm}, // Po [2] KAWI DANDA..KAWI DOUBLE DANDA + {0x11F50, 0x11F59, prNumeric}, // Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE + {0x11FB0, 0x11FB0, prOLetter}, // Lo LISU LETTER YHA + {0x12000, 0x12399, prOLetter}, // Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U + {0x12400, 0x1246E, prOLetter}, // Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM + {0x12480, 0x12543, prOLetter}, // Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU + {0x12F90, 0x12FF0, prOLetter}, // Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 + {0x13000, 0x1342F, prOLetter}, // Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D + {0x13430, 0x1343F, prFormat}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prExtend}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13441, 0x13446, prOLetter}, // Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN + {0x13447, 0x13455, prExtend}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x14400, 0x14646, prOLetter}, // Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 + {0x16800, 0x16A38, prOLetter}, // Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ + {0x16A40, 0x16A5E, prOLetter}, // Lo [31] MRO LETTER TA..MRO LETTER TEK + {0x16A60, 0x16A69, prNumeric}, // Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE + {0x16A6E, 0x16A6F, prSTerm}, // Po [2] MRO DANDA..MRO DOUBLE DANDA + {0x16A70, 0x16ABE, prOLetter}, // Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA + {0x16AC0, 0x16AC9, prNumeric}, // Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE + {0x16AD0, 0x16AED, prOLetter}, // Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I + {0x16AF0, 0x16AF4, prExtend}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16AF5, 0x16AF5, prSTerm}, // Po BASSA VAH FULL STOP + {0x16B00, 0x16B2F, prOLetter}, // Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU + {0x16B30, 0x16B36, prExtend}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16B37, 0x16B38, prSTerm}, // Po [2] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS TSHAB CEEB + {0x16B40, 0x16B43, prOLetter}, // Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM + {0x16B44, 0x16B44, prSTerm}, // Po PAHAWH HMONG SIGN XAUS + {0x16B50, 0x16B59, prNumeric}, // Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE + {0x16B63, 0x16B77, prOLetter}, // Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS + {0x16B7D, 0x16B8F, prOLetter}, // Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ + {0x16E40, 0x16E5F, prUpper}, // L& [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y + {0x16E60, 0x16E7F, prLower}, // L& [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y + {0x16E98, 0x16E98, prSTerm}, // Po MEDEFAIDRIN FULL STOP + {0x16F00, 0x16F4A, prOLetter}, // Lo [75] MIAO LETTER PA..MIAO LETTER RTE + {0x16F4F, 0x16F4F, prExtend}, // Mn MIAO SIGN CONSONANT MODIFIER BAR + {0x16F50, 0x16F50, prOLetter}, // Lo MIAO LETTER NASALIZATION + {0x16F51, 0x16F87, prExtend}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prExtend}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16F93, 0x16F9F, prOLetter}, // Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 + {0x16FE0, 0x16FE1, prOLetter}, // Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK + {0x16FE3, 0x16FE3, prOLetter}, // Lm OLD CHINESE ITERATION MARK + {0x16FE4, 0x16FE4, prExtend}, // Mn KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prExtend}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x17000, 0x187F7, prOLetter}, // Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 + {0x18800, 0x18CD5, prOLetter}, // Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 + {0x18D00, 0x18D08, prOLetter}, // Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 + {0x1AFF0, 0x1AFF3, prOLetter}, // Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 + {0x1AFF5, 0x1AFFB, prOLetter}, // Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 + {0x1AFFD, 0x1AFFE, prOLetter}, // Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 + {0x1B000, 0x1B122, prOLetter}, // Lo [291] KATAKANA LETTER ARCHAIC E..KATAKANA LETTER ARCHAIC WU + {0x1B132, 0x1B132, prOLetter}, // Lo HIRAGANA LETTER SMALL KO + {0x1B150, 0x1B152, prOLetter}, // Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO + {0x1B155, 0x1B155, prOLetter}, // Lo KATAKANA LETTER SMALL KO + {0x1B164, 0x1B167, prOLetter}, // Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N + {0x1B170, 0x1B2FB, prOLetter}, // Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB + {0x1BC00, 0x1BC6A, prOLetter}, // Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M + {0x1BC70, 0x1BC7C, prOLetter}, // Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK + {0x1BC80, 0x1BC88, prOLetter}, // Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL + {0x1BC90, 0x1BC99, prOLetter}, // Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW + {0x1BC9D, 0x1BC9E, prExtend}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BC9F, 0x1BC9F, prSTerm}, // Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP + {0x1BCA0, 0x1BCA3, prFormat}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prExtend}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prExtend}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1D165, 0x1D166, prExtend}, // Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prExtend}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16D, 0x1D172, prExtend}, // Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prFormat}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prExtend}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D185, 0x1D18B, prExtend}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D1AA, 0x1D1AD, prExtend}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D242, 0x1D244, prExtend}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1D400, 0x1D419, prUpper}, // L& [26] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL BOLD CAPITAL Z + {0x1D41A, 0x1D433, prLower}, // L& [26] MATHEMATICAL BOLD SMALL A..MATHEMATICAL BOLD SMALL Z + {0x1D434, 0x1D44D, prUpper}, // L& [26] MATHEMATICAL ITALIC CAPITAL A..MATHEMATICAL ITALIC CAPITAL Z + {0x1D44E, 0x1D454, prLower}, // L& [7] MATHEMATICAL ITALIC SMALL A..MATHEMATICAL ITALIC SMALL G + {0x1D456, 0x1D467, prLower}, // L& [18] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL ITALIC SMALL Z + {0x1D468, 0x1D481, prUpper}, // L& [26] MATHEMATICAL BOLD ITALIC CAPITAL A..MATHEMATICAL BOLD ITALIC CAPITAL Z + {0x1D482, 0x1D49B, prLower}, // L& [26] MATHEMATICAL BOLD ITALIC SMALL A..MATHEMATICAL BOLD ITALIC SMALL Z + {0x1D49C, 0x1D49C, prUpper}, // L& MATHEMATICAL SCRIPT CAPITAL A + {0x1D49E, 0x1D49F, prUpper}, // L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D + {0x1D4A2, 0x1D4A2, prUpper}, // L& MATHEMATICAL SCRIPT CAPITAL G + {0x1D4A5, 0x1D4A6, prUpper}, // L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K + {0x1D4A9, 0x1D4AC, prUpper}, // L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q + {0x1D4AE, 0x1D4B5, prUpper}, // L& [8] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT CAPITAL Z + {0x1D4B6, 0x1D4B9, prLower}, // L& [4] MATHEMATICAL SCRIPT SMALL A..MATHEMATICAL SCRIPT SMALL D + {0x1D4BB, 0x1D4BB, prLower}, // L& MATHEMATICAL SCRIPT SMALL F + {0x1D4BD, 0x1D4C3, prLower}, // L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N + {0x1D4C5, 0x1D4CF, prLower}, // L& [11] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL SCRIPT SMALL Z + {0x1D4D0, 0x1D4E9, prUpper}, // L& [26] MATHEMATICAL BOLD SCRIPT CAPITAL A..MATHEMATICAL BOLD SCRIPT CAPITAL Z + {0x1D4EA, 0x1D503, prLower}, // L& [26] MATHEMATICAL BOLD SCRIPT SMALL A..MATHEMATICAL BOLD SCRIPT SMALL Z + {0x1D504, 0x1D505, prUpper}, // L& [2] MATHEMATICAL FRAKTUR CAPITAL A..MATHEMATICAL FRAKTUR CAPITAL B + {0x1D507, 0x1D50A, prUpper}, // L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G + {0x1D50D, 0x1D514, prUpper}, // L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q + {0x1D516, 0x1D51C, prUpper}, // L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y + {0x1D51E, 0x1D537, prLower}, // L& [26] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL FRAKTUR SMALL Z + {0x1D538, 0x1D539, prUpper}, // L& [2] MATHEMATICAL DOUBLE-STRUCK CAPITAL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B + {0x1D53B, 0x1D53E, prUpper}, // L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G + {0x1D540, 0x1D544, prUpper}, // L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M + {0x1D546, 0x1D546, prUpper}, // L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O + {0x1D54A, 0x1D550, prUpper}, // L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + {0x1D552, 0x1D56B, prLower}, // L& [26] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL DOUBLE-STRUCK SMALL Z + {0x1D56C, 0x1D585, prUpper}, // L& [26] MATHEMATICAL BOLD FRAKTUR CAPITAL A..MATHEMATICAL BOLD FRAKTUR CAPITAL Z + {0x1D586, 0x1D59F, prLower}, // L& [26] MATHEMATICAL BOLD FRAKTUR SMALL A..MATHEMATICAL BOLD FRAKTUR SMALL Z + {0x1D5A0, 0x1D5B9, prUpper}, // L& [26] MATHEMATICAL SANS-SERIF CAPITAL A..MATHEMATICAL SANS-SERIF CAPITAL Z + {0x1D5BA, 0x1D5D3, prLower}, // L& [26] MATHEMATICAL SANS-SERIF SMALL A..MATHEMATICAL SANS-SERIF SMALL Z + {0x1D5D4, 0x1D5ED, prUpper}, // L& [26] MATHEMATICAL SANS-SERIF BOLD CAPITAL A..MATHEMATICAL SANS-SERIF BOLD CAPITAL Z + {0x1D5EE, 0x1D607, prLower}, // L& [26] MATHEMATICAL SANS-SERIF BOLD SMALL A..MATHEMATICAL SANS-SERIF BOLD SMALL Z + {0x1D608, 0x1D621, prUpper}, // L& [26] MATHEMATICAL SANS-SERIF ITALIC CAPITAL A..MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z + {0x1D622, 0x1D63B, prLower}, // L& [26] MATHEMATICAL SANS-SERIF ITALIC SMALL A..MATHEMATICAL SANS-SERIF ITALIC SMALL Z + {0x1D63C, 0x1D655, prUpper}, // L& [26] MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z + {0x1D656, 0x1D66F, prLower}, // L& [26] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z + {0x1D670, 0x1D689, prUpper}, // L& [26] MATHEMATICAL MONOSPACE CAPITAL A..MATHEMATICAL MONOSPACE CAPITAL Z + {0x1D68A, 0x1D6A5, prLower}, // L& [28] MATHEMATICAL MONOSPACE SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J + {0x1D6A8, 0x1D6C0, prUpper}, // L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA + {0x1D6C2, 0x1D6DA, prLower}, // L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA + {0x1D6DC, 0x1D6E1, prLower}, // L& [6] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL BOLD PI SYMBOL + {0x1D6E2, 0x1D6FA, prUpper}, // L& [25] MATHEMATICAL ITALIC CAPITAL ALPHA..MATHEMATICAL ITALIC CAPITAL OMEGA + {0x1D6FC, 0x1D714, prLower}, // L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA + {0x1D716, 0x1D71B, prLower}, // L& [6] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL ITALIC PI SYMBOL + {0x1D71C, 0x1D734, prUpper}, // L& [25] MATHEMATICAL BOLD ITALIC CAPITAL ALPHA..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA + {0x1D736, 0x1D74E, prLower}, // L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA + {0x1D750, 0x1D755, prLower}, // L& [6] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC PI SYMBOL + {0x1D756, 0x1D76E, prUpper}, // L& [25] MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA + {0x1D770, 0x1D788, prLower}, // L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA + {0x1D78A, 0x1D78F, prLower}, // L& [6] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD PI SYMBOL + {0x1D790, 0x1D7A8, prUpper}, // L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA + {0x1D7AA, 0x1D7C2, prLower}, // L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA + {0x1D7C4, 0x1D7C9, prLower}, // L& [6] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL + {0x1D7CA, 0x1D7CA, prUpper}, // L& MATHEMATICAL BOLD CAPITAL DIGAMMA + {0x1D7CB, 0x1D7CB, prLower}, // L& MATHEMATICAL BOLD SMALL DIGAMMA + {0x1D7CE, 0x1D7FF, prNumeric}, // Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + {0x1DA00, 0x1DA36, prExtend}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA3B, 0x1DA6C, prExtend}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA75, 0x1DA75, prExtend}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA84, 0x1DA84, prExtend}, // Mn SIGNWRITING LOCATION HEAD NECK + {0x1DA88, 0x1DA88, prSTerm}, // Po SIGNWRITING FULL STOP + {0x1DA9B, 0x1DA9F, prExtend}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prExtend}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1DF00, 0x1DF09, prLower}, // L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK + {0x1DF0A, 0x1DF0A, prOLetter}, // Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK + {0x1DF0B, 0x1DF1E, prLower}, // L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL + {0x1DF25, 0x1DF2A, prLower}, // L& [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK + {0x1E000, 0x1E006, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prExtend}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prExtend}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prExtend}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E030, 0x1E06D, prLower}, // Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE + {0x1E08F, 0x1E08F, prExtend}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E100, 0x1E12C, prOLetter}, // Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W + {0x1E130, 0x1E136, prExtend}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E137, 0x1E13D, prOLetter}, // Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER + {0x1E140, 0x1E149, prNumeric}, // Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE + {0x1E14E, 0x1E14E, prOLetter}, // Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ + {0x1E290, 0x1E2AD, prOLetter}, // Lo [30] TOTO LETTER PA..TOTO LETTER A + {0x1E2AE, 0x1E2AE, prExtend}, // Mn TOTO SIGN RISING TONE + {0x1E2C0, 0x1E2EB, prOLetter}, // Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH + {0x1E2EC, 0x1E2EF, prExtend}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E2F0, 0x1E2F9, prNumeric}, // Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE + {0x1E4D0, 0x1E4EA, prOLetter}, // Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL + {0x1E4EB, 0x1E4EB, prOLetter}, // Lm NAG MUNDARI SIGN OJOD + {0x1E4EC, 0x1E4EF, prExtend}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E4F0, 0x1E4F9, prNumeric}, // Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE + {0x1E7E0, 0x1E7E6, prOLetter}, // Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO + {0x1E7E8, 0x1E7EB, prOLetter}, // Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE + {0x1E7ED, 0x1E7EE, prOLetter}, // Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE + {0x1E7F0, 0x1E7FE, prOLetter}, // Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE + {0x1E800, 0x1E8C4, prOLetter}, // Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON + {0x1E8D0, 0x1E8D6, prExtend}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E900, 0x1E921, prUpper}, // L& [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA + {0x1E922, 0x1E943, prLower}, // L& [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA + {0x1E944, 0x1E94A, prExtend}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1E94B, 0x1E94B, prOLetter}, // Lm ADLAM NASALIZATION MARK + {0x1E950, 0x1E959, prNumeric}, // Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE + {0x1EE00, 0x1EE03, prOLetter}, // Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL + {0x1EE05, 0x1EE1F, prOLetter}, // Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF + {0x1EE21, 0x1EE22, prOLetter}, // Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM + {0x1EE24, 0x1EE24, prOLetter}, // Lo ARABIC MATHEMATICAL INITIAL HEH + {0x1EE27, 0x1EE27, prOLetter}, // Lo ARABIC MATHEMATICAL INITIAL HAH + {0x1EE29, 0x1EE32, prOLetter}, // Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF + {0x1EE34, 0x1EE37, prOLetter}, // Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH + {0x1EE39, 0x1EE39, prOLetter}, // Lo ARABIC MATHEMATICAL INITIAL DAD + {0x1EE3B, 0x1EE3B, prOLetter}, // Lo ARABIC MATHEMATICAL INITIAL GHAIN + {0x1EE42, 0x1EE42, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED JEEM + {0x1EE47, 0x1EE47, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED HAH + {0x1EE49, 0x1EE49, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED YEH + {0x1EE4B, 0x1EE4B, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED LAM + {0x1EE4D, 0x1EE4F, prOLetter}, // Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN + {0x1EE51, 0x1EE52, prOLetter}, // Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF + {0x1EE54, 0x1EE54, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED SHEEN + {0x1EE57, 0x1EE57, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED KHAH + {0x1EE59, 0x1EE59, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED DAD + {0x1EE5B, 0x1EE5B, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED GHAIN + {0x1EE5D, 0x1EE5D, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON + {0x1EE5F, 0x1EE5F, prOLetter}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF + {0x1EE61, 0x1EE62, prOLetter}, // Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM + {0x1EE64, 0x1EE64, prOLetter}, // Lo ARABIC MATHEMATICAL STRETCHED HEH + {0x1EE67, 0x1EE6A, prOLetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF + {0x1EE6C, 0x1EE72, prOLetter}, // Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF + {0x1EE74, 0x1EE77, prOLetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH + {0x1EE79, 0x1EE7C, prOLetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH + {0x1EE7E, 0x1EE7E, prOLetter}, // Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH + {0x1EE80, 0x1EE89, prOLetter}, // Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH + {0x1EE8B, 0x1EE9B, prOLetter}, // Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN + {0x1EEA1, 0x1EEA3, prOLetter}, // Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL + {0x1EEA5, 0x1EEA9, prOLetter}, // Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH + {0x1EEAB, 0x1EEBB, prOLetter}, // Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN + {0x1F130, 0x1F149, prUpper}, // So [26] SQUARED LATIN CAPITAL LETTER A..SQUARED LATIN CAPITAL LETTER Z + {0x1F150, 0x1F169, prUpper}, // So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z + {0x1F170, 0x1F189, prUpper}, // So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z + {0x1F676, 0x1F678, prClose}, // So [3] SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT..SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT + {0x1FBF0, 0x1FBF9, prNumeric}, // Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE + {0x20000, 0x2A6DF, prOLetter}, // Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF + {0x2A700, 0x2B739, prOLetter}, // Lo [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739 + {0x2B740, 0x2B81D, prOLetter}, // Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D + {0x2B820, 0x2CEA1, prOLetter}, // Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 + {0x2CEB0, 0x2EBE0, prOLetter}, // Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 + {0x2F800, 0x2FA1D, prOLetter}, // Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + {0x30000, 0x3134A, prOLetter}, // Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A + {0x31350, 0x323AF, prOLetter}, // Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF + {0xE0001, 0xE0001, prFormat}, // Cf LANGUAGE TAG + {0xE0020, 0xE007F, prExtend}, // Cf [96] TAG SPACE..CANCEL TAG + {0xE0100, 0xE01EF, prExtend}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 +} diff --git a/vendor/github.com/rivo/uniseg/sentencerules.go b/vendor/github.com/rivo/uniseg/sentencerules.go new file mode 100644 index 000000000..0b29c7bdb --- /dev/null +++ b/vendor/github.com/rivo/uniseg/sentencerules.go @@ -0,0 +1,276 @@ +package uniseg + +import "unicode/utf8" + +// The states of the sentence break parser. +const ( + sbAny = iota + sbCR + sbParaSep + sbATerm + sbUpper + sbLower + sbSB7 + sbSB8Close + sbSB8Sp + sbSTerm + sbSB8aClose + sbSB8aSp +) + +// sbTransitions implements the sentence break parser's state transitions. It's +// anologous to [grTransitions], see comments there for details. +// +// Unicode version 15.0.0. +func sbTransitions(state, prop int) (newState int, sentenceBreak bool, rule int) { + switch uint64(state) | uint64(prop)<<32 { + // SB3. + case sbAny | prCR<<32: + return sbCR, false, 9990 + case sbCR | prLF<<32: + return sbParaSep, false, 30 + + // SB4. + case sbAny | prSep<<32: + return sbParaSep, false, 9990 + case sbAny | prLF<<32: + return sbParaSep, false, 9990 + case sbParaSep | prAny<<32: + return sbAny, true, 40 + case sbCR | prAny<<32: + return sbAny, true, 40 + + // SB6. + case sbAny | prATerm<<32: + return sbATerm, false, 9990 + case sbATerm | prNumeric<<32: + return sbAny, false, 60 + case sbSB7 | prNumeric<<32: + return sbAny, false, 60 // Because ATerm also appears in SB7. + + // SB7. + case sbAny | prUpper<<32: + return sbUpper, false, 9990 + case sbAny | prLower<<32: + return sbLower, false, 9990 + case sbUpper | prATerm<<32: + return sbSB7, false, 70 + case sbLower | prATerm<<32: + return sbSB7, false, 70 + case sbSB7 | prUpper<<32: + return sbUpper, false, 70 + + // SB8a. + case sbAny | prSTerm<<32: + return sbSTerm, false, 9990 + case sbATerm | prSContinue<<32: + return sbAny, false, 81 + case sbATerm | prATerm<<32: + return sbATerm, false, 81 + case sbATerm | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB7 | prSContinue<<32: + return sbAny, false, 81 + case sbSB7 | prATerm<<32: + return sbATerm, false, 81 + case sbSB7 | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB8Close | prSContinue<<32: + return sbAny, false, 81 + case sbSB8Close | prATerm<<32: + return sbATerm, false, 81 + case sbSB8Close | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB8Sp | prSContinue<<32: + return sbAny, false, 81 + case sbSB8Sp | prATerm<<32: + return sbATerm, false, 81 + case sbSB8Sp | prSTerm<<32: + return sbSTerm, false, 81 + case sbSTerm | prSContinue<<32: + return sbAny, false, 81 + case sbSTerm | prATerm<<32: + return sbATerm, false, 81 + case sbSTerm | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB8aClose | prSContinue<<32: + return sbAny, false, 81 + case sbSB8aClose | prATerm<<32: + return sbATerm, false, 81 + case sbSB8aClose | prSTerm<<32: + return sbSTerm, false, 81 + case sbSB8aSp | prSContinue<<32: + return sbAny, false, 81 + case sbSB8aSp | prATerm<<32: + return sbATerm, false, 81 + case sbSB8aSp | prSTerm<<32: + return sbSTerm, false, 81 + + // SB9. + case sbATerm | prClose<<32: + return sbSB8Close, false, 90 + case sbSB7 | prClose<<32: + return sbSB8Close, false, 90 + case sbSB8Close | prClose<<32: + return sbSB8Close, false, 90 + case sbATerm | prSp<<32: + return sbSB8Sp, false, 90 + case sbSB7 | prSp<<32: + return sbSB8Sp, false, 90 + case sbSB8Close | prSp<<32: + return sbSB8Sp, false, 90 + case sbSTerm | prClose<<32: + return sbSB8aClose, false, 90 + case sbSB8aClose | prClose<<32: + return sbSB8aClose, false, 90 + case sbSTerm | prSp<<32: + return sbSB8aSp, false, 90 + case sbSB8aClose | prSp<<32: + return sbSB8aSp, false, 90 + case sbATerm | prSep<<32: + return sbParaSep, false, 90 + case sbATerm | prCR<<32: + return sbParaSep, false, 90 + case sbATerm | prLF<<32: + return sbParaSep, false, 90 + case sbSB7 | prSep<<32: + return sbParaSep, false, 90 + case sbSB7 | prCR<<32: + return sbParaSep, false, 90 + case sbSB7 | prLF<<32: + return sbParaSep, false, 90 + case sbSB8Close | prSep<<32: + return sbParaSep, false, 90 + case sbSB8Close | prCR<<32: + return sbParaSep, false, 90 + case sbSB8Close | prLF<<32: + return sbParaSep, false, 90 + case sbSTerm | prSep<<32: + return sbParaSep, false, 90 + case sbSTerm | prCR<<32: + return sbParaSep, false, 90 + case sbSTerm | prLF<<32: + return sbParaSep, false, 90 + case sbSB8aClose | prSep<<32: + return sbParaSep, false, 90 + case sbSB8aClose | prCR<<32: + return sbParaSep, false, 90 + case sbSB8aClose | prLF<<32: + return sbParaSep, false, 90 + + // SB10. + case sbSB8Sp | prSp<<32: + return sbSB8Sp, false, 100 + case sbSB8aSp | prSp<<32: + return sbSB8aSp, false, 100 + case sbSB8Sp | prSep<<32: + return sbParaSep, false, 100 + case sbSB8Sp | prCR<<32: + return sbParaSep, false, 100 + case sbSB8Sp | prLF<<32: + return sbParaSep, false, 100 + + // SB11. + case sbATerm | prAny<<32: + return sbAny, true, 110 + case sbSB7 | prAny<<32: + return sbAny, true, 110 + case sbSB8Close | prAny<<32: + return sbAny, true, 110 + case sbSB8Sp | prAny<<32: + return sbAny, true, 110 + case sbSTerm | prAny<<32: + return sbAny, true, 110 + case sbSB8aClose | prAny<<32: + return sbAny, true, 110 + case sbSB8aSp | prAny<<32: + return sbAny, true, 110 + // We'll always break after ParaSep due to SB4. + + default: + return -1, false, -1 + } +} + +// transitionSentenceBreakState determines the new state of the sentence break +// parser given the current state and the next code point. It also returns +// whether a sentence boundary was detected. If more than one code point is +// needed to determine the new state, the byte slice or the string starting +// after rune "r" can be used (whichever is not nil or empty) for further +// lookups. +func transitionSentenceBreakState(state int, r rune, b []byte, str string) (newState int, sentenceBreak bool) { + // Determine the property of the next character. + nextProperty := property(sentenceBreakCodePoints, r) + + // SB5 (Replacing Ignore Rules). + if nextProperty == prExtend || nextProperty == prFormat { + if state == sbParaSep || state == sbCR { + return sbAny, true // Make sure we don't apply SB5 to SB3 or SB4. + } + if state < 0 { + return sbAny, true // SB1. + } + return state, false + } + + // Find the applicable transition in the table. + var rule int + newState, sentenceBreak, rule = sbTransitions(state, nextProperty) + if newState < 0 { + // No specific transition found. Try the less specific ones. + anyPropState, anyPropProp, anyPropRule := sbTransitions(state, prAny) + anyStateState, anyStateProp, anyStateRule := sbTransitions(sbAny, nextProperty) + if anyPropState >= 0 && anyStateState >= 0 { + // Both apply. We'll use a mix (see comments for grTransitions). + newState, sentenceBreak, rule = anyStateState, anyStateProp, anyStateRule + if anyPropRule < anyStateRule { + sentenceBreak, rule = anyPropProp, anyPropRule + } + } else if anyPropState >= 0 { + // We only have a specific state. + newState, sentenceBreak, rule = anyPropState, anyPropProp, anyPropRule + // This branch will probably never be reached because okAnyState will + // always be true given the current transition map. But we keep it here + // for future modifications to the transition map where this may not be + // true anymore. + } else if anyStateState >= 0 { + // We only have a specific property. + newState, sentenceBreak, rule = anyStateState, anyStateProp, anyStateRule + } else { + // No known transition. SB999: Any × Any. + newState, sentenceBreak, rule = sbAny, false, 9990 + } + } + + // SB8. + if rule > 80 && (state == sbATerm || state == sbSB8Close || state == sbSB8Sp || state == sbSB7) { + // Check the right side of the rule. + var length int + for nextProperty != prOLetter && + nextProperty != prUpper && + nextProperty != prLower && + nextProperty != prSep && + nextProperty != prCR && + nextProperty != prLF && + nextProperty != prATerm && + nextProperty != prSTerm { + // Move on to the next rune. + if b != nil { // Byte slice version. + r, length = utf8.DecodeRune(b) + b = b[length:] + } else { // String version. + r, length = utf8.DecodeRuneInString(str) + str = str[length:] + } + if r == utf8.RuneError { + break + } + nextProperty = property(sentenceBreakCodePoints, r) + } + if nextProperty == prLower { + return sbLower, false + } + } + + return +} diff --git a/vendor/github.com/rivo/uniseg/step.go b/vendor/github.com/rivo/uniseg/step.go new file mode 100644 index 000000000..9b72c5e59 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/step.go @@ -0,0 +1,242 @@ +package uniseg + +import "unicode/utf8" + +// The bit masks used to extract boundary information returned by [Step]. +const ( + MaskLine = 3 + MaskWord = 4 + MaskSentence = 8 +) + +// The number of bits to shift the boundary information returned by [Step] to +// obtain the monospace width of the grapheme cluster. +const ShiftWidth = 4 + +// The bit positions by which boundary flags are shifted by the [Step] function. +// These must correspond to the Mask constants. +const ( + shiftWord = 2 + shiftSentence = 3 + // shiftwWidth is ShiftWidth above. No mask as these are always the remaining bits. +) + +// The bit positions by which states are shifted by the [Step] function. These +// values must ensure state values defined for each of the boundary algorithms +// don't overlap (and that they all still fit in a single int). These must +// correspond to the Mask constants. +const ( + shiftWordState = 4 + shiftSentenceState = 9 + shiftLineState = 13 + shiftPropState = 21 // No mask as these are always the remaining bits. +) + +// The bit mask used to extract the state returned by the [Step] function, after +// shifting. These values must correspond to the shift constants. +const ( + maskGraphemeState = 0xf + maskWordState = 0x1f + maskSentenceState = 0xf + maskLineState = 0xff +) + +// Step returns the first grapheme cluster (user-perceived character) found in +// the given byte slice. It also returns information about the boundary between +// that grapheme cluster and the one following it as well as the monospace width +// of the grapheme cluster. There are three types of boundary information: word +// boundaries, sentence boundaries, and line breaks. This function is therefore +// a combination of [FirstGraphemeCluster], [FirstWord], [FirstSentence], and +// [FirstLineSegment]. +// +// The "boundaries" return value can be evaluated as follows: +// +// - boundaries&MaskWord != 0: The boundary is a word boundary. +// - boundaries&MaskWord == 0: The boundary is not a word boundary. +// - boundaries&MaskSentence != 0: The boundary is a sentence boundary. +// - boundaries&MaskSentence == 0: The boundary is not a sentence boundary. +// - boundaries&MaskLine == LineDontBreak: You must not break the line at the +// boundary. +// - boundaries&MaskLine == LineMustBreak: You must break the line at the +// boundary. +// - boundaries&MaskLine == LineCanBreak: You may or may not break the line at +// the boundary. +// - boundaries >> ShiftWidth: The width of the grapheme cluster for most +// monospace fonts where a value of 1 represents one character cell. +// +// This function can be called continuously to extract all grapheme clusters +// from a byte slice, as illustrated in the examples below. +// +// If you don't know which state to pass, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified grapheme cluster. If the length of the +// "rest" slice is 0, the entire byte slice "b" has been processed. The +// "cluster" byte slice is the sub-slice of the input slice containing the +// first identified grapheme cluster. +// +// Given an empty byte slice "b", the function returns nil values. +// +// While slightly less convenient than using the Graphemes class, this function +// has much better performance and makes no allocations. It lends itself well to +// large byte slices. +// +// Note that in accordance with [UAX #14 LB3], the final segment will end with +// a mandatory line break (boundaries&MaskLine == LineMustBreak). You can choose +// to ignore this by checking if the length of the "rest" slice is 0 and calling +// [HasTrailingLineBreak] or [HasTrailingLineBreakInString] on the last rune. +// +// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm +func Step(b []byte, state int) (cluster, rest []byte, boundaries int, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + var prop int + if state < 0 { + prop = propertyGraphemes(r) + } else { + prop = state >> shiftPropState + } + return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState) + } + + // If we don't know the state, determine it now. + var graphemeState, wordState, sentenceState, lineState, firstProp int + remainder := b[length:] + if state < 0 { + graphemeState, firstProp, _ = transitionGraphemeState(state, r) + wordState, _ = transitionWordBreakState(state, r, remainder, "") + sentenceState, _ = transitionSentenceBreakState(state, r, remainder, "") + lineState, _ = transitionLineBreakState(state, r, remainder, "") + } else { + graphemeState = state & maskGraphemeState + wordState = (state >> shiftWordState) & maskWordState + sentenceState = (state >> shiftSentenceState) & maskSentenceState + lineState = (state >> shiftLineState) & maskLineState + firstProp = state >> shiftPropState + } + + // Transition until we find a grapheme cluster boundary. + width := runeWidth(r, firstProp) + for { + var ( + graphemeBoundary, wordBoundary, sentenceBoundary bool + lineBreak, prop int + ) + + r, l := utf8.DecodeRune(remainder) + remainder = b[length+l:] + + graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r) + wordState, wordBoundary = transitionWordBreakState(wordState, r, remainder, "") + sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, remainder, "") + lineState, lineBreak = transitionLineBreakState(lineState, r, remainder, "") + + if graphemeBoundary { + boundary := lineBreak | (width << ShiftWidth) + if wordBoundary { + boundary |= 1 << shiftWord + } + if sentenceBoundary { + boundary |= 1 << shiftSentence + } + return b[:length], b[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState) + } + + if firstProp == prExtendedPictographic { + if r == vs15 { + width = 1 + } else if r == vs16 { + width = 2 + } + } else if firstProp != prRegionalIndicator && firstProp != prL { + width += runeWidth(r, prop) + } + + length += l + if len(b) <= length { + return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState) + } + } +} + +// StepString is like [Step] but its input and outputs are strings. +func StepString(str string, state int) (cluster, rest string, boundaries int, newState int) { + // An empty byte slice returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + prop := propertyGraphemes(r) + return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) + } + + // If we don't know the state, determine it now. + var graphemeState, wordState, sentenceState, lineState, firstProp int + remainder := str[length:] + if state < 0 { + graphemeState, firstProp, _ = transitionGraphemeState(state, r) + wordState, _ = transitionWordBreakState(state, r, nil, remainder) + sentenceState, _ = transitionSentenceBreakState(state, r, nil, remainder) + lineState, _ = transitionLineBreakState(state, r, nil, remainder) + } else { + graphemeState = state & maskGraphemeState + wordState = (state >> shiftWordState) & maskWordState + sentenceState = (state >> shiftSentenceState) & maskSentenceState + lineState = (state >> shiftLineState) & maskLineState + firstProp = state >> shiftPropState + } + + // Transition until we find a grapheme cluster boundary. + width := runeWidth(r, firstProp) + for { + var ( + graphemeBoundary, wordBoundary, sentenceBoundary bool + lineBreak, prop int + ) + + r, l := utf8.DecodeRuneInString(remainder) + remainder = str[length+l:] + + graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r) + wordState, wordBoundary = transitionWordBreakState(wordState, r, nil, remainder) + sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, nil, remainder) + lineState, lineBreak = transitionLineBreakState(lineState, r, nil, remainder) + + if graphemeBoundary { + boundary := lineBreak | (width << ShiftWidth) + if wordBoundary { + boundary |= 1 << shiftWord + } + if sentenceBoundary { + boundary |= 1 << shiftSentence + } + return str[:length], str[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState) + } + + if firstProp == prExtendedPictographic { + if r == vs15 { + width = 1 + } else if r == vs16 { + width = 2 + } + } else if firstProp != prRegionalIndicator && firstProp != prL { + width += runeWidth(r, prop) + } + + length += l + if len(str) <= length { + return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState) + } + } +} diff --git a/vendor/github.com/rivo/uniseg/width.go b/vendor/github.com/rivo/uniseg/width.go new file mode 100644 index 000000000..975a9f134 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/width.go @@ -0,0 +1,61 @@ +package uniseg + +// EastAsianAmbiguousWidth specifies the monospace width for East Asian +// characters classified as Ambiguous. The default is 1 but some rare fonts +// render them with a width of 2. +var EastAsianAmbiguousWidth = 1 + +// runeWidth returns the monospace width for the given rune. The provided +// grapheme property is a value mapped by the [graphemeCodePoints] table. +// +// Every rune has a width of 1, except for runes with the following properties +// (evaluated in this order): +// +// - Control, CR, LF, Extend, ZWJ: Width of 0 +// - \u2e3a, TWO-EM DASH: Width of 3 +// - \u2e3b, THREE-EM DASH: Width of 4 +// - East-Asian width Fullwidth and Wide: Width of 2 (Ambiguous and Neutral +// have a width of 1) +// - Regional Indicator: Width of 2 +// - Extended Pictographic: Width of 2, unless Emoji Presentation is "No". +func runeWidth(r rune, graphemeProperty int) int { + switch graphemeProperty { + case prControl, prCR, prLF, prExtend, prZWJ: + return 0 + case prRegionalIndicator: + return 2 + case prExtendedPictographic: + if property(emojiPresentation, r) == prEmojiPresentation { + return 2 + } + return 1 + } + + switch r { + case 0x2e3a: + return 3 + case 0x2e3b: + return 4 + } + + switch propertyEastAsianWidth(r) { + case prW, prF: + return 2 + case prA: + return EastAsianAmbiguousWidth + } + + return 1 +} + +// StringWidth returns the monospace width for the given string, that is, the +// number of same-size cells to be occupied by the string. +func StringWidth(s string) (width int) { + state := -1 + for len(s) > 0 { + var w int + _, s, w, state = FirstGraphemeClusterInString(s, state) + width += w + } + return +} diff --git a/vendor/github.com/rivo/uniseg/word.go b/vendor/github.com/rivo/uniseg/word.go new file mode 100644 index 000000000..34fba7f29 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/word.go @@ -0,0 +1,89 @@ +package uniseg + +import "unicode/utf8" + +// FirstWord returns the first word found in the given byte slice according to +// the rules of [Unicode Standard Annex #29, Word Boundaries]. This function can +// be called continuously to extract all words from a byte slice, as illustrated +// in the example below. +// +// If you don't know the current state, for example when calling the function +// for the first time, you must pass -1. For consecutive calls, pass the state +// and rest slice returned by the previous call. +// +// The "rest" slice is the sub-slice of the original byte slice "b" starting +// after the last byte of the identified word. If the length of the "rest" slice +// is 0, the entire byte slice "b" has been processed. The "word" byte slice is +// the sub-slice of the input slice containing the identified word. +// +// Given an empty byte slice "b", the function returns nil values. +// +// [Unicode Standard Annex #29, Word Boundaries]: http://unicode.org/reports/tr29/#Word_Boundaries +func FirstWord(b []byte, state int) (word, rest []byte, newState int) { + // An empty byte slice returns nothing. + if len(b) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRune(b) + if len(b) <= length { // If we're already past the end, there is nothing else to parse. + return b, nil, wbAny + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionWordBreakState(state, r, b[length:], "") + } + + // Transition until we find a boundary. + var boundary bool + for { + r, l := utf8.DecodeRune(b[length:]) + state, boundary = transitionWordBreakState(state, r, b[length+l:], "") + + if boundary { + return b[:length], b[length:], state + } + + length += l + if len(b) <= length { + return b, nil, wbAny + } + } +} + +// FirstWordInString is like [FirstWord] but its input and outputs are strings. +func FirstWordInString(str string, state int) (word, rest string, newState int) { + // An empty byte slice returns nothing. + if len(str) == 0 { + return + } + + // Extract the first rune. + r, length := utf8.DecodeRuneInString(str) + if len(str) <= length { // If we're already past the end, there is nothing else to parse. + return str, "", wbAny + } + + // If we don't know the state, determine it now. + if state < 0 { + state, _ = transitionWordBreakState(state, r, nil, str[length:]) + } + + // Transition until we find a boundary. + var boundary bool + for { + r, l := utf8.DecodeRuneInString(str[length:]) + state, boundary = transitionWordBreakState(state, r, nil, str[length+l:]) + + if boundary { + return str[:length], str[length:], state + } + + length += l + if len(str) <= length { + return str, "", wbAny + } + } +} diff --git a/vendor/github.com/rivo/uniseg/wordproperties.go b/vendor/github.com/rivo/uniseg/wordproperties.go new file mode 100644 index 000000000..277ca1006 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/wordproperties.go @@ -0,0 +1,1883 @@ +// Code generated via go generate from gen_properties.go. DO NOT EDIT. + +package uniseg + +// workBreakCodePoints are taken from +// https://www.unicode.org/Public/15.0.0/ucd/auxiliary/WordBreakProperty.txt +// and +// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt +// ("Extended_Pictographic" only) +// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode +// license agreement. +var workBreakCodePoints = [][3]int{ + {0x000A, 0x000A, prLF}, // Cc + {0x000B, 0x000C, prNewline}, // Cc [2] .. + {0x000D, 0x000D, prCR}, // Cc + {0x0020, 0x0020, prWSegSpace}, // Zs SPACE + {0x0022, 0x0022, prDoubleQuote}, // Po QUOTATION MARK + {0x0027, 0x0027, prSingleQuote}, // Po APOSTROPHE + {0x002C, 0x002C, prMidNum}, // Po COMMA + {0x002E, 0x002E, prMidNumLet}, // Po FULL STOP + {0x0030, 0x0039, prNumeric}, // Nd [10] DIGIT ZERO..DIGIT NINE + {0x003A, 0x003A, prMidLetter}, // Po COLON + {0x003B, 0x003B, prMidNum}, // Po SEMICOLON + {0x0041, 0x005A, prALetter}, // L& [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z + {0x005F, 0x005F, prExtendNumLet}, // Pc LOW LINE + {0x0061, 0x007A, prALetter}, // L& [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z + {0x0085, 0x0085, prNewline}, // Cc + {0x00A9, 0x00A9, prExtendedPictographic}, // E0.6 [1] (©️) copyright + {0x00AA, 0x00AA, prALetter}, // Lo FEMININE ORDINAL INDICATOR + {0x00AD, 0x00AD, prFormat}, // Cf SOFT HYPHEN + {0x00AE, 0x00AE, prExtendedPictographic}, // E0.6 [1] (®️) registered + {0x00B5, 0x00B5, prALetter}, // L& MICRO SIGN + {0x00B7, 0x00B7, prMidLetter}, // Po MIDDLE DOT + {0x00BA, 0x00BA, prALetter}, // Lo MASCULINE ORDINAL INDICATOR + {0x00C0, 0x00D6, prALetter}, // L& [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS + {0x00D8, 0x00F6, prALetter}, // L& [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS + {0x00F8, 0x01BA, prALetter}, // L& [195] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL + {0x01BB, 0x01BB, prALetter}, // Lo LATIN LETTER TWO WITH STROKE + {0x01BC, 0x01BF, prALetter}, // L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN + {0x01C0, 0x01C3, prALetter}, // Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK + {0x01C4, 0x0293, prALetter}, // L& [208] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER EZH WITH CURL + {0x0294, 0x0294, prALetter}, // Lo LATIN LETTER GLOTTAL STOP + {0x0295, 0x02AF, prALetter}, // L& [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL + {0x02B0, 0x02C1, prALetter}, // Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP + {0x02C2, 0x02C5, prALetter}, // Sk [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD + {0x02C6, 0x02D1, prALetter}, // Lm [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON + {0x02D2, 0x02D7, prALetter}, // Sk [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN + {0x02DE, 0x02DF, prALetter}, // Sk [2] MODIFIER LETTER RHOTIC HOOK..MODIFIER LETTER CROSS ACCENT + {0x02E0, 0x02E4, prALetter}, // Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP + {0x02E5, 0x02EB, prALetter}, // Sk [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK + {0x02EC, 0x02EC, prALetter}, // Lm MODIFIER LETTER VOICING + {0x02ED, 0x02ED, prALetter}, // Sk MODIFIER LETTER UNASPIRATED + {0x02EE, 0x02EE, prALetter}, // Lm MODIFIER LETTER DOUBLE APOSTROPHE + {0x02EF, 0x02FF, prALetter}, // Sk [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW + {0x0300, 0x036F, prExtend}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X + {0x0370, 0x0373, prALetter}, // L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI + {0x0374, 0x0374, prALetter}, // Lm GREEK NUMERAL SIGN + {0x0376, 0x0377, prALetter}, // L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA + {0x037A, 0x037A, prALetter}, // Lm GREEK YPOGEGRAMMENI + {0x037B, 0x037D, prALetter}, // L& [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL + {0x037E, 0x037E, prMidNum}, // Po GREEK QUESTION MARK + {0x037F, 0x037F, prALetter}, // L& GREEK CAPITAL LETTER YOT + {0x0386, 0x0386, prALetter}, // L& GREEK CAPITAL LETTER ALPHA WITH TONOS + {0x0387, 0x0387, prMidLetter}, // Po GREEK ANO TELEIA + {0x0388, 0x038A, prALetter}, // L& [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS + {0x038C, 0x038C, prALetter}, // L& GREEK CAPITAL LETTER OMICRON WITH TONOS + {0x038E, 0x03A1, prALetter}, // L& [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO + {0x03A3, 0x03F5, prALetter}, // L& [83] GREEK CAPITAL LETTER SIGMA..GREEK LUNATE EPSILON SYMBOL + {0x03F7, 0x0481, prALetter}, // L& [139] GREEK CAPITAL LETTER SHO..CYRILLIC SMALL LETTER KOPPA + {0x0483, 0x0487, prExtend}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE + {0x0488, 0x0489, prExtend}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN + {0x048A, 0x052F, prALetter}, // L& [166] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER EL WITH DESCENDER + {0x0531, 0x0556, prALetter}, // L& [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH + {0x0559, 0x0559, prALetter}, // Lm ARMENIAN MODIFIER LETTER LEFT HALF RING + {0x055A, 0x055C, prALetter}, // Po [3] ARMENIAN APOSTROPHE..ARMENIAN EXCLAMATION MARK + {0x055E, 0x055E, prALetter}, // Po ARMENIAN QUESTION MARK + {0x055F, 0x055F, prMidLetter}, // Po ARMENIAN ABBREVIATION MARK + {0x0560, 0x0588, prALetter}, // L& [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE + {0x0589, 0x0589, prMidNum}, // Po ARMENIAN FULL STOP + {0x058A, 0x058A, prALetter}, // Pd ARMENIAN HYPHEN + {0x0591, 0x05BD, prExtend}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG + {0x05BF, 0x05BF, prExtend}, // Mn HEBREW POINT RAFE + {0x05C1, 0x05C2, prExtend}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT + {0x05C4, 0x05C5, prExtend}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT + {0x05C7, 0x05C7, prExtend}, // Mn HEBREW POINT QAMATS QATAN + {0x05D0, 0x05EA, prHebrewLetter}, // Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV + {0x05EF, 0x05F2, prHebrewLetter}, // Lo [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD + {0x05F3, 0x05F3, prALetter}, // Po HEBREW PUNCTUATION GERESH + {0x05F4, 0x05F4, prMidLetter}, // Po HEBREW PUNCTUATION GERSHAYIM + {0x0600, 0x0605, prFormat}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE + {0x060C, 0x060D, prMidNum}, // Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR + {0x0610, 0x061A, prExtend}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA + {0x061C, 0x061C, prFormat}, // Cf ARABIC LETTER MARK + {0x0620, 0x063F, prALetter}, // Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE + {0x0640, 0x0640, prALetter}, // Lm ARABIC TATWEEL + {0x0641, 0x064A, prALetter}, // Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH + {0x064B, 0x065F, prExtend}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW + {0x0660, 0x0669, prNumeric}, // Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE + {0x066B, 0x066B, prNumeric}, // Po ARABIC DECIMAL SEPARATOR + {0x066C, 0x066C, prMidNum}, // Po ARABIC THOUSANDS SEPARATOR + {0x066E, 0x066F, prALetter}, // Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF + {0x0670, 0x0670, prExtend}, // Mn ARABIC LETTER SUPERSCRIPT ALEF + {0x0671, 0x06D3, prALetter}, // Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE + {0x06D5, 0x06D5, prALetter}, // Lo ARABIC LETTER AE + {0x06D6, 0x06DC, prExtend}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN + {0x06DD, 0x06DD, prFormat}, // Cf ARABIC END OF AYAH + {0x06DF, 0x06E4, prExtend}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA + {0x06E5, 0x06E6, prALetter}, // Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH + {0x06E7, 0x06E8, prExtend}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON + {0x06EA, 0x06ED, prExtend}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM + {0x06EE, 0x06EF, prALetter}, // Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V + {0x06F0, 0x06F9, prNumeric}, // Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE + {0x06FA, 0x06FC, prALetter}, // Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW + {0x06FF, 0x06FF, prALetter}, // Lo ARABIC LETTER HEH WITH INVERTED V + {0x070F, 0x070F, prFormat}, // Cf SYRIAC ABBREVIATION MARK + {0x0710, 0x0710, prALetter}, // Lo SYRIAC LETTER ALAPH + {0x0711, 0x0711, prExtend}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH + {0x0712, 0x072F, prALetter}, // Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH + {0x0730, 0x074A, prExtend}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH + {0x074D, 0x07A5, prALetter}, // Lo [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU + {0x07A6, 0x07B0, prExtend}, // Mn [11] THAANA ABAFILI..THAANA SUKUN + {0x07B1, 0x07B1, prALetter}, // Lo THAANA LETTER NAA + {0x07C0, 0x07C9, prNumeric}, // Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE + {0x07CA, 0x07EA, prALetter}, // Lo [33] NKO LETTER A..NKO LETTER JONA RA + {0x07EB, 0x07F3, prExtend}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE + {0x07F4, 0x07F5, prALetter}, // Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE + {0x07F8, 0x07F8, prMidNum}, // Po NKO COMMA + {0x07FA, 0x07FA, prALetter}, // Lm NKO LAJANYALAN + {0x07FD, 0x07FD, prExtend}, // Mn NKO DANTAYALAN + {0x0800, 0x0815, prALetter}, // Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF + {0x0816, 0x0819, prExtend}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH + {0x081A, 0x081A, prALetter}, // Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT + {0x081B, 0x0823, prExtend}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A + {0x0824, 0x0824, prALetter}, // Lm SAMARITAN MODIFIER LETTER SHORT A + {0x0825, 0x0827, prExtend}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U + {0x0828, 0x0828, prALetter}, // Lm SAMARITAN MODIFIER LETTER I + {0x0829, 0x082D, prExtend}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA + {0x0840, 0x0858, prALetter}, // Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN + {0x0859, 0x085B, prExtend}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK + {0x0860, 0x086A, prALetter}, // Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA + {0x0870, 0x0887, prALetter}, // Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT + {0x0889, 0x088E, prALetter}, // Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL + {0x0890, 0x0891, prFormat}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE + {0x0898, 0x089F, prExtend}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA + {0x08A0, 0x08C8, prALetter}, // Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF + {0x08C9, 0x08C9, prALetter}, // Lm ARABIC SMALL FARSI YEH + {0x08CA, 0x08E1, prExtend}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA + {0x08E2, 0x08E2, prFormat}, // Cf ARABIC DISPUTED END OF AYAH + {0x08E3, 0x0902, prExtend}, // Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA + {0x0903, 0x0903, prExtend}, // Mc DEVANAGARI SIGN VISARGA + {0x0904, 0x0939, prALetter}, // Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA + {0x093A, 0x093A, prExtend}, // Mn DEVANAGARI VOWEL SIGN OE + {0x093B, 0x093B, prExtend}, // Mc DEVANAGARI VOWEL SIGN OOE + {0x093C, 0x093C, prExtend}, // Mn DEVANAGARI SIGN NUKTA + {0x093D, 0x093D, prALetter}, // Lo DEVANAGARI SIGN AVAGRAHA + {0x093E, 0x0940, prExtend}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II + {0x0941, 0x0948, prExtend}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI + {0x0949, 0x094C, prExtend}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU + {0x094D, 0x094D, prExtend}, // Mn DEVANAGARI SIGN VIRAMA + {0x094E, 0x094F, prExtend}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW + {0x0950, 0x0950, prALetter}, // Lo DEVANAGARI OM + {0x0951, 0x0957, prExtend}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE + {0x0958, 0x0961, prALetter}, // Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL + {0x0962, 0x0963, prExtend}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL + {0x0966, 0x096F, prNumeric}, // Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE + {0x0971, 0x0971, prALetter}, // Lm DEVANAGARI SIGN HIGH SPACING DOT + {0x0972, 0x0980, prALetter}, // Lo [15] DEVANAGARI LETTER CANDRA A..BENGALI ANJI + {0x0981, 0x0981, prExtend}, // Mn BENGALI SIGN CANDRABINDU + {0x0982, 0x0983, prExtend}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA + {0x0985, 0x098C, prALetter}, // Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L + {0x098F, 0x0990, prALetter}, // Lo [2] BENGALI LETTER E..BENGALI LETTER AI + {0x0993, 0x09A8, prALetter}, // Lo [22] BENGALI LETTER O..BENGALI LETTER NA + {0x09AA, 0x09B0, prALetter}, // Lo [7] BENGALI LETTER PA..BENGALI LETTER RA + {0x09B2, 0x09B2, prALetter}, // Lo BENGALI LETTER LA + {0x09B6, 0x09B9, prALetter}, // Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA + {0x09BC, 0x09BC, prExtend}, // Mn BENGALI SIGN NUKTA + {0x09BD, 0x09BD, prALetter}, // Lo BENGALI SIGN AVAGRAHA + {0x09BE, 0x09C0, prExtend}, // Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II + {0x09C1, 0x09C4, prExtend}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR + {0x09C7, 0x09C8, prExtend}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI + {0x09CB, 0x09CC, prExtend}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU + {0x09CD, 0x09CD, prExtend}, // Mn BENGALI SIGN VIRAMA + {0x09CE, 0x09CE, prALetter}, // Lo BENGALI LETTER KHANDA TA + {0x09D7, 0x09D7, prExtend}, // Mc BENGALI AU LENGTH MARK + {0x09DC, 0x09DD, prALetter}, // Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA + {0x09DF, 0x09E1, prALetter}, // Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL + {0x09E2, 0x09E3, prExtend}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL + {0x09E6, 0x09EF, prNumeric}, // Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE + {0x09F0, 0x09F1, prALetter}, // Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL + {0x09FC, 0x09FC, prALetter}, // Lo BENGALI LETTER VEDIC ANUSVARA + {0x09FE, 0x09FE, prExtend}, // Mn BENGALI SANDHI MARK + {0x0A01, 0x0A02, prExtend}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI + {0x0A03, 0x0A03, prExtend}, // Mc GURMUKHI SIGN VISARGA + {0x0A05, 0x0A0A, prALetter}, // Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU + {0x0A0F, 0x0A10, prALetter}, // Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI + {0x0A13, 0x0A28, prALetter}, // Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA + {0x0A2A, 0x0A30, prALetter}, // Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA + {0x0A32, 0x0A33, prALetter}, // Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA + {0x0A35, 0x0A36, prALetter}, // Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA + {0x0A38, 0x0A39, prALetter}, // Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA + {0x0A3C, 0x0A3C, prExtend}, // Mn GURMUKHI SIGN NUKTA + {0x0A3E, 0x0A40, prExtend}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II + {0x0A41, 0x0A42, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU + {0x0A47, 0x0A48, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI + {0x0A4B, 0x0A4D, prExtend}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA + {0x0A51, 0x0A51, prExtend}, // Mn GURMUKHI SIGN UDAAT + {0x0A59, 0x0A5C, prALetter}, // Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA + {0x0A5E, 0x0A5E, prALetter}, // Lo GURMUKHI LETTER FA + {0x0A66, 0x0A6F, prNumeric}, // Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE + {0x0A70, 0x0A71, prExtend}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK + {0x0A72, 0x0A74, prALetter}, // Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR + {0x0A75, 0x0A75, prExtend}, // Mn GURMUKHI SIGN YAKASH + {0x0A81, 0x0A82, prExtend}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA + {0x0A83, 0x0A83, prExtend}, // Mc GUJARATI SIGN VISARGA + {0x0A85, 0x0A8D, prALetter}, // Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E + {0x0A8F, 0x0A91, prALetter}, // Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O + {0x0A93, 0x0AA8, prALetter}, // Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA + {0x0AAA, 0x0AB0, prALetter}, // Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA + {0x0AB2, 0x0AB3, prALetter}, // Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA + {0x0AB5, 0x0AB9, prALetter}, // Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA + {0x0ABC, 0x0ABC, prExtend}, // Mn GUJARATI SIGN NUKTA + {0x0ABD, 0x0ABD, prALetter}, // Lo GUJARATI SIGN AVAGRAHA + {0x0ABE, 0x0AC0, prExtend}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II + {0x0AC1, 0x0AC5, prExtend}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E + {0x0AC7, 0x0AC8, prExtend}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI + {0x0AC9, 0x0AC9, prExtend}, // Mc GUJARATI VOWEL SIGN CANDRA O + {0x0ACB, 0x0ACC, prExtend}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU + {0x0ACD, 0x0ACD, prExtend}, // Mn GUJARATI SIGN VIRAMA + {0x0AD0, 0x0AD0, prALetter}, // Lo GUJARATI OM + {0x0AE0, 0x0AE1, prALetter}, // Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL + {0x0AE2, 0x0AE3, prExtend}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL + {0x0AE6, 0x0AEF, prNumeric}, // Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE + {0x0AF9, 0x0AF9, prALetter}, // Lo GUJARATI LETTER ZHA + {0x0AFA, 0x0AFF, prExtend}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE + {0x0B01, 0x0B01, prExtend}, // Mn ORIYA SIGN CANDRABINDU + {0x0B02, 0x0B03, prExtend}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA + {0x0B05, 0x0B0C, prALetter}, // Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L + {0x0B0F, 0x0B10, prALetter}, // Lo [2] ORIYA LETTER E..ORIYA LETTER AI + {0x0B13, 0x0B28, prALetter}, // Lo [22] ORIYA LETTER O..ORIYA LETTER NA + {0x0B2A, 0x0B30, prALetter}, // Lo [7] ORIYA LETTER PA..ORIYA LETTER RA + {0x0B32, 0x0B33, prALetter}, // Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA + {0x0B35, 0x0B39, prALetter}, // Lo [5] ORIYA LETTER VA..ORIYA LETTER HA + {0x0B3C, 0x0B3C, prExtend}, // Mn ORIYA SIGN NUKTA + {0x0B3D, 0x0B3D, prALetter}, // Lo ORIYA SIGN AVAGRAHA + {0x0B3E, 0x0B3E, prExtend}, // Mc ORIYA VOWEL SIGN AA + {0x0B3F, 0x0B3F, prExtend}, // Mn ORIYA VOWEL SIGN I + {0x0B40, 0x0B40, prExtend}, // Mc ORIYA VOWEL SIGN II + {0x0B41, 0x0B44, prExtend}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR + {0x0B47, 0x0B48, prExtend}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI + {0x0B4B, 0x0B4C, prExtend}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU + {0x0B4D, 0x0B4D, prExtend}, // Mn ORIYA SIGN VIRAMA + {0x0B55, 0x0B56, prExtend}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK + {0x0B57, 0x0B57, prExtend}, // Mc ORIYA AU LENGTH MARK + {0x0B5C, 0x0B5D, prALetter}, // Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA + {0x0B5F, 0x0B61, prALetter}, // Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL + {0x0B62, 0x0B63, prExtend}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL + {0x0B66, 0x0B6F, prNumeric}, // Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE + {0x0B71, 0x0B71, prALetter}, // Lo ORIYA LETTER WA + {0x0B82, 0x0B82, prExtend}, // Mn TAMIL SIGN ANUSVARA + {0x0B83, 0x0B83, prALetter}, // Lo TAMIL SIGN VISARGA + {0x0B85, 0x0B8A, prALetter}, // Lo [6] TAMIL LETTER A..TAMIL LETTER UU + {0x0B8E, 0x0B90, prALetter}, // Lo [3] TAMIL LETTER E..TAMIL LETTER AI + {0x0B92, 0x0B95, prALetter}, // Lo [4] TAMIL LETTER O..TAMIL LETTER KA + {0x0B99, 0x0B9A, prALetter}, // Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA + {0x0B9C, 0x0B9C, prALetter}, // Lo TAMIL LETTER JA + {0x0B9E, 0x0B9F, prALetter}, // Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA + {0x0BA3, 0x0BA4, prALetter}, // Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA + {0x0BA8, 0x0BAA, prALetter}, // Lo [3] TAMIL LETTER NA..TAMIL LETTER PA + {0x0BAE, 0x0BB9, prALetter}, // Lo [12] TAMIL LETTER MA..TAMIL LETTER HA + {0x0BBE, 0x0BBF, prExtend}, // Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I + {0x0BC0, 0x0BC0, prExtend}, // Mn TAMIL VOWEL SIGN II + {0x0BC1, 0x0BC2, prExtend}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU + {0x0BC6, 0x0BC8, prExtend}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI + {0x0BCA, 0x0BCC, prExtend}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU + {0x0BCD, 0x0BCD, prExtend}, // Mn TAMIL SIGN VIRAMA + {0x0BD0, 0x0BD0, prALetter}, // Lo TAMIL OM + {0x0BD7, 0x0BD7, prExtend}, // Mc TAMIL AU LENGTH MARK + {0x0BE6, 0x0BEF, prNumeric}, // Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE + {0x0C00, 0x0C00, prExtend}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE + {0x0C01, 0x0C03, prExtend}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA + {0x0C04, 0x0C04, prExtend}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE + {0x0C05, 0x0C0C, prALetter}, // Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L + {0x0C0E, 0x0C10, prALetter}, // Lo [3] TELUGU LETTER E..TELUGU LETTER AI + {0x0C12, 0x0C28, prALetter}, // Lo [23] TELUGU LETTER O..TELUGU LETTER NA + {0x0C2A, 0x0C39, prALetter}, // Lo [16] TELUGU LETTER PA..TELUGU LETTER HA + {0x0C3C, 0x0C3C, prExtend}, // Mn TELUGU SIGN NUKTA + {0x0C3D, 0x0C3D, prALetter}, // Lo TELUGU SIGN AVAGRAHA + {0x0C3E, 0x0C40, prExtend}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II + {0x0C41, 0x0C44, prExtend}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR + {0x0C46, 0x0C48, prExtend}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI + {0x0C4A, 0x0C4D, prExtend}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA + {0x0C55, 0x0C56, prExtend}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK + {0x0C58, 0x0C5A, prALetter}, // Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA + {0x0C5D, 0x0C5D, prALetter}, // Lo TELUGU LETTER NAKAARA POLLU + {0x0C60, 0x0C61, prALetter}, // Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL + {0x0C62, 0x0C63, prExtend}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL + {0x0C66, 0x0C6F, prNumeric}, // Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE + {0x0C80, 0x0C80, prALetter}, // Lo KANNADA SIGN SPACING CANDRABINDU + {0x0C81, 0x0C81, prExtend}, // Mn KANNADA SIGN CANDRABINDU + {0x0C82, 0x0C83, prExtend}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA + {0x0C85, 0x0C8C, prALetter}, // Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L + {0x0C8E, 0x0C90, prALetter}, // Lo [3] KANNADA LETTER E..KANNADA LETTER AI + {0x0C92, 0x0CA8, prALetter}, // Lo [23] KANNADA LETTER O..KANNADA LETTER NA + {0x0CAA, 0x0CB3, prALetter}, // Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA + {0x0CB5, 0x0CB9, prALetter}, // Lo [5] KANNADA LETTER VA..KANNADA LETTER HA + {0x0CBC, 0x0CBC, prExtend}, // Mn KANNADA SIGN NUKTA + {0x0CBD, 0x0CBD, prALetter}, // Lo KANNADA SIGN AVAGRAHA + {0x0CBE, 0x0CBE, prExtend}, // Mc KANNADA VOWEL SIGN AA + {0x0CBF, 0x0CBF, prExtend}, // Mn KANNADA VOWEL SIGN I + {0x0CC0, 0x0CC4, prExtend}, // Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR + {0x0CC6, 0x0CC6, prExtend}, // Mn KANNADA VOWEL SIGN E + {0x0CC7, 0x0CC8, prExtend}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI + {0x0CCA, 0x0CCB, prExtend}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO + {0x0CCC, 0x0CCD, prExtend}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA + {0x0CD5, 0x0CD6, prExtend}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK + {0x0CDD, 0x0CDE, prALetter}, // Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA + {0x0CE0, 0x0CE1, prALetter}, // Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL + {0x0CE2, 0x0CE3, prExtend}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL + {0x0CE6, 0x0CEF, prNumeric}, // Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE + {0x0CF1, 0x0CF2, prALetter}, // Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA + {0x0CF3, 0x0CF3, prExtend}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT + {0x0D00, 0x0D01, prExtend}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU + {0x0D02, 0x0D03, prExtend}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA + {0x0D04, 0x0D0C, prALetter}, // Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L + {0x0D0E, 0x0D10, prALetter}, // Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI + {0x0D12, 0x0D3A, prALetter}, // Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA + {0x0D3B, 0x0D3C, prExtend}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA + {0x0D3D, 0x0D3D, prALetter}, // Lo MALAYALAM SIGN AVAGRAHA + {0x0D3E, 0x0D40, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II + {0x0D41, 0x0D44, prExtend}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR + {0x0D46, 0x0D48, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI + {0x0D4A, 0x0D4C, prExtend}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU + {0x0D4D, 0x0D4D, prExtend}, // Mn MALAYALAM SIGN VIRAMA + {0x0D4E, 0x0D4E, prALetter}, // Lo MALAYALAM LETTER DOT REPH + {0x0D54, 0x0D56, prALetter}, // Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL + {0x0D57, 0x0D57, prExtend}, // Mc MALAYALAM AU LENGTH MARK + {0x0D5F, 0x0D61, prALetter}, // Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL + {0x0D62, 0x0D63, prExtend}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL + {0x0D66, 0x0D6F, prNumeric}, // Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE + {0x0D7A, 0x0D7F, prALetter}, // Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K + {0x0D81, 0x0D81, prExtend}, // Mn SINHALA SIGN CANDRABINDU + {0x0D82, 0x0D83, prExtend}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA + {0x0D85, 0x0D96, prALetter}, // Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA + {0x0D9A, 0x0DB1, prALetter}, // Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA + {0x0DB3, 0x0DBB, prALetter}, // Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA + {0x0DBD, 0x0DBD, prALetter}, // Lo SINHALA LETTER DANTAJA LAYANNA + {0x0DC0, 0x0DC6, prALetter}, // Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA + {0x0DCA, 0x0DCA, prExtend}, // Mn SINHALA SIGN AL-LAKUNA + {0x0DCF, 0x0DD1, prExtend}, // Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA + {0x0DD2, 0x0DD4, prExtend}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA + {0x0DD6, 0x0DD6, prExtend}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA + {0x0DD8, 0x0DDF, prExtend}, // Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA + {0x0DE6, 0x0DEF, prNumeric}, // Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE + {0x0DF2, 0x0DF3, prExtend}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA + {0x0E31, 0x0E31, prExtend}, // Mn THAI CHARACTER MAI HAN-AKAT + {0x0E34, 0x0E3A, prExtend}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU + {0x0E47, 0x0E4E, prExtend}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN + {0x0E50, 0x0E59, prNumeric}, // Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE + {0x0EB1, 0x0EB1, prExtend}, // Mn LAO VOWEL SIGN MAI KAN + {0x0EB4, 0x0EBC, prExtend}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO + {0x0EC8, 0x0ECE, prExtend}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN + {0x0ED0, 0x0ED9, prNumeric}, // Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE + {0x0F00, 0x0F00, prALetter}, // Lo TIBETAN SYLLABLE OM + {0x0F18, 0x0F19, prExtend}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + {0x0F20, 0x0F29, prNumeric}, // Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE + {0x0F35, 0x0F35, prExtend}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA + {0x0F37, 0x0F37, prExtend}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS + {0x0F39, 0x0F39, prExtend}, // Mn TIBETAN MARK TSA -PHRU + {0x0F3E, 0x0F3F, prExtend}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES + {0x0F40, 0x0F47, prALetter}, // Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA + {0x0F49, 0x0F6C, prALetter}, // Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA + {0x0F71, 0x0F7E, prExtend}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO + {0x0F7F, 0x0F7F, prExtend}, // Mc TIBETAN SIGN RNAM BCAD + {0x0F80, 0x0F84, prExtend}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA + {0x0F86, 0x0F87, prExtend}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS + {0x0F88, 0x0F8C, prALetter}, // Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN + {0x0F8D, 0x0F97, prExtend}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA + {0x0F99, 0x0FBC, prExtend}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA + {0x0FC6, 0x0FC6, prExtend}, // Mn TIBETAN SYMBOL PADMA GDAN + {0x102B, 0x102C, prExtend}, // Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA + {0x102D, 0x1030, prExtend}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU + {0x1031, 0x1031, prExtend}, // Mc MYANMAR VOWEL SIGN E + {0x1032, 0x1037, prExtend}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW + {0x1038, 0x1038, prExtend}, // Mc MYANMAR SIGN VISARGA + {0x1039, 0x103A, prExtend}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT + {0x103B, 0x103C, prExtend}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA + {0x103D, 0x103E, prExtend}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA + {0x1040, 0x1049, prNumeric}, // Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE + {0x1056, 0x1057, prExtend}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR + {0x1058, 0x1059, prExtend}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL + {0x105E, 0x1060, prExtend}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA + {0x1062, 0x1064, prExtend}, // Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO + {0x1067, 0x106D, prExtend}, // Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 + {0x1071, 0x1074, prExtend}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE + {0x1082, 0x1082, prExtend}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA + {0x1083, 0x1084, prExtend}, // Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E + {0x1085, 0x1086, prExtend}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y + {0x1087, 0x108C, prExtend}, // Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 + {0x108D, 0x108D, prExtend}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + {0x108F, 0x108F, prExtend}, // Mc MYANMAR SIGN RUMAI PALAUNG TONE-5 + {0x1090, 0x1099, prNumeric}, // Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE + {0x109A, 0x109C, prExtend}, // Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A + {0x109D, 0x109D, prExtend}, // Mn MYANMAR VOWEL SIGN AITON AI + {0x10A0, 0x10C5, prALetter}, // L& [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE + {0x10C7, 0x10C7, prALetter}, // L& GEORGIAN CAPITAL LETTER YN + {0x10CD, 0x10CD, prALetter}, // L& GEORGIAN CAPITAL LETTER AEN + {0x10D0, 0x10FA, prALetter}, // L& [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN + {0x10FC, 0x10FC, prALetter}, // Lm MODIFIER LETTER GEORGIAN NAR + {0x10FD, 0x10FF, prALetter}, // L& [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN + {0x1100, 0x1248, prALetter}, // Lo [329] HANGUL CHOSEONG KIYEOK..ETHIOPIC SYLLABLE QWA + {0x124A, 0x124D, prALetter}, // Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE + {0x1250, 0x1256, prALetter}, // Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO + {0x1258, 0x1258, prALetter}, // Lo ETHIOPIC SYLLABLE QHWA + {0x125A, 0x125D, prALetter}, // Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE + {0x1260, 0x1288, prALetter}, // Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA + {0x128A, 0x128D, prALetter}, // Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE + {0x1290, 0x12B0, prALetter}, // Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA + {0x12B2, 0x12B5, prALetter}, // Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE + {0x12B8, 0x12BE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO + {0x12C0, 0x12C0, prALetter}, // Lo ETHIOPIC SYLLABLE KXWA + {0x12C2, 0x12C5, prALetter}, // Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE + {0x12C8, 0x12D6, prALetter}, // Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O + {0x12D8, 0x1310, prALetter}, // Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA + {0x1312, 0x1315, prALetter}, // Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE + {0x1318, 0x135A, prALetter}, // Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA + {0x135D, 0x135F, prExtend}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK + {0x1380, 0x138F, prALetter}, // Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE + {0x13A0, 0x13F5, prALetter}, // L& [86] CHEROKEE LETTER A..CHEROKEE LETTER MV + {0x13F8, 0x13FD, prALetter}, // L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV + {0x1401, 0x166C, prALetter}, // Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA + {0x166F, 0x167F, prALetter}, // Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W + {0x1680, 0x1680, prWSegSpace}, // Zs OGHAM SPACE MARK + {0x1681, 0x169A, prALetter}, // Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH + {0x16A0, 0x16EA, prALetter}, // Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X + {0x16EE, 0x16F0, prALetter}, // Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL + {0x16F1, 0x16F8, prALetter}, // Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC + {0x1700, 0x1711, prALetter}, // Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA + {0x1712, 0x1714, prExtend}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA + {0x1715, 0x1715, prExtend}, // Mc TAGALOG SIGN PAMUDPOD + {0x171F, 0x1731, prALetter}, // Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA + {0x1732, 0x1733, prExtend}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U + {0x1734, 0x1734, prExtend}, // Mc HANUNOO SIGN PAMUDPOD + {0x1740, 0x1751, prALetter}, // Lo [18] BUHID LETTER A..BUHID LETTER HA + {0x1752, 0x1753, prExtend}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U + {0x1760, 0x176C, prALetter}, // Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA + {0x176E, 0x1770, prALetter}, // Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA + {0x1772, 0x1773, prExtend}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U + {0x17B4, 0x17B5, prExtend}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA + {0x17B6, 0x17B6, prExtend}, // Mc KHMER VOWEL SIGN AA + {0x17B7, 0x17BD, prExtend}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA + {0x17BE, 0x17C5, prExtend}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU + {0x17C6, 0x17C6, prExtend}, // Mn KHMER SIGN NIKAHIT + {0x17C7, 0x17C8, prExtend}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU + {0x17C9, 0x17D3, prExtend}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT + {0x17DD, 0x17DD, prExtend}, // Mn KHMER SIGN ATTHACAN + {0x17E0, 0x17E9, prNumeric}, // Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE + {0x180B, 0x180D, prExtend}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE + {0x180E, 0x180E, prFormat}, // Cf MONGOLIAN VOWEL SEPARATOR + {0x180F, 0x180F, prExtend}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR + {0x1810, 0x1819, prNumeric}, // Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE + {0x1820, 0x1842, prALetter}, // Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI + {0x1843, 0x1843, prALetter}, // Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN + {0x1844, 0x1878, prALetter}, // Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS + {0x1880, 0x1884, prALetter}, // Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA + {0x1885, 0x1886, prExtend}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA + {0x1887, 0x18A8, prALetter}, // Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA + {0x18A9, 0x18A9, prExtend}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA + {0x18AA, 0x18AA, prALetter}, // Lo MONGOLIAN LETTER MANCHU ALI GALI LHA + {0x18B0, 0x18F5, prALetter}, // Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S + {0x1900, 0x191E, prALetter}, // Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA + {0x1920, 0x1922, prExtend}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U + {0x1923, 0x1926, prExtend}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU + {0x1927, 0x1928, prExtend}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O + {0x1929, 0x192B, prExtend}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA + {0x1930, 0x1931, prExtend}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA + {0x1932, 0x1932, prExtend}, // Mn LIMBU SMALL LETTER ANUSVARA + {0x1933, 0x1938, prExtend}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA + {0x1939, 0x193B, prExtend}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I + {0x1946, 0x194F, prNumeric}, // Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE + {0x19D0, 0x19D9, prNumeric}, // Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE + {0x1A00, 0x1A16, prALetter}, // Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA + {0x1A17, 0x1A18, prExtend}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U + {0x1A19, 0x1A1A, prExtend}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O + {0x1A1B, 0x1A1B, prExtend}, // Mn BUGINESE VOWEL SIGN AE + {0x1A55, 0x1A55, prExtend}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA + {0x1A56, 0x1A56, prExtend}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA + {0x1A57, 0x1A57, prExtend}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI + {0x1A58, 0x1A5E, prExtend}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA + {0x1A60, 0x1A60, prExtend}, // Mn TAI THAM SIGN SAKOT + {0x1A61, 0x1A61, prExtend}, // Mc TAI THAM VOWEL SIGN A + {0x1A62, 0x1A62, prExtend}, // Mn TAI THAM VOWEL SIGN MAI SAT + {0x1A63, 0x1A64, prExtend}, // Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA + {0x1A65, 0x1A6C, prExtend}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW + {0x1A6D, 0x1A72, prExtend}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI + {0x1A73, 0x1A7C, prExtend}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN + {0x1A7F, 0x1A7F, prExtend}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT + {0x1A80, 0x1A89, prNumeric}, // Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE + {0x1A90, 0x1A99, prNumeric}, // Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE + {0x1AB0, 0x1ABD, prExtend}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW + {0x1ABE, 0x1ABE, prExtend}, // Me COMBINING PARENTHESES OVERLAY + {0x1ABF, 0x1ACE, prExtend}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T + {0x1B00, 0x1B03, prExtend}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG + {0x1B04, 0x1B04, prExtend}, // Mc BALINESE SIGN BISAH + {0x1B05, 0x1B33, prALetter}, // Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA + {0x1B34, 0x1B34, prExtend}, // Mn BALINESE SIGN REREKAN + {0x1B35, 0x1B35, prExtend}, // Mc BALINESE VOWEL SIGN TEDUNG + {0x1B36, 0x1B3A, prExtend}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA + {0x1B3B, 0x1B3B, prExtend}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG + {0x1B3C, 0x1B3C, prExtend}, // Mn BALINESE VOWEL SIGN LA LENGA + {0x1B3D, 0x1B41, prExtend}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG + {0x1B42, 0x1B42, prExtend}, // Mn BALINESE VOWEL SIGN PEPET + {0x1B43, 0x1B44, prExtend}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG + {0x1B45, 0x1B4C, prALetter}, // Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA + {0x1B50, 0x1B59, prNumeric}, // Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE + {0x1B6B, 0x1B73, prExtend}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG + {0x1B80, 0x1B81, prExtend}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR + {0x1B82, 0x1B82, prExtend}, // Mc SUNDANESE SIGN PANGWISAD + {0x1B83, 0x1BA0, prALetter}, // Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA + {0x1BA1, 0x1BA1, prExtend}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL + {0x1BA2, 0x1BA5, prExtend}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU + {0x1BA6, 0x1BA7, prExtend}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG + {0x1BA8, 0x1BA9, prExtend}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG + {0x1BAA, 0x1BAA, prExtend}, // Mc SUNDANESE SIGN PAMAAEH + {0x1BAB, 0x1BAD, prExtend}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA + {0x1BAE, 0x1BAF, prALetter}, // Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA + {0x1BB0, 0x1BB9, prNumeric}, // Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE + {0x1BBA, 0x1BE5, prALetter}, // Lo [44] SUNDANESE AVAGRAHA..BATAK LETTER U + {0x1BE6, 0x1BE6, prExtend}, // Mn BATAK SIGN TOMPI + {0x1BE7, 0x1BE7, prExtend}, // Mc BATAK VOWEL SIGN E + {0x1BE8, 0x1BE9, prExtend}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE + {0x1BEA, 0x1BEC, prExtend}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O + {0x1BED, 0x1BED, prExtend}, // Mn BATAK VOWEL SIGN KARO O + {0x1BEE, 0x1BEE, prExtend}, // Mc BATAK VOWEL SIGN U + {0x1BEF, 0x1BF1, prExtend}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H + {0x1BF2, 0x1BF3, prExtend}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN + {0x1C00, 0x1C23, prALetter}, // Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A + {0x1C24, 0x1C2B, prExtend}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU + {0x1C2C, 0x1C33, prExtend}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T + {0x1C34, 0x1C35, prExtend}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG + {0x1C36, 0x1C37, prExtend}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA + {0x1C40, 0x1C49, prNumeric}, // Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE + {0x1C4D, 0x1C4F, prALetter}, // Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA + {0x1C50, 0x1C59, prNumeric}, // Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE + {0x1C5A, 0x1C77, prALetter}, // Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH + {0x1C78, 0x1C7D, prALetter}, // Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD + {0x1C80, 0x1C88, prALetter}, // L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK + {0x1C90, 0x1CBA, prALetter}, // L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN + {0x1CBD, 0x1CBF, prALetter}, // L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN + {0x1CD0, 0x1CD2, prExtend}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA + {0x1CD4, 0x1CE0, prExtend}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + {0x1CE1, 0x1CE1, prExtend}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + {0x1CE2, 0x1CE8, prExtend}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL + {0x1CE9, 0x1CEC, prALetter}, // Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL + {0x1CED, 0x1CED, prExtend}, // Mn VEDIC SIGN TIRYAK + {0x1CEE, 0x1CF3, prALetter}, // Lo [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA + {0x1CF4, 0x1CF4, prExtend}, // Mn VEDIC TONE CANDRA ABOVE + {0x1CF5, 0x1CF6, prALetter}, // Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA + {0x1CF7, 0x1CF7, prExtend}, // Mc VEDIC SIGN ATIKRAMA + {0x1CF8, 0x1CF9, prExtend}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE + {0x1CFA, 0x1CFA, prALetter}, // Lo VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA + {0x1D00, 0x1D2B, prALetter}, // L& [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL + {0x1D2C, 0x1D6A, prALetter}, // Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI + {0x1D6B, 0x1D77, prALetter}, // L& [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G + {0x1D78, 0x1D78, prALetter}, // Lm MODIFIER LETTER CYRILLIC EN + {0x1D79, 0x1D9A, prALetter}, // L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK + {0x1D9B, 0x1DBF, prALetter}, // Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA + {0x1DC0, 0x1DFF, prExtend}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + {0x1E00, 0x1F15, prALetter}, // L& [278] LATIN CAPITAL LETTER A WITH RING BELOW..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA + {0x1F18, 0x1F1D, prALetter}, // L& [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA + {0x1F20, 0x1F45, prALetter}, // L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA + {0x1F48, 0x1F4D, prALetter}, // L& [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA + {0x1F50, 0x1F57, prALetter}, // L& [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI + {0x1F59, 0x1F59, prALetter}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA + {0x1F5B, 0x1F5B, prALetter}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA + {0x1F5D, 0x1F5D, prALetter}, // L& GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA + {0x1F5F, 0x1F7D, prALetter}, // L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA + {0x1F80, 0x1FB4, prALetter}, // L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI + {0x1FB6, 0x1FBC, prALetter}, // L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI + {0x1FBE, 0x1FBE, prALetter}, // L& GREEK PROSGEGRAMMENI + {0x1FC2, 0x1FC4, prALetter}, // L& [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI + {0x1FC6, 0x1FCC, prALetter}, // L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI + {0x1FD0, 0x1FD3, prALetter}, // L& [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + {0x1FD6, 0x1FDB, prALetter}, // L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA + {0x1FE0, 0x1FEC, prALetter}, // L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA + {0x1FF2, 0x1FF4, prALetter}, // L& [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI + {0x1FF6, 0x1FFC, prALetter}, // L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + {0x2000, 0x2006, prWSegSpace}, // Zs [7] EN QUAD..SIX-PER-EM SPACE + {0x2008, 0x200A, prWSegSpace}, // Zs [3] PUNCTUATION SPACE..HAIR SPACE + {0x200C, 0x200C, prExtend}, // Cf ZERO WIDTH NON-JOINER + {0x200D, 0x200D, prZWJ}, // Cf ZERO WIDTH JOINER + {0x200E, 0x200F, prFormat}, // Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK + {0x2018, 0x2018, prMidNumLet}, // Pi LEFT SINGLE QUOTATION MARK + {0x2019, 0x2019, prMidNumLet}, // Pf RIGHT SINGLE QUOTATION MARK + {0x2024, 0x2024, prMidNumLet}, // Po ONE DOT LEADER + {0x2027, 0x2027, prMidLetter}, // Po HYPHENATION POINT + {0x2028, 0x2028, prNewline}, // Zl LINE SEPARATOR + {0x2029, 0x2029, prNewline}, // Zp PARAGRAPH SEPARATOR + {0x202A, 0x202E, prFormat}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE + {0x202F, 0x202F, prExtendNumLet}, // Zs NARROW NO-BREAK SPACE + {0x203C, 0x203C, prExtendedPictographic}, // E0.6 [1] (‼️) double exclamation mark + {0x203F, 0x2040, prExtendNumLet}, // Pc [2] UNDERTIE..CHARACTER TIE + {0x2044, 0x2044, prMidNum}, // Sm FRACTION SLASH + {0x2049, 0x2049, prExtendedPictographic}, // E0.6 [1] (⁉️) exclamation question mark + {0x2054, 0x2054, prExtendNumLet}, // Pc INVERTED UNDERTIE + {0x205F, 0x205F, prWSegSpace}, // Zs MEDIUM MATHEMATICAL SPACE + {0x2060, 0x2064, prFormat}, // Cf [5] WORD JOINER..INVISIBLE PLUS + {0x2066, 0x206F, prFormat}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES + {0x2071, 0x2071, prALetter}, // Lm SUPERSCRIPT LATIN SMALL LETTER I + {0x207F, 0x207F, prALetter}, // Lm SUPERSCRIPT LATIN SMALL LETTER N + {0x2090, 0x209C, prALetter}, // Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T + {0x20D0, 0x20DC, prExtend}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE + {0x20DD, 0x20E0, prExtend}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH + {0x20E1, 0x20E1, prExtend}, // Mn COMBINING LEFT RIGHT ARROW ABOVE + {0x20E2, 0x20E4, prExtend}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE + {0x20E5, 0x20F0, prExtend}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE + {0x2102, 0x2102, prALetter}, // L& DOUBLE-STRUCK CAPITAL C + {0x2107, 0x2107, prALetter}, // L& EULER CONSTANT + {0x210A, 0x2113, prALetter}, // L& [10] SCRIPT SMALL G..SCRIPT SMALL L + {0x2115, 0x2115, prALetter}, // L& DOUBLE-STRUCK CAPITAL N + {0x2119, 0x211D, prALetter}, // L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R + {0x2122, 0x2122, prExtendedPictographic}, // E0.6 [1] (™️) trade mark + {0x2124, 0x2124, prALetter}, // L& DOUBLE-STRUCK CAPITAL Z + {0x2126, 0x2126, prALetter}, // L& OHM SIGN + {0x2128, 0x2128, prALetter}, // L& BLACK-LETTER CAPITAL Z + {0x212A, 0x212D, prALetter}, // L& [4] KELVIN SIGN..BLACK-LETTER CAPITAL C + {0x212F, 0x2134, prALetter}, // L& [6] SCRIPT SMALL E..SCRIPT SMALL O + {0x2135, 0x2138, prALetter}, // Lo [4] ALEF SYMBOL..DALET SYMBOL + {0x2139, 0x2139, prExtendedPictographic}, // E0.6 [1] (ℹ️) information + {0x2139, 0x2139, prALetter}, // L& INFORMATION SOURCE + {0x213C, 0x213F, prALetter}, // L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI + {0x2145, 0x2149, prALetter}, // L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J + {0x214E, 0x214E, prALetter}, // L& TURNED SMALL F + {0x2160, 0x2182, prALetter}, // Nl [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND + {0x2183, 0x2184, prALetter}, // L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C + {0x2185, 0x2188, prALetter}, // Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND + {0x2194, 0x2199, prExtendedPictographic}, // E0.6 [6] (↔️..↙️) left-right arrow..down-left arrow + {0x21A9, 0x21AA, prExtendedPictographic}, // E0.6 [2] (↩️..↪️) right arrow curving left..left arrow curving right + {0x231A, 0x231B, prExtendedPictographic}, // E0.6 [2] (⌚..⌛) watch..hourglass done + {0x2328, 0x2328, prExtendedPictographic}, // E1.0 [1] (⌨️) keyboard + {0x2388, 0x2388, prExtendedPictographic}, // E0.0 [1] (⎈) HELM SYMBOL + {0x23CF, 0x23CF, prExtendedPictographic}, // E1.0 [1] (⏏️) eject button + {0x23E9, 0x23EC, prExtendedPictographic}, // E0.6 [4] (⏩..⏬) fast-forward button..fast down button + {0x23ED, 0x23EE, prExtendedPictographic}, // E0.7 [2] (⏭️..⏮️) next track button..last track button + {0x23EF, 0x23EF, prExtendedPictographic}, // E1.0 [1] (⏯️) play or pause button + {0x23F0, 0x23F0, prExtendedPictographic}, // E0.6 [1] (⏰) alarm clock + {0x23F1, 0x23F2, prExtendedPictographic}, // E1.0 [2] (⏱️..⏲️) stopwatch..timer clock + {0x23F3, 0x23F3, prExtendedPictographic}, // E0.6 [1] (⏳) hourglass not done + {0x23F8, 0x23FA, prExtendedPictographic}, // E0.7 [3] (⏸️..⏺️) pause button..record button + {0x24B6, 0x24E9, prALetter}, // So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z + {0x24C2, 0x24C2, prExtendedPictographic}, // E0.6 [1] (Ⓜ️) circled M + {0x25AA, 0x25AB, prExtendedPictographic}, // E0.6 [2] (▪️..▫️) black small square..white small square + {0x25B6, 0x25B6, prExtendedPictographic}, // E0.6 [1] (▶️) play button + {0x25C0, 0x25C0, prExtendedPictographic}, // E0.6 [1] (◀️) reverse button + {0x25FB, 0x25FE, prExtendedPictographic}, // E0.6 [4] (◻️..◾) white medium square..black medium-small square + {0x2600, 0x2601, prExtendedPictographic}, // E0.6 [2] (☀️..☁️) sun..cloud + {0x2602, 0x2603, prExtendedPictographic}, // E0.7 [2] (☂️..☃️) umbrella..snowman + {0x2604, 0x2604, prExtendedPictographic}, // E1.0 [1] (☄️) comet + {0x2605, 0x2605, prExtendedPictographic}, // E0.0 [1] (★) BLACK STAR + {0x2607, 0x260D, prExtendedPictographic}, // E0.0 [7] (☇..☍) LIGHTNING..OPPOSITION + {0x260E, 0x260E, prExtendedPictographic}, // E0.6 [1] (☎️) telephone + {0x260F, 0x2610, prExtendedPictographic}, // E0.0 [2] (☏..☐) WHITE TELEPHONE..BALLOT BOX + {0x2611, 0x2611, prExtendedPictographic}, // E0.6 [1] (☑️) check box with check + {0x2612, 0x2612, prExtendedPictographic}, // E0.0 [1] (☒) BALLOT BOX WITH X + {0x2614, 0x2615, prExtendedPictographic}, // E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage + {0x2616, 0x2617, prExtendedPictographic}, // E0.0 [2] (☖..☗) WHITE SHOGI PIECE..BLACK SHOGI PIECE + {0x2618, 0x2618, prExtendedPictographic}, // E1.0 [1] (☘️) shamrock + {0x2619, 0x261C, prExtendedPictographic}, // E0.0 [4] (☙..☜) REVERSED ROTATED FLORAL HEART BULLET..WHITE LEFT POINTING INDEX + {0x261D, 0x261D, prExtendedPictographic}, // E0.6 [1] (☝️) index pointing up + {0x261E, 0x261F, prExtendedPictographic}, // E0.0 [2] (☞..☟) WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX + {0x2620, 0x2620, prExtendedPictographic}, // E1.0 [1] (☠️) skull and crossbones + {0x2621, 0x2621, prExtendedPictographic}, // E0.0 [1] (☡) CAUTION SIGN + {0x2622, 0x2623, prExtendedPictographic}, // E1.0 [2] (☢️..☣️) radioactive..biohazard + {0x2624, 0x2625, prExtendedPictographic}, // E0.0 [2] (☤..☥) CADUCEUS..ANKH + {0x2626, 0x2626, prExtendedPictographic}, // E1.0 [1] (☦️) orthodox cross + {0x2627, 0x2629, prExtendedPictographic}, // E0.0 [3] (☧..☩) CHI RHO..CROSS OF JERUSALEM + {0x262A, 0x262A, prExtendedPictographic}, // E0.7 [1] (☪️) star and crescent + {0x262B, 0x262D, prExtendedPictographic}, // E0.0 [3] (☫..☭) FARSI SYMBOL..HAMMER AND SICKLE + {0x262E, 0x262E, prExtendedPictographic}, // E1.0 [1] (☮️) peace symbol + {0x262F, 0x262F, prExtendedPictographic}, // E0.7 [1] (☯️) yin yang + {0x2630, 0x2637, prExtendedPictographic}, // E0.0 [8] (☰..☷) TRIGRAM FOR HEAVEN..TRIGRAM FOR EARTH + {0x2638, 0x2639, prExtendedPictographic}, // E0.7 [2] (☸️..☹️) wheel of dharma..frowning face + {0x263A, 0x263A, prExtendedPictographic}, // E0.6 [1] (☺️) smiling face + {0x263B, 0x263F, prExtendedPictographic}, // E0.0 [5] (☻..☿) BLACK SMILING FACE..MERCURY + {0x2640, 0x2640, prExtendedPictographic}, // E4.0 [1] (♀️) female sign + {0x2641, 0x2641, prExtendedPictographic}, // E0.0 [1] (♁) EARTH + {0x2642, 0x2642, prExtendedPictographic}, // E4.0 [1] (♂️) male sign + {0x2643, 0x2647, prExtendedPictographic}, // E0.0 [5] (♃..♇) JUPITER..PLUTO + {0x2648, 0x2653, prExtendedPictographic}, // E0.6 [12] (♈..♓) Aries..Pisces + {0x2654, 0x265E, prExtendedPictographic}, // E0.0 [11] (♔..♞) WHITE CHESS KING..BLACK CHESS KNIGHT + {0x265F, 0x265F, prExtendedPictographic}, // E11.0 [1] (♟️) chess pawn + {0x2660, 0x2660, prExtendedPictographic}, // E0.6 [1] (♠️) spade suit + {0x2661, 0x2662, prExtendedPictographic}, // E0.0 [2] (♡..♢) WHITE HEART SUIT..WHITE DIAMOND SUIT + {0x2663, 0x2663, prExtendedPictographic}, // E0.6 [1] (♣️) club suit + {0x2664, 0x2664, prExtendedPictographic}, // E0.0 [1] (♤) WHITE SPADE SUIT + {0x2665, 0x2666, prExtendedPictographic}, // E0.6 [2] (♥️..♦️) heart suit..diamond suit + {0x2667, 0x2667, prExtendedPictographic}, // E0.0 [1] (♧) WHITE CLUB SUIT + {0x2668, 0x2668, prExtendedPictographic}, // E0.6 [1] (♨️) hot springs + {0x2669, 0x267A, prExtendedPictographic}, // E0.0 [18] (♩..♺) QUARTER NOTE..RECYCLING SYMBOL FOR GENERIC MATERIALS + {0x267B, 0x267B, prExtendedPictographic}, // E0.6 [1] (♻️) recycling symbol + {0x267C, 0x267D, prExtendedPictographic}, // E0.0 [2] (♼..♽) RECYCLED PAPER SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL + {0x267E, 0x267E, prExtendedPictographic}, // E11.0 [1] (♾️) infinity + {0x267F, 0x267F, prExtendedPictographic}, // E0.6 [1] (♿) wheelchair symbol + {0x2680, 0x2685, prExtendedPictographic}, // E0.0 [6] (⚀..⚅) DIE FACE-1..DIE FACE-6 + {0x2690, 0x2691, prExtendedPictographic}, // E0.0 [2] (⚐..⚑) WHITE FLAG..BLACK FLAG + {0x2692, 0x2692, prExtendedPictographic}, // E1.0 [1] (⚒️) hammer and pick + {0x2693, 0x2693, prExtendedPictographic}, // E0.6 [1] (⚓) anchor + {0x2694, 0x2694, prExtendedPictographic}, // E1.0 [1] (⚔️) crossed swords + {0x2695, 0x2695, prExtendedPictographic}, // E4.0 [1] (⚕️) medical symbol + {0x2696, 0x2697, prExtendedPictographic}, // E1.0 [2] (⚖️..⚗️) balance scale..alembic + {0x2698, 0x2698, prExtendedPictographic}, // E0.0 [1] (⚘) FLOWER + {0x2699, 0x2699, prExtendedPictographic}, // E1.0 [1] (⚙️) gear + {0x269A, 0x269A, prExtendedPictographic}, // E0.0 [1] (⚚) STAFF OF HERMES + {0x269B, 0x269C, prExtendedPictographic}, // E1.0 [2] (⚛️..⚜️) atom symbol..fleur-de-lis + {0x269D, 0x269F, prExtendedPictographic}, // E0.0 [3] (⚝..⚟) OUTLINED WHITE STAR..THREE LINES CONVERGING LEFT + {0x26A0, 0x26A1, prExtendedPictographic}, // E0.6 [2] (⚠️..⚡) warning..high voltage + {0x26A2, 0x26A6, prExtendedPictographic}, // E0.0 [5] (⚢..⚦) DOUBLED FEMALE SIGN..MALE WITH STROKE SIGN + {0x26A7, 0x26A7, prExtendedPictographic}, // E13.0 [1] (⚧️) transgender symbol + {0x26A8, 0x26A9, prExtendedPictographic}, // E0.0 [2] (⚨..⚩) VERTICAL MALE WITH STROKE SIGN..HORIZONTAL MALE WITH STROKE SIGN + {0x26AA, 0x26AB, prExtendedPictographic}, // E0.6 [2] (⚪..⚫) white circle..black circle + {0x26AC, 0x26AF, prExtendedPictographic}, // E0.0 [4] (⚬..⚯) MEDIUM SMALL WHITE CIRCLE..UNMARRIED PARTNERSHIP SYMBOL + {0x26B0, 0x26B1, prExtendedPictographic}, // E1.0 [2] (⚰️..⚱️) coffin..funeral urn + {0x26B2, 0x26BC, prExtendedPictographic}, // E0.0 [11] (⚲..⚼) NEUTER..SESQUIQUADRATE + {0x26BD, 0x26BE, prExtendedPictographic}, // E0.6 [2] (⚽..⚾) soccer ball..baseball + {0x26BF, 0x26C3, prExtendedPictographic}, // E0.0 [5] (⚿..⛃) SQUARED KEY..BLACK DRAUGHTS KING + {0x26C4, 0x26C5, prExtendedPictographic}, // E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud + {0x26C6, 0x26C7, prExtendedPictographic}, // E0.0 [2] (⛆..⛇) RAIN..BLACK SNOWMAN + {0x26C8, 0x26C8, prExtendedPictographic}, // E0.7 [1] (⛈️) cloud with lightning and rain + {0x26C9, 0x26CD, prExtendedPictographic}, // E0.0 [5] (⛉..⛍) TURNED WHITE SHOGI PIECE..DISABLED CAR + {0x26CE, 0x26CE, prExtendedPictographic}, // E0.6 [1] (⛎) Ophiuchus + {0x26CF, 0x26CF, prExtendedPictographic}, // E0.7 [1] (⛏️) pick + {0x26D0, 0x26D0, prExtendedPictographic}, // E0.0 [1] (⛐) CAR SLIDING + {0x26D1, 0x26D1, prExtendedPictographic}, // E0.7 [1] (⛑️) rescue worker’s helmet + {0x26D2, 0x26D2, prExtendedPictographic}, // E0.0 [1] (⛒) CIRCLED CROSSING LANES + {0x26D3, 0x26D3, prExtendedPictographic}, // E0.7 [1] (⛓️) chains + {0x26D4, 0x26D4, prExtendedPictographic}, // E0.6 [1] (⛔) no entry + {0x26D5, 0x26E8, prExtendedPictographic}, // E0.0 [20] (⛕..⛨) ALTERNATE ONE-WAY LEFT WAY TRAFFIC..BLACK CROSS ON SHIELD + {0x26E9, 0x26E9, prExtendedPictographic}, // E0.7 [1] (⛩️) shinto shrine + {0x26EA, 0x26EA, prExtendedPictographic}, // E0.6 [1] (⛪) church + {0x26EB, 0x26EF, prExtendedPictographic}, // E0.0 [5] (⛫..⛯) CASTLE..MAP SYMBOL FOR LIGHTHOUSE + {0x26F0, 0x26F1, prExtendedPictographic}, // E0.7 [2] (⛰️..⛱️) mountain..umbrella on ground + {0x26F2, 0x26F3, prExtendedPictographic}, // E0.6 [2] (⛲..⛳) fountain..flag in hole + {0x26F4, 0x26F4, prExtendedPictographic}, // E0.7 [1] (⛴️) ferry + {0x26F5, 0x26F5, prExtendedPictographic}, // E0.6 [1] (⛵) sailboat + {0x26F6, 0x26F6, prExtendedPictographic}, // E0.0 [1] (⛶) SQUARE FOUR CORNERS + {0x26F7, 0x26F9, prExtendedPictographic}, // E0.7 [3] (⛷️..⛹️) skier..person bouncing ball + {0x26FA, 0x26FA, prExtendedPictographic}, // E0.6 [1] (⛺) tent + {0x26FB, 0x26FC, prExtendedPictographic}, // E0.0 [2] (⛻..⛼) JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL + {0x26FD, 0x26FD, prExtendedPictographic}, // E0.6 [1] (⛽) fuel pump + {0x26FE, 0x2701, prExtendedPictographic}, // E0.0 [4] (⛾..✁) CUP ON BLACK SQUARE..UPPER BLADE SCISSORS + {0x2702, 0x2702, prExtendedPictographic}, // E0.6 [1] (✂️) scissors + {0x2703, 0x2704, prExtendedPictographic}, // E0.0 [2] (✃..✄) LOWER BLADE SCISSORS..WHITE SCISSORS + {0x2705, 0x2705, prExtendedPictographic}, // E0.6 [1] (✅) check mark button + {0x2708, 0x270C, prExtendedPictographic}, // E0.6 [5] (✈️..✌️) airplane..victory hand + {0x270D, 0x270D, prExtendedPictographic}, // E0.7 [1] (✍️) writing hand + {0x270E, 0x270E, prExtendedPictographic}, // E0.0 [1] (✎) LOWER RIGHT PENCIL + {0x270F, 0x270F, prExtendedPictographic}, // E0.6 [1] (✏️) pencil + {0x2710, 0x2711, prExtendedPictographic}, // E0.0 [2] (✐..✑) UPPER RIGHT PENCIL..WHITE NIB + {0x2712, 0x2712, prExtendedPictographic}, // E0.6 [1] (✒️) black nib + {0x2714, 0x2714, prExtendedPictographic}, // E0.6 [1] (✔️) check mark + {0x2716, 0x2716, prExtendedPictographic}, // E0.6 [1] (✖️) multiply + {0x271D, 0x271D, prExtendedPictographic}, // E0.7 [1] (✝️) latin cross + {0x2721, 0x2721, prExtendedPictographic}, // E0.7 [1] (✡️) star of David + {0x2728, 0x2728, prExtendedPictographic}, // E0.6 [1] (✨) sparkles + {0x2733, 0x2734, prExtendedPictographic}, // E0.6 [2] (✳️..✴️) eight-spoked asterisk..eight-pointed star + {0x2744, 0x2744, prExtendedPictographic}, // E0.6 [1] (❄️) snowflake + {0x2747, 0x2747, prExtendedPictographic}, // E0.6 [1] (❇️) sparkle + {0x274C, 0x274C, prExtendedPictographic}, // E0.6 [1] (❌) cross mark + {0x274E, 0x274E, prExtendedPictographic}, // E0.6 [1] (❎) cross mark button + {0x2753, 0x2755, prExtendedPictographic}, // E0.6 [3] (❓..❕) red question mark..white exclamation mark + {0x2757, 0x2757, prExtendedPictographic}, // E0.6 [1] (❗) red exclamation mark + {0x2763, 0x2763, prExtendedPictographic}, // E1.0 [1] (❣️) heart exclamation + {0x2764, 0x2764, prExtendedPictographic}, // E0.6 [1] (❤️) red heart + {0x2765, 0x2767, prExtendedPictographic}, // E0.0 [3] (❥..❧) ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET + {0x2795, 0x2797, prExtendedPictographic}, // E0.6 [3] (➕..➗) plus..divide + {0x27A1, 0x27A1, prExtendedPictographic}, // E0.6 [1] (➡️) right arrow + {0x27B0, 0x27B0, prExtendedPictographic}, // E0.6 [1] (➰) curly loop + {0x27BF, 0x27BF, prExtendedPictographic}, // E1.0 [1] (➿) double curly loop + {0x2934, 0x2935, prExtendedPictographic}, // E0.6 [2] (⤴️..⤵️) right arrow curving up..right arrow curving down + {0x2B05, 0x2B07, prExtendedPictographic}, // E0.6 [3] (⬅️..⬇️) left arrow..down arrow + {0x2B1B, 0x2B1C, prExtendedPictographic}, // E0.6 [2] (⬛..⬜) black large square..white large square + {0x2B50, 0x2B50, prExtendedPictographic}, // E0.6 [1] (⭐) star + {0x2B55, 0x2B55, prExtendedPictographic}, // E0.6 [1] (⭕) hollow red circle + {0x2C00, 0x2C7B, prALetter}, // L& [124] GLAGOLITIC CAPITAL LETTER AZU..LATIN LETTER SMALL CAPITAL TURNED E + {0x2C7C, 0x2C7D, prALetter}, // Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V + {0x2C7E, 0x2CE4, prALetter}, // L& [103] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC SYMBOL KAI + {0x2CEB, 0x2CEE, prALetter}, // L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA + {0x2CEF, 0x2CF1, prExtend}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS + {0x2CF2, 0x2CF3, prALetter}, // L& [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI + {0x2D00, 0x2D25, prALetter}, // L& [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE + {0x2D27, 0x2D27, prALetter}, // L& GEORGIAN SMALL LETTER YN + {0x2D2D, 0x2D2D, prALetter}, // L& GEORGIAN SMALL LETTER AEN + {0x2D30, 0x2D67, prALetter}, // Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO + {0x2D6F, 0x2D6F, prALetter}, // Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK + {0x2D7F, 0x2D7F, prExtend}, // Mn TIFINAGH CONSONANT JOINER + {0x2D80, 0x2D96, prALetter}, // Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE + {0x2DA0, 0x2DA6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO + {0x2DA8, 0x2DAE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO + {0x2DB0, 0x2DB6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO + {0x2DB8, 0x2DBE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO + {0x2DC0, 0x2DC6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO + {0x2DC8, 0x2DCE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO + {0x2DD0, 0x2DD6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO + {0x2DD8, 0x2DDE, prALetter}, // Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO + {0x2DE0, 0x2DFF, prExtend}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + {0x2E2F, 0x2E2F, prALetter}, // Lm VERTICAL TILDE + {0x3000, 0x3000, prWSegSpace}, // Zs IDEOGRAPHIC SPACE + {0x3005, 0x3005, prALetter}, // Lm IDEOGRAPHIC ITERATION MARK + {0x302A, 0x302D, prExtend}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK + {0x302E, 0x302F, prExtend}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK + {0x3030, 0x3030, prExtendedPictographic}, // E0.6 [1] (〰️) wavy dash + {0x3031, 0x3035, prKatakana}, // Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF + {0x303B, 0x303B, prALetter}, // Lm VERTICAL IDEOGRAPHIC ITERATION MARK + {0x303C, 0x303C, prALetter}, // Lo MASU MARK + {0x303D, 0x303D, prExtendedPictographic}, // E0.6 [1] (〽️) part alternation mark + {0x3099, 0x309A, prExtend}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x309B, 0x309C, prKatakana}, // Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x30A0, 0x30A0, prKatakana}, // Pd KATAKANA-HIRAGANA DOUBLE HYPHEN + {0x30A1, 0x30FA, prKatakana}, // Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO + {0x30FC, 0x30FE, prKatakana}, // Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK + {0x30FF, 0x30FF, prKatakana}, // Lo KATAKANA DIGRAPH KOTO + {0x3105, 0x312F, prALetter}, // Lo [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN + {0x3131, 0x318E, prALetter}, // Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE + {0x31A0, 0x31BF, prALetter}, // Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH + {0x31F0, 0x31FF, prKatakana}, // Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO + {0x3297, 0x3297, prExtendedPictographic}, // E0.6 [1] (㊗️) Japanese “congratulations” button + {0x3299, 0x3299, prExtendedPictographic}, // E0.6 [1] (㊙️) Japanese “secret” button + {0x32D0, 0x32FE, prKatakana}, // So [47] CIRCLED KATAKANA A..CIRCLED KATAKANA WO + {0x3300, 0x3357, prKatakana}, // So [88] SQUARE APAATO..SQUARE WATTO + {0xA000, 0xA014, prALetter}, // Lo [21] YI SYLLABLE IT..YI SYLLABLE E + {0xA015, 0xA015, prALetter}, // Lm YI SYLLABLE WU + {0xA016, 0xA48C, prALetter}, // Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR + {0xA4D0, 0xA4F7, prALetter}, // Lo [40] LISU LETTER BA..LISU LETTER OE + {0xA4F8, 0xA4FD, prALetter}, // Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU + {0xA500, 0xA60B, prALetter}, // Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG + {0xA60C, 0xA60C, prALetter}, // Lm VAI SYLLABLE LENGTHENER + {0xA610, 0xA61F, prALetter}, // Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG + {0xA620, 0xA629, prNumeric}, // Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE + {0xA62A, 0xA62B, prALetter}, // Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO + {0xA640, 0xA66D, prALetter}, // L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O + {0xA66E, 0xA66E, prALetter}, // Lo CYRILLIC LETTER MULTIOCULAR O + {0xA66F, 0xA66F, prExtend}, // Mn COMBINING CYRILLIC VZMET + {0xA670, 0xA672, prExtend}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + {0xA674, 0xA67D, prExtend}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK + {0xA67F, 0xA67F, prALetter}, // Lm CYRILLIC PAYEROK + {0xA680, 0xA69B, prALetter}, // L& [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O + {0xA69C, 0xA69D, prALetter}, // Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN + {0xA69E, 0xA69F, prExtend}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E + {0xA6A0, 0xA6E5, prALetter}, // Lo [70] BAMUM LETTER A..BAMUM LETTER KI + {0xA6E6, 0xA6EF, prALetter}, // Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM + {0xA6F0, 0xA6F1, prExtend}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS + {0xA708, 0xA716, prALetter}, // Sk [15] MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR + {0xA717, 0xA71F, prALetter}, // Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK + {0xA720, 0xA721, prALetter}, // Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE + {0xA722, 0xA76F, prALetter}, // L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON + {0xA770, 0xA770, prALetter}, // Lm MODIFIER LETTER US + {0xA771, 0xA787, prALetter}, // L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T + {0xA788, 0xA788, prALetter}, // Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT + {0xA789, 0xA78A, prALetter}, // Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN + {0xA78B, 0xA78E, prALetter}, // L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT + {0xA78F, 0xA78F, prALetter}, // Lo LATIN LETTER SINOLOGICAL DOT + {0xA790, 0xA7CA, prALetter}, // L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY + {0xA7D0, 0xA7D1, prALetter}, // L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G + {0xA7D3, 0xA7D3, prALetter}, // L& LATIN SMALL LETTER DOUBLE THORN + {0xA7D5, 0xA7D9, prALetter}, // L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S + {0xA7F2, 0xA7F4, prALetter}, // Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q + {0xA7F5, 0xA7F6, prALetter}, // L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H + {0xA7F7, 0xA7F7, prALetter}, // Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I + {0xA7F8, 0xA7F9, prALetter}, // Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE + {0xA7FA, 0xA7FA, prALetter}, // L& LATIN LETTER SMALL CAPITAL TURNED M + {0xA7FB, 0xA801, prALetter}, // Lo [7] LATIN EPIGRAPHIC LETTER REVERSED F..SYLOTI NAGRI LETTER I + {0xA802, 0xA802, prExtend}, // Mn SYLOTI NAGRI SIGN DVISVARA + {0xA803, 0xA805, prALetter}, // Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O + {0xA806, 0xA806, prExtend}, // Mn SYLOTI NAGRI SIGN HASANTA + {0xA807, 0xA80A, prALetter}, // Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO + {0xA80B, 0xA80B, prExtend}, // Mn SYLOTI NAGRI SIGN ANUSVARA + {0xA80C, 0xA822, prALetter}, // Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO + {0xA823, 0xA824, prExtend}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I + {0xA825, 0xA826, prExtend}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E + {0xA827, 0xA827, prExtend}, // Mc SYLOTI NAGRI VOWEL SIGN OO + {0xA82C, 0xA82C, prExtend}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA + {0xA840, 0xA873, prALetter}, // Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU + {0xA880, 0xA881, prExtend}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA + {0xA882, 0xA8B3, prALetter}, // Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA + {0xA8B4, 0xA8C3, prExtend}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU + {0xA8C4, 0xA8C5, prExtend}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU + {0xA8D0, 0xA8D9, prNumeric}, // Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE + {0xA8E0, 0xA8F1, prExtend}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA + {0xA8F2, 0xA8F7, prALetter}, // Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA + {0xA8FB, 0xA8FB, prALetter}, // Lo DEVANAGARI HEADSTROKE + {0xA8FD, 0xA8FE, prALetter}, // Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY + {0xA8FF, 0xA8FF, prExtend}, // Mn DEVANAGARI VOWEL SIGN AY + {0xA900, 0xA909, prNumeric}, // Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE + {0xA90A, 0xA925, prALetter}, // Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO + {0xA926, 0xA92D, prExtend}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU + {0xA930, 0xA946, prALetter}, // Lo [23] REJANG LETTER KA..REJANG LETTER A + {0xA947, 0xA951, prExtend}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R + {0xA952, 0xA953, prExtend}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA + {0xA960, 0xA97C, prALetter}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH + {0xA980, 0xA982, prExtend}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR + {0xA983, 0xA983, prExtend}, // Mc JAVANESE SIGN WIGNYAN + {0xA984, 0xA9B2, prALetter}, // Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA + {0xA9B3, 0xA9B3, prExtend}, // Mn JAVANESE SIGN CECAK TELU + {0xA9B4, 0xA9B5, prExtend}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG + {0xA9B6, 0xA9B9, prExtend}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT + {0xA9BA, 0xA9BB, prExtend}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE + {0xA9BC, 0xA9BD, prExtend}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET + {0xA9BE, 0xA9C0, prExtend}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON + {0xA9CF, 0xA9CF, prALetter}, // Lm JAVANESE PANGRANGKEP + {0xA9D0, 0xA9D9, prNumeric}, // Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE + {0xA9E5, 0xA9E5, prExtend}, // Mn MYANMAR SIGN SHAN SAW + {0xA9F0, 0xA9F9, prNumeric}, // Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE + {0xAA00, 0xAA28, prALetter}, // Lo [41] CHAM LETTER A..CHAM LETTER HA + {0xAA29, 0xAA2E, prExtend}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE + {0xAA2F, 0xAA30, prExtend}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI + {0xAA31, 0xAA32, prExtend}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE + {0xAA33, 0xAA34, prExtend}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA + {0xAA35, 0xAA36, prExtend}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA + {0xAA40, 0xAA42, prALetter}, // Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG + {0xAA43, 0xAA43, prExtend}, // Mn CHAM CONSONANT SIGN FINAL NG + {0xAA44, 0xAA4B, prALetter}, // Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS + {0xAA4C, 0xAA4C, prExtend}, // Mn CHAM CONSONANT SIGN FINAL M + {0xAA4D, 0xAA4D, prExtend}, // Mc CHAM CONSONANT SIGN FINAL H + {0xAA50, 0xAA59, prNumeric}, // Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE + {0xAA7B, 0xAA7B, prExtend}, // Mc MYANMAR SIGN PAO KAREN TONE + {0xAA7C, 0xAA7C, prExtend}, // Mn MYANMAR SIGN TAI LAING TONE-2 + {0xAA7D, 0xAA7D, prExtend}, // Mc MYANMAR SIGN TAI LAING TONE-5 + {0xAAB0, 0xAAB0, prExtend}, // Mn TAI VIET MAI KANG + {0xAAB2, 0xAAB4, prExtend}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U + {0xAAB7, 0xAAB8, prExtend}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA + {0xAABE, 0xAABF, prExtend}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK + {0xAAC1, 0xAAC1, prExtend}, // Mn TAI VIET TONE MAI THO + {0xAAE0, 0xAAEA, prALetter}, // Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA + {0xAAEB, 0xAAEB, prExtend}, // Mc MEETEI MAYEK VOWEL SIGN II + {0xAAEC, 0xAAED, prExtend}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI + {0xAAEE, 0xAAEF, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU + {0xAAF2, 0xAAF2, prALetter}, // Lo MEETEI MAYEK ANJI + {0xAAF3, 0xAAF4, prALetter}, // Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK + {0xAAF5, 0xAAF5, prExtend}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA + {0xAAF6, 0xAAF6, prExtend}, // Mn MEETEI MAYEK VIRAMA + {0xAB01, 0xAB06, prALetter}, // Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO + {0xAB09, 0xAB0E, prALetter}, // Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO + {0xAB11, 0xAB16, prALetter}, // Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO + {0xAB20, 0xAB26, prALetter}, // Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO + {0xAB28, 0xAB2E, prALetter}, // Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO + {0xAB30, 0xAB5A, prALetter}, // L& [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG + {0xAB5B, 0xAB5B, prALetter}, // Sk MODIFIER BREVE WITH INVERTED BREVE + {0xAB5C, 0xAB5F, prALetter}, // Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK + {0xAB60, 0xAB68, prALetter}, // L& [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE + {0xAB69, 0xAB69, prALetter}, // Lm MODIFIER LETTER SMALL TURNED W + {0xAB70, 0xABBF, prALetter}, // L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA + {0xABC0, 0xABE2, prALetter}, // Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM + {0xABE3, 0xABE4, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP + {0xABE5, 0xABE5, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN ANAP + {0xABE6, 0xABE7, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP + {0xABE8, 0xABE8, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN UNAP + {0xABE9, 0xABEA, prExtend}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG + {0xABEC, 0xABEC, prExtend}, // Mc MEETEI MAYEK LUM IYEK + {0xABED, 0xABED, prExtend}, // Mn MEETEI MAYEK APUN IYEK + {0xABF0, 0xABF9, prNumeric}, // Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE + {0xAC00, 0xD7A3, prALetter}, // Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH + {0xD7B0, 0xD7C6, prALetter}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E + {0xD7CB, 0xD7FB, prALetter}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH + {0xFB00, 0xFB06, prALetter}, // L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST + {0xFB13, 0xFB17, prALetter}, // L& [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH + {0xFB1D, 0xFB1D, prHebrewLetter}, // Lo HEBREW LETTER YOD WITH HIRIQ + {0xFB1E, 0xFB1E, prExtend}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA + {0xFB1F, 0xFB28, prHebrewLetter}, // Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV + {0xFB2A, 0xFB36, prHebrewLetter}, // Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH + {0xFB38, 0xFB3C, prHebrewLetter}, // Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH + {0xFB3E, 0xFB3E, prHebrewLetter}, // Lo HEBREW LETTER MEM WITH DAGESH + {0xFB40, 0xFB41, prHebrewLetter}, // Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH + {0xFB43, 0xFB44, prHebrewLetter}, // Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH + {0xFB46, 0xFB4F, prHebrewLetter}, // Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED + {0xFB50, 0xFBB1, prALetter}, // Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM + {0xFBD3, 0xFD3D, prALetter}, // Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM + {0xFD50, 0xFD8F, prALetter}, // Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM + {0xFD92, 0xFDC7, prALetter}, // Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM + {0xFDF0, 0xFDFB, prALetter}, // Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU + {0xFE00, 0xFE0F, prExtend}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 + {0xFE10, 0xFE10, prMidNum}, // Po PRESENTATION FORM FOR VERTICAL COMMA + {0xFE13, 0xFE13, prMidLetter}, // Po PRESENTATION FORM FOR VERTICAL COLON + {0xFE14, 0xFE14, prMidNum}, // Po PRESENTATION FORM FOR VERTICAL SEMICOLON + {0xFE20, 0xFE2F, prExtend}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF + {0xFE33, 0xFE34, prExtendNumLet}, // Pc [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE + {0xFE4D, 0xFE4F, prExtendNumLet}, // Pc [3] DASHED LOW LINE..WAVY LOW LINE + {0xFE50, 0xFE50, prMidNum}, // Po SMALL COMMA + {0xFE52, 0xFE52, prMidNumLet}, // Po SMALL FULL STOP + {0xFE54, 0xFE54, prMidNum}, // Po SMALL SEMICOLON + {0xFE55, 0xFE55, prMidLetter}, // Po SMALL COLON + {0xFE70, 0xFE74, prALetter}, // Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM + {0xFE76, 0xFEFC, prALetter}, // Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM + {0xFEFF, 0xFEFF, prFormat}, // Cf ZERO WIDTH NO-BREAK SPACE + {0xFF07, 0xFF07, prMidNumLet}, // Po FULLWIDTH APOSTROPHE + {0xFF0C, 0xFF0C, prMidNum}, // Po FULLWIDTH COMMA + {0xFF0E, 0xFF0E, prMidNumLet}, // Po FULLWIDTH FULL STOP + {0xFF10, 0xFF19, prNumeric}, // Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE + {0xFF1A, 0xFF1A, prMidLetter}, // Po FULLWIDTH COLON + {0xFF1B, 0xFF1B, prMidNum}, // Po FULLWIDTH SEMICOLON + {0xFF21, 0xFF3A, prALetter}, // L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z + {0xFF3F, 0xFF3F, prExtendNumLet}, // Pc FULLWIDTH LOW LINE + {0xFF41, 0xFF5A, prALetter}, // L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z + {0xFF66, 0xFF6F, prKatakana}, // Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU + {0xFF70, 0xFF70, prKatakana}, // Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0xFF71, 0xFF9D, prKatakana}, // Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N + {0xFF9E, 0xFF9F, prExtend}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + {0xFFA0, 0xFFBE, prALetter}, // Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH + {0xFFC2, 0xFFC7, prALetter}, // Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E + {0xFFCA, 0xFFCF, prALetter}, // Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE + {0xFFD2, 0xFFD7, prALetter}, // Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU + {0xFFDA, 0xFFDC, prALetter}, // Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I + {0xFFF9, 0xFFFB, prFormat}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR + {0x10000, 0x1000B, prALetter}, // Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE + {0x1000D, 0x10026, prALetter}, // Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO + {0x10028, 0x1003A, prALetter}, // Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO + {0x1003C, 0x1003D, prALetter}, // Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE + {0x1003F, 0x1004D, prALetter}, // Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO + {0x10050, 0x1005D, prALetter}, // Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 + {0x10080, 0x100FA, prALetter}, // Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 + {0x10140, 0x10174, prALetter}, // Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS + {0x101FD, 0x101FD, prExtend}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE + {0x10280, 0x1029C, prALetter}, // Lo [29] LYCIAN LETTER A..LYCIAN LETTER X + {0x102A0, 0x102D0, prALetter}, // Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3 + {0x102E0, 0x102E0, prExtend}, // Mn COPTIC EPACT THOUSANDS MARK + {0x10300, 0x1031F, prALetter}, // Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS + {0x1032D, 0x10340, prALetter}, // Lo [20] OLD ITALIC LETTER YE..GOTHIC LETTER PAIRTHRA + {0x10341, 0x10341, prALetter}, // Nl GOTHIC LETTER NINETY + {0x10342, 0x10349, prALetter}, // Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL + {0x1034A, 0x1034A, prALetter}, // Nl GOTHIC LETTER NINE HUNDRED + {0x10350, 0x10375, prALetter}, // Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA + {0x10376, 0x1037A, prExtend}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII + {0x10380, 0x1039D, prALetter}, // Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU + {0x103A0, 0x103C3, prALetter}, // Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA + {0x103C8, 0x103CF, prALetter}, // Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH + {0x103D1, 0x103D5, prALetter}, // Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED + {0x10400, 0x1044F, prALetter}, // L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW + {0x10450, 0x1049D, prALetter}, // Lo [78] SHAVIAN LETTER PEEP..OSMANYA LETTER OO + {0x104A0, 0x104A9, prNumeric}, // Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE + {0x104B0, 0x104D3, prALetter}, // L& [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA + {0x104D8, 0x104FB, prALetter}, // L& [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA + {0x10500, 0x10527, prALetter}, // Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE + {0x10530, 0x10563, prALetter}, // Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW + {0x10570, 0x1057A, prALetter}, // L& [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA + {0x1057C, 0x1058A, prALetter}, // L& [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE + {0x1058C, 0x10592, prALetter}, // L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE + {0x10594, 0x10595, prALetter}, // L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE + {0x10597, 0x105A1, prALetter}, // L& [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA + {0x105A3, 0x105B1, prALetter}, // L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE + {0x105B3, 0x105B9, prALetter}, // L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE + {0x105BB, 0x105BC, prALetter}, // L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE + {0x10600, 0x10736, prALetter}, // Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 + {0x10740, 0x10755, prALetter}, // Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE + {0x10760, 0x10767, prALetter}, // Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 + {0x10780, 0x10785, prALetter}, // Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK + {0x10787, 0x107B0, prALetter}, // Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK + {0x107B2, 0x107BA, prALetter}, // Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL + {0x10800, 0x10805, prALetter}, // Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA + {0x10808, 0x10808, prALetter}, // Lo CYPRIOT SYLLABLE JO + {0x1080A, 0x10835, prALetter}, // Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO + {0x10837, 0x10838, prALetter}, // Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE + {0x1083C, 0x1083C, prALetter}, // Lo CYPRIOT SYLLABLE ZA + {0x1083F, 0x10855, prALetter}, // Lo [23] CYPRIOT SYLLABLE ZO..IMPERIAL ARAMAIC LETTER TAW + {0x10860, 0x10876, prALetter}, // Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW + {0x10880, 0x1089E, prALetter}, // Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW + {0x108E0, 0x108F2, prALetter}, // Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH + {0x108F4, 0x108F5, prALetter}, // Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW + {0x10900, 0x10915, prALetter}, // Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU + {0x10920, 0x10939, prALetter}, // Lo [26] LYDIAN LETTER A..LYDIAN LETTER C + {0x10980, 0x109B7, prALetter}, // Lo [56] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC CURSIVE LETTER DA + {0x109BE, 0x109BF, prALetter}, // Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN + {0x10A00, 0x10A00, prALetter}, // Lo KHAROSHTHI LETTER A + {0x10A01, 0x10A03, prExtend}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R + {0x10A05, 0x10A06, prExtend}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O + {0x10A0C, 0x10A0F, prExtend}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA + {0x10A10, 0x10A13, prALetter}, // Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA + {0x10A15, 0x10A17, prALetter}, // Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA + {0x10A19, 0x10A35, prALetter}, // Lo [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA + {0x10A38, 0x10A3A, prExtend}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW + {0x10A3F, 0x10A3F, prExtend}, // Mn KHAROSHTHI VIRAMA + {0x10A60, 0x10A7C, prALetter}, // Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH + {0x10A80, 0x10A9C, prALetter}, // Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH + {0x10AC0, 0x10AC7, prALetter}, // Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW + {0x10AC9, 0x10AE4, prALetter}, // Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW + {0x10AE5, 0x10AE6, prExtend}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW + {0x10B00, 0x10B35, prALetter}, // Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE + {0x10B40, 0x10B55, prALetter}, // Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW + {0x10B60, 0x10B72, prALetter}, // Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW + {0x10B80, 0x10B91, prALetter}, // Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW + {0x10C00, 0x10C48, prALetter}, // Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH + {0x10C80, 0x10CB2, prALetter}, // L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US + {0x10CC0, 0x10CF2, prALetter}, // L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US + {0x10D00, 0x10D23, prALetter}, // Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA + {0x10D24, 0x10D27, prExtend}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI + {0x10D30, 0x10D39, prNumeric}, // Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE + {0x10E80, 0x10EA9, prALetter}, // Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET + {0x10EAB, 0x10EAC, prExtend}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK + {0x10EB0, 0x10EB1, prALetter}, // Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE + {0x10EFD, 0x10EFF, prExtend}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA + {0x10F00, 0x10F1C, prALetter}, // Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL + {0x10F27, 0x10F27, prALetter}, // Lo OLD SOGDIAN LIGATURE AYIN-DALETH + {0x10F30, 0x10F45, prALetter}, // Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN + {0x10F46, 0x10F50, prExtend}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW + {0x10F70, 0x10F81, prALetter}, // Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH + {0x10F82, 0x10F85, prExtend}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW + {0x10FB0, 0x10FC4, prALetter}, // Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW + {0x10FE0, 0x10FF6, prALetter}, // Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH + {0x11000, 0x11000, prExtend}, // Mc BRAHMI SIGN CANDRABINDU + {0x11001, 0x11001, prExtend}, // Mn BRAHMI SIGN ANUSVARA + {0x11002, 0x11002, prExtend}, // Mc BRAHMI SIGN VISARGA + {0x11003, 0x11037, prALetter}, // Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA + {0x11038, 0x11046, prExtend}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA + {0x11066, 0x1106F, prNumeric}, // Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE + {0x11070, 0x11070, prExtend}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA + {0x11071, 0x11072, prALetter}, // Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O + {0x11073, 0x11074, prExtend}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O + {0x11075, 0x11075, prALetter}, // Lo BRAHMI LETTER OLD TAMIL LLA + {0x1107F, 0x11081, prExtend}, // Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA + {0x11082, 0x11082, prExtend}, // Mc KAITHI SIGN VISARGA + {0x11083, 0x110AF, prALetter}, // Lo [45] KAITHI LETTER A..KAITHI LETTER HA + {0x110B0, 0x110B2, prExtend}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II + {0x110B3, 0x110B6, prExtend}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI + {0x110B7, 0x110B8, prExtend}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU + {0x110B9, 0x110BA, prExtend}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA + {0x110BD, 0x110BD, prFormat}, // Cf KAITHI NUMBER SIGN + {0x110C2, 0x110C2, prExtend}, // Mn KAITHI VOWEL SIGN VOCALIC R + {0x110CD, 0x110CD, prFormat}, // Cf KAITHI NUMBER SIGN ABOVE + {0x110D0, 0x110E8, prALetter}, // Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE + {0x110F0, 0x110F9, prNumeric}, // Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE + {0x11100, 0x11102, prExtend}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA + {0x11103, 0x11126, prALetter}, // Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA + {0x11127, 0x1112B, prExtend}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU + {0x1112C, 0x1112C, prExtend}, // Mc CHAKMA VOWEL SIGN E + {0x1112D, 0x11134, prExtend}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA + {0x11136, 0x1113F, prNumeric}, // Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE + {0x11144, 0x11144, prALetter}, // Lo CHAKMA LETTER LHAA + {0x11145, 0x11146, prExtend}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI + {0x11147, 0x11147, prALetter}, // Lo CHAKMA LETTER VAA + {0x11150, 0x11172, prALetter}, // Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA + {0x11173, 0x11173, prExtend}, // Mn MAHAJANI SIGN NUKTA + {0x11176, 0x11176, prALetter}, // Lo MAHAJANI LIGATURE SHRI + {0x11180, 0x11181, prExtend}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA + {0x11182, 0x11182, prExtend}, // Mc SHARADA SIGN VISARGA + {0x11183, 0x111B2, prALetter}, // Lo [48] SHARADA LETTER A..SHARADA LETTER HA + {0x111B3, 0x111B5, prExtend}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II + {0x111B6, 0x111BE, prExtend}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O + {0x111BF, 0x111C0, prExtend}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA + {0x111C1, 0x111C4, prALetter}, // Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM + {0x111C9, 0x111CC, prExtend}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK + {0x111CE, 0x111CE, prExtend}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E + {0x111CF, 0x111CF, prExtend}, // Mn SHARADA SIGN INVERTED CANDRABINDU + {0x111D0, 0x111D9, prNumeric}, // Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE + {0x111DA, 0x111DA, prALetter}, // Lo SHARADA EKAM + {0x111DC, 0x111DC, prALetter}, // Lo SHARADA HEADSTROKE + {0x11200, 0x11211, prALetter}, // Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA + {0x11213, 0x1122B, prALetter}, // Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA + {0x1122C, 0x1122E, prExtend}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II + {0x1122F, 0x11231, prExtend}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI + {0x11232, 0x11233, prExtend}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU + {0x11234, 0x11234, prExtend}, // Mn KHOJKI SIGN ANUSVARA + {0x11235, 0x11235, prExtend}, // Mc KHOJKI SIGN VIRAMA + {0x11236, 0x11237, prExtend}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA + {0x1123E, 0x1123E, prExtend}, // Mn KHOJKI SIGN SUKUN + {0x1123F, 0x11240, prALetter}, // Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I + {0x11241, 0x11241, prExtend}, // Mn KHOJKI VOWEL SIGN VOCALIC R + {0x11280, 0x11286, prALetter}, // Lo [7] MULTANI LETTER A..MULTANI LETTER GA + {0x11288, 0x11288, prALetter}, // Lo MULTANI LETTER GHA + {0x1128A, 0x1128D, prALetter}, // Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA + {0x1128F, 0x1129D, prALetter}, // Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA + {0x1129F, 0x112A8, prALetter}, // Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA + {0x112B0, 0x112DE, prALetter}, // Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA + {0x112DF, 0x112DF, prExtend}, // Mn KHUDAWADI SIGN ANUSVARA + {0x112E0, 0x112E2, prExtend}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II + {0x112E3, 0x112EA, prExtend}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA + {0x112F0, 0x112F9, prNumeric}, // Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE + {0x11300, 0x11301, prExtend}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU + {0x11302, 0x11303, prExtend}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA + {0x11305, 0x1130C, prALetter}, // Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L + {0x1130F, 0x11310, prALetter}, // Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI + {0x11313, 0x11328, prALetter}, // Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA + {0x1132A, 0x11330, prALetter}, // Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA + {0x11332, 0x11333, prALetter}, // Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA + {0x11335, 0x11339, prALetter}, // Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA + {0x1133B, 0x1133C, prExtend}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA + {0x1133D, 0x1133D, prALetter}, // Lo GRANTHA SIGN AVAGRAHA + {0x1133E, 0x1133F, prExtend}, // Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I + {0x11340, 0x11340, prExtend}, // Mn GRANTHA VOWEL SIGN II + {0x11341, 0x11344, prExtend}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR + {0x11347, 0x11348, prExtend}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI + {0x1134B, 0x1134D, prExtend}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA + {0x11350, 0x11350, prALetter}, // Lo GRANTHA OM + {0x11357, 0x11357, prExtend}, // Mc GRANTHA AU LENGTH MARK + {0x1135D, 0x11361, prALetter}, // Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL + {0x11362, 0x11363, prExtend}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL + {0x11366, 0x1136C, prExtend}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX + {0x11370, 0x11374, prExtend}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA + {0x11400, 0x11434, prALetter}, // Lo [53] NEWA LETTER A..NEWA LETTER HA + {0x11435, 0x11437, prExtend}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II + {0x11438, 0x1143F, prExtend}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI + {0x11440, 0x11441, prExtend}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU + {0x11442, 0x11444, prExtend}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA + {0x11445, 0x11445, prExtend}, // Mc NEWA SIGN VISARGA + {0x11446, 0x11446, prExtend}, // Mn NEWA SIGN NUKTA + {0x11447, 0x1144A, prALetter}, // Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI + {0x11450, 0x11459, prNumeric}, // Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE + {0x1145E, 0x1145E, prExtend}, // Mn NEWA SANDHI MARK + {0x1145F, 0x11461, prALetter}, // Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA + {0x11480, 0x114AF, prALetter}, // Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA + {0x114B0, 0x114B2, prExtend}, // Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II + {0x114B3, 0x114B8, prExtend}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL + {0x114B9, 0x114B9, prExtend}, // Mc TIRHUTA VOWEL SIGN E + {0x114BA, 0x114BA, prExtend}, // Mn TIRHUTA VOWEL SIGN SHORT E + {0x114BB, 0x114BE, prExtend}, // Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU + {0x114BF, 0x114C0, prExtend}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA + {0x114C1, 0x114C1, prExtend}, // Mc TIRHUTA SIGN VISARGA + {0x114C2, 0x114C3, prExtend}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA + {0x114C4, 0x114C5, prALetter}, // Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG + {0x114C7, 0x114C7, prALetter}, // Lo TIRHUTA OM + {0x114D0, 0x114D9, prNumeric}, // Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE + {0x11580, 0x115AE, prALetter}, // Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA + {0x115AF, 0x115B1, prExtend}, // Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II + {0x115B2, 0x115B5, prExtend}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR + {0x115B8, 0x115BB, prExtend}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU + {0x115BC, 0x115BD, prExtend}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA + {0x115BE, 0x115BE, prExtend}, // Mc SIDDHAM SIGN VISARGA + {0x115BF, 0x115C0, prExtend}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA + {0x115D8, 0x115DB, prALetter}, // Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U + {0x115DC, 0x115DD, prExtend}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU + {0x11600, 0x1162F, prALetter}, // Lo [48] MODI LETTER A..MODI LETTER LLA + {0x11630, 0x11632, prExtend}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II + {0x11633, 0x1163A, prExtend}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI + {0x1163B, 0x1163C, prExtend}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU + {0x1163D, 0x1163D, prExtend}, // Mn MODI SIGN ANUSVARA + {0x1163E, 0x1163E, prExtend}, // Mc MODI SIGN VISARGA + {0x1163F, 0x11640, prExtend}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA + {0x11644, 0x11644, prALetter}, // Lo MODI SIGN HUVA + {0x11650, 0x11659, prNumeric}, // Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE + {0x11680, 0x116AA, prALetter}, // Lo [43] TAKRI LETTER A..TAKRI LETTER RRA + {0x116AB, 0x116AB, prExtend}, // Mn TAKRI SIGN ANUSVARA + {0x116AC, 0x116AC, prExtend}, // Mc TAKRI SIGN VISARGA + {0x116AD, 0x116AD, prExtend}, // Mn TAKRI VOWEL SIGN AA + {0x116AE, 0x116AF, prExtend}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II + {0x116B0, 0x116B5, prExtend}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU + {0x116B6, 0x116B6, prExtend}, // Mc TAKRI SIGN VIRAMA + {0x116B7, 0x116B7, prExtend}, // Mn TAKRI SIGN NUKTA + {0x116B8, 0x116B8, prALetter}, // Lo TAKRI LETTER ARCHAIC KHA + {0x116C0, 0x116C9, prNumeric}, // Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE + {0x1171D, 0x1171F, prExtend}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA + {0x11720, 0x11721, prExtend}, // Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA + {0x11722, 0x11725, prExtend}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU + {0x11726, 0x11726, prExtend}, // Mc AHOM VOWEL SIGN E + {0x11727, 0x1172B, prExtend}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER + {0x11730, 0x11739, prNumeric}, // Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE + {0x11800, 0x1182B, prALetter}, // Lo [44] DOGRA LETTER A..DOGRA LETTER RRA + {0x1182C, 0x1182E, prExtend}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II + {0x1182F, 0x11837, prExtend}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA + {0x11838, 0x11838, prExtend}, // Mc DOGRA SIGN VISARGA + {0x11839, 0x1183A, prExtend}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA + {0x118A0, 0x118DF, prALetter}, // L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO + {0x118E0, 0x118E9, prNumeric}, // Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE + {0x118FF, 0x11906, prALetter}, // Lo [8] WARANG CITI OM..DIVES AKURU LETTER E + {0x11909, 0x11909, prALetter}, // Lo DIVES AKURU LETTER O + {0x1190C, 0x11913, prALetter}, // Lo [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA + {0x11915, 0x11916, prALetter}, // Lo [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA + {0x11918, 0x1192F, prALetter}, // Lo [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA + {0x11930, 0x11935, prExtend}, // Mc [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E + {0x11937, 0x11938, prExtend}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O + {0x1193B, 0x1193C, prExtend}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU + {0x1193D, 0x1193D, prExtend}, // Mc DIVES AKURU SIGN HALANTA + {0x1193E, 0x1193E, prExtend}, // Mn DIVES AKURU VIRAMA + {0x1193F, 0x1193F, prALetter}, // Lo DIVES AKURU PREFIXED NASAL SIGN + {0x11940, 0x11940, prExtend}, // Mc DIVES AKURU MEDIAL YA + {0x11941, 0x11941, prALetter}, // Lo DIVES AKURU INITIAL RA + {0x11942, 0x11942, prExtend}, // Mc DIVES AKURU MEDIAL RA + {0x11943, 0x11943, prExtend}, // Mn DIVES AKURU SIGN NUKTA + {0x11950, 0x11959, prNumeric}, // Nd [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE + {0x119A0, 0x119A7, prALetter}, // Lo [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR + {0x119AA, 0x119D0, prALetter}, // Lo [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA + {0x119D1, 0x119D3, prExtend}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II + {0x119D4, 0x119D7, prExtend}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR + {0x119DA, 0x119DB, prExtend}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI + {0x119DC, 0x119DF, prExtend}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA + {0x119E0, 0x119E0, prExtend}, // Mn NANDINAGARI SIGN VIRAMA + {0x119E1, 0x119E1, prALetter}, // Lo NANDINAGARI SIGN AVAGRAHA + {0x119E3, 0x119E3, prALetter}, // Lo NANDINAGARI HEADSTROKE + {0x119E4, 0x119E4, prExtend}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E + {0x11A00, 0x11A00, prALetter}, // Lo ZANABAZAR SQUARE LETTER A + {0x11A01, 0x11A0A, prExtend}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK + {0x11A0B, 0x11A32, prALetter}, // Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA + {0x11A33, 0x11A38, prExtend}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA + {0x11A39, 0x11A39, prExtend}, // Mc ZANABAZAR SQUARE SIGN VISARGA + {0x11A3A, 0x11A3A, prALetter}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA + {0x11A3B, 0x11A3E, prExtend}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA + {0x11A47, 0x11A47, prExtend}, // Mn ZANABAZAR SQUARE SUBJOINER + {0x11A50, 0x11A50, prALetter}, // Lo SOYOMBO LETTER A + {0x11A51, 0x11A56, prExtend}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE + {0x11A57, 0x11A58, prExtend}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU + {0x11A59, 0x11A5B, prExtend}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK + {0x11A5C, 0x11A89, prALetter}, // Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA + {0x11A8A, 0x11A96, prExtend}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA + {0x11A97, 0x11A97, prExtend}, // Mc SOYOMBO SIGN VISARGA + {0x11A98, 0x11A99, prExtend}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER + {0x11A9D, 0x11A9D, prALetter}, // Lo SOYOMBO MARK PLUTA + {0x11AB0, 0x11AF8, prALetter}, // Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL + {0x11C00, 0x11C08, prALetter}, // Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L + {0x11C0A, 0x11C2E, prALetter}, // Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA + {0x11C2F, 0x11C2F, prExtend}, // Mc BHAIKSUKI VOWEL SIGN AA + {0x11C30, 0x11C36, prExtend}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L + {0x11C38, 0x11C3D, prExtend}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA + {0x11C3E, 0x11C3E, prExtend}, // Mc BHAIKSUKI SIGN VISARGA + {0x11C3F, 0x11C3F, prExtend}, // Mn BHAIKSUKI SIGN VIRAMA + {0x11C40, 0x11C40, prALetter}, // Lo BHAIKSUKI SIGN AVAGRAHA + {0x11C50, 0x11C59, prNumeric}, // Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE + {0x11C72, 0x11C8F, prALetter}, // Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A + {0x11C92, 0x11CA7, prExtend}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA + {0x11CA9, 0x11CA9, prExtend}, // Mc MARCHEN SUBJOINED LETTER YA + {0x11CAA, 0x11CB0, prExtend}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA + {0x11CB1, 0x11CB1, prExtend}, // Mc MARCHEN VOWEL SIGN I + {0x11CB2, 0x11CB3, prExtend}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E + {0x11CB4, 0x11CB4, prExtend}, // Mc MARCHEN VOWEL SIGN O + {0x11CB5, 0x11CB6, prExtend}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU + {0x11D00, 0x11D06, prALetter}, // Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E + {0x11D08, 0x11D09, prALetter}, // Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O + {0x11D0B, 0x11D30, prALetter}, // Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA + {0x11D31, 0x11D36, prExtend}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R + {0x11D3A, 0x11D3A, prExtend}, // Mn MASARAM GONDI VOWEL SIGN E + {0x11D3C, 0x11D3D, prExtend}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O + {0x11D3F, 0x11D45, prExtend}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA + {0x11D46, 0x11D46, prALetter}, // Lo MASARAM GONDI REPHA + {0x11D47, 0x11D47, prExtend}, // Mn MASARAM GONDI RA-KARA + {0x11D50, 0x11D59, prNumeric}, // Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE + {0x11D60, 0x11D65, prALetter}, // Lo [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU + {0x11D67, 0x11D68, prALetter}, // Lo [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI + {0x11D6A, 0x11D89, prALetter}, // Lo [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA + {0x11D8A, 0x11D8E, prExtend}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU + {0x11D90, 0x11D91, prExtend}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI + {0x11D93, 0x11D94, prExtend}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU + {0x11D95, 0x11D95, prExtend}, // Mn GUNJALA GONDI SIGN ANUSVARA + {0x11D96, 0x11D96, prExtend}, // Mc GUNJALA GONDI SIGN VISARGA + {0x11D97, 0x11D97, prExtend}, // Mn GUNJALA GONDI VIRAMA + {0x11D98, 0x11D98, prALetter}, // Lo GUNJALA GONDI OM + {0x11DA0, 0x11DA9, prNumeric}, // Nd [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE + {0x11EE0, 0x11EF2, prALetter}, // Lo [19] MAKASAR LETTER KA..MAKASAR ANGKA + {0x11EF3, 0x11EF4, prExtend}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U + {0x11EF5, 0x11EF6, prExtend}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O + {0x11F00, 0x11F01, prExtend}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA + {0x11F02, 0x11F02, prALetter}, // Lo KAWI SIGN REPHA + {0x11F03, 0x11F03, prExtend}, // Mc KAWI SIGN VISARGA + {0x11F04, 0x11F10, prALetter}, // Lo [13] KAWI LETTER A..KAWI LETTER O + {0x11F12, 0x11F33, prALetter}, // Lo [34] KAWI LETTER KA..KAWI LETTER JNYA + {0x11F34, 0x11F35, prExtend}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA + {0x11F36, 0x11F3A, prExtend}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R + {0x11F3E, 0x11F3F, prExtend}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI + {0x11F40, 0x11F40, prExtend}, // Mn KAWI VOWEL SIGN EU + {0x11F41, 0x11F41, prExtend}, // Mc KAWI SIGN KILLER + {0x11F42, 0x11F42, prExtend}, // Mn KAWI CONJOINER + {0x11F50, 0x11F59, prNumeric}, // Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE + {0x11FB0, 0x11FB0, prALetter}, // Lo LISU LETTER YHA + {0x12000, 0x12399, prALetter}, // Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U + {0x12400, 0x1246E, prALetter}, // Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM + {0x12480, 0x12543, prALetter}, // Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU + {0x12F90, 0x12FF0, prALetter}, // Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 + {0x13000, 0x1342F, prALetter}, // Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D + {0x13430, 0x1343F, prFormat}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE + {0x13440, 0x13440, prExtend}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY + {0x13441, 0x13446, prALetter}, // Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN + {0x13447, 0x13455, prExtend}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED + {0x14400, 0x14646, prALetter}, // Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 + {0x16800, 0x16A38, prALetter}, // Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ + {0x16A40, 0x16A5E, prALetter}, // Lo [31] MRO LETTER TA..MRO LETTER TEK + {0x16A60, 0x16A69, prNumeric}, // Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE + {0x16A70, 0x16ABE, prALetter}, // Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA + {0x16AC0, 0x16AC9, prNumeric}, // Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE + {0x16AD0, 0x16AED, prALetter}, // Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I + {0x16AF0, 0x16AF4, prExtend}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE + {0x16B00, 0x16B2F, prALetter}, // Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU + {0x16B30, 0x16B36, prExtend}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM + {0x16B40, 0x16B43, prALetter}, // Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM + {0x16B50, 0x16B59, prNumeric}, // Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE + {0x16B63, 0x16B77, prALetter}, // Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS + {0x16B7D, 0x16B8F, prALetter}, // Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ + {0x16E40, 0x16E7F, prALetter}, // L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y + {0x16F00, 0x16F4A, prALetter}, // Lo [75] MIAO LETTER PA..MIAO LETTER RTE + {0x16F4F, 0x16F4F, prExtend}, // Mn MIAO SIGN CONSONANT MODIFIER BAR + {0x16F50, 0x16F50, prALetter}, // Lo MIAO LETTER NASALIZATION + {0x16F51, 0x16F87, prExtend}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI + {0x16F8F, 0x16F92, prExtend}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW + {0x16F93, 0x16F9F, prALetter}, // Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 + {0x16FE0, 0x16FE1, prALetter}, // Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK + {0x16FE3, 0x16FE3, prALetter}, // Lm OLD CHINESE ITERATION MARK + {0x16FE4, 0x16FE4, prExtend}, // Mn KHITAN SMALL SCRIPT FILLER + {0x16FF0, 0x16FF1, prExtend}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY + {0x1AFF0, 0x1AFF3, prKatakana}, // Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 + {0x1AFF5, 0x1AFFB, prKatakana}, // Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 + {0x1AFFD, 0x1AFFE, prKatakana}, // Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 + {0x1B000, 0x1B000, prKatakana}, // Lo KATAKANA LETTER ARCHAIC E + {0x1B120, 0x1B122, prKatakana}, // Lo [3] KATAKANA LETTER ARCHAIC YI..KATAKANA LETTER ARCHAIC WU + {0x1B155, 0x1B155, prKatakana}, // Lo KATAKANA LETTER SMALL KO + {0x1B164, 0x1B167, prKatakana}, // Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N + {0x1BC00, 0x1BC6A, prALetter}, // Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M + {0x1BC70, 0x1BC7C, prALetter}, // Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK + {0x1BC80, 0x1BC88, prALetter}, // Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL + {0x1BC90, 0x1BC99, prALetter}, // Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW + {0x1BC9D, 0x1BC9E, prExtend}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK + {0x1BCA0, 0x1BCA3, prFormat}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP + {0x1CF00, 0x1CF2D, prExtend}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT + {0x1CF30, 0x1CF46, prExtend}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG + {0x1D165, 0x1D166, prExtend}, // Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM + {0x1D167, 0x1D169, prExtend}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 + {0x1D16D, 0x1D172, prExtend}, // Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 + {0x1D173, 0x1D17A, prFormat}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE + {0x1D17B, 0x1D182, prExtend}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE + {0x1D185, 0x1D18B, prExtend}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE + {0x1D1AA, 0x1D1AD, prExtend}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO + {0x1D242, 0x1D244, prExtend}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME + {0x1D400, 0x1D454, prALetter}, // L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G + {0x1D456, 0x1D49C, prALetter}, // L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A + {0x1D49E, 0x1D49F, prALetter}, // L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D + {0x1D4A2, 0x1D4A2, prALetter}, // L& MATHEMATICAL SCRIPT CAPITAL G + {0x1D4A5, 0x1D4A6, prALetter}, // L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K + {0x1D4A9, 0x1D4AC, prALetter}, // L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q + {0x1D4AE, 0x1D4B9, prALetter}, // L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D + {0x1D4BB, 0x1D4BB, prALetter}, // L& MATHEMATICAL SCRIPT SMALL F + {0x1D4BD, 0x1D4C3, prALetter}, // L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N + {0x1D4C5, 0x1D505, prALetter}, // L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B + {0x1D507, 0x1D50A, prALetter}, // L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G + {0x1D50D, 0x1D514, prALetter}, // L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q + {0x1D516, 0x1D51C, prALetter}, // L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y + {0x1D51E, 0x1D539, prALetter}, // L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B + {0x1D53B, 0x1D53E, prALetter}, // L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G + {0x1D540, 0x1D544, prALetter}, // L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M + {0x1D546, 0x1D546, prALetter}, // L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O + {0x1D54A, 0x1D550, prALetter}, // L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + {0x1D552, 0x1D6A5, prALetter}, // L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J + {0x1D6A8, 0x1D6C0, prALetter}, // L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA + {0x1D6C2, 0x1D6DA, prALetter}, // L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA + {0x1D6DC, 0x1D6FA, prALetter}, // L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA + {0x1D6FC, 0x1D714, prALetter}, // L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA + {0x1D716, 0x1D734, prALetter}, // L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA + {0x1D736, 0x1D74E, prALetter}, // L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA + {0x1D750, 0x1D76E, prALetter}, // L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA + {0x1D770, 0x1D788, prALetter}, // L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA + {0x1D78A, 0x1D7A8, prALetter}, // L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA + {0x1D7AA, 0x1D7C2, prALetter}, // L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA + {0x1D7C4, 0x1D7CB, prALetter}, // L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA + {0x1D7CE, 0x1D7FF, prNumeric}, // Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE + {0x1DA00, 0x1DA36, prExtend}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN + {0x1DA3B, 0x1DA6C, prExtend}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT + {0x1DA75, 0x1DA75, prExtend}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS + {0x1DA84, 0x1DA84, prExtend}, // Mn SIGNWRITING LOCATION HEAD NECK + {0x1DA9B, 0x1DA9F, prExtend}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 + {0x1DAA1, 0x1DAAF, prExtend}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 + {0x1DF00, 0x1DF09, prALetter}, // L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK + {0x1DF0A, 0x1DF0A, prALetter}, // Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK + {0x1DF0B, 0x1DF1E, prALetter}, // L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL + {0x1DF25, 0x1DF2A, prALetter}, // L& [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK + {0x1E000, 0x1E006, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE + {0x1E008, 0x1E018, prExtend}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU + {0x1E01B, 0x1E021, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI + {0x1E023, 0x1E024, prExtend}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS + {0x1E026, 0x1E02A, prExtend}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA + {0x1E030, 0x1E06D, prALetter}, // Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE + {0x1E08F, 0x1E08F, prExtend}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + {0x1E100, 0x1E12C, prALetter}, // Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W + {0x1E130, 0x1E136, prExtend}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D + {0x1E137, 0x1E13D, prALetter}, // Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER + {0x1E140, 0x1E149, prNumeric}, // Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE + {0x1E14E, 0x1E14E, prALetter}, // Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ + {0x1E290, 0x1E2AD, prALetter}, // Lo [30] TOTO LETTER PA..TOTO LETTER A + {0x1E2AE, 0x1E2AE, prExtend}, // Mn TOTO SIGN RISING TONE + {0x1E2C0, 0x1E2EB, prALetter}, // Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH + {0x1E2EC, 0x1E2EF, prExtend}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI + {0x1E2F0, 0x1E2F9, prNumeric}, // Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE + {0x1E4D0, 0x1E4EA, prALetter}, // Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL + {0x1E4EB, 0x1E4EB, prALetter}, // Lm NAG MUNDARI SIGN OJOD + {0x1E4EC, 0x1E4EF, prExtend}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH + {0x1E4F0, 0x1E4F9, prNumeric}, // Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE + {0x1E7E0, 0x1E7E6, prALetter}, // Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO + {0x1E7E8, 0x1E7EB, prALetter}, // Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE + {0x1E7ED, 0x1E7EE, prALetter}, // Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE + {0x1E7F0, 0x1E7FE, prALetter}, // Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE + {0x1E800, 0x1E8C4, prALetter}, // Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON + {0x1E8D0, 0x1E8D6, prExtend}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS + {0x1E900, 0x1E943, prALetter}, // L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA + {0x1E944, 0x1E94A, prExtend}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA + {0x1E94B, 0x1E94B, prALetter}, // Lm ADLAM NASALIZATION MARK + {0x1E950, 0x1E959, prNumeric}, // Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE + {0x1EE00, 0x1EE03, prALetter}, // Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL + {0x1EE05, 0x1EE1F, prALetter}, // Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF + {0x1EE21, 0x1EE22, prALetter}, // Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM + {0x1EE24, 0x1EE24, prALetter}, // Lo ARABIC MATHEMATICAL INITIAL HEH + {0x1EE27, 0x1EE27, prALetter}, // Lo ARABIC MATHEMATICAL INITIAL HAH + {0x1EE29, 0x1EE32, prALetter}, // Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF + {0x1EE34, 0x1EE37, prALetter}, // Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH + {0x1EE39, 0x1EE39, prALetter}, // Lo ARABIC MATHEMATICAL INITIAL DAD + {0x1EE3B, 0x1EE3B, prALetter}, // Lo ARABIC MATHEMATICAL INITIAL GHAIN + {0x1EE42, 0x1EE42, prALetter}, // Lo ARABIC MATHEMATICAL TAILED JEEM + {0x1EE47, 0x1EE47, prALetter}, // Lo ARABIC MATHEMATICAL TAILED HAH + {0x1EE49, 0x1EE49, prALetter}, // Lo ARABIC MATHEMATICAL TAILED YEH + {0x1EE4B, 0x1EE4B, prALetter}, // Lo ARABIC MATHEMATICAL TAILED LAM + {0x1EE4D, 0x1EE4F, prALetter}, // Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN + {0x1EE51, 0x1EE52, prALetter}, // Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF + {0x1EE54, 0x1EE54, prALetter}, // Lo ARABIC MATHEMATICAL TAILED SHEEN + {0x1EE57, 0x1EE57, prALetter}, // Lo ARABIC MATHEMATICAL TAILED KHAH + {0x1EE59, 0x1EE59, prALetter}, // Lo ARABIC MATHEMATICAL TAILED DAD + {0x1EE5B, 0x1EE5B, prALetter}, // Lo ARABIC MATHEMATICAL TAILED GHAIN + {0x1EE5D, 0x1EE5D, prALetter}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON + {0x1EE5F, 0x1EE5F, prALetter}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF + {0x1EE61, 0x1EE62, prALetter}, // Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM + {0x1EE64, 0x1EE64, prALetter}, // Lo ARABIC MATHEMATICAL STRETCHED HEH + {0x1EE67, 0x1EE6A, prALetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF + {0x1EE6C, 0x1EE72, prALetter}, // Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF + {0x1EE74, 0x1EE77, prALetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH + {0x1EE79, 0x1EE7C, prALetter}, // Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH + {0x1EE7E, 0x1EE7E, prALetter}, // Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH + {0x1EE80, 0x1EE89, prALetter}, // Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH + {0x1EE8B, 0x1EE9B, prALetter}, // Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN + {0x1EEA1, 0x1EEA3, prALetter}, // Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL + {0x1EEA5, 0x1EEA9, prALetter}, // Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH + {0x1EEAB, 0x1EEBB, prALetter}, // Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN + {0x1F000, 0x1F003, prExtendedPictographic}, // E0.0 [4] (🀀..🀃) MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND + {0x1F004, 0x1F004, prExtendedPictographic}, // E0.6 [1] (🀄) mahjong red dragon + {0x1F005, 0x1F0CE, prExtendedPictographic}, // E0.0 [202] (🀅..🃎) MAHJONG TILE GREEN DRAGON..PLAYING CARD KING OF DIAMONDS + {0x1F0CF, 0x1F0CF, prExtendedPictographic}, // E0.6 [1] (🃏) joker + {0x1F0D0, 0x1F0FF, prExtendedPictographic}, // E0.0 [48] (🃐..🃿) .. + {0x1F10D, 0x1F10F, prExtendedPictographic}, // E0.0 [3] (🄍..🄏) CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH + {0x1F12F, 0x1F12F, prExtendedPictographic}, // E0.0 [1] (🄯) COPYLEFT SYMBOL + {0x1F130, 0x1F149, prALetter}, // So [26] SQUARED LATIN CAPITAL LETTER A..SQUARED LATIN CAPITAL LETTER Z + {0x1F150, 0x1F169, prALetter}, // So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z + {0x1F16C, 0x1F16F, prExtendedPictographic}, // E0.0 [4] (🅬..🅯) RAISED MR SIGN..CIRCLED HUMAN FIGURE + {0x1F170, 0x1F189, prALetter}, // So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z + {0x1F170, 0x1F171, prExtendedPictographic}, // E0.6 [2] (🅰️..🅱️) A button (blood type)..B button (blood type) + {0x1F17E, 0x1F17F, prExtendedPictographic}, // E0.6 [2] (🅾️..🅿️) O button (blood type)..P button + {0x1F18E, 0x1F18E, prExtendedPictographic}, // E0.6 [1] (🆎) AB button (blood type) + {0x1F191, 0x1F19A, prExtendedPictographic}, // E0.6 [10] (🆑..🆚) CL button..VS button + {0x1F1AD, 0x1F1E5, prExtendedPictographic}, // E0.0 [57] (🆭..🇥) MASK WORK SYMBOL.. + {0x1F1E6, 0x1F1FF, prRegionalIndicator}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z + {0x1F201, 0x1F202, prExtendedPictographic}, // E0.6 [2] (🈁..🈂️) Japanese “here” button..Japanese “service charge” button + {0x1F203, 0x1F20F, prExtendedPictographic}, // E0.0 [13] (🈃..🈏) .. + {0x1F21A, 0x1F21A, prExtendedPictographic}, // E0.6 [1] (🈚) Japanese “free of charge” button + {0x1F22F, 0x1F22F, prExtendedPictographic}, // E0.6 [1] (🈯) Japanese “reserved” button + {0x1F232, 0x1F23A, prExtendedPictographic}, // E0.6 [9] (🈲..🈺) Japanese “prohibited” button..Japanese “open for business” button + {0x1F23C, 0x1F23F, prExtendedPictographic}, // E0.0 [4] (🈼..🈿) .. + {0x1F249, 0x1F24F, prExtendedPictographic}, // E0.0 [7] (🉉..🉏) .. + {0x1F250, 0x1F251, prExtendedPictographic}, // E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button + {0x1F252, 0x1F2FF, prExtendedPictographic}, // E0.0 [174] (🉒..🋿) .. + {0x1F300, 0x1F30C, prExtendedPictographic}, // E0.6 [13] (🌀..🌌) cyclone..milky way + {0x1F30D, 0x1F30E, prExtendedPictographic}, // E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas + {0x1F30F, 0x1F30F, prExtendedPictographic}, // E0.6 [1] (🌏) globe showing Asia-Australia + {0x1F310, 0x1F310, prExtendedPictographic}, // E1.0 [1] (🌐) globe with meridians + {0x1F311, 0x1F311, prExtendedPictographic}, // E0.6 [1] (🌑) new moon + {0x1F312, 0x1F312, prExtendedPictographic}, // E1.0 [1] (🌒) waxing crescent moon + {0x1F313, 0x1F315, prExtendedPictographic}, // E0.6 [3] (🌓..🌕) first quarter moon..full moon + {0x1F316, 0x1F318, prExtendedPictographic}, // E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon + {0x1F319, 0x1F319, prExtendedPictographic}, // E0.6 [1] (🌙) crescent moon + {0x1F31A, 0x1F31A, prExtendedPictographic}, // E1.0 [1] (🌚) new moon face + {0x1F31B, 0x1F31B, prExtendedPictographic}, // E0.6 [1] (🌛) first quarter moon face + {0x1F31C, 0x1F31C, prExtendedPictographic}, // E0.7 [1] (🌜) last quarter moon face + {0x1F31D, 0x1F31E, prExtendedPictographic}, // E1.0 [2] (🌝..🌞) full moon face..sun with face + {0x1F31F, 0x1F320, prExtendedPictographic}, // E0.6 [2] (🌟..🌠) glowing star..shooting star + {0x1F321, 0x1F321, prExtendedPictographic}, // E0.7 [1] (🌡️) thermometer + {0x1F322, 0x1F323, prExtendedPictographic}, // E0.0 [2] (🌢..🌣) BLACK DROPLET..WHITE SUN + {0x1F324, 0x1F32C, prExtendedPictographic}, // E0.7 [9] (🌤️..🌬️) sun behind small cloud..wind face + {0x1F32D, 0x1F32F, prExtendedPictographic}, // E1.0 [3] (🌭..🌯) hot dog..burrito + {0x1F330, 0x1F331, prExtendedPictographic}, // E0.6 [2] (🌰..🌱) chestnut..seedling + {0x1F332, 0x1F333, prExtendedPictographic}, // E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree + {0x1F334, 0x1F335, prExtendedPictographic}, // E0.6 [2] (🌴..🌵) palm tree..cactus + {0x1F336, 0x1F336, prExtendedPictographic}, // E0.7 [1] (🌶️) hot pepper + {0x1F337, 0x1F34A, prExtendedPictographic}, // E0.6 [20] (🌷..🍊) tulip..tangerine + {0x1F34B, 0x1F34B, prExtendedPictographic}, // E1.0 [1] (🍋) lemon + {0x1F34C, 0x1F34F, prExtendedPictographic}, // E0.6 [4] (🍌..🍏) banana..green apple + {0x1F350, 0x1F350, prExtendedPictographic}, // E1.0 [1] (🍐) pear + {0x1F351, 0x1F37B, prExtendedPictographic}, // E0.6 [43] (🍑..🍻) peach..clinking beer mugs + {0x1F37C, 0x1F37C, prExtendedPictographic}, // E1.0 [1] (🍼) baby bottle + {0x1F37D, 0x1F37D, prExtendedPictographic}, // E0.7 [1] (🍽️) fork and knife with plate + {0x1F37E, 0x1F37F, prExtendedPictographic}, // E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn + {0x1F380, 0x1F393, prExtendedPictographic}, // E0.6 [20] (🎀..🎓) ribbon..graduation cap + {0x1F394, 0x1F395, prExtendedPictographic}, // E0.0 [2] (🎔..🎕) HEART WITH TIP ON THE LEFT..BOUQUET OF FLOWERS + {0x1F396, 0x1F397, prExtendedPictographic}, // E0.7 [2] (🎖️..🎗️) military medal..reminder ribbon + {0x1F398, 0x1F398, prExtendedPictographic}, // E0.0 [1] (🎘) MUSICAL KEYBOARD WITH JACKS + {0x1F399, 0x1F39B, prExtendedPictographic}, // E0.7 [3] (🎙️..🎛️) studio microphone..control knobs + {0x1F39C, 0x1F39D, prExtendedPictographic}, // E0.0 [2] (🎜..🎝) BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES + {0x1F39E, 0x1F39F, prExtendedPictographic}, // E0.7 [2] (🎞️..🎟️) film frames..admission tickets + {0x1F3A0, 0x1F3C4, prExtendedPictographic}, // E0.6 [37] (🎠..🏄) carousel horse..person surfing + {0x1F3C5, 0x1F3C5, prExtendedPictographic}, // E1.0 [1] (🏅) sports medal + {0x1F3C6, 0x1F3C6, prExtendedPictographic}, // E0.6 [1] (🏆) trophy + {0x1F3C7, 0x1F3C7, prExtendedPictographic}, // E1.0 [1] (🏇) horse racing + {0x1F3C8, 0x1F3C8, prExtendedPictographic}, // E0.6 [1] (🏈) american football + {0x1F3C9, 0x1F3C9, prExtendedPictographic}, // E1.0 [1] (🏉) rugby football + {0x1F3CA, 0x1F3CA, prExtendedPictographic}, // E0.6 [1] (🏊) person swimming + {0x1F3CB, 0x1F3CE, prExtendedPictographic}, // E0.7 [4] (🏋️..🏎️) person lifting weights..racing car + {0x1F3CF, 0x1F3D3, prExtendedPictographic}, // E1.0 [5] (🏏..🏓) cricket game..ping pong + {0x1F3D4, 0x1F3DF, prExtendedPictographic}, // E0.7 [12] (🏔️..🏟️) snow-capped mountain..stadium + {0x1F3E0, 0x1F3E3, prExtendedPictographic}, // E0.6 [4] (🏠..🏣) house..Japanese post office + {0x1F3E4, 0x1F3E4, prExtendedPictographic}, // E1.0 [1] (🏤) post office + {0x1F3E5, 0x1F3F0, prExtendedPictographic}, // E0.6 [12] (🏥..🏰) hospital..castle + {0x1F3F1, 0x1F3F2, prExtendedPictographic}, // E0.0 [2] (🏱..🏲) WHITE PENNANT..BLACK PENNANT + {0x1F3F3, 0x1F3F3, prExtendedPictographic}, // E0.7 [1] (🏳️) white flag + {0x1F3F4, 0x1F3F4, prExtendedPictographic}, // E1.0 [1] (🏴) black flag + {0x1F3F5, 0x1F3F5, prExtendedPictographic}, // E0.7 [1] (🏵️) rosette + {0x1F3F6, 0x1F3F6, prExtendedPictographic}, // E0.0 [1] (🏶) BLACK ROSETTE + {0x1F3F7, 0x1F3F7, prExtendedPictographic}, // E0.7 [1] (🏷️) label + {0x1F3F8, 0x1F3FA, prExtendedPictographic}, // E1.0 [3] (🏸..🏺) badminton..amphora + {0x1F3FB, 0x1F3FF, prExtend}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + {0x1F400, 0x1F407, prExtendedPictographic}, // E1.0 [8] (🐀..🐇) rat..rabbit + {0x1F408, 0x1F408, prExtendedPictographic}, // E0.7 [1] (🐈) cat + {0x1F409, 0x1F40B, prExtendedPictographic}, // E1.0 [3] (🐉..🐋) dragon..whale + {0x1F40C, 0x1F40E, prExtendedPictographic}, // E0.6 [3] (🐌..🐎) snail..horse + {0x1F40F, 0x1F410, prExtendedPictographic}, // E1.0 [2] (🐏..🐐) ram..goat + {0x1F411, 0x1F412, prExtendedPictographic}, // E0.6 [2] (🐑..🐒) ewe..monkey + {0x1F413, 0x1F413, prExtendedPictographic}, // E1.0 [1] (🐓) rooster + {0x1F414, 0x1F414, prExtendedPictographic}, // E0.6 [1] (🐔) chicken + {0x1F415, 0x1F415, prExtendedPictographic}, // E0.7 [1] (🐕) dog + {0x1F416, 0x1F416, prExtendedPictographic}, // E1.0 [1] (🐖) pig + {0x1F417, 0x1F429, prExtendedPictographic}, // E0.6 [19] (🐗..🐩) boar..poodle + {0x1F42A, 0x1F42A, prExtendedPictographic}, // E1.0 [1] (🐪) camel + {0x1F42B, 0x1F43E, prExtendedPictographic}, // E0.6 [20] (🐫..🐾) two-hump camel..paw prints + {0x1F43F, 0x1F43F, prExtendedPictographic}, // E0.7 [1] (🐿️) chipmunk + {0x1F440, 0x1F440, prExtendedPictographic}, // E0.6 [1] (👀) eyes + {0x1F441, 0x1F441, prExtendedPictographic}, // E0.7 [1] (👁️) eye + {0x1F442, 0x1F464, prExtendedPictographic}, // E0.6 [35] (👂..👤) ear..bust in silhouette + {0x1F465, 0x1F465, prExtendedPictographic}, // E1.0 [1] (👥) busts in silhouette + {0x1F466, 0x1F46B, prExtendedPictographic}, // E0.6 [6] (👦..👫) boy..woman and man holding hands + {0x1F46C, 0x1F46D, prExtendedPictographic}, // E1.0 [2] (👬..👭) men holding hands..women holding hands + {0x1F46E, 0x1F4AC, prExtendedPictographic}, // E0.6 [63] (👮..💬) police officer..speech balloon + {0x1F4AD, 0x1F4AD, prExtendedPictographic}, // E1.0 [1] (💭) thought balloon + {0x1F4AE, 0x1F4B5, prExtendedPictographic}, // E0.6 [8] (💮..💵) white flower..dollar banknote + {0x1F4B6, 0x1F4B7, prExtendedPictographic}, // E1.0 [2] (💶..💷) euro banknote..pound banknote + {0x1F4B8, 0x1F4EB, prExtendedPictographic}, // E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag + {0x1F4EC, 0x1F4ED, prExtendedPictographic}, // E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag + {0x1F4EE, 0x1F4EE, prExtendedPictographic}, // E0.6 [1] (📮) postbox + {0x1F4EF, 0x1F4EF, prExtendedPictographic}, // E1.0 [1] (📯) postal horn + {0x1F4F0, 0x1F4F4, prExtendedPictographic}, // E0.6 [5] (📰..📴) newspaper..mobile phone off + {0x1F4F5, 0x1F4F5, prExtendedPictographic}, // E1.0 [1] (📵) no mobile phones + {0x1F4F6, 0x1F4F7, prExtendedPictographic}, // E0.6 [2] (📶..📷) antenna bars..camera + {0x1F4F8, 0x1F4F8, prExtendedPictographic}, // E1.0 [1] (📸) camera with flash + {0x1F4F9, 0x1F4FC, prExtendedPictographic}, // E0.6 [4] (📹..📼) video camera..videocassette + {0x1F4FD, 0x1F4FD, prExtendedPictographic}, // E0.7 [1] (📽️) film projector + {0x1F4FE, 0x1F4FE, prExtendedPictographic}, // E0.0 [1] (📾) PORTABLE STEREO + {0x1F4FF, 0x1F502, prExtendedPictographic}, // E1.0 [4] (📿..🔂) prayer beads..repeat single button + {0x1F503, 0x1F503, prExtendedPictographic}, // E0.6 [1] (🔃) clockwise vertical arrows + {0x1F504, 0x1F507, prExtendedPictographic}, // E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker + {0x1F508, 0x1F508, prExtendedPictographic}, // E0.7 [1] (🔈) speaker low volume + {0x1F509, 0x1F509, prExtendedPictographic}, // E1.0 [1] (🔉) speaker medium volume + {0x1F50A, 0x1F514, prExtendedPictographic}, // E0.6 [11] (🔊..🔔) speaker high volume..bell + {0x1F515, 0x1F515, prExtendedPictographic}, // E1.0 [1] (🔕) bell with slash + {0x1F516, 0x1F52B, prExtendedPictographic}, // E0.6 [22] (🔖..🔫) bookmark..water pistol + {0x1F52C, 0x1F52D, prExtendedPictographic}, // E1.0 [2] (🔬..🔭) microscope..telescope + {0x1F52E, 0x1F53D, prExtendedPictographic}, // E0.6 [16] (🔮..🔽) crystal ball..downwards button + {0x1F546, 0x1F548, prExtendedPictographic}, // E0.0 [3] (🕆..🕈) WHITE LATIN CROSS..CELTIC CROSS + {0x1F549, 0x1F54A, prExtendedPictographic}, // E0.7 [2] (🕉️..🕊️) om..dove + {0x1F54B, 0x1F54E, prExtendedPictographic}, // E1.0 [4] (🕋..🕎) kaaba..menorah + {0x1F54F, 0x1F54F, prExtendedPictographic}, // E0.0 [1] (🕏) BOWL OF HYGIEIA + {0x1F550, 0x1F55B, prExtendedPictographic}, // E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock + {0x1F55C, 0x1F567, prExtendedPictographic}, // E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty + {0x1F568, 0x1F56E, prExtendedPictographic}, // E0.0 [7] (🕨..🕮) RIGHT SPEAKER..BOOK + {0x1F56F, 0x1F570, prExtendedPictographic}, // E0.7 [2] (🕯️..🕰️) candle..mantelpiece clock + {0x1F571, 0x1F572, prExtendedPictographic}, // E0.0 [2] (🕱..🕲) BLACK SKULL AND CROSSBONES..NO PIRACY + {0x1F573, 0x1F579, prExtendedPictographic}, // E0.7 [7] (🕳️..🕹️) hole..joystick + {0x1F57A, 0x1F57A, prExtendedPictographic}, // E3.0 [1] (🕺) man dancing + {0x1F57B, 0x1F586, prExtendedPictographic}, // E0.0 [12] (🕻..🖆) LEFT HAND TELEPHONE RECEIVER..PEN OVER STAMPED ENVELOPE + {0x1F587, 0x1F587, prExtendedPictographic}, // E0.7 [1] (🖇️) linked paperclips + {0x1F588, 0x1F589, prExtendedPictographic}, // E0.0 [2] (🖈..🖉) BLACK PUSHPIN..LOWER LEFT PENCIL + {0x1F58A, 0x1F58D, prExtendedPictographic}, // E0.7 [4] (🖊️..🖍️) pen..crayon + {0x1F58E, 0x1F58F, prExtendedPictographic}, // E0.0 [2] (🖎..🖏) LEFT WRITING HAND..TURNED OK HAND SIGN + {0x1F590, 0x1F590, prExtendedPictographic}, // E0.7 [1] (🖐️) hand with fingers splayed + {0x1F591, 0x1F594, prExtendedPictographic}, // E0.0 [4] (🖑..🖔) REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND + {0x1F595, 0x1F596, prExtendedPictographic}, // E1.0 [2] (🖕..🖖) middle finger..vulcan salute + {0x1F597, 0x1F5A3, prExtendedPictographic}, // E0.0 [13] (🖗..🖣) WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX + {0x1F5A4, 0x1F5A4, prExtendedPictographic}, // E3.0 [1] (🖤) black heart + {0x1F5A5, 0x1F5A5, prExtendedPictographic}, // E0.7 [1] (🖥️) desktop computer + {0x1F5A6, 0x1F5A7, prExtendedPictographic}, // E0.0 [2] (🖦..🖧) KEYBOARD AND MOUSE..THREE NETWORKED COMPUTERS + {0x1F5A8, 0x1F5A8, prExtendedPictographic}, // E0.7 [1] (🖨️) printer + {0x1F5A9, 0x1F5B0, prExtendedPictographic}, // E0.0 [8] (🖩..🖰) POCKET CALCULATOR..TWO BUTTON MOUSE + {0x1F5B1, 0x1F5B2, prExtendedPictographic}, // E0.7 [2] (🖱️..🖲️) computer mouse..trackball + {0x1F5B3, 0x1F5BB, prExtendedPictographic}, // E0.0 [9] (🖳..🖻) OLD PERSONAL COMPUTER..DOCUMENT WITH PICTURE + {0x1F5BC, 0x1F5BC, prExtendedPictographic}, // E0.7 [1] (🖼️) framed picture + {0x1F5BD, 0x1F5C1, prExtendedPictographic}, // E0.0 [5] (🖽..🗁) FRAME WITH TILES..OPEN FOLDER + {0x1F5C2, 0x1F5C4, prExtendedPictographic}, // E0.7 [3] (🗂️..🗄️) card index dividers..file cabinet + {0x1F5C5, 0x1F5D0, prExtendedPictographic}, // E0.0 [12] (🗅..🗐) EMPTY NOTE..PAGES + {0x1F5D1, 0x1F5D3, prExtendedPictographic}, // E0.7 [3] (🗑️..🗓️) wastebasket..spiral calendar + {0x1F5D4, 0x1F5DB, prExtendedPictographic}, // E0.0 [8] (🗔..🗛) DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL + {0x1F5DC, 0x1F5DE, prExtendedPictographic}, // E0.7 [3] (🗜️..🗞️) clamp..rolled-up newspaper + {0x1F5DF, 0x1F5E0, prExtendedPictographic}, // E0.0 [2] (🗟..🗠) PAGE WITH CIRCLED TEXT..STOCK CHART + {0x1F5E1, 0x1F5E1, prExtendedPictographic}, // E0.7 [1] (🗡️) dagger + {0x1F5E2, 0x1F5E2, prExtendedPictographic}, // E0.0 [1] (🗢) LIPS + {0x1F5E3, 0x1F5E3, prExtendedPictographic}, // E0.7 [1] (🗣️) speaking head + {0x1F5E4, 0x1F5E7, prExtendedPictographic}, // E0.0 [4] (🗤..🗧) THREE RAYS ABOVE..THREE RAYS RIGHT + {0x1F5E8, 0x1F5E8, prExtendedPictographic}, // E2.0 [1] (🗨️) left speech bubble + {0x1F5E9, 0x1F5EE, prExtendedPictographic}, // E0.0 [6] (🗩..🗮) RIGHT SPEECH BUBBLE..LEFT ANGER BUBBLE + {0x1F5EF, 0x1F5EF, prExtendedPictographic}, // E0.7 [1] (🗯️) right anger bubble + {0x1F5F0, 0x1F5F2, prExtendedPictographic}, // E0.0 [3] (🗰..🗲) MOOD BUBBLE..LIGHTNING MOOD + {0x1F5F3, 0x1F5F3, prExtendedPictographic}, // E0.7 [1] (🗳️) ballot box with ballot + {0x1F5F4, 0x1F5F9, prExtendedPictographic}, // E0.0 [6] (🗴..🗹) BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK + {0x1F5FA, 0x1F5FA, prExtendedPictographic}, // E0.7 [1] (🗺️) world map + {0x1F5FB, 0x1F5FF, prExtendedPictographic}, // E0.6 [5] (🗻..🗿) mount fuji..moai + {0x1F600, 0x1F600, prExtendedPictographic}, // E1.0 [1] (😀) grinning face + {0x1F601, 0x1F606, prExtendedPictographic}, // E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face + {0x1F607, 0x1F608, prExtendedPictographic}, // E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns + {0x1F609, 0x1F60D, prExtendedPictographic}, // E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes + {0x1F60E, 0x1F60E, prExtendedPictographic}, // E1.0 [1] (😎) smiling face with sunglasses + {0x1F60F, 0x1F60F, prExtendedPictographic}, // E0.6 [1] (😏) smirking face + {0x1F610, 0x1F610, prExtendedPictographic}, // E0.7 [1] (😐) neutral face + {0x1F611, 0x1F611, prExtendedPictographic}, // E1.0 [1] (😑) expressionless face + {0x1F612, 0x1F614, prExtendedPictographic}, // E0.6 [3] (😒..😔) unamused face..pensive face + {0x1F615, 0x1F615, prExtendedPictographic}, // E1.0 [1] (😕) confused face + {0x1F616, 0x1F616, prExtendedPictographic}, // E0.6 [1] (😖) confounded face + {0x1F617, 0x1F617, prExtendedPictographic}, // E1.0 [1] (😗) kissing face + {0x1F618, 0x1F618, prExtendedPictographic}, // E0.6 [1] (😘) face blowing a kiss + {0x1F619, 0x1F619, prExtendedPictographic}, // E1.0 [1] (😙) kissing face with smiling eyes + {0x1F61A, 0x1F61A, prExtendedPictographic}, // E0.6 [1] (😚) kissing face with closed eyes + {0x1F61B, 0x1F61B, prExtendedPictographic}, // E1.0 [1] (😛) face with tongue + {0x1F61C, 0x1F61E, prExtendedPictographic}, // E0.6 [3] (😜..😞) winking face with tongue..disappointed face + {0x1F61F, 0x1F61F, prExtendedPictographic}, // E1.0 [1] (😟) worried face + {0x1F620, 0x1F625, prExtendedPictographic}, // E0.6 [6] (😠..😥) angry face..sad but relieved face + {0x1F626, 0x1F627, prExtendedPictographic}, // E1.0 [2] (😦..😧) frowning face with open mouth..anguished face + {0x1F628, 0x1F62B, prExtendedPictographic}, // E0.6 [4] (😨..😫) fearful face..tired face + {0x1F62C, 0x1F62C, prExtendedPictographic}, // E1.0 [1] (😬) grimacing face + {0x1F62D, 0x1F62D, prExtendedPictographic}, // E0.6 [1] (😭) loudly crying face + {0x1F62E, 0x1F62F, prExtendedPictographic}, // E1.0 [2] (😮..😯) face with open mouth..hushed face + {0x1F630, 0x1F633, prExtendedPictographic}, // E0.6 [4] (😰..😳) anxious face with sweat..flushed face + {0x1F634, 0x1F634, prExtendedPictographic}, // E1.0 [1] (😴) sleeping face + {0x1F635, 0x1F635, prExtendedPictographic}, // E0.6 [1] (😵) face with crossed-out eyes + {0x1F636, 0x1F636, prExtendedPictographic}, // E1.0 [1] (😶) face without mouth + {0x1F637, 0x1F640, prExtendedPictographic}, // E0.6 [10] (😷..🙀) face with medical mask..weary cat + {0x1F641, 0x1F644, prExtendedPictographic}, // E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes + {0x1F645, 0x1F64F, prExtendedPictographic}, // E0.6 [11] (🙅..🙏) person gesturing NO..folded hands + {0x1F680, 0x1F680, prExtendedPictographic}, // E0.6 [1] (🚀) rocket + {0x1F681, 0x1F682, prExtendedPictographic}, // E1.0 [2] (🚁..🚂) helicopter..locomotive + {0x1F683, 0x1F685, prExtendedPictographic}, // E0.6 [3] (🚃..🚅) railway car..bullet train + {0x1F686, 0x1F686, prExtendedPictographic}, // E1.0 [1] (🚆) train + {0x1F687, 0x1F687, prExtendedPictographic}, // E0.6 [1] (🚇) metro + {0x1F688, 0x1F688, prExtendedPictographic}, // E1.0 [1] (🚈) light rail + {0x1F689, 0x1F689, prExtendedPictographic}, // E0.6 [1] (🚉) station + {0x1F68A, 0x1F68B, prExtendedPictographic}, // E1.0 [2] (🚊..🚋) tram..tram car + {0x1F68C, 0x1F68C, prExtendedPictographic}, // E0.6 [1] (🚌) bus + {0x1F68D, 0x1F68D, prExtendedPictographic}, // E0.7 [1] (🚍) oncoming bus + {0x1F68E, 0x1F68E, prExtendedPictographic}, // E1.0 [1] (🚎) trolleybus + {0x1F68F, 0x1F68F, prExtendedPictographic}, // E0.6 [1] (🚏) bus stop + {0x1F690, 0x1F690, prExtendedPictographic}, // E1.0 [1] (🚐) minibus + {0x1F691, 0x1F693, prExtendedPictographic}, // E0.6 [3] (🚑..🚓) ambulance..police car + {0x1F694, 0x1F694, prExtendedPictographic}, // E0.7 [1] (🚔) oncoming police car + {0x1F695, 0x1F695, prExtendedPictographic}, // E0.6 [1] (🚕) taxi + {0x1F696, 0x1F696, prExtendedPictographic}, // E1.0 [1] (🚖) oncoming taxi + {0x1F697, 0x1F697, prExtendedPictographic}, // E0.6 [1] (🚗) automobile + {0x1F698, 0x1F698, prExtendedPictographic}, // E0.7 [1] (🚘) oncoming automobile + {0x1F699, 0x1F69A, prExtendedPictographic}, // E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck + {0x1F69B, 0x1F6A1, prExtendedPictographic}, // E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway + {0x1F6A2, 0x1F6A2, prExtendedPictographic}, // E0.6 [1] (🚢) ship + {0x1F6A3, 0x1F6A3, prExtendedPictographic}, // E1.0 [1] (🚣) person rowing boat + {0x1F6A4, 0x1F6A5, prExtendedPictographic}, // E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light + {0x1F6A6, 0x1F6A6, prExtendedPictographic}, // E1.0 [1] (🚦) vertical traffic light + {0x1F6A7, 0x1F6AD, prExtendedPictographic}, // E0.6 [7] (🚧..🚭) construction..no smoking + {0x1F6AE, 0x1F6B1, prExtendedPictographic}, // E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water + {0x1F6B2, 0x1F6B2, prExtendedPictographic}, // E0.6 [1] (🚲) bicycle + {0x1F6B3, 0x1F6B5, prExtendedPictographic}, // E1.0 [3] (🚳..🚵) no bicycles..person mountain biking + {0x1F6B6, 0x1F6B6, prExtendedPictographic}, // E0.6 [1] (🚶) person walking + {0x1F6B7, 0x1F6B8, prExtendedPictographic}, // E1.0 [2] (🚷..🚸) no pedestrians..children crossing + {0x1F6B9, 0x1F6BE, prExtendedPictographic}, // E0.6 [6] (🚹..🚾) men’s room..water closet + {0x1F6BF, 0x1F6BF, prExtendedPictographic}, // E1.0 [1] (🚿) shower + {0x1F6C0, 0x1F6C0, prExtendedPictographic}, // E0.6 [1] (🛀) person taking bath + {0x1F6C1, 0x1F6C5, prExtendedPictographic}, // E1.0 [5] (🛁..🛅) bathtub..left luggage + {0x1F6C6, 0x1F6CA, prExtendedPictographic}, // E0.0 [5] (🛆..🛊) TRIANGLE WITH ROUNDED CORNERS..GIRLS SYMBOL + {0x1F6CB, 0x1F6CB, prExtendedPictographic}, // E0.7 [1] (🛋️) couch and lamp + {0x1F6CC, 0x1F6CC, prExtendedPictographic}, // E1.0 [1] (🛌) person in bed + {0x1F6CD, 0x1F6CF, prExtendedPictographic}, // E0.7 [3] (🛍️..🛏️) shopping bags..bed + {0x1F6D0, 0x1F6D0, prExtendedPictographic}, // E1.0 [1] (🛐) place of worship + {0x1F6D1, 0x1F6D2, prExtendedPictographic}, // E3.0 [2] (🛑..🛒) stop sign..shopping cart + {0x1F6D3, 0x1F6D4, prExtendedPictographic}, // E0.0 [2] (🛓..🛔) STUPA..PAGODA + {0x1F6D5, 0x1F6D5, prExtendedPictographic}, // E12.0 [1] (🛕) hindu temple + {0x1F6D6, 0x1F6D7, prExtendedPictographic}, // E13.0 [2] (🛖..🛗) hut..elevator + {0x1F6D8, 0x1F6DB, prExtendedPictographic}, // E0.0 [4] (🛘..🛛) .. + {0x1F6DC, 0x1F6DC, prExtendedPictographic}, // E15.0 [1] (🛜) wireless + {0x1F6DD, 0x1F6DF, prExtendedPictographic}, // E14.0 [3] (🛝..🛟) playground slide..ring buoy + {0x1F6E0, 0x1F6E5, prExtendedPictographic}, // E0.7 [6] (🛠️..🛥️) hammer and wrench..motor boat + {0x1F6E6, 0x1F6E8, prExtendedPictographic}, // E0.0 [3] (🛦..🛨) UP-POINTING MILITARY AIRPLANE..UP-POINTING SMALL AIRPLANE + {0x1F6E9, 0x1F6E9, prExtendedPictographic}, // E0.7 [1] (🛩️) small airplane + {0x1F6EA, 0x1F6EA, prExtendedPictographic}, // E0.0 [1] (🛪) NORTHEAST-POINTING AIRPLANE + {0x1F6EB, 0x1F6EC, prExtendedPictographic}, // E1.0 [2] (🛫..🛬) airplane departure..airplane arrival + {0x1F6ED, 0x1F6EF, prExtendedPictographic}, // E0.0 [3] (🛭..🛯) .. + {0x1F6F0, 0x1F6F0, prExtendedPictographic}, // E0.7 [1] (🛰️) satellite + {0x1F6F1, 0x1F6F2, prExtendedPictographic}, // E0.0 [2] (🛱..🛲) ONCOMING FIRE ENGINE..DIESEL LOCOMOTIVE + {0x1F6F3, 0x1F6F3, prExtendedPictographic}, // E0.7 [1] (🛳️) passenger ship + {0x1F6F4, 0x1F6F6, prExtendedPictographic}, // E3.0 [3] (🛴..🛶) kick scooter..canoe + {0x1F6F7, 0x1F6F8, prExtendedPictographic}, // E5.0 [2] (🛷..🛸) sled..flying saucer + {0x1F6F9, 0x1F6F9, prExtendedPictographic}, // E11.0 [1] (🛹) skateboard + {0x1F6FA, 0x1F6FA, prExtendedPictographic}, // E12.0 [1] (🛺) auto rickshaw + {0x1F6FB, 0x1F6FC, prExtendedPictographic}, // E13.0 [2] (🛻..🛼) pickup truck..roller skate + {0x1F6FD, 0x1F6FF, prExtendedPictographic}, // E0.0 [3] (🛽..🛿) .. + {0x1F774, 0x1F77F, prExtendedPictographic}, // E0.0 [12] (🝴..🝿) LOT OF FORTUNE..ORCUS + {0x1F7D5, 0x1F7DF, prExtendedPictographic}, // E0.0 [11] (🟕..🟟) CIRCLED TRIANGLE.. + {0x1F7E0, 0x1F7EB, prExtendedPictographic}, // E12.0 [12] (🟠..🟫) orange circle..brown square + {0x1F7EC, 0x1F7EF, prExtendedPictographic}, // E0.0 [4] (🟬..🟯) .. + {0x1F7F0, 0x1F7F0, prExtendedPictographic}, // E14.0 [1] (🟰) heavy equals sign + {0x1F7F1, 0x1F7FF, prExtendedPictographic}, // E0.0 [15] (🟱..🟿) .. + {0x1F80C, 0x1F80F, prExtendedPictographic}, // E0.0 [4] (🠌..🠏) .. + {0x1F848, 0x1F84F, prExtendedPictographic}, // E0.0 [8] (🡈..🡏) .. + {0x1F85A, 0x1F85F, prExtendedPictographic}, // E0.0 [6] (🡚..🡟) .. + {0x1F888, 0x1F88F, prExtendedPictographic}, // E0.0 [8] (🢈..🢏) .. + {0x1F8AE, 0x1F8FF, prExtendedPictographic}, // E0.0 [82] (🢮..🣿) .. + {0x1F90C, 0x1F90C, prExtendedPictographic}, // E13.0 [1] (🤌) pinched fingers + {0x1F90D, 0x1F90F, prExtendedPictographic}, // E12.0 [3] (🤍..🤏) white heart..pinching hand + {0x1F910, 0x1F918, prExtendedPictographic}, // E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns + {0x1F919, 0x1F91E, prExtendedPictographic}, // E3.0 [6] (🤙..🤞) call me hand..crossed fingers + {0x1F91F, 0x1F91F, prExtendedPictographic}, // E5.0 [1] (🤟) love-you gesture + {0x1F920, 0x1F927, prExtendedPictographic}, // E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face + {0x1F928, 0x1F92F, prExtendedPictographic}, // E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head + {0x1F930, 0x1F930, prExtendedPictographic}, // E3.0 [1] (🤰) pregnant woman + {0x1F931, 0x1F932, prExtendedPictographic}, // E5.0 [2] (🤱..🤲) breast-feeding..palms up together + {0x1F933, 0x1F93A, prExtendedPictographic}, // E3.0 [8] (🤳..🤺) selfie..person fencing + {0x1F93C, 0x1F93E, prExtendedPictographic}, // E3.0 [3] (🤼..🤾) people wrestling..person playing handball + {0x1F93F, 0x1F93F, prExtendedPictographic}, // E12.0 [1] (🤿) diving mask + {0x1F940, 0x1F945, prExtendedPictographic}, // E3.0 [6] (🥀..🥅) wilted flower..goal net + {0x1F947, 0x1F94B, prExtendedPictographic}, // E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform + {0x1F94C, 0x1F94C, prExtendedPictographic}, // E5.0 [1] (🥌) curling stone + {0x1F94D, 0x1F94F, prExtendedPictographic}, // E11.0 [3] (🥍..🥏) lacrosse..flying disc + {0x1F950, 0x1F95E, prExtendedPictographic}, // E3.0 [15] (🥐..🥞) croissant..pancakes + {0x1F95F, 0x1F96B, prExtendedPictographic}, // E5.0 [13] (🥟..🥫) dumpling..canned food + {0x1F96C, 0x1F970, prExtendedPictographic}, // E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts + {0x1F971, 0x1F971, prExtendedPictographic}, // E12.0 [1] (🥱) yawning face + {0x1F972, 0x1F972, prExtendedPictographic}, // E13.0 [1] (🥲) smiling face with tear + {0x1F973, 0x1F976, prExtendedPictographic}, // E11.0 [4] (🥳..🥶) partying face..cold face + {0x1F977, 0x1F978, prExtendedPictographic}, // E13.0 [2] (🥷..🥸) ninja..disguised face + {0x1F979, 0x1F979, prExtendedPictographic}, // E14.0 [1] (🥹) face holding back tears + {0x1F97A, 0x1F97A, prExtendedPictographic}, // E11.0 [1] (🥺) pleading face + {0x1F97B, 0x1F97B, prExtendedPictographic}, // E12.0 [1] (🥻) sari + {0x1F97C, 0x1F97F, prExtendedPictographic}, // E11.0 [4] (🥼..🥿) lab coat..flat shoe + {0x1F980, 0x1F984, prExtendedPictographic}, // E1.0 [5] (🦀..🦄) crab..unicorn + {0x1F985, 0x1F991, prExtendedPictographic}, // E3.0 [13] (🦅..🦑) eagle..squid + {0x1F992, 0x1F997, prExtendedPictographic}, // E5.0 [6] (🦒..🦗) giraffe..cricket + {0x1F998, 0x1F9A2, prExtendedPictographic}, // E11.0 [11] (🦘..🦢) kangaroo..swan + {0x1F9A3, 0x1F9A4, prExtendedPictographic}, // E13.0 [2] (🦣..🦤) mammoth..dodo + {0x1F9A5, 0x1F9AA, prExtendedPictographic}, // E12.0 [6] (🦥..🦪) sloth..oyster + {0x1F9AB, 0x1F9AD, prExtendedPictographic}, // E13.0 [3] (🦫..🦭) beaver..seal + {0x1F9AE, 0x1F9AF, prExtendedPictographic}, // E12.0 [2] (🦮..🦯) guide dog..white cane + {0x1F9B0, 0x1F9B9, prExtendedPictographic}, // E11.0 [10] (🦰..🦹) red hair..supervillain + {0x1F9BA, 0x1F9BF, prExtendedPictographic}, // E12.0 [6] (🦺..🦿) safety vest..mechanical leg + {0x1F9C0, 0x1F9C0, prExtendedPictographic}, // E1.0 [1] (🧀) cheese wedge + {0x1F9C1, 0x1F9C2, prExtendedPictographic}, // E11.0 [2] (🧁..🧂) cupcake..salt + {0x1F9C3, 0x1F9CA, prExtendedPictographic}, // E12.0 [8] (🧃..🧊) beverage box..ice + {0x1F9CB, 0x1F9CB, prExtendedPictographic}, // E13.0 [1] (🧋) bubble tea + {0x1F9CC, 0x1F9CC, prExtendedPictographic}, // E14.0 [1] (🧌) troll + {0x1F9CD, 0x1F9CF, prExtendedPictographic}, // E12.0 [3] (🧍..🧏) person standing..deaf person + {0x1F9D0, 0x1F9E6, prExtendedPictographic}, // E5.0 [23] (🧐..🧦) face with monocle..socks + {0x1F9E7, 0x1F9FF, prExtendedPictographic}, // E11.0 [25] (🧧..🧿) red envelope..nazar amulet + {0x1FA00, 0x1FA6F, prExtendedPictographic}, // E0.0 [112] (🨀..🩯) NEUTRAL CHESS KING.. + {0x1FA70, 0x1FA73, prExtendedPictographic}, // E12.0 [4] (🩰..🩳) ballet shoes..shorts + {0x1FA74, 0x1FA74, prExtendedPictographic}, // E13.0 [1] (🩴) thong sandal + {0x1FA75, 0x1FA77, prExtendedPictographic}, // E15.0 [3] (🩵..🩷) light blue heart..pink heart + {0x1FA78, 0x1FA7A, prExtendedPictographic}, // E12.0 [3] (🩸..🩺) drop of blood..stethoscope + {0x1FA7B, 0x1FA7C, prExtendedPictographic}, // E14.0 [2] (🩻..🩼) x-ray..crutch + {0x1FA7D, 0x1FA7F, prExtendedPictographic}, // E0.0 [3] (🩽..🩿) .. + {0x1FA80, 0x1FA82, prExtendedPictographic}, // E12.0 [3] (🪀..🪂) yo-yo..parachute + {0x1FA83, 0x1FA86, prExtendedPictographic}, // E13.0 [4] (🪃..🪆) boomerang..nesting dolls + {0x1FA87, 0x1FA88, prExtendedPictographic}, // E15.0 [2] (🪇..🪈) maracas..flute + {0x1FA89, 0x1FA8F, prExtendedPictographic}, // E0.0 [7] (🪉..🪏) .. + {0x1FA90, 0x1FA95, prExtendedPictographic}, // E12.0 [6] (🪐..🪕) ringed planet..banjo + {0x1FA96, 0x1FAA8, prExtendedPictographic}, // E13.0 [19] (🪖..🪨) military helmet..rock + {0x1FAA9, 0x1FAAC, prExtendedPictographic}, // E14.0 [4] (🪩..🪬) mirror ball..hamsa + {0x1FAAD, 0x1FAAF, prExtendedPictographic}, // E15.0 [3] (🪭..🪯) folding hand fan..khanda + {0x1FAB0, 0x1FAB6, prExtendedPictographic}, // E13.0 [7] (🪰..🪶) fly..feather + {0x1FAB7, 0x1FABA, prExtendedPictographic}, // E14.0 [4] (🪷..🪺) lotus..nest with eggs + {0x1FABB, 0x1FABD, prExtendedPictographic}, // E15.0 [3] (🪻..🪽) hyacinth..wing + {0x1FABE, 0x1FABE, prExtendedPictographic}, // E0.0 [1] (🪾) + {0x1FABF, 0x1FABF, prExtendedPictographic}, // E15.0 [1] (🪿) goose + {0x1FAC0, 0x1FAC2, prExtendedPictographic}, // E13.0 [3] (🫀..🫂) anatomical heart..people hugging + {0x1FAC3, 0x1FAC5, prExtendedPictographic}, // E14.0 [3] (🫃..🫅) pregnant man..person with crown + {0x1FAC6, 0x1FACD, prExtendedPictographic}, // E0.0 [8] (🫆..🫍) .. + {0x1FACE, 0x1FACF, prExtendedPictographic}, // E15.0 [2] (🫎..🫏) moose..donkey + {0x1FAD0, 0x1FAD6, prExtendedPictographic}, // E13.0 [7] (🫐..🫖) blueberries..teapot + {0x1FAD7, 0x1FAD9, prExtendedPictographic}, // E14.0 [3] (🫗..🫙) pouring liquid..jar + {0x1FADA, 0x1FADB, prExtendedPictographic}, // E15.0 [2] (🫚..🫛) ginger root..pea pod + {0x1FADC, 0x1FADF, prExtendedPictographic}, // E0.0 [4] (🫜..🫟) .. + {0x1FAE0, 0x1FAE7, prExtendedPictographic}, // E14.0 [8] (🫠..🫧) melting face..bubbles + {0x1FAE8, 0x1FAE8, prExtendedPictographic}, // E15.0 [1] (🫨) shaking face + {0x1FAE9, 0x1FAEF, prExtendedPictographic}, // E0.0 [7] (🫩..🫯) .. + {0x1FAF0, 0x1FAF6, prExtendedPictographic}, // E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands + {0x1FAF7, 0x1FAF8, prExtendedPictographic}, // E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand + {0x1FAF9, 0x1FAFF, prExtendedPictographic}, // E0.0 [7] (🫹..🫿) .. + {0x1FBF0, 0x1FBF9, prNumeric}, // Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE + {0x1FC00, 0x1FFFD, prExtendedPictographic}, // E0.0[1022] (🰀..🿽) .. + {0xE0001, 0xE0001, prFormat}, // Cf LANGUAGE TAG + {0xE0020, 0xE007F, prExtend}, // Cf [96] TAG SPACE..CANCEL TAG + {0xE0100, 0xE01EF, prExtend}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 +} diff --git a/vendor/github.com/rivo/uniseg/wordrules.go b/vendor/github.com/rivo/uniseg/wordrules.go new file mode 100644 index 000000000..57a8c6831 --- /dev/null +++ b/vendor/github.com/rivo/uniseg/wordrules.go @@ -0,0 +1,282 @@ +package uniseg + +import "unicode/utf8" + +// The states of the word break parser. +const ( + wbAny = iota + wbCR + wbLF + wbNewline + wbWSegSpace + wbHebrewLetter + wbALetter + wbWB7 + wbWB7c + wbNumeric + wbWB11 + wbKatakana + wbExtendNumLet + wbOddRI + wbEvenRI + wbZWJBit = 16 // This bit is set for any states followed by at least one zero-width joiner (see WB4 and WB3c). +) + +// wbTransitions implements the word break parser's state transitions. It's +// anologous to [grTransitions], see comments there for details. +// +// Unicode version 15.0.0. +func wbTransitions(state, prop int) (newState int, wordBreak bool, rule int) { + switch uint64(state) | uint64(prop)<<32 { + // WB3b. + case wbAny | prNewline<<32: + return wbNewline, true, 32 + case wbAny | prCR<<32: + return wbCR, true, 32 + case wbAny | prLF<<32: + return wbLF, true, 32 + + // WB3a. + case wbNewline | prAny<<32: + return wbAny, true, 31 + case wbCR | prAny<<32: + return wbAny, true, 31 + case wbLF | prAny<<32: + return wbAny, true, 31 + + // WB3. + case wbCR | prLF<<32: + return wbLF, false, 30 + + // WB3d. + case wbAny | prWSegSpace<<32: + return wbWSegSpace, true, 9990 + case wbWSegSpace | prWSegSpace<<32: + return wbWSegSpace, false, 34 + + // WB5. + case wbAny | prALetter<<32: + return wbALetter, true, 9990 + case wbAny | prHebrewLetter<<32: + return wbHebrewLetter, true, 9990 + case wbALetter | prALetter<<32: + return wbALetter, false, 50 + case wbALetter | prHebrewLetter<<32: + return wbHebrewLetter, false, 50 + case wbHebrewLetter | prALetter<<32: + return wbALetter, false, 50 + case wbHebrewLetter | prHebrewLetter<<32: + return wbHebrewLetter, false, 50 + + // WB7. Transitions to wbWB7 handled by transitionWordBreakState(). + case wbWB7 | prALetter<<32: + return wbALetter, false, 70 + case wbWB7 | prHebrewLetter<<32: + return wbHebrewLetter, false, 70 + + // WB7a. + case wbHebrewLetter | prSingleQuote<<32: + return wbAny, false, 71 + + // WB7c. Transitions to wbWB7c handled by transitionWordBreakState(). + case wbWB7c | prHebrewLetter<<32: + return wbHebrewLetter, false, 73 + + // WB8. + case wbAny | prNumeric<<32: + return wbNumeric, true, 9990 + case wbNumeric | prNumeric<<32: + return wbNumeric, false, 80 + + // WB9. + case wbALetter | prNumeric<<32: + return wbNumeric, false, 90 + case wbHebrewLetter | prNumeric<<32: + return wbNumeric, false, 90 + + // WB10. + case wbNumeric | prALetter<<32: + return wbALetter, false, 100 + case wbNumeric | prHebrewLetter<<32: + return wbHebrewLetter, false, 100 + + // WB11. Transitions to wbWB11 handled by transitionWordBreakState(). + case wbWB11 | prNumeric<<32: + return wbNumeric, false, 110 + + // WB13. + case wbAny | prKatakana<<32: + return wbKatakana, true, 9990 + case wbKatakana | prKatakana<<32: + return wbKatakana, false, 130 + + // WB13a. + case wbAny | prExtendNumLet<<32: + return wbExtendNumLet, true, 9990 + case wbALetter | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + case wbHebrewLetter | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + case wbNumeric | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + case wbKatakana | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + case wbExtendNumLet | prExtendNumLet<<32: + return wbExtendNumLet, false, 131 + + // WB13b. + case wbExtendNumLet | prALetter<<32: + return wbALetter, false, 132 + case wbExtendNumLet | prHebrewLetter<<32: + return wbHebrewLetter, false, 132 + case wbExtendNumLet | prNumeric<<32: + return wbNumeric, false, 132 + case wbExtendNumLet | prKatakana<<32: + return wbKatakana, false, 132 + + default: + return -1, false, -1 + } +} + +// transitionWordBreakState determines the new state of the word break parser +// given the current state and the next code point. It also returns whether a +// word boundary was detected. If more than one code point is needed to +// determine the new state, the byte slice or the string starting after rune "r" +// can be used (whichever is not nil or empty) for further lookups. +func transitionWordBreakState(state int, r rune, b []byte, str string) (newState int, wordBreak bool) { + // Determine the property of the next character. + nextProperty := property(workBreakCodePoints, r) + + // "Replacing Ignore Rules". + if nextProperty == prZWJ { + // WB4 (for zero-width joiners). + if state == wbNewline || state == wbCR || state == wbLF { + return wbAny | wbZWJBit, true // Make sure we don't apply WB4 to WB3a. + } + if state < 0 { + return wbAny | wbZWJBit, false + } + return state | wbZWJBit, false + } else if nextProperty == prExtend || nextProperty == prFormat { + // WB4 (for Extend and Format). + if state == wbNewline || state == wbCR || state == wbLF { + return wbAny, true // Make sure we don't apply WB4 to WB3a. + } + if state == wbWSegSpace || state == wbAny|wbZWJBit { + return wbAny, false // We don't break but this is also not WB3d or WB3c. + } + if state < 0 { + return wbAny, false + } + return state, false + } else if nextProperty == prExtendedPictographic && state >= 0 && state&wbZWJBit != 0 { + // WB3c. + return wbAny, false + } + if state >= 0 { + state = state &^ wbZWJBit + } + + // Find the applicable transition in the table. + var rule int + newState, wordBreak, rule = wbTransitions(state, nextProperty) + if newState < 0 { + // No specific transition found. Try the less specific ones. + anyPropState, anyPropWordBreak, anyPropRule := wbTransitions(state, prAny) + anyStateState, anyStateWordBreak, anyStateRule := wbTransitions(wbAny, nextProperty) + if anyPropState >= 0 && anyStateState >= 0 { + // Both apply. We'll use a mix (see comments for grTransitions). + newState, wordBreak, rule = anyStateState, anyStateWordBreak, anyStateRule + if anyPropRule < anyStateRule { + wordBreak, rule = anyPropWordBreak, anyPropRule + } + } else if anyPropState >= 0 { + // We only have a specific state. + newState, wordBreak, rule = anyPropState, anyPropWordBreak, anyPropRule + // This branch will probably never be reached because okAnyState will + // always be true given the current transition map. But we keep it here + // for future modifications to the transition map where this may not be + // true anymore. + } else if anyStateState >= 0 { + // We only have a specific property. + newState, wordBreak, rule = anyStateState, anyStateWordBreak, anyStateRule + } else { + // No known transition. WB999: Any ÷ Any. + newState, wordBreak, rule = wbAny, true, 9990 + } + } + + // For those rules that need to look up runes further in the string, we + // determine the property after nextProperty, skipping over Format, Extend, + // and ZWJ (according to WB4). It's -1 if not needed, if such a rune cannot + // be determined (because the text ends or the rune is faulty). + farProperty := -1 + if rule > 60 && + (state == wbALetter || state == wbHebrewLetter || state == wbNumeric) && + (nextProperty == prMidLetter || nextProperty == prMidNumLet || nextProperty == prSingleQuote || // WB6. + nextProperty == prDoubleQuote || // WB7b. + nextProperty == prMidNum) { // WB12. + for { + var ( + r rune + length int + ) + if b != nil { // Byte slice version. + r, length = utf8.DecodeRune(b) + b = b[length:] + } else { // String version. + r, length = utf8.DecodeRuneInString(str) + str = str[length:] + } + if r == utf8.RuneError { + break + } + prop := property(workBreakCodePoints, r) + if prop == prExtend || prop == prFormat || prop == prZWJ { + continue + } + farProperty = prop + break + } + } + + // WB6. + if rule > 60 && + (state == wbALetter || state == wbHebrewLetter) && + (nextProperty == prMidLetter || nextProperty == prMidNumLet || nextProperty == prSingleQuote) && + (farProperty == prALetter || farProperty == prHebrewLetter) { + return wbWB7, false + } + + // WB7b. + if rule > 72 && + state == wbHebrewLetter && + nextProperty == prDoubleQuote && + farProperty == prHebrewLetter { + return wbWB7c, false + } + + // WB12. + if rule > 120 && + state == wbNumeric && + (nextProperty == prMidNum || nextProperty == prMidNumLet || nextProperty == prSingleQuote) && + farProperty == prNumeric { + return wbWB11, false + } + + // WB15 and WB16. + if newState == wbAny && nextProperty == prRegionalIndicator { + if state != wbOddRI && state != wbEvenRI { // Includes state == -1. + // Transition into the first RI. + return wbOddRI, true + } + if state == wbOddRI { + // Don't break pairs of Regional Indicators. + return wbEvenRI, false + } + return wbOddRI, true // We can break after a pair. + } + + return +} diff --git a/vendor/golang.org/x/crypto/hkdf/hkdf.go b/vendor/golang.org/x/crypto/hkdf/hkdf.go new file mode 100644 index 000000000..3bee66294 --- /dev/null +++ b/vendor/golang.org/x/crypto/hkdf/hkdf.go @@ -0,0 +1,95 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation +// Function (HKDF) as defined in RFC 5869. +// +// HKDF is a cryptographic key derivation function (KDF) with the goal of +// expanding limited input keying material into one or more cryptographically +// strong secret keys. +package hkdf + +import ( + "crypto/hmac" + "errors" + "hash" + "io" +) + +// Extract generates a pseudorandom key for use with Expand from an input secret +// and an optional independent salt. +// +// Only use this function if you need to reuse the extracted key with multiple +// Expand invocations and different context values. Most common scenarios, +// including the generation of multiple keys, should use New instead. +func Extract(hash func() hash.Hash, secret, salt []byte) []byte { + if salt == nil { + salt = make([]byte, hash().Size()) + } + extractor := hmac.New(hash, salt) + extractor.Write(secret) + return extractor.Sum(nil) +} + +type hkdf struct { + expander hash.Hash + size int + + info []byte + counter byte + + prev []byte + buf []byte +} + +func (f *hkdf) Read(p []byte) (int, error) { + // Check whether enough data can be generated + need := len(p) + remains := len(f.buf) + int(255-f.counter+1)*f.size + if remains < need { + return 0, errors.New("hkdf: entropy limit reached") + } + // Read any leftover from the buffer + n := copy(p, f.buf) + p = p[n:] + + // Fill the rest of the buffer + for len(p) > 0 { + if f.counter > 1 { + f.expander.Reset() + } + f.expander.Write(f.prev) + f.expander.Write(f.info) + f.expander.Write([]byte{f.counter}) + f.prev = f.expander.Sum(f.prev[:0]) + f.counter++ + + // Copy the new batch into p + f.buf = f.prev + n = copy(p, f.buf) + p = p[n:] + } + // Save leftovers for next run + f.buf = f.buf[n:] + + return need, nil +} + +// Expand returns a Reader, from which keys can be read, using the given +// pseudorandom key and optional context info, skipping the extraction step. +// +// The pseudorandomKey should have been generated by Extract, or be a uniformly +// random or pseudorandom cryptographically strong key. See RFC 5869, Section +// 3.3. Most common scenarios will want to use New instead. +func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader { + expander := hmac.New(hash, pseudorandomKey) + return &hkdf{expander, expander.Size(), info, 1, nil, nil} +} + +// New returns a Reader, from which keys can be read, using the given hash, +// secret, salt and context info. Salt and info can be nil. +func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader { + prk := Extract(hash, secret, salt) + return Expand(hash, prk, info) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index e155c29f3..030cc6f3a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -84,6 +84,9 @@ github.com/Masterminds/semver/v3 # github.com/Masterminds/sprig/v3 v3.2.3 ## explicit; go 1.13 github.com/Masterminds/sprig/v3 +# github.com/SherClockHolmes/webpush-go v1.3.0 +## explicit; go 1.13 +github.com/SherClockHolmes/webpush-go # github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 ## explicit; go 1.13 github.com/asaskevich/govalidator @@ -594,6 +597,9 @@ github.com/quasoft/memstore # github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec ## explicit; go 1.12 github.com/remyoudompheng/bigfft +# github.com/rivo/uniseg v0.4.7 +## explicit; go 1.18 +github.com/rivo/uniseg # github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a ## explicit; go 1.22.0 github.com/rogpeppe/go-internal/fmtsort @@ -1086,6 +1092,7 @@ golang.org/x/crypto/blowfish golang.org/x/crypto/chacha20 golang.org/x/crypto/curve25519 golang.org/x/crypto/ed25519 +golang.org/x/crypto/hkdf golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 golang.org/x/crypto/pbkdf2 From 3720251fcaf0362275aa71d5ff1efcbdcc226374 Mon Sep 17 00:00:00 2001 From: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:02:13 +0000 Subject: [PATCH 05/16] [feature] show status edits on frontend (#3678) * add 'edited-at' field to status info web template * make the edited-at text italic * small change in phrasing --- web/source/css/status.css | 6 +++++- web/template/status_info.tmpl | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/web/source/css/status.css b/web/source/css/status.css index 97713dae2..f08310921 100644 --- a/web/source/css/status.css +++ b/web/source/css/status.css @@ -436,6 +436,10 @@ main { display: flex; flex-wrap: wrap; column-gap: 1rem; + + .edited-at { + font-style: italic; + } } .stats-item { @@ -443,7 +447,7 @@ main { gap: 0.4rem; } - .stats-item:not(.published-at) { + .stats-item:not(.published-at):not(.edited-at) { z-index: 1; user-select: none; } diff --git a/web/template/status_info.tmpl b/web/template/status_info.tmpl index c5ba3ef35..366300071 100644 --- a/web/template/status_info.tmpl +++ b/web/template/status_info.tmpl @@ -26,6 +26,14 @@ + {{- if .EditedAt -}} +
+
Edited
+
+ (last edited ) +
+
+ {{ end }}
From 71b50353ebb9dd844dc6a04590d191123a332a58 Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:36:34 +0000 Subject: [PATCH 06/16] [feature] Process incoming Undo Announce properly (#3676) * [feature] Process incoming Undo Announce properly * test undo announce --- internal/federation/federatingdb/undo.go | 82 +++++++++++++++++++ internal/processing/workers/fromfediapi.go | 39 +++++++++ .../processing/workers/fromfediapi_test.go | 56 +++++++++++++ 3 files changed, 177 insertions(+) diff --git a/internal/federation/federatingdb/undo.go b/internal/federation/federatingdb/undo.go index b3e0a2825..42c934d44 100644 --- a/internal/federation/federatingdb/undo.go +++ b/internal/federation/federatingdb/undo.go @@ -29,6 +29,7 @@ "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/messages" ) func (f *federatingDB) Undo(ctx context.Context, undo vocab.ActivityStreamsUndo) error { @@ -89,6 +90,18 @@ func (f *federatingDB) Undo(ctx context.Context, undo vocab.ActivityStreamsUndo) return err } + // UNDO ANNOUNCE + case ap.ActivityAnnounce: + if err := f.undoAnnounce( + ctx, + receivingAcct, + requestingAcct, + undo, + asType, + ); err != nil { + return err + } + // UNHANDLED default: log.Debugf(ctx, "unhandled object type: %s", name) @@ -323,3 +336,72 @@ func (f *federatingDB) undoBlock( log.Debug(ctx, "Block undone") return nil } + +func (f *federatingDB) undoAnnounce( + ctx context.Context, + receivingAcct *gtsmodel.Account, + requestingAcct *gtsmodel.Account, + undo vocab.ActivityStreamsUndo, + t vocab.Type, +) error { + asAnnounce, ok := t.(vocab.ActivityStreamsAnnounce) + if !ok { + err := fmt.Errorf("%T not parseable as vocab.ActivityStreamsAnnounce", t) + return gtserror.SetMalformed(err) + } + + // Make sure the Undo actor owns the + // Announce they're trying to undo. + if !sameActor( + undo.GetActivityStreamsActor(), + asAnnounce.GetActivityStreamsActor(), + ) { + // Ignore this Activity. + return nil + } + + // Convert AS Announce to *gtsmodel.Status, + // retrieving origin account + target status. + boost, isNew, err := f.converter.ASAnnounceToStatus( + // Use barebones as we don't + // need to populate attachments + // on boosted status, mentions, etc. + gtscontext.SetBarebones(ctx), + asAnnounce, + ) + if err != nil && !errors.Is(err, db.ErrNoEntries) { + err := gtserror.Newf("error converting AS Announce to boost: %w", err) + return err + } + + if boost == nil { + // We were missing origin or + // target(s) for this Announce, + // so we cannot Undo anything. + return nil + } + + if isNew { + // We hadn't seen this boost + // before anyway, so there's + // nothing to Undo. + return nil + } + + // Ensure requester == announcer. + if boost.AccountID != requestingAcct.ID { + const text = "requestingAcct was not Block origin" + return gtserror.NewErrorForbidden(errors.New(text), text) + } + + // Looks valid. Process side effects asynchronously. + f.state.Workers.Federator.Queue.Push(&messages.FromFediAPI{ + APObjectType: ap.ActivityAnnounce, + APActivityType: ap.ActivityUndo, + GTSModel: boost, + Receiving: receivingAcct, + Requesting: requestingAcct, + }) + + return nil +} diff --git a/internal/processing/workers/fromfediapi.go b/internal/processing/workers/fromfediapi.go index 096e285f6..cf93a5ec5 100644 --- a/internal/processing/workers/fromfediapi.go +++ b/internal/processing/workers/fromfediapi.go @@ -189,6 +189,14 @@ func (p *Processor) ProcessFromFediAPI(ctx context.Context, fMsg *messages.FromF if fMsg.APObjectType == ap.ActorPerson { return p.fediAPI.MoveAccount(ctx, fMsg) } + + // UNDO SOMETHING + case ap.ActivityUndo: + + // UNDO ANNOUNCE + if fMsg.APObjectType == ap.ActivityAnnounce { + return p.fediAPI.UndoAnnounce(ctx, fMsg) + } } return gtserror.Newf("unhandled: %s %s", fMsg.APActivityType, fMsg.APObjectType) @@ -1159,3 +1167,34 @@ func (p *fediAPI) RejectAnnounce(ctx context.Context, fMsg *messages.FromFediAPI return nil } + +func (p *fediAPI) UndoAnnounce( + ctx context.Context, + fMsg *messages.FromFediAPI, +) error { + boost, ok := fMsg.GTSModel.(*gtsmodel.Status) + if !ok { + return gtserror.Newf("%T not parseable as *gtsmodel.Status", fMsg.GTSModel) + } + + // Delete the boost wrapper itself. + if err := p.state.DB.DeleteStatusByID(ctx, boost.ID); err != nil { + return gtserror.Newf("db error deleting boost: %w", err) + } + + // Update statuses count for the requesting account. + if err := p.utils.decrementStatusesCount(ctx, fMsg.Requesting, boost); err != nil { + log.Errorf(ctx, "error updating account stats: %v", err) + } + + // Remove the boost wrapper from all timelines. + if err := p.surface.deleteStatusFromTimelines(ctx, boost.ID); err != nil { + log.Errorf(ctx, "error removing timelined boost: %v", err) + } + + // Interaction counts changed on the boosted status; + // uncache the prepared version from all timelines. + p.surface.invalidateStatusFromTimelines(ctx, boost.BoostOfID) + + return nil +} diff --git a/internal/processing/workers/fromfediapi_test.go b/internal/processing/workers/fromfediapi_test.go index 70886d698..f3e719890 100644 --- a/internal/processing/workers/fromfediapi_test.go +++ b/internal/processing/workers/fromfediapi_test.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" + "errors" "fmt" "io" "testing" @@ -29,6 +30,7 @@ "github.com/superseriousbusiness/gotosocial/internal/ap" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/gtscontext" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/stream" @@ -679,6 +681,60 @@ func (suite *FromFediAPITestSuite) TestMoveAccount() { suite.WithinDuration(time.Now(), move.SucceededAt, 1*time.Minute) } +func (suite *FromFediAPITestSuite) TestUndoAnnounce() { + var ( + ctx = context.Background() + testStructs = testrig.SetupTestStructs(rMediaPath, rTemplatePath) + requestingAcct = suite.testAccounts["remote_account_1"] + receivingAcct = suite.testAccounts["local_account_1"] + boostedStatus = suite.testStatuses["admin_account_status_1"] + ) + defer testrig.TearDownTestStructs(testStructs) + + // Have remote_account_1 boost admin_account. + boost, err := testStructs.TypeConverter.StatusToBoost( + ctx, + boostedStatus, + requestingAcct, + "", + ) + if err != nil { + suite.FailNow(err.Error()) + } + + // Set the boost URI + URL to + // fossbros-anonymous.io. + boost.URI = "https://fossbros-anonymous.io/users/foss_satan/" + boost.ID + boost.URL = boost.URI + + // Store the boost. + if err := testStructs.State.DB.PutStatus(ctx, boost); err != nil { + suite.FailNow(err.Error()) + } + + // Process the Undo. + err = testStructs.Processor.Workers().ProcessFromFediAPI(ctx, &messages.FromFediAPI{ + APObjectType: ap.ActivityAnnounce, + APActivityType: ap.ActivityUndo, + GTSModel: boost, + Receiving: receivingAcct, + Requesting: requestingAcct, + }) + suite.NoError(err) + + // Wait for side effects to trigger: + // the boost should be deleted. + if !testrig.WaitFor(func() bool { + _, err := testStructs.State.DB.GetStatusByID( + gtscontext.SetBarebones(ctx), + boost.ID, + ) + return errors.Is(err, db.ErrNoEntries) + }) { + suite.FailNow("timed out waiting for boost to be removed") + } +} + func TestFromFederatorTestSuite(t *testing.T) { suite.Run(t, &FromFediAPITestSuite{}) } From 4c052c85f583a41b2c26428555552186284fe7a7 Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Fri, 24 Jan 2025 17:09:55 +0000 Subject: [PATCH 07/16] [bugfix] Rename domain perm sub migration to unique date (#3679) * [bugfix] Rename domain perm sub migration to unique date * add repeat migration --- ...112745_domain_permission_subscriptions.go} | 0 ...124164400_domain_perm_sub_migration_fix.go | 82 +++++++++++++++++++ 2 files changed, 82 insertions(+) rename internal/db/bundb/migrations/{20241022153016_domain_permission_subscriptions.go => 20250119112745_domain_permission_subscriptions.go} (100%) create mode 100644 internal/db/bundb/migrations/20250124164400_domain_perm_sub_migration_fix.go diff --git a/internal/db/bundb/migrations/20241022153016_domain_permission_subscriptions.go b/internal/db/bundb/migrations/20250119112745_domain_permission_subscriptions.go similarity index 100% rename from internal/db/bundb/migrations/20241022153016_domain_permission_subscriptions.go rename to internal/db/bundb/migrations/20250119112745_domain_permission_subscriptions.go diff --git a/internal/db/bundb/migrations/20250124164400_domain_perm_sub_migration_fix.go b/internal/db/bundb/migrations/20250124164400_domain_perm_sub_migration_fix.go new file mode 100644 index 000000000..5914c752a --- /dev/null +++ b/internal/db/bundb/migrations/20250124164400_domain_perm_sub_migration_fix.go @@ -0,0 +1,82 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package migrations + +import ( + "context" + + gtsmodel "github.com/superseriousbusiness/gotosocial/internal/db/bundb/migrations/20241022153016_domain_permission_subscriptions" + "github.com/uptrace/bun" +) + +// This file exists because tobi is a silly billy and named two migration files +// with the same date part, so the latter migration didn't always run properly. +// The file just repeats migrations in 20250119112745_domain_permission_subscriptions.go, +// which will be a noop in most cases, but will fix some issues for those who +// were running snapshots between GtS v0.17.0 and GtS v0.18.0. +// +// See https://github.com/superseriousbusiness/gotosocial/pull/3679. +func init() { + up := func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + // Create `domain_permission_subscriptions`. + if _, err := tx. + NewCreateTable(). + Model((*gtsmodel.DomainPermissionSubscription)(nil)). + IfNotExists(). + Exec(ctx); err != nil { + return err + } + + // Create indexes. Indices. Indie sexes. + if _, err := tx. + NewCreateIndex(). + Table("domain_permission_subscriptions"). + // Filter on permission type. + Index("domain_permission_subscriptions_permission_type_idx"). + Column("permission_type"). + IfNotExists(). + Exec(ctx); err != nil { + return err + } + + if _, err := tx. + NewCreateIndex(). + Table("domain_permission_subscriptions"). + // Sort by priority DESC. + Index("domain_permission_subscriptions_priority_order_idx"). + ColumnExpr("? DESC", bun.Ident("priority")). + IfNotExists(). + Exec(ctx); err != nil { + return err + } + + return nil + }) + } + + down := func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + return nil + }) + } + + if err := Migrations.Register(up, down); err != nil { + panic(err) + } +} From 3ab2d8621b9d6bca1739eec93fd8ce885185a5bc Mon Sep 17 00:00:00 2001 From: Vyr Cossont Date: Sun, 26 Jan 2025 00:51:28 -0800 Subject: [PATCH 08/16] [docs] Swagger: fix filter context params by moving enum list from the list type to the item type (#3684) Reported by `@modulus:matrix.org` --- docs/api/swagger.yaml | 48 ++++++++++---------- internal/api/client/filters/v1/filterpost.go | 12 ++--- internal/api/client/filters/v1/filterput.go | 12 ++--- internal/api/client/filters/v2/filterpost.go | 12 ++--- internal/api/client/filters/v2/filterput.go | 12 ++--- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/api/swagger.yaml b/docs/api/swagger.yaml index 5165f8c9e..d95825b6e 100644 --- a/docs/api/swagger.yaml +++ b/docs/api/swagger.yaml @@ -7954,14 +7954,14 @@ paths: The contexts in which the filter should be applied. Sample: home, public - enum: - - home - - notifications - - public - - thread - - account in: formData items: + enum: + - home + - notifications + - public + - thread + - account type: string minItems: 1 name: context[] @@ -8108,14 +8108,14 @@ paths: The contexts in which the filter should be applied. Sample: home, public - enum: - - home - - notifications - - public - - thread - - account in: formData items: + enum: + - home + - notifications + - public + - thread + - account type: string minItems: 1 name: context[] @@ -11835,14 +11835,14 @@ paths: The contexts in which the filter should be applied. Sample: home, public - enum: - - home - - notifications - - public - - thread - - account in: formData items: + enum: + - home + - notifications + - public + - thread + - account type: string minItems: 1 name: context[] @@ -12029,14 +12029,14 @@ paths: The contexts in which the filter should be applied. Sample: home, public - enum: - - home - - notifications - - public - - thread - - account in: formData items: + enum: + - home + - notifications + - public + - thread + - account type: string minItems: 1 name: context[] diff --git a/internal/api/client/filters/v1/filterpost.go b/internal/api/client/filters/v1/filterpost.go index 95a810f8b..a58f2273d 100644 --- a/internal/api/client/filters/v1/filterpost.go +++ b/internal/api/client/filters/v1/filterpost.go @@ -63,16 +63,16 @@ // The contexts in which the filter should be applied. // // Sample: home, public -// enum: -// - home -// - notifications -// - public -// - thread -// - account // type: array // items: // type: // string +// enum: +// - home +// - notifications +// - public +// - thread +// - account // collectionFormat: multi // minItems: 1 // uniqueItems: true diff --git a/internal/api/client/filters/v1/filterput.go b/internal/api/client/filters/v1/filterput.go index 60915624e..edaf8104d 100644 --- a/internal/api/client/filters/v1/filterput.go +++ b/internal/api/client/filters/v1/filterput.go @@ -69,16 +69,16 @@ // The contexts in which the filter should be applied. // // Sample: home, public -// enum: -// - home -// - notifications -// - public -// - thread -// - account // type: array // items: // type: // string +// enum: +// - home +// - notifications +// - public +// - thread +// - account // collectionFormat: multi // minItems: 1 // uniqueItems: true diff --git a/internal/api/client/filters/v2/filterpost.go b/internal/api/client/filters/v2/filterpost.go index ad6e83060..5e87df617 100644 --- a/internal/api/client/filters/v2/filterpost.go +++ b/internal/api/client/filters/v2/filterpost.go @@ -65,16 +65,16 @@ // The contexts in which the filter should be applied. // // Sample: home, public -// enum: -// - home -// - notifications -// - public -// - thread -// - account // type: array // items: // type: // string +// enum: +// - home +// - notifications +// - public +// - thread +// - account // collectionFormat: multi // minItems: 1 // uniqueItems: true diff --git a/internal/api/client/filters/v2/filterput.go b/internal/api/client/filters/v2/filterput.go index 9c1b56dd6..58d3f4a22 100644 --- a/internal/api/client/filters/v2/filterput.go +++ b/internal/api/client/filters/v2/filterput.go @@ -98,16 +98,16 @@ // The contexts in which the filter should be applied. // // Sample: home, public -// enum: -// - home -// - notifications -// - public -// - thread -// - account // type: array // items: // type: // string +// enum: +// - home +// - notifications +// - public +// - thread +// - account // collectionFormat: multi // minItems: 1 // uniqueItems: true From 2a466811473e22d132736506c716e649caf76371 Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Sun, 26 Jan 2025 12:21:57 +0100 Subject: [PATCH 09/16] [chore] Allow suppressing trusted-proxies warning by disabling rate limiting (#3686) --- docs/configuration/trusted_proxies.md | 10 +++++++++- internal/api/util/template.go | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/configuration/trusted_proxies.md b/docs/configuration/trusted_proxies.md index 6852e22e1..3f339fa1d 100644 --- a/docs/configuration/trusted_proxies.md +++ b/docs/configuration/trusted_proxies.md @@ -63,9 +63,17 @@ If you are using docker compose, your docker-compose.yaml file should look somet ################################ ``` -Once you have made the necessary configuration changes, restart your instance and refresh the home page. If the message is gone, then the problem is resolved! +Once you have made the necessary configuration changes, **restart your instance** and refresh the home page. + +If the message is gone, then the problem is resolved! If you still see the warning message but with a different suggested IP range to add to `trusted-proxies`, then follow the same steps as above again, including the new suggested IP range in your config in addition to the one you just added. !!! tip "Cloudflare IP Addresses" If you are running with a CDN/proxy such as Cloudflare in front of your GoToSocial instance (not recommended), then you may need to add one or more of the Cloudflare IP addresses to your `trusted-proxies` in order to have rate limiting work properly. You can find a list of Cloudflare IP addresses here: https://www.cloudflare.com/ips/ + +## I can't seem to get `trusted-proxies` configured properly, can I just disable the warning? + +There are some situations where it's not practically possible to get `trusted-proxies` configured correctly to detect the real client IP of incoming requests For example, if you're running GoToSocial behind a home internet router that cannot inject an `X-Forwarded-For` header, then your suggested entry to add to `trusted-proxies` will look something like `192.168.x.x`, but adding this to `trusted-proxies` won't resolve the issue. + +If you've tried everything, then you can disable the warning message by just turning off rate limiting entirely, ie., by setting `advanced-rate-limit-requests` to 0 in your config.yaml, or setting the environment variable `GTS_ADVANCED_RATE_LIMIT_REQUESTS` to 0. Don't forget to **restart your instance** after changing this setting. diff --git a/internal/api/util/template.go b/internal/api/util/template.go index fcfd80956..f58563660 100644 --- a/internal/api/util/template.go +++ b/internal/api/util/template.go @@ -23,6 +23,7 @@ "github.com/gin-gonic/gin" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/config" ) // WebPage encapsulates variables for @@ -96,6 +97,17 @@ func injectTrustedProxiesRec( c *gin.Context, obj map[string]any, ) { + if config.GetAdvancedRateLimitRequests() <= 0 { + // If rate limiting is disabled entirely + // there's no point in giving a trusted + // proxies rec, as proper clientIP is + // basically only used for rate limiting. + return + } + + // clientIP = the client IP that gin + // derives based on x-forwarded-for + // and current trusted proxies. clientIP := c.ClientIP() if clientIP == "127.0.0.1" { // Suggest precise 127.0.0.1/32. @@ -119,7 +131,9 @@ func injectTrustedProxiesRec( if !hasRemoteIPHeader { // Upstream hasn't set a - // remote IP header, bail. + // remote IP header so we're + // probably not in a reverse + // proxy setup, bail. return } From 5c96702cb5d9461b35c232858a3c91ab699dec7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:06:46 +0000 Subject: [PATCH 10/16] [chore]: Bump github.com/gin-contrib/gzip from 1.1.0 to 1.2.2 (#3693) Bumps [github.com/gin-contrib/gzip](https://github.com/gin-contrib/gzip) from 1.1.0 to 1.2.2. - [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.1.0...v1.2.2) --- updated-dependencies: - dependency-name: github.com/gin-contrib/gzip dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 17 +- go.sum | 35 +- .../github.com/bytedance/sonic/.codespellrc | 5 + vendor/github.com/bytedance/sonic/README.md | 11 +- vendor/github.com/bytedance/sonic/api.go | 4 +- .../bytedance/sonic/ast/api_compat.go | 2 +- .../github.com/bytedance/sonic/ast/decode.go | 2 +- .../bytedance/sonic/ast/iterator.go | 2 +- vendor/github.com/bytedance/sonic/ast/node.go | 22 +- .../bytedance/sonic/decoder/decoder_compat.go | 4 +- .../bytedance/sonic/decoder/decoder_native.go | 2 +- vendor/github.com/bytedance/sonic/go.work.sum | 2 + .../internal/decoder/api/decoder_arm64.go | 2 +- .../decoder/jitdec/assembler_regabi_amd64.go | 8 +- .../sonic/internal/decoder/jitdec/compiler.go | 2 +- .../sonic/internal/decoder/jitdec/pools.go | 4 +- .../sonic/internal/decoder/optdec/compiler.go | 4 +- .../sonic/internal/decoder/optdec/helper.go | 8 +- .../sonic/internal/decoder/optdec/native.go | 6 +- .../sonic/internal/decoder/optdec/node.go | 4 +- .../sonic/internal/encoder/alg/sort.go | 2 +- .../encoder/x86/assembler_regabi_amd64.go | 2 +- .../sonic/internal/optcaching/fcache.go | 6 +- .../bytedance/sonic/internal/rt/stubs.go | 2 +- .../bytedance/sonic/loader/funcdata_compat.go | 4 +- .../bytedance/sonic/loader/funcdata_go117.go | 4 +- .../bytedance/sonic/loader/funcdata_latest.go | 4 +- .../sonic/loader/internal/abi/abi_amd64.go | 377 +- .../loader/internal/abi/abi_legacy_amd64.go | 291 +- .../loader/internal/abi/abi_regabi_amd64.go | 431 +- .../sonic/loader/internal/iasm/expr/ast.go | 273 + .../loader/internal}/iasm/expr/errors.go | 26 +- .../sonic/loader/internal/iasm/expr/ops.go | 67 + .../sonic/loader/internal/iasm/expr/parser.go | 331 + .../sonic/loader/internal}/iasm/expr/pools.go | 20 +- .../sonic/loader/internal}/iasm/expr/term.go | 4 +- .../sonic/loader/internal}/iasm/expr/utils.go | 64 +- .../sonic/loader/internal/iasm/x86_64/arch.go | 251 + .../sonic/loader/internal}/iasm/x86_64/asm.s | 0 .../loader/internal}/iasm/x86_64/eface.go | 70 +- .../loader/internal/iasm/x86_64/encodings.go | 836 + .../internal/iasm/x86_64/instructions.go | 1077 + .../iasm/x86_64/instructions_table.go | 24 + .../loader/internal}/iasm/x86_64/operands.go | 0 .../loader/internal}/iasm/x86_64/pools.go | 0 .../loader/internal}/iasm/x86_64/program.go | 2 +- .../loader/internal/iasm/x86_64/registers.go | 747 + .../loader/internal/iasm/x86_64/utils.go | 147 + .../bytedance/sonic/option/option.go | 2 +- .../bytedance/sonic/unquote/unquote.go | 4 +- .../github.com/bytedance/sonic/utf8/utf8.go | 2 +- .../github.com/cloudwego/iasm/LICENSE-APACHE | 177 - vendor/github.com/cloudwego/iasm/expr/ast.go | 261 - vendor/github.com/cloudwego/iasm/expr/ops.go | 67 - .../github.com/cloudwego/iasm/expr/parser.go | 329 - .../github.com/cloudwego/iasm/x86_64/arch.go | 251 - .../cloudwego/iasm/x86_64/assembler.go | 1819 - .../cloudwego/iasm/x86_64/assembler_alias.go | 49 - .../cloudwego/iasm/x86_64/encodings.go | 691 - .../cloudwego/iasm/x86_64/instructions.go | 97210 ---------------- .../iasm/x86_64/instructions_table.go | 12307 -- .../cloudwego/iasm/x86_64/registers.go | 693 - .../github.com/cloudwego/iasm/x86_64/utils.go | 147 - .../mimetype/internal/magic/archive.go | 11 +- .../mimetype/internal/magic/zip.go | 19 + .../mimetype/supported_mimes.md | 3 +- .../gabriel-vasile/mimetype/tree.go | 7 +- vendor/github.com/gin-contrib/gzip/README.md | 41 +- vendor/github.com/gin-contrib/gzip/gzip.go | 28 + vendor/github.com/gin-contrib/gzip/handler.go | 90 +- vendor/github.com/gin-contrib/gzip/options.go | 208 +- .../github.com/gin-contrib/sse/.golangci.yml | 3 + .../gin-contrib/sse/.goreleaser.yaml | 29 + vendor/github.com/gin-contrib/sse/.travis.yml | 26 - vendor/github.com/gin-contrib/sse/README.md | 42 +- .../github.com/gin-contrib/sse/sse-encoder.go | 10 +- .../go-playground/validator/v10/README.md | 150 +- .../protobuf/internal/impl/message_opaque.go | 24 +- .../protobuf/internal/version/version.go | 2 +- vendor/modules.txt | 26 +- 80 files changed, 5055 insertions(+), 114881 deletions(-) create mode 100644 vendor/github.com/bytedance/sonic/.codespellrc create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ast.go rename vendor/github.com/{cloudwego => bytedance/sonic/loader/internal}/iasm/expr/errors.go (75%) create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ops.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/parser.go rename vendor/github.com/{cloudwego => bytedance/sonic/loader/internal}/iasm/expr/pools.go (76%) rename vendor/github.com/{cloudwego => bytedance/sonic/loader/internal}/iasm/expr/term.go (94%) rename vendor/github.com/{cloudwego => bytedance/sonic/loader/internal}/iasm/expr/utils.go (53%) create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/arch.go rename vendor/github.com/{cloudwego => bytedance/sonic/loader/internal}/iasm/x86_64/asm.s (100%) rename vendor/github.com/{cloudwego => bytedance/sonic/loader/internal}/iasm/x86_64/eface.go (52%) create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/encodings.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions_table.go rename vendor/github.com/{cloudwego => bytedance/sonic/loader/internal}/iasm/x86_64/operands.go (100%) rename vendor/github.com/{cloudwego => bytedance/sonic/loader/internal}/iasm/x86_64/pools.go (100%) rename vendor/github.com/{cloudwego => bytedance/sonic/loader/internal}/iasm/x86_64/program.go (99%) create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/registers.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/utils.go delete mode 100644 vendor/github.com/cloudwego/iasm/LICENSE-APACHE delete mode 100644 vendor/github.com/cloudwego/iasm/expr/ast.go delete mode 100644 vendor/github.com/cloudwego/iasm/expr/ops.go delete mode 100644 vendor/github.com/cloudwego/iasm/expr/parser.go delete mode 100644 vendor/github.com/cloudwego/iasm/x86_64/arch.go delete mode 100644 vendor/github.com/cloudwego/iasm/x86_64/assembler.go delete mode 100644 vendor/github.com/cloudwego/iasm/x86_64/assembler_alias.go delete mode 100644 vendor/github.com/cloudwego/iasm/x86_64/encodings.go delete mode 100644 vendor/github.com/cloudwego/iasm/x86_64/instructions.go delete mode 100644 vendor/github.com/cloudwego/iasm/x86_64/instructions_table.go delete mode 100644 vendor/github.com/cloudwego/iasm/x86_64/registers.go delete mode 100644 vendor/github.com/cloudwego/iasm/x86_64/utils.go create mode 100644 vendor/github.com/gin-contrib/sse/.golangci.yml create mode 100644 vendor/github.com/gin-contrib/sse/.goreleaser.yaml delete mode 100644 vendor/github.com/gin-contrib/sse/.travis.yml diff --git a/go.mod b/go.mod index d9bf90289..218e52273 100644 --- a/go.mod +++ b/go.mod @@ -48,7 +48,7 @@ require ( github.com/buckket/go-blurhash v1.1.0 github.com/coreos/go-oidc/v3 v3.12.0 github.com/gin-contrib/cors v1.7.3 - github.com/gin-contrib/gzip v1.1.0 + github.com/gin-contrib/gzip v1.2.2 github.com/gin-contrib/sessions v1.0.2 github.com/gin-gonic/gin v1.10.0 github.com/go-playground/form/v4 v4.2.1 @@ -114,13 +114,12 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bytedance/sonic v1.12.6 // indirect - github.com/bytedance/sonic/loader v0.2.1 // indirect + github.com/bytedance/sonic v1.12.7 // indirect + github.com/bytedance/sonic/loader v0.2.2 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cilium/ebpf v0.9.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect github.com/containerd/cgroups/v3 v3.0.1 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -133,8 +132,8 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.7 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.0.0 // indirect github.com/go-errors/errors v1.1.1 // indirect github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect @@ -154,7 +153,7 @@ require ( github.com/go-openapi/validate v0.24.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.23.0 // indirect + github.com/go-playground/validator/v10 v10.24.0 // indirect github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect github.com/goccy/go-json v0.10.4 // indirect github.com/godbus/dbus/v5 v5.0.4 // indirect @@ -230,7 +229,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/arch v0.12.0 // indirect + golang.org/x/arch v0.13.0 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/sync v0.10.0 // indirect @@ -239,7 +238,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/grpc v1.66.1 // indirect - google.golang.org/protobuf v1.36.1 // indirect + google.golang.org/protobuf v1.36.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect diff --git a/go.sum b/go.sum index a4b0e6cfa..769b0bee0 100644 --- a/go.sum +++ b/go.sum @@ -103,11 +103,11 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/buckket/go-blurhash v1.1.0 h1:X5M6r0LIvwdvKiUtiNcRL2YlmOfMzYobI3VCKCZc9Do= github.com/buckket/go-blurhash v1.1.0/go.mod h1:aT2iqo5W9vu9GpyoLErKfTHwgODsZp3bQfXjXJUxNb8= -github.com/bytedance/sonic v1.12.6 h1:/isNmCUF2x3Sh8RAp/4mh4ZGkcFAX/hLrzrK3AvpRzk= -github.com/bytedance/sonic v1.12.6/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q= +github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E= -github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.2 h1:jxAJuN9fOot/cyz5Q6dUuMJF5OqQ6+5GfA8FjjQ0R4o= +github.com/bytedance/sonic/loader v0.2.2/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -121,7 +121,6 @@ github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnx github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdknSRMDrAr8mfxPCfSZolH+/qQnyQ= @@ -175,18 +174,18 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor v1.5.1 h1:XjQWBgdmQyqimslUh5r4tUGmoqzHmBFQOImkWGi2awg= github.com/fxamacker/cbor v1.5.1/go.mod h1:3aPGItF174ni7dDzd6JZ206H8cmr4GDNBGpPa971zsU= -github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= -github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gin-contrib/cors v1.7.3 h1:hV+a5xp8hwJoTw7OY+a70FsL8JkVVFTXw9EcfrYUdns= github.com/gin-contrib/cors v1.7.3/go.mod h1:M3bcKZhxzsvI+rlRSkkxHyljJt1ESd93COUvemZ79j4= -github.com/gin-contrib/gzip v1.1.0 h1:kVw7Nr9M+Z6Ch4qo7aGMbiqxDeyQFru+07MgAcUF62M= -github.com/gin-contrib/gzip v1.1.0/go.mod h1:iHJXCup4CWiKyPUEl+GwkHjchl+YyYuMKbOCiXujPIA= +github.com/gin-contrib/gzip v1.2.2 h1:iUU/EYCM8ENfkjmZaVrxbjF/ZC267Iqv5S0MMCMEliI= +github.com/gin-contrib/gzip v1.2.2/go.mod h1:C1a5cacjlDsS20cKnHlZRCPUu57D3qH6B2pV0rl+Y/s= github.com/gin-contrib/sessions v1.0.2 h1:UaIjUvTH1cMeOdj3in6dl+Xb6It8RiKRF9Z1anbUyCA= github.com/gin-contrib/sessions v1.0.2/go.mod h1:KxKxWqWP5LJVDCInulOl4WbLzK2KSPlLesfZ66wRvMs= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= +github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -238,8 +237,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= -github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg= +github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= github.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= @@ -517,6 +516,7 @@ github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -526,6 +526,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -661,8 +662,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg= -golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA= +golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -959,8 +960,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= +google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/bytedance/sonic/.codespellrc b/vendor/github.com/bytedance/sonic/.codespellrc new file mode 100644 index 000000000..1ccef98d5 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/.codespellrc @@ -0,0 +1,5 @@ +[codespell] +# ignore test files, go project names, binary files via `skip` and special var/regex via `ignore-words` +skip = fuzz,*_test.tmpl,testdata,*_test.go,go.mod,go.sum,*.gz +ignore-words = .github/workflows/.ignore_words +check-filenames = true diff --git a/vendor/github.com/bytedance/sonic/README.md b/vendor/github.com/bytedance/sonic/README.md index 5f609b1c3..576c15bce 100644 --- a/vendor/github.com/bytedance/sonic/README.md +++ b/vendor/github.com/bytedance/sonic/README.md @@ -211,7 +211,7 @@ ret, err := Encode(v, EscapeHTML) // ret == `{"\u0026\u0026":{"X":"\u003c\u003e" ### Compact Format -Sonic encodes primitive objects (struct/map...) as compact-format JSON by default, except marshaling `json.RawMessage` or `json.Marshaler`: sonic ensures validating their output JSON but **DONOT** compacting them for performance concerns. We provide the option `encoder.CompactMarshaler` to add compacting process. +Sonic encodes primitive objects (struct/map...) as compact-format JSON by default, except marshaling `json.RawMessage` or `json.Marshaler`: sonic ensures validating their output JSON but **DO NOT** compacting them for performance concerns. We provide the option `encoder.CompactMarshaler` to add compacting process. ### Print Error @@ -480,9 +480,9 @@ But `ast.Visitor` is not a very handy API. You might need to write a lot of code ### Buffer Size -Sonic use memory pool in many places like `encoder.Encode`, `ast.Node.MarshalJSON` to improve performace, which may produce more memory usage (in-use) when server's load is high. See [issue 614](https://github.com/bytedance/sonic/issues/614). Therefore, we introduce some options to let user control the behavior of memory pool. See [option](https://pkg.go.dev/github.com/bytedance/sonic@v1.11.9/option#pkg-variables) package. +Sonic use memory pool in many places like `encoder.Encode`, `ast.Node.MarshalJSON` to improve performance, which may produce more memory usage (in-use) when server's load is high. See [issue 614](https://github.com/bytedance/sonic/issues/614). Therefore, we introduce some options to let user control the behavior of memory pool. See [option](https://pkg.go.dev/github.com/bytedance/sonic@v1.11.9/option#pkg-variables) package. -### Faster JSON skip +### Faster JSON Skip For security, sonic use [FSM](native/skip_one.c) algorithm to validate JSON when decoding raw JSON or encoding `json.Marshaler`, which is much slower (1~10x) than [SIMD-searching-pair](native/skip_one_fast.c) algorithm. If user has many redundant JSON value and DO NOT NEED to strictly validate JSON correctness, you can enable below options: @@ -490,6 +490,11 @@ For security, sonic use [FSM](native/skip_one.c) algorithm to validate JSON whe - `Config.NoValidateJSONMarshaler`: avoid validating JSON when encoding `json.Marshaler` - `SearchOption.ValidateJSON`: indicates if validate located JSON value when `Get` +## JSON-Path Support (GJSON) + +[tidwall/gjson](https://github.com/tidwall/gjson) has provided a comprehensive and popular JSON-Path API, and + a lot of older codes heavily relies on it. Therefore, we provides a wrapper library, which combines gjson's API with sonic's SIMD algorithm to boost up the performance. See [cloudwego/gjson](https://github.com/cloudwego/gjson). + ## Community Sonic is a subproject of [CloudWeGo](https://www.cloudwego.io/). We are committed to building a cloud native ecosystem. diff --git a/vendor/github.com/bytedance/sonic/api.go b/vendor/github.com/bytedance/sonic/api.go index af6be70a4..406715eca 100644 --- a/vendor/github.com/bytedance/sonic/api.go +++ b/vendor/github.com/bytedance/sonic/api.go @@ -77,7 +77,7 @@ type Config struct { // CopyString indicates decoder to decode string values by copying instead of referring. CopyString bool - // ValidateString indicates decoder and encoder to valid string values: decoder will return errors + // ValidateString indicates decoder and encoder to validate string values: decoder will return errors // when unescaped control chars(\u0000-\u001f) in the string value of JSON. ValidateString bool @@ -120,7 +120,7 @@ type Config struct { // API is a binding of specific config. // This interface is inspired by github.com/json-iterator/go, -// and has same behaviors under equavilent config. +// and has same behaviors under equivalent config. type API interface { // MarshalToString returns the JSON encoding string of v MarshalToString(v interface{}) (string, error) diff --git a/vendor/github.com/bytedance/sonic/ast/api_compat.go b/vendor/github.com/bytedance/sonic/ast/api_compat.go index a349afc0b..6541e219d 100644 --- a/vendor/github.com/bytedance/sonic/ast/api_compat.go +++ b/vendor/github.com/bytedance/sonic/ast/api_compat.go @@ -34,7 +34,7 @@ func quote(buf *[]byte, val string) { quoteString(buf, val) } -// unquote unescapes a internal JSON string (it doesn't count quotas at the begining and end) +// unquote unescapes an internal JSON string (it doesn't count quotas at the beginning and end) func unquote(src string) (string, types.ParsingError) { sp := rt.IndexChar(src, -1) out, ok := unquoteBytes(rt.BytesFrom(sp, len(src)+2, len(src)+2)) diff --git a/vendor/github.com/bytedance/sonic/ast/decode.go b/vendor/github.com/bytedance/sonic/ast/decode.go index 27aaf1408..135ee6eb8 100644 --- a/vendor/github.com/bytedance/sonic/ast/decode.go +++ b/vendor/github.com/bytedance/sonic/ast/decode.go @@ -27,7 +27,7 @@ "github.com/bytedance/sonic/internal/utils" ) -// Hack: this is used for both checking space and cause firendly compile errors in 32-bit arch. +// Hack: this is used for both checking space and cause friendly compile errors in 32-bit arch. const _Sonic_Not_Support_32Bit_Arch__Checking_32Bit_Arch_Here = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n') var bytesNull = []byte("null") diff --git a/vendor/github.com/bytedance/sonic/ast/iterator.go b/vendor/github.com/bytedance/sonic/ast/iterator.go index 076647154..1052dd0a0 100644 --- a/vendor/github.com/bytedance/sonic/ast/iterator.go +++ b/vendor/github.com/bytedance/sonic/ast/iterator.go @@ -173,7 +173,7 @@ func (s Sequence) String() string { // ForEach scans one V_OBJECT node's children from JSON head to tail, // and pass the Sequence and Node of corresponding JSON value. // -// Especailly, if the node is not V_ARRAY or V_OBJECT, +// Especially, if the node is not V_ARRAY or V_OBJECT, // the node itself will be returned and Sequence.Index == -1. // // NOTICE: A unsetted node WON'T trigger sc, but its index still counts into Path.Index diff --git a/vendor/github.com/bytedance/sonic/ast/node.go b/vendor/github.com/bytedance/sonic/ast/node.go index 0fbcf7835..2bb504850 100644 --- a/vendor/github.com/bytedance/sonic/ast/node.go +++ b/vendor/github.com/bytedance/sonic/ast/node.go @@ -140,7 +140,7 @@ func (self *Node) Check() error { // isRaw returns true if node's underlying value is raw json // -// Deprecated: not concurent safe +// Deprecated: not concurrent safe func (self Node) IsRaw() bool { return self.t & _V_RAW != 0 } @@ -440,7 +440,7 @@ func (self *Node) String() (string, error) { } } -// StrictString returns string value (unescaped), includeing V_STRING, V_ANY of string. +// StrictString returns string value (unescaped), including V_STRING, V_ANY of string. // In other cases, it will return empty string. func (self *Node) StrictString() (string, error) { if err := self.checkRaw(); err != nil { @@ -509,7 +509,7 @@ func (self *Node) Float64() (float64, error) { } } -// Float64 exports underlying float64 value, includeing V_NUMBER, V_ANY +// Float64 exports underlying float64 value, including V_NUMBER, V_ANY func (self *Node) StrictFloat64() (float64, error) { if err := self.checkRaw(); err != nil { return 0.0, err @@ -527,7 +527,7 @@ func (self *Node) StrictFloat64() (float64, error) { } } -/** Sequencial Value Methods **/ +/** Sequential Value Methods **/ // Len returns children count of a array|object|string node // WARN: For partially loaded node, it also works but only counts the parsed children @@ -611,7 +611,7 @@ func (self *Node) Unset(key string) (bool, error) { if err := self.should(types.V_OBJECT); err != nil { return false, err } - // NOTICE: must get acurate length before deduct + // NOTICE: must get accurate length before deduct if err := self.skipAllKey(); err != nil { return false, err } @@ -657,7 +657,7 @@ func (self *Node) SetAnyByIndex(index int, val interface{}) (bool, error) { return self.SetByIndex(index, NewAny(val)) } -// UnsetByIndex REOMVE (softly) the node of given index. +// UnsetByIndex REMOVE (softly) the node of given index. // // WARN: this will change address of elements, which is a dangerous action. // Use Unset() for object or Pop() for array instead. @@ -957,7 +957,7 @@ func (self *Node) MapUseNumber() (map[string]interface{}, error) { return self.toGenericObjectUseNumber() } -// MapUseNode scans both parsed and non-parsed chidren nodes, +// MapUseNode scans both parsed and non-parsed children nodes, // and map them by their keys func (self *Node) MapUseNode() (map[string]Node, error) { if self.isAny() { @@ -1102,7 +1102,7 @@ func (self *Node) ArrayUseNumber() ([]interface{}, error) { return self.toGenericArrayUseNumber() } -// ArrayUseNode copys both parsed and non-parsed chidren nodes, +// ArrayUseNode copies both parsed and non-parsed children nodes, // and indexes them by original order func (self *Node) ArrayUseNode() ([]Node, error) { if self.isAny() { @@ -1147,9 +1147,9 @@ func (self *Node) unsafeArray() (*linkedNodes, error) { return (*linkedNodes)(self.p), nil } -// Interface loads all children under all pathes from this node, +// Interface loads all children under all paths from this node, // and converts itself as generic type. -// WARN: all numberic nodes are casted to float64 +// WARN: all numeric nodes are casted to float64 func (self *Node) Interface() (interface{}, error) { if err := self.checkRaw(); err != nil { return nil, err @@ -1193,7 +1193,7 @@ func (self *Node) packAny() interface{} { } // InterfaceUseNumber works same with Interface() -// except numberic nodes are casted to json.Number +// except numeric nodes are casted to json.Number func (self *Node) InterfaceUseNumber() (interface{}, error) { if err := self.checkRaw(); err != nil { return nil, err diff --git a/vendor/github.com/bytedance/sonic/decoder/decoder_compat.go b/vendor/github.com/bytedance/sonic/decoder/decoder_compat.go index 81e1ae4e3..a0e1de4da 100644 --- a/vendor/github.com/bytedance/sonic/decoder/decoder_compat.go +++ b/vendor/github.com/bytedance/sonic/decoder/decoder_compat.go @@ -192,5 +192,5 @@ func (s SyntaxError) Error() string { return (*json.SyntaxError)(unsafe.Pointer(&s)).Error() } -// MismatchTypeError represents dismatching between json and object -type MismatchTypeError json.UnmarshalTypeError \ No newline at end of file +// MismatchTypeError represents mismatching between json and object +type MismatchTypeError json.UnmarshalTypeError diff --git a/vendor/github.com/bytedance/sonic/decoder/decoder_native.go b/vendor/github.com/bytedance/sonic/decoder/decoder_native.go index 9317d57f6..450dfb624 100644 --- a/vendor/github.com/bytedance/sonic/decoder/decoder_native.go +++ b/vendor/github.com/bytedance/sonic/decoder/decoder_native.go @@ -30,7 +30,7 @@ // SyntaxError represents json syntax error type SyntaxError = api.SyntaxError -// MismatchTypeError represents dismatching between json and object +// MismatchTypeError represents mismatching between json and object type MismatchTypeError = api.MismatchTypeError // Options for decode. diff --git a/vendor/github.com/bytedance/sonic/go.work.sum b/vendor/github.com/bytedance/sonic/go.work.sum index d59625879..b434dee51 100644 --- a/vendor/github.com/bytedance/sonic/go.work.sum +++ b/vendor/github.com/bytedance/sonic/go.work.sum @@ -1 +1,3 @@ github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.2/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/api/decoder_arm64.go b/vendor/github.com/bytedance/sonic/internal/decoder/api/decoder_arm64.go index 65a9478b4..16e55965a 100644 --- a/vendor/github.com/bytedance/sonic/internal/decoder/api/decoder_arm64.go +++ b/vendor/github.com/bytedance/sonic/internal/decoder/api/decoder_arm64.go @@ -30,7 +30,7 @@ func init() { - // whe in aarch64. we enable all optimize + // when in aarch64, we enable all optimization envs.EnableOptDec() envs.EnableFastMap() } diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/assembler_regabi_amd64.go b/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/assembler_regabi_amd64.go index 76eef333b..42b8b502f 100644 --- a/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/assembler_regabi_amd64.go +++ b/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/assembler_regabi_amd64.go @@ -67,7 +67,7 @@ */ const ( - _FP_args = 72 // 72 bytes to pass and spill register arguements + _FP_args = 72 // 72 bytes to pass and spill register arguments _FP_fargs = 80 // 80 bytes for passing arguments to other Go functions _FP_saves = 48 // 48 bytes for saving the registers before CALL instructions _FP_locals = 144 // 144 bytes for local variables @@ -203,9 +203,9 @@ var _VAR_fl = jit.Ptr(_SP, _FP_fargs + _FP_saves + 112) var ( - _VAR_et = jit.Ptr(_SP, _FP_fargs + _FP_saves + 120) // save dismatched type + _VAR_et = jit.Ptr(_SP, _FP_fargs + _FP_saves + 120) // save mismatched type _VAR_pc = jit.Ptr(_SP, _FP_fargs + _FP_saves + 128) // save skip return pc - _VAR_ic = jit.Ptr(_SP, _FP_fargs + _FP_saves + 136) // save dismatched position + _VAR_ic = jit.Ptr(_SP, _FP_fargs + _FP_saves + 136) // save mismatched position ) type _Assembler struct { @@ -1361,7 +1361,7 @@ func (self *_Assembler) _asm_OP_num(_ *_Instr) { self.Emit("MOVQ", _R9, _VAR_pc) self.Sjmp("JMP" , _LB_skip_one) - /* assgin string */ + /* assign string */ self.Link("_num_next_{n}") self.slice_from_r(_AX, 0) self.Emit("BTQ", jit.Imm(_F_copy_string), _ARG_fv) diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/compiler.go b/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/compiler.go index a097d171d..33191262a 100644 --- a/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/compiler.go +++ b/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/compiler.go @@ -736,7 +736,7 @@ func (self *_Compiler) compilePtr(p *_Program, sp int, et reflect.Type) { self.tab[et] = true /* not inline the pointer type - * recursing the defined pointer type's elem will casue issue379. + * recursing the defined pointer type's elem will cause issue379. */ self.compileOps(p, sp, et) } diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/pools.go b/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/pools.go index 01868cb2f..200af6a60 100644 --- a/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/pools.go +++ b/vendor/github.com/bytedance/sonic/internal/decoder/jitdec/pools.go @@ -63,8 +63,8 @@ type _Stack struct { vp unsafe.Pointer, sb *_Stack, fv uint64, - sv string, // DO NOT pass value to this arguement, since it is only used for local _VAR_sv - vk unsafe.Pointer, // DO NOT pass value to this arguement, since it is only used for local _VAR_vk + sv string, // DO NOT pass value to this argument, since it is only used for local _VAR_sv + vk unsafe.Pointer, // DO NOT pass value to this argument, since it is only used for local _VAR_vk ) (int, error) var _KeepAlive struct { diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go index fd164af93..7d9d60a01 100644 --- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go +++ b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/compiler.go @@ -177,7 +177,7 @@ func (c *compiler) compilePtr(vt reflect.Type) decFunc { c.enter(vt) defer c.exit(vt) - // specail logic for Named Ptr, issue 379 + // special logic for Named Ptr, issue 379 if reflect.PtrTo(vt.Elem()) != vt { c.namedPtr = true return &ptrDecoder{ @@ -432,7 +432,7 @@ func (c *compiler) tryCompilePtrUnmarshaler(vt reflect.Type, strOpt bool) decFun /* check for `encoding.TextMarshaler` with pointer receiver */ if pt.Implements(encodingTextUnmarshalerType) { - /* TextUnmarshal not support ,strig tag */ + /* TextUnmarshal not support, string tag */ if strOpt { panicForInvalidStrType(vt) } diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go index 7bf8a8f39..61faa6c80 100644 --- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go +++ b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/helper.go @@ -11,7 +11,7 @@ func SkipNumberFast(json string, start int) (int, bool) { - // find the number ending, we pasred in native, it alway valid + // find the number ending, we parsed in native, it always valid pos := start for pos < len(json) && json[pos] != ']' && json[pos] != '}' && json[pos] != ',' { if json[pos] >= '0' && json[pos] <= '9' || json[pos] == '.' || json[pos] == '-' || json[pos] == '+' || json[pos] == 'e' || json[pos] == 'E' { @@ -40,7 +40,7 @@ func ValidNumberFast(raw string) bool { return false } - // check trainling chars + // check trailing chars for ret < len(raw) { return false } @@ -49,7 +49,7 @@ func ValidNumberFast(raw string) bool { } func SkipOneFast2(json string, pos *int) (int, error) { - // find the number ending, we pasred in sonic-cpp, it alway valid + // find the number ending, we parsed in sonic-cpp, it always valid start := native.SkipOneFast(&json, pos) if start < 0 { return -1, error_syntax(*pos, json, types.ParsingError(-start).Error()) @@ -58,7 +58,7 @@ func SkipOneFast2(json string, pos *int) (int, error) { } func SkipOneFast(json string, pos int) (string, error) { - // find the number ending, we pasred in sonic-cpp, it alway valid + // find the number ending, we parsed in sonic-cpp, it always valid start := native.SkipOneFast(&json, &pos) if start < 0 { // TODO: details error code diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go index 29a0136ae..5dadec0b7 100644 --- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go +++ b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/native.go @@ -61,13 +61,13 @@ type node struct { val uint64 } -// should consitent with native/parser.c +// should consistent with native/parser.c type _nospaceBlock struct { _ [8]byte _ [8]byte } -// should consitent with native/parser.c +// should consistent with native/parser.c type nodeBuf struct { ncur uintptr parent int64 @@ -84,7 +84,7 @@ func (self *nodeBuf) init(nodes []node) { self.parent = -1 } -// should consitent with native/parser.c +// should consistent with native/parser.c type Parser struct { Json string padded []byte diff --git a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go index 3f60a3368..b23901e38 100644 --- a/vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go +++ b/vendor/github.com/bytedance/sonic/internal/decoder/optdec/node.go @@ -372,7 +372,7 @@ func (val Node) ParseF64(ctx *Context) (float64, bool) { } func (val Node) ParseString(ctx *Context) (string, bool) { - // shoud not use AsStrRef + // should not use AsStrRef s, ok := val.AsStr(ctx) if !ok { return "", false @@ -391,7 +391,7 @@ func (val Node) ParseString(ctx *Context) (string, bool) { func (val Node) ParseNumber(ctx *Context) (json.Number, bool) { - // shoud not use AsStrRef + // should not use AsStrRef s, ok := val.AsStr(ctx) if !ok { return json.Number(""), false diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/alg/sort.go b/vendor/github.com/bytedance/sonic/internal/encoder/alg/sort.go index 9b69bce9a..5bb0f9011 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/alg/sort.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/alg/sort.go @@ -46,7 +46,7 @@ func radixQsort(kvs []_MapPair, d, maxDepth int) { } // kvs[0:lt] < v = kvs[lt:gt] < kvs[gt:len(kvs)] - // Native implemention: + // Native implementation: // radixQsort(kvs[:lt], d, maxDepth) // if p > -1 { // radixQsort(kvs[lt:gt], d+1, maxDepth) diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go b/vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go index 95f452a02..c0912fb81 100644 --- a/vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go +++ b/vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go @@ -673,7 +673,7 @@ func (self *Assembler) encode_string(doubleQuote bool) { self.Sjmp("JMP", _LB_panic) self.Link("_str_next_{n}") - /* openning quote, check for double quote */ + /* opening quote, check for double quote */ if !doubleQuote { self.check_size_r(_AX, 2) // SIZE $2 self.add_char('"') // CHAR $'"' diff --git a/vendor/github.com/bytedance/sonic/internal/optcaching/fcache.go b/vendor/github.com/bytedance/sonic/internal/optcaching/fcache.go index afa7e7105..40b3e081f 100644 --- a/vendor/github.com/bytedance/sonic/internal/optcaching/fcache.go +++ b/vendor/github.com/bytedance/sonic/internal/optcaching/fcache.go @@ -84,7 +84,7 @@ func NewSmallFieldMap (hint int) *SmallFieldMap { func (self *SmallFieldMap) Set(fields []resolver.FieldMeta) { if len(fields) > 8 { - panic("small field map shoud use in small struct") + panic("small field map should use in small struct") } for i, f := range fields { @@ -254,7 +254,7 @@ type keysInfo struct { func (self *NormalFieldMap) Set(fields []resolver.FieldMeta) { if len(fields) <=8 || len(fields) > 128 { - panic("normal field map shoud use in small struct") + panic("normal field map should use in small struct") } // allocate the flat map in []byte @@ -278,7 +278,7 @@ func (self *NormalFieldMap) Set(fields []resolver.FieldMeta) { } - // add a padding size at last to make it firendly for SIMD. + // add a padding size at last to make it friendly for SIMD. self.keys = make([]byte, _HdrSize + 2 * kvLen, _HdrSize + 2 * kvLen + _PaddingSize) self.lowOffset = _HdrSize + kvLen diff --git a/vendor/github.com/bytedance/sonic/internal/rt/stubs.go b/vendor/github.com/bytedance/sonic/internal/rt/stubs.go index 5104a0793..1074f491b 100644 --- a/vendor/github.com/bytedance/sonic/internal/rt/stubs.go +++ b/vendor/github.com/bytedance/sonic/internal/rt/stubs.go @@ -153,7 +153,7 @@ func MakeSlice(oldPtr unsafe.Pointer, et *GoType, newLen int) *GoSlice { new := GrowSlice(et, *old, newLen) - // we sould clear the memory from [oldLen:newLen] + // we should clear the memory from [oldLen:newLen] if et.PtrData == 0 { oldlenmem := uintptr(old.Len) * et.Size newlenmem := uintptr(newLen) * et.Size diff --git a/vendor/github.com/bytedance/sonic/loader/funcdata_compat.go b/vendor/github.com/bytedance/sonic/loader/funcdata_compat.go index 17c840613..b4a24bcd6 100644 --- a/vendor/github.com/bytedance/sonic/loader/funcdata_compat.go +++ b/vendor/github.com/bytedance/sonic/loader/funcdata_compat.go @@ -329,7 +329,7 @@ funcs := *funcsp funcnametab, nameOffs := makeFuncnameTab(funcs) mod.funcnametab = funcnametab - // mmap() text and funcdata segements + // mmap() text and funcdata segments p := os.Getpagesize() size := int(rnd(int64(len(text)), int64(p))) addr := mmap(size) @@ -389,7 +389,7 @@ funcnameOffset: getOffsetOf(moduledata{}, "funcnametab"), pclnOffset: getOffsetOf(moduledata{}, "pclntable"), } - // sepecial case: gcdata and gcbss must by non-empty + // special case: gcdata and gcbss must by non-empty mod.gcdata = uintptr(unsafe.Pointer(&emptyByte)) mod.gcbss = uintptr(unsafe.Pointer(&emptyByte)) diff --git a/vendor/github.com/bytedance/sonic/loader/funcdata_go117.go b/vendor/github.com/bytedance/sonic/loader/funcdata_go117.go index 623283d09..1cae26898 100644 --- a/vendor/github.com/bytedance/sonic/loader/funcdata_go117.go +++ b/vendor/github.com/bytedance/sonic/loader/funcdata_go117.go @@ -330,7 +330,7 @@ funcs := *funcsp funcnametab, nameOffs := makeFuncnameTab(funcs) mod.funcnametab = funcnametab - // mmap() text and funcdata segements + // mmap() text and funcdata segments p := os.Getpagesize() size := int(rnd(int64(len(text)), int64(p))) addr := mmap(size) @@ -390,7 +390,7 @@ funcnameOffset: getOffsetOf(moduledata{}, "funcnametab"), pclnOffset: getOffsetOf(moduledata{}, "pclntable"), } - // sepecial case: gcdata and gcbss must by non-empty + // special case: gcdata and gcbss must by non-empty mod.gcdata = uintptr(unsafe.Pointer(&emptyByte)) mod.gcbss = uintptr(unsafe.Pointer(&emptyByte)) diff --git a/vendor/github.com/bytedance/sonic/loader/funcdata_latest.go b/vendor/github.com/bytedance/sonic/loader/funcdata_latest.go index b19fa6b7d..8b6018bdc 100644 --- a/vendor/github.com/bytedance/sonic/loader/funcdata_latest.go +++ b/vendor/github.com/bytedance/sonic/loader/funcdata_latest.go @@ -222,7 +222,7 @@ funcs := *funcsp funcnametab, nameOffs := makeFuncnameTab(funcs) mod.funcnametab = funcnametab - // mmap() text and funcdata segements + // mmap() text and funcdata segments p := os.Getpagesize() size := int(rnd(int64(len(text)), int64(p))) addr := mmap(size) @@ -283,7 +283,7 @@ funcnameOffset: getOffsetOf(moduledata{}, "funcnametab"), pclnOffset: getOffsetOf(moduledata{}, "pclntable"), } - // sepecial case: gcdata and gcbss must by non-empty + // special case: gcdata and gcbss must by non-empty mod.gcdata = uintptr(unsafe.Pointer(&emptyByte)) mod.gcbss = uintptr(unsafe.Pointer(&emptyByte)) diff --git a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go index c2b45a8e1..2969c3bba 100644 --- a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go @@ -17,266 +17,285 @@ package abi import ( - `fmt` - `reflect` - `unsafe` + "fmt" + "reflect" + "unsafe" - . `github.com/cloudwego/iasm/x86_64` + x64 "github.com/bytedance/sonic/loader/internal/iasm/x86_64" +) + +type ( + Register = x64.Register + Register64 = x64.Register64 + XMMRegister = x64.XMMRegister + Program = x64.Program + MemoryOperand = x64.MemoryOperand + Label = x64.Label +) + +var ( + Ptr = x64.Ptr + DefaultArch = x64.DefaultArch + CreateLabel = x64.CreateLabel ) const ( - PtrSize = 8 // pointer size - PtrAlign = 8 // pointer alignment + RAX = x64.RAX + RSP = x64.RSP + RBP = x64.RBP + R12 = x64.R12 + R14 = x64.R14 + R15 = x64.R15 +) + +const ( + PtrSize = 8 // pointer size + PtrAlign = 8 // pointer alignment ) var iregOrderC = []Register{ - RDI, - RSI, - RDX, - RCX, - R8, - R9, + x64.RDI, + x64.RSI, + x64.RDX, + x64.RCX, + x64.R8, + x64.R9, } var xregOrderC = []Register{ - XMM0, - XMM1, - XMM2, - XMM3, - XMM4, - XMM5, - XMM6, - XMM7, + x64.XMM0, + x64.XMM1, + x64.XMM2, + x64.XMM3, + x64.XMM4, + x64.XMM5, + x64.XMM6, + x64.XMM7, } var ( - intType = reflect.TypeOf(0) - ptrType = reflect.TypeOf(unsafe.Pointer(nil)) + intType = reflect.TypeOf(0) + ptrType = reflect.TypeOf(unsafe.Pointer(nil)) ) func (self *Frame) argv(i int) *MemoryOperand { - return Ptr(RSP, int32(self.Prev() + self.desc.Args[i].Mem)) + return Ptr(RSP, int32(self.Prev()+self.desc.Args[i].Mem)) } // spillv is used for growstack spill registers func (self *Frame) spillv(i int) *MemoryOperand { - // remain one slot for caller return pc - return Ptr(RSP, PtrSize + int32(self.desc.Args[i].Mem)) + // remain one slot for caller return pc + return Ptr(RSP, PtrSize+int32(self.desc.Args[i].Mem)) } func (self *Frame) retv(i int) *MemoryOperand { - return Ptr(RSP, int32(self.Prev() + self.desc.Rets[i].Mem)) + return Ptr(RSP, int32(self.Prev()+self.desc.Rets[i].Mem)) } func (self *Frame) resv(i int) *MemoryOperand { - return Ptr(RSP, int32(self.Offs() - uint32((i+1) * PtrSize))) + return Ptr(RSP, int32(self.Offs()-uint32((i+1)*PtrSize))) } func (self *Frame) emitGrowStack(p *Program, entry *Label) { - // spill all register arguments - for i, v := range self.desc.Args { - if v.InRegister { - if v.IsFloat == floatKind64 { - p.MOVSD(v.Reg, self.spillv(i)) - } else if v.IsFloat == floatKind32 { - p.MOVSS(v.Reg, self.spillv(i)) - }else { - p.MOVQ(v.Reg, self.spillv(i)) - } - } - } + // spill all register arguments + for i, v := range self.desc.Args { + if v.InRegister { + if v.IsFloat == floatKind64 { + p.MOVSD(v.Reg, self.spillv(i)) + } else if v.IsFloat == floatKind32 { + p.MOVSS(v.Reg, self.spillv(i)) + } else { + p.MOVQ(v.Reg, self.spillv(i)) + } + } + } - // call runtime.morestack_noctxt - p.MOVQ(F_morestack_noctxt, R12) - p.CALLQ(R12) - // load all register arguments - for i, v := range self.desc.Args { - if v.InRegister { - if v.IsFloat == floatKind64 { - p.MOVSD(self.spillv(i), v.Reg) - } else if v.IsFloat == floatKind32 { - p.MOVSS(self.spillv(i), v.Reg) - }else { - p.MOVQ(self.spillv(i), v.Reg) - } - } - } + // call runtime.morestack_noctxt + p.MOVQ(F_morestack_noctxt, R12) + p.CALLQ(R12) + // load all register arguments + for i, v := range self.desc.Args { + if v.InRegister { + if v.IsFloat == floatKind64 { + p.MOVSD(self.spillv(i), v.Reg) + } else if v.IsFloat == floatKind32 { + p.MOVSS(self.spillv(i), v.Reg) + } else { + p.MOVQ(self.spillv(i), v.Reg) + } + } + } - // jump back to the function entry - p.JMP(entry) + // jump back to the function entry + p.JMP(entry) } func (self *Frame) GrowStackTextSize() uint32 { - p := DefaultArch.CreateProgram() - // spill all register arguments - for i, v := range self.desc.Args { - if v.InRegister { - if v.IsFloat == floatKind64 { - p.MOVSD(v.Reg, self.spillv(i)) - } else if v.IsFloat == floatKind32 { - p.MOVSS(v.Reg, self.spillv(i)) - }else { - p.MOVQ(v.Reg, self.spillv(i)) - } - } - } + p := DefaultArch.CreateProgram() + // spill all register arguments + for i, v := range self.desc.Args { + if v.InRegister { + if v.IsFloat == floatKind64 { + p.MOVSD(v.Reg, self.spillv(i)) + } else if v.IsFloat == floatKind32 { + p.MOVSS(v.Reg, self.spillv(i)) + } else { + p.MOVQ(v.Reg, self.spillv(i)) + } + } + } - // call runtime.morestack_noctxt - p.MOVQ(F_morestack_noctxt, R12) - p.CALLQ(R12) - // load all register arguments - for i, v := range self.desc.Args { - if v.InRegister { - if v.IsFloat == floatKind64 { - p.MOVSD(self.spillv(i), v.Reg) - } else if v.IsFloat == floatKind32 { - p.MOVSS(self.spillv(i), v.Reg) - } else { - p.MOVQ(self.spillv(i), v.Reg) - } - } - } + // call runtime.morestack_noctxt + p.MOVQ(F_morestack_noctxt, R12) + p.CALLQ(R12) + // load all register arguments + for i, v := range self.desc.Args { + if v.InRegister { + if v.IsFloat == floatKind64 { + p.MOVSD(self.spillv(i), v.Reg) + } else if v.IsFloat == floatKind32 { + p.MOVSS(self.spillv(i), v.Reg) + } else { + p.MOVQ(self.spillv(i), v.Reg) + } + } + } - // jump back to the function entry - l := CreateLabel("") - p.Link(l) - p.JMP(l) + // jump back to the function entry + l := CreateLabel("") + p.Link(l) + p.JMP(l) - return uint32(len(p.Assemble(0))) + return uint32(len(p.Assemble(0))) } func (self *Frame) emitPrologue(p *Program) { - p.SUBQ(self.Size(), RSP) - p.MOVQ(RBP, Ptr(RSP, int32(self.Offs()))) - p.LEAQ(Ptr(RSP, int32(self.Offs())), RBP) + p.SUBQ(self.Size(), RSP) + p.MOVQ(RBP, Ptr(RSP, int32(self.Offs()))) + p.LEAQ(Ptr(RSP, int32(self.Offs())), RBP) } func (self *Frame) emitEpilogue(p *Program) { - p.MOVQ(Ptr(RSP, int32(self.Offs())), RBP) - p.ADDQ(self.Size(), RSP) - p.RET() + p.MOVQ(Ptr(RSP, int32(self.Offs())), RBP) + p.ADDQ(self.Size(), RSP) + p.RET() } func (self *Frame) emitReserveRegs(p *Program) { - // spill reserved registers - for i, r := range ReservedRegs(self.ccall) { - switch r.(type) { - case Register64: - p.MOVQ(r, self.resv(i)) - case XMMRegister: - p.MOVSD(r, self.resv(i)) - default: - panic(fmt.Sprintf("unsupported register type %t to reserve", r)) - } - } + // spill reserved registers + for i, r := range ReservedRegs(self.ccall) { + switch r.(type) { + case Register64: + p.MOVQ(r, self.resv(i)) + case XMMRegister: + p.MOVSD(r, self.resv(i)) + default: + panic(fmt.Sprintf("unsupported register type %t to reserve", r)) + } + } } func (self *Frame) emitSpillPtrs(p *Program) { - // spill pointer argument registers - for i, r := range self.desc.Args { - if r.InRegister && r.IsPointer { - p.MOVQ(r.Reg, self.argv(i)) - } - } + // spill pointer argument registers + for i, r := range self.desc.Args { + if r.InRegister && r.IsPointer { + p.MOVQ(r.Reg, self.argv(i)) + } + } } func (self *Frame) emitClearPtrs(p *Program) { - // spill pointer argument registers - for i, r := range self.desc.Args { - if r.InRegister && r.IsPointer { - p.MOVQ(int64(0), self.argv(i)) - } - } + // spill pointer argument registers + for i, r := range self.desc.Args { + if r.InRegister && r.IsPointer { + p.MOVQ(int64(0), self.argv(i)) + } + } } func (self *Frame) emitCallC(p *Program, addr uintptr) { - p.MOVQ(addr, RAX) - p.CALLQ(RAX) + p.MOVQ(addr, RAX) + p.CALLQ(RAX) } type floatKind uint8 const ( - notFloatKind floatKind = iota - floatKind32 - floatKind64 + notFloatKind floatKind = iota + floatKind32 + floatKind64 ) type Parameter struct { - InRegister bool - IsPointer bool - IsFloat floatKind - Reg Register - Mem uint32 - Type reflect.Type + InRegister bool + IsPointer bool + IsFloat floatKind + Reg Register + Mem uint32 + Type reflect.Type } func mkIReg(vt reflect.Type, reg Register64) (p Parameter) { - p.Reg = reg - p.Type = vt - p.InRegister = true - p.IsPointer = isPointer(vt) - return + p.Reg = reg + p.Type = vt + p.InRegister = true + p.IsPointer = isPointer(vt) + return } func isFloat(vt reflect.Type) floatKind { - switch vt.Kind() { - case reflect.Float32: - return floatKind32 - case reflect.Float64: - return floatKind64 - default: - return notFloatKind - } + switch vt.Kind() { + case reflect.Float32: + return floatKind32 + case reflect.Float64: + return floatKind64 + default: + return notFloatKind + } } func mkXReg(vt reflect.Type, reg XMMRegister) (p Parameter) { - p.Reg = reg - p.Type = vt - p.InRegister = true - p.IsFloat = isFloat(vt) - return + p.Reg = reg + p.Type = vt + p.InRegister = true + p.IsFloat = isFloat(vt) + return } func mkStack(vt reflect.Type, mem uint32) (p Parameter) { - p.Mem = mem - p.Type = vt - p.InRegister = false - p.IsPointer = isPointer(vt) - p.IsFloat = isFloat(vt) - return + p.Mem = mem + p.Type = vt + p.InRegister = false + p.IsPointer = isPointer(vt) + p.IsFloat = isFloat(vt) + return } func (self Parameter) String() string { - if self.InRegister { - return fmt.Sprintf("[%%%s, Pointer(%v), Float(%v)]", self.Reg, self.IsPointer, self.IsFloat) - } else { - return fmt.Sprintf("[%d(FP), Pointer(%v), Float(%v)]", self.Mem, self.IsPointer, self.IsFloat) - } + if self.InRegister { + return fmt.Sprintf("[%%%s, Pointer(%v), Float(%v)]", self.Reg, self.IsPointer, self.IsFloat) + } else { + return fmt.Sprintf("[%d(FP), Pointer(%v), Float(%v)]", self.Mem, self.IsPointer, self.IsFloat) + } } func CallC(addr uintptr, fr Frame, maxStack uintptr) []byte { - p := DefaultArch.CreateProgram() + p := DefaultArch.CreateProgram() - stack := CreateLabel("_stack_grow") - entry := CreateLabel("_entry") - p.Link(entry) - fr.emitStackCheck(p, stack, maxStack) - fr.emitPrologue(p) - fr.emitReserveRegs(p) - fr.emitSpillPtrs(p) - fr.emitExchangeArgs(p) - fr.emitCallC(p, addr) - fr.emitExchangeRets(p) - fr.emitRestoreRegs(p) - fr.emitEpilogue(p) - p.Link(stack) - fr.emitGrowStack(p, entry) + stack := CreateLabel("_stack_grow") + entry := CreateLabel("_entry") + p.Link(entry) + fr.emitStackCheck(p, stack, maxStack) + fr.emitPrologue(p) + fr.emitReserveRegs(p) + fr.emitSpillPtrs(p) + fr.emitExchangeArgs(p) + fr.emitCallC(p, addr) + fr.emitExchangeRets(p) + fr.emitRestoreRegs(p) + fr.emitEpilogue(p) + p.Link(stack) + fr.emitGrowStack(p, entry) - return p.Assemble(0) + return p.Assemble(0) } - - -func (self *Frame) emitDebug(p *Program) { - p.INT(3) -} \ No newline at end of file diff --git a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go index 298c48178..722c0696f 100644 --- a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go @@ -20,163 +20,196 @@ package abi import ( - `fmt` - `reflect` - `runtime` - - . `github.com/cloudwego/iasm/x86_64` + "fmt" + "reflect" + "runtime" ) func ReservedRegs(callc bool) []Register { - return nil + return nil } func salloc(p []Parameter, sp uint32, vt reflect.Type) (uint32, []Parameter) { - switch vt.Kind() { - case reflect.Bool : return sp + 8, append(p, mkStack(reflect.TypeOf(false), sp)) - case reflect.Int : return sp + 8, append(p, mkStack(intType, sp)) - case reflect.Int8 : return sp + 8, append(p, mkStack(reflect.TypeOf(int8(0)), sp)) - case reflect.Int16 : return sp + 8, append(p, mkStack(reflect.TypeOf(int16(0)), sp)) - case reflect.Int32 : return sp + 8, append(p, mkStack(reflect.TypeOf(int32(0)), sp)) - case reflect.Int64 : return sp + 8, append(p, mkStack(reflect.TypeOf(int64(0)), sp)) - case reflect.Uint : return sp + 8, append(p, mkStack(reflect.TypeOf(uint(0)), sp)) - case reflect.Uint8 : return sp + 8, append(p, mkStack(reflect.TypeOf(uint8(0)), sp)) - case reflect.Uint16 : return sp + 8, append(p, mkStack(reflect.TypeOf(uint16(0)), sp)) - case reflect.Uint32 : return sp + 8, append(p, mkStack(reflect.TypeOf(uint32(0)), sp)) - case reflect.Uint64 : return sp + 8, append(p, mkStack(reflect.TypeOf(uint64(0)), sp)) - case reflect.Uintptr : return sp + 8, append(p, mkStack(reflect.TypeOf(uintptr(0)), sp)) - case reflect.Float32 : return sp + 8, append(p, mkStack(reflect.TypeOf(float32(0)), sp)) - case reflect.Float64 : return sp + 8, append(p, mkStack(reflect.TypeOf(float64(0)), sp)) - case reflect.Complex64 : panic("abi: go116: not implemented: complex64") - case reflect.Complex128 : panic("abi: go116: not implemented: complex128") - case reflect.Array : panic("abi: go116: not implemented: arrays") - case reflect.Chan : return sp + 8, append(p, mkStack(reflect.TypeOf((chan int)(nil)), sp)) - case reflect.Func : return sp + 8, append(p, mkStack(reflect.TypeOf((func())(nil)), sp)) - case reflect.Map : return sp + 8, append(p, mkStack(reflect.TypeOf((map[int]int)(nil)), sp)) - case reflect.Ptr : return sp + 8, append(p, mkStack(reflect.TypeOf((*int)(nil)), sp)) - case reflect.UnsafePointer : return sp + 8, append(p, mkStack(ptrType, sp)) - case reflect.Interface : return sp + 16, append(p, mkStack(ptrType, sp), mkStack(ptrType, sp + 8)) - case reflect.Slice : return sp + 24, append(p, mkStack(ptrType, sp), mkStack(intType, sp + 8), mkStack(intType, sp + 16)) - case reflect.String : return sp + 16, append(p, mkStack(ptrType, sp), mkStack(intType, sp + 8)) - case reflect.Struct : panic("abi: go116: not implemented: structs") - default : panic("abi: invalid value type") - } + switch vt.Kind() { + case reflect.Bool: + return sp + 8, append(p, mkStack(reflect.TypeOf(false), sp)) + case reflect.Int: + return sp + 8, append(p, mkStack(intType, sp)) + case reflect.Int8: + return sp + 8, append(p, mkStack(reflect.TypeOf(int8(0)), sp)) + case reflect.Int16: + return sp + 8, append(p, mkStack(reflect.TypeOf(int16(0)), sp)) + case reflect.Int32: + return sp + 8, append(p, mkStack(reflect.TypeOf(int32(0)), sp)) + case reflect.Int64: + return sp + 8, append(p, mkStack(reflect.TypeOf(int64(0)), sp)) + case reflect.Uint: + return sp + 8, append(p, mkStack(reflect.TypeOf(uint(0)), sp)) + case reflect.Uint8: + return sp + 8, append(p, mkStack(reflect.TypeOf(uint8(0)), sp)) + case reflect.Uint16: + return sp + 8, append(p, mkStack(reflect.TypeOf(uint16(0)), sp)) + case reflect.Uint32: + return sp + 8, append(p, mkStack(reflect.TypeOf(uint32(0)), sp)) + case reflect.Uint64: + return sp + 8, append(p, mkStack(reflect.TypeOf(uint64(0)), sp)) + case reflect.Uintptr: + return sp + 8, append(p, mkStack(reflect.TypeOf(uintptr(0)), sp)) + case reflect.Float32: + return sp + 8, append(p, mkStack(reflect.TypeOf(float32(0)), sp)) + case reflect.Float64: + return sp + 8, append(p, mkStack(reflect.TypeOf(float64(0)), sp)) + case reflect.Complex64: + panic("abi: go116: not implemented: complex64") + case reflect.Complex128: + panic("abi: go116: not implemented: complex128") + case reflect.Array: + panic("abi: go116: not implemented: arrays") + case reflect.Chan: + return sp + 8, append(p, mkStack(reflect.TypeOf((chan int)(nil)), sp)) + case reflect.Func: + return sp + 8, append(p, mkStack(reflect.TypeOf((func())(nil)), sp)) + case reflect.Map: + return sp + 8, append(p, mkStack(reflect.TypeOf((map[int]int)(nil)), sp)) + case reflect.Ptr: + return sp + 8, append(p, mkStack(reflect.TypeOf((*int)(nil)), sp)) + case reflect.UnsafePointer: + return sp + 8, append(p, mkStack(ptrType, sp)) + case reflect.Interface: + return sp + 16, append(p, mkStack(ptrType, sp), mkStack(ptrType, sp+8)) + case reflect.Slice: + return sp + 24, append(p, mkStack(ptrType, sp), mkStack(intType, sp+8), mkStack(intType, sp+16)) + case reflect.String: + return sp + 16, append(p, mkStack(ptrType, sp), mkStack(intType, sp+8)) + case reflect.Struct: + panic("abi: go116: not implemented: structs") + default: + panic("abi: invalid value type") + } } func NewFunctionLayout(ft reflect.Type) FunctionLayout { - var sp uint32 - var fn FunctionLayout + var sp uint32 + var fn FunctionLayout - /* assign every arguments */ - for i := 0; i < ft.NumIn(); i++ { - sp, fn.Args = salloc(fn.Args, sp, ft.In(i)) - } + /* assign every arguments */ + for i := 0; i < ft.NumIn(); i++ { + sp, fn.Args = salloc(fn.Args, sp, ft.In(i)) + } - /* assign every return value */ - for i := 0; i < ft.NumOut(); i++ { - sp, fn.Rets = salloc(fn.Rets, sp, ft.Out(i)) - } + /* assign every return value */ + for i := 0; i < ft.NumOut(); i++ { + sp, fn.Rets = salloc(fn.Rets, sp, ft.Out(i)) + } - /* update function ID and stack pointer */ - fn.FP = sp - return fn + /* update function ID and stack pointer */ + fn.FP = sp + return fn } func (self *Frame) emitExchangeArgs(p *Program) { - iregArgs, xregArgs := 0, 0 - for _, v := range self.desc.Args { - if v.IsFloat != notFloatKind { - xregArgs += 1 - } else { - iregArgs += 1 - } - } + iregArgs, xregArgs := 0, 0 + for _, v := range self.desc.Args { + if v.IsFloat != notFloatKind { + xregArgs += 1 + } else { + iregArgs += 1 + } + } - if iregArgs > len(iregOrderC) { - panic("too many arguments, only support at most 6 integer arguments now") - } - if xregArgs > len(xregOrderC) { - panic("too many arguments, only support at most 8 float arguments now") - } + if iregArgs > len(iregOrderC) { + panic("too many arguments, only support at most 6 integer arguments now") + } + if xregArgs > len(xregOrderC) { + panic("too many arguments, only support at most 8 float arguments now") + } - ic, xc := iregArgs, xregArgs - for i := 0; i < len(self.desc.Args); i++ { - arg := self.desc.Args[i] - if arg.IsFloat == floatKind64 { - p.MOVSD(self.argv(i), xregOrderC[xregArgs - xc]) - xc -= 1 - } else if arg.IsFloat == floatKind32 { - p.MOVSS(self.argv(i), xregOrderC[xregArgs - xc]) - xc -= 1 - } else { - p.MOVQ(self.argv(i), iregOrderC[iregArgs - ic]) - ic -= 1 - } - } + ic, xc := iregArgs, xregArgs + for i := 0; i < len(self.desc.Args); i++ { + arg := self.desc.Args[i] + if arg.IsFloat == floatKind64 { + p.MOVSD(self.argv(i), xregOrderC[xregArgs-xc]) + xc -= 1 + } else if arg.IsFloat == floatKind32 { + p.MOVSS(self.argv(i), xregOrderC[xregArgs-xc]) + xc -= 1 + } else { + p.MOVQ(self.argv(i), iregOrderC[iregArgs-ic]) + ic -= 1 + } + } } func (self *Frame) emitStackCheck(p *Program, to *Label, maxStack uintptr) { - // get the current goroutine - switch runtime.GOOS { - case "linux" : p.MOVQ(Abs(-8), R14).FS() - case "darwin" : p.MOVQ(Abs(0x30), R14).GS() - case "windows": break // windows always stores G pointer at R14 - default : panic("unsupported operating system") - } - - // check the stack guard - p.LEAQ(Ptr(RSP, -int32(self.Size() + uint32(maxStack))), RAX) - p.CMPQ(Ptr(R14, _G_stackguard0), RAX) - p.JBE(to) + // get the current goroutine + switch runtime.GOOS { + case "linux": + p.MOVQ(Abs(-8), R14).FS() + case "darwin": + p.MOVQ(Abs(0x30), R14).GS() + case "windows": + break // windows always stores G pointer at R14 + default: + panic("unsupported operating system") + } + + // check the stack guard + p.LEAQ(Ptr(RSP, -int32(self.Size()+uint32(maxStack))), RAX) + p.CMPQ(Ptr(R14, _G_stackguard0), RAX) + p.JBE(to) } func (self *Frame) StackCheckTextSize() uint32 { - p := DefaultArch.CreateProgram() + p := DefaultArch.CreateProgram() - // get the current goroutine - switch runtime.GOOS { - case "linux" : p.MOVQ(Abs(-8), R14).FS() - case "darwin" : p.MOVQ(Abs(0x30), R14).GS() - case "windows": break // windows always stores G pointer at R14 - default : panic("unsupported operating system") - } - - // check the stack guard - p.LEAQ(Ptr(RSP, -int32(self.Size())), RAX) - p.CMPQ(Ptr(R14, _G_stackguard0), RAX) - l := CreateLabel("") - p.Link(l) - p.JBE(l) + // get the current goroutine + switch runtime.GOOS { + case "linux": + p.MOVQ(Abs(-8), R14).FS() + case "darwin": + p.MOVQ(Abs(0x30), R14).GS() + case "windows": + break // windows always stores G pointer at R14 + default: + panic("unsupported operating system") + } - return uint32(len(p.Assemble(0))) + // check the stack guard + p.LEAQ(Ptr(RSP, -int32(self.Size())), RAX) + p.CMPQ(Ptr(R14, _G_stackguard0), RAX) + l := CreateLabel("") + p.Link(l) + p.JBE(l) + + return uint32(len(p.Assemble(0))) } func (self *Frame) emitExchangeRets(p *Program) { - if len(self.desc.Rets) > 1 { - panic("too many results, only support one result now") - } - // store result - if len(self.desc.Rets) ==1 { - if self.desc.Rets[0].IsFloat == floatKind64 { - p.MOVSD(xregOrderC[0], self.retv(0)) - } else if self.desc.Rets[0].IsFloat == floatKind32 { - p.MOVSS(xregOrderC[0], self.retv(0)) - } else { - p.MOVQ(RAX, self.retv(0)) - } - } + if len(self.desc.Rets) > 1 { + panic("too many results, only support one result now") + } + // store result + if len(self.desc.Rets) == 1 { + if self.desc.Rets[0].IsFloat == floatKind64 { + p.MOVSD(xregOrderC[0], self.retv(0)) + } else if self.desc.Rets[0].IsFloat == floatKind32 { + p.MOVSS(xregOrderC[0], self.retv(0)) + } else { + p.MOVQ(RAX, self.retv(0)) + } + } } func (self *Frame) emitRestoreRegs(p *Program) { - // load reserved registers - for i, r := range ReservedRegs(self.ccall) { - switch r.(type) { - case Register64: - p.MOVQ(self.resv(i), r) - case XMMRegister: - p.MOVSD(self.resv(i), r) - default: - panic(fmt.Sprintf("unsupported register type %t to reserve", r)) - } - } -} \ No newline at end of file + // load reserved registers + for i, r := range ReservedRegs(self.ccall) { + switch r.(type) { + case Register64: + p.MOVQ(self.resv(i), r) + case XMMRegister: + p.MOVSD(self.resv(i), r) + default: + panic(fmt.Sprintf("unsupported register type %t to reserve", r)) + } + } +} diff --git a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go index 5a31dea89..d4c940de3 100644 --- a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go @@ -26,10 +26,10 @@ package abi import ( - `fmt` - `reflect` + "fmt" + "reflect" - . `github.com/cloudwego/iasm/x86_64` + x64 "github.com/bytedance/sonic/loader/internal/iasm/x86_64" ) /** Frame Structure of the Generated Function @@ -59,258 +59,287 @@ RSP -------------------------------|↓ lower addresses */ -const zeroRegGo = XMM15 +const zeroRegGo = x64.XMM15 -var iregOrderGo = [...]Register64 { - RAX,// RDI - RBX,// RSI - RCX,// RDX - RDI,// RCX - RSI,// R8 - R8, // R9 - R9, - R10, - R11, +var iregOrderGo = [...]Register64{ + x64.RAX, // RDI + x64.RBX, // RSI + x64.RCX, // RDX + x64.RDI, // RCX + x64.RSI, // R8 + x64.R8, // R9 + x64.R9, + x64.R10, + x64.R11, } -var xregOrderGo = [...]XMMRegister { - XMM0, - XMM1, - XMM2, - XMM3, - XMM4, - XMM5, - XMM6, - XMM7, - XMM8, - XMM9, - XMM10, - XMM11, - XMM12, - XMM13, - XMM14, +var xregOrderGo = [...]XMMRegister{ + x64.XMM0, + x64.XMM1, + x64.XMM2, + x64.XMM3, + x64.XMM4, + x64.XMM5, + x64.XMM6, + x64.XMM7, + x64.XMM8, + x64.XMM9, + x64.XMM10, + x64.XMM11, + x64.XMM12, + x64.XMM13, + x64.XMM14, } func ReservedRegs(callc bool) []Register { - if callc { - return nil - } - return []Register { - R14, // current goroutine - R15, // GOT reference - } + if callc { + return nil + } + return []Register{ + R14, // current goroutine + R15, // GOT reference + } } type stackAlloc struct { - s uint32 - i int - x int + s uint32 + i int + x int } func (self *stackAlloc) reset() { - self.i, self.x = 0, 0 + self.i, self.x = 0, 0 } func (self *stackAlloc) ireg(vt reflect.Type) (p Parameter) { - p = mkIReg(vt, iregOrderGo[self.i]) - self.i++ - return + p = mkIReg(vt, iregOrderGo[self.i]) + self.i++ + return } func (self *stackAlloc) xreg(vt reflect.Type) (p Parameter) { - p = mkXReg(vt, xregOrderGo[self.x]) - self.x++ - return + p = mkXReg(vt, xregOrderGo[self.x]) + self.x++ + return } func (self *stackAlloc) stack(vt reflect.Type) (p Parameter) { - p = mkStack(vt, self.s) - self.s += uint32(vt.Size()) - return + p = mkStack(vt, self.s) + self.s += uint32(vt.Size()) + return } func (self *stackAlloc) spill(n uint32, a int) uint32 { - self.s = alignUp(self.s, a) + n - return self.s + self.s = alignUp(self.s, a) + n + return self.s } func (self *stackAlloc) alloc(p []Parameter, vt reflect.Type) []Parameter { - nb := vt.Size() - vk := vt.Kind() + nb := vt.Size() + vk := vt.Kind() - /* zero-sized objects are allocated on stack */ - if nb == 0 { - return append(p, mkStack(intType, self.s)) - } + /* zero-sized objects are allocated on stack */ + if nb == 0 { + return append(p, mkStack(intType, self.s)) + } - /* check for value type */ - switch vk { - case reflect.Bool : return self.valloc(p, reflect.TypeOf(false)) - case reflect.Int : return self.valloc(p, intType) - case reflect.Int8 : return self.valloc(p, reflect.TypeOf(int8(0))) - case reflect.Int16 : return self.valloc(p, reflect.TypeOf(int16(0))) - case reflect.Int32 : return self.valloc(p, reflect.TypeOf(uint32(0))) - case reflect.Int64 : return self.valloc(p, reflect.TypeOf(int64(0))) - case reflect.Uint : return self.valloc(p, reflect.TypeOf(uint(0))) - case reflect.Uint8 : return self.valloc(p, reflect.TypeOf(uint8(0))) - case reflect.Uint16 : return self.valloc(p, reflect.TypeOf(uint16(0))) - case reflect.Uint32 : return self.valloc(p, reflect.TypeOf(uint32(0))) - case reflect.Uint64 : return self.valloc(p, reflect.TypeOf(uint64(0))) - case reflect.Uintptr : return self.valloc(p, reflect.TypeOf(uintptr(0))) - case reflect.Float32 : return self.valloc(p, reflect.TypeOf(float32(0))) - case reflect.Float64 : return self.valloc(p, reflect.TypeOf(float64(0))) - case reflect.Complex64 : panic("abi: go117: not implemented: complex64") - case reflect.Complex128 : panic("abi: go117: not implemented: complex128") - case reflect.Array : panic("abi: go117: not implemented: arrays") - case reflect.Chan : return self.valloc(p, reflect.TypeOf((chan int)(nil))) - case reflect.Func : return self.valloc(p, reflect.TypeOf((func())(nil))) - case reflect.Map : return self.valloc(p, reflect.TypeOf((map[int]int)(nil))) - case reflect.Ptr : return self.valloc(p, reflect.TypeOf((*int)(nil))) - case reflect.UnsafePointer : return self.valloc(p, ptrType) - case reflect.Interface : return self.valloc(p, ptrType, ptrType) - case reflect.Slice : return self.valloc(p, ptrType, intType, intType) - case reflect.String : return self.valloc(p, ptrType, intType) - case reflect.Struct : panic("abi: go117: not implemented: structs") - default : panic("abi: invalid value type") - } + /* check for value type */ + switch vk { + case reflect.Bool: + return self.valloc(p, reflect.TypeOf(false)) + case reflect.Int: + return self.valloc(p, intType) + case reflect.Int8: + return self.valloc(p, reflect.TypeOf(int8(0))) + case reflect.Int16: + return self.valloc(p, reflect.TypeOf(int16(0))) + case reflect.Int32: + return self.valloc(p, reflect.TypeOf(uint32(0))) + case reflect.Int64: + return self.valloc(p, reflect.TypeOf(int64(0))) + case reflect.Uint: + return self.valloc(p, reflect.TypeOf(uint(0))) + case reflect.Uint8: + return self.valloc(p, reflect.TypeOf(uint8(0))) + case reflect.Uint16: + return self.valloc(p, reflect.TypeOf(uint16(0))) + case reflect.Uint32: + return self.valloc(p, reflect.TypeOf(uint32(0))) + case reflect.Uint64: + return self.valloc(p, reflect.TypeOf(uint64(0))) + case reflect.Uintptr: + return self.valloc(p, reflect.TypeOf(uintptr(0))) + case reflect.Float32: + return self.valloc(p, reflect.TypeOf(float32(0))) + case reflect.Float64: + return self.valloc(p, reflect.TypeOf(float64(0))) + case reflect.Complex64: + panic("abi: go117: not implemented: complex64") + case reflect.Complex128: + panic("abi: go117: not implemented: complex128") + case reflect.Array: + panic("abi: go117: not implemented: arrays") + case reflect.Chan: + return self.valloc(p, reflect.TypeOf((chan int)(nil))) + case reflect.Func: + return self.valloc(p, reflect.TypeOf((func())(nil))) + case reflect.Map: + return self.valloc(p, reflect.TypeOf((map[int]int)(nil))) + case reflect.Ptr: + return self.valloc(p, reflect.TypeOf((*int)(nil))) + case reflect.UnsafePointer: + return self.valloc(p, ptrType) + case reflect.Interface: + return self.valloc(p, ptrType, ptrType) + case reflect.Slice: + return self.valloc(p, ptrType, intType, intType) + case reflect.String: + return self.valloc(p, ptrType, intType) + case reflect.Struct: + panic("abi: go117: not implemented: structs") + default: + panic("abi: invalid value type") + } } func (self *stackAlloc) valloc(p []Parameter, vts ...reflect.Type) []Parameter { - for _, vt := range vts { - enum := isFloat(vt) - if enum != notFloatKind && self.x < len(xregOrderGo) { - p = append(p, self.xreg(vt)) - } else if enum == notFloatKind && self.i < len(iregOrderGo) { - p = append(p, self.ireg(vt)) - } else { - p = append(p, self.stack(vt)) - } - } - return p + for _, vt := range vts { + enum := isFloat(vt) + if enum != notFloatKind && self.x < len(xregOrderGo) { + p = append(p, self.xreg(vt)) + } else if enum == notFloatKind && self.i < len(iregOrderGo) { + p = append(p, self.ireg(vt)) + } else { + p = append(p, self.stack(vt)) + } + } + return p } func NewFunctionLayout(ft reflect.Type) FunctionLayout { - var sa stackAlloc - var fn FunctionLayout + var sa stackAlloc + var fn FunctionLayout - /* assign every arguments */ - for i := 0; i < ft.NumIn(); i++ { - fn.Args = sa.alloc(fn.Args, ft.In(i)) - } + /* assign every arguments */ + for i := 0; i < ft.NumIn(); i++ { + fn.Args = sa.alloc(fn.Args, ft.In(i)) + } - /* reset the register counter, and add a pointer alignment field */ - sa.reset() + /* reset the register counter, and add a pointer alignment field */ + sa.reset() - /* assign every return value */ - for i := 0; i < ft.NumOut(); i++ { - fn.Rets = sa.alloc(fn.Rets, ft.Out(i)) - } + /* assign every return value */ + for i := 0; i < ft.NumOut(); i++ { + fn.Rets = sa.alloc(fn.Rets, ft.Out(i)) + } - sa.spill(0, PtrAlign) + sa.spill(0, PtrAlign) - /* assign spill slots */ - for i := 0; i < len(fn.Args); i++ { - if fn.Args[i].InRegister { - fn.Args[i].Mem = sa.spill(PtrSize, PtrAlign) - PtrSize - } - } + /* assign spill slots */ + for i := 0; i < len(fn.Args); i++ { + if fn.Args[i].InRegister { + fn.Args[i].Mem = sa.spill(PtrSize, PtrAlign) - PtrSize + } + } - /* add the final pointer alignment field */ - fn.FP = sa.spill(0, PtrAlign) - return fn + /* add the final pointer alignment field */ + fn.FP = sa.spill(0, PtrAlign) + return fn } func (self *Frame) emitExchangeArgs(p *Program) { - iregArgs := make([]Parameter, 0, len(self.desc.Args)) - xregArgs := 0 - for _, v := range self.desc.Args { - if v.InRegister { - if v.IsFloat != notFloatKind { - xregArgs += 1 - } else { - iregArgs = append(iregArgs, v) - } - } else { - panic("not support stack-assgined arguments now") - } - } - if xregArgs > len(xregOrderC) { - panic("too many arguments, only support at most 8 integer register arguments now") - } + iregArgs := make([]Parameter, 0, len(self.desc.Args)) + xregArgs := 0 + for _, v := range self.desc.Args { + if v.InRegister { + if v.IsFloat != notFloatKind { + xregArgs += 1 + } else { + iregArgs = append(iregArgs, v) + } + } else { + panic("not support stack-assgined arguments now") + } + } + if xregArgs > len(xregOrderC) { + panic("too many arguments, only support at most 8 integer register arguments now") + } - switch len(iregArgs) { - case 0, 1, 2, 3: { - //Fast-Path: when arguments count are less than four, just exchange the registers - for i := 0; i < len(iregArgs); i++ { - p.MOVQ(iregOrderGo[i], iregOrderC[i]) - } - } - case 4, 5, 6: { - // need to spill 3th ~ regArgs registers before exchange - for i := 3; i < len(iregArgs); i++ { - arg := iregArgs[i] - // pointer args have already been spilled - if !arg.IsPointer { - p.MOVQ(iregOrderGo[i], Ptr(RSP, int32(self.Prev() + arg.Mem))) - } - } - p.MOVQ(iregOrderGo[0], iregOrderC[0]) - p.MOVQ(iregOrderGo[1], iregOrderC[1]) - p.MOVQ(iregOrderGo[2], iregOrderC[2]) - for i := 3; i < len(iregArgs); i++ { - arg := iregArgs[i] - p.MOVQ(Ptr(RSP, int32(self.Prev() + arg.Mem)), iregOrderC[i]) - } - } - default: - panic("too many arguments, only support at most 6 integer register arguments now") - } + switch len(iregArgs) { + case 0, 1, 2, 3: + { + //Fast-Path: when arguments count are less than four, just exchange the registers + for i := 0; i < len(iregArgs); i++ { + p.MOVQ(iregOrderGo[i], iregOrderC[i]) + } + } + case 4, 5, 6: + { + // need to spill 3th ~ regArgs registers before exchange + for i := 3; i < len(iregArgs); i++ { + arg := iregArgs[i] + // pointer args have already been spilled + if !arg.IsPointer { + p.MOVQ(iregOrderGo[i], Ptr(RSP, int32(self.Prev()+arg.Mem))) + } + } + p.MOVQ(iregOrderGo[0], iregOrderC[0]) + p.MOVQ(iregOrderGo[1], iregOrderC[1]) + p.MOVQ(iregOrderGo[2], iregOrderC[2]) + for i := 3; i < len(iregArgs); i++ { + arg := iregArgs[i] + p.MOVQ(Ptr(RSP, int32(self.Prev()+arg.Mem)), iregOrderC[i]) + } + } + default: + panic("too many arguments, only support at most 6 integer register arguments now") + } } func (self *Frame) emitStackCheck(p *Program, to *Label, maxStack uintptr) { - p.LEAQ(Ptr(RSP, int32(-(self.Size() + uint32(maxStack)))), R12) - p.CMPQ(Ptr(R14, _G_stackguard0), R12) - p.JBE(to) + p.LEAQ(Ptr(RSP, int32(-(self.Size()+uint32(maxStack)))), R12) + p.CMPQ(Ptr(R14, _G_stackguard0), R12) + p.JBE(to) } func (self *Frame) StackCheckTextSize() uint32 { - p := DefaultArch.CreateProgram() - p.LEAQ(Ptr(RSP, int32(-(self.Size()))), R12) - p.CMPQ(Ptr(R14, _G_stackguard0), R12) - to := CreateLabel("") - p.Link(to) - p.JBE(to) - return uint32(len(p.Assemble(0))) + p := DefaultArch.CreateProgram() + p.LEAQ(Ptr(RSP, int32(-(self.Size()))), R12) + p.CMPQ(Ptr(R14, _G_stackguard0), R12) + to := CreateLabel("") + p.Link(to) + p.JBE(to) + return uint32(len(p.Assemble(0))) } func (self *Frame) emitExchangeRets(p *Program) { - if len(self.desc.Rets) > 1 { - panic("too many results, only support one result now") - } - // store result - if len(self.desc.Rets) == 1 && !self.desc.Rets[0].InRegister { - if self.desc.Rets[0].IsFloat == floatKind64 { - p.MOVSD(xregOrderC[0], self.retv(0)) - } else if self.desc.Rets[0].IsFloat == floatKind32 { - p.MOVSS(xregOrderC[0], self.retv(0)) - } else { - p.MOVQ(RAX, self.retv(0)) - } - } + if len(self.desc.Rets) > 1 { + panic("too many results, only support one result now") + } + // store result + if len(self.desc.Rets) == 1 && !self.desc.Rets[0].InRegister { + if self.desc.Rets[0].IsFloat == floatKind64 { + p.MOVSD(xregOrderC[0], self.retv(0)) + } else if self.desc.Rets[0].IsFloat == floatKind32 { + p.MOVSS(xregOrderC[0], self.retv(0)) + } else { + p.MOVQ(RAX, self.retv(0)) + } + } } func (self *Frame) emitRestoreRegs(p *Program) { - // load reserved registers - for i, r := range ReservedRegs(self.ccall) { - switch r.(type) { - case Register64: - p.MOVQ(self.resv(i), r) - case XMMRegister: - p.MOVSD(self.resv(i), r) - default: - panic(fmt.Sprintf("unsupported register type %t to reserve", r)) - } - } - // zero xmm15 for go abi - p.XORPS(zeroRegGo, zeroRegGo) -} \ No newline at end of file + // load reserved registers + for i, r := range ReservedRegs(self.ccall) { + switch r.(type) { + case Register64: + p.MOVQ(self.resv(i), r) + case XMMRegister: + p.MOVSD(self.resv(i), r) + default: + panic(fmt.Sprintf("unsupported register type %t to reserve", r)) + } + } + // zero xmm15 for go abi + p.XORPS(zeroRegGo, zeroRegGo) +} diff --git a/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ast.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ast.go new file mode 100644 index 000000000..d340c5c55 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ast.go @@ -0,0 +1,273 @@ +// +// 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") + } +} diff --git a/vendor/github.com/cloudwego/iasm/expr/errors.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/errors.go similarity index 75% rename from vendor/github.com/cloudwego/iasm/expr/errors.go rename to vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/errors.go index ece4cb8dd..791c18bd6 100644 --- a/vendor/github.com/cloudwego/iasm/expr/errors.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/errors.go @@ -17,37 +17,37 @@ package expr import ( - `fmt` + "fmt" ) // SyntaxError represents a syntax error in the expression. type SyntaxError struct { - Pos int - Reason string + Pos int + Reason string } func newSyntaxError(pos int, reason string) *SyntaxError { - return &SyntaxError { - Pos : pos, - Reason : reason, - } + return &SyntaxError{ + Pos: pos, + Reason: reason, + } } func (self *SyntaxError) Error() string { - return fmt.Sprintf("Syntax error at position %d: %s", self.Pos, self.Reason) + 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 + Reason string } func newRuntimeError(reason string) *RuntimeError { - return &RuntimeError { - Reason: reason, - } + return &RuntimeError{ + Reason: reason, + } } func (self *RuntimeError) Error() string { - return "Runtime error: " + self.Reason + return "Runtime error: " + self.Reason } diff --git a/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ops.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ops.go new file mode 100644 index 000000000..8502dbc9d --- /dev/null +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ops.go @@ -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 +} diff --git a/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/parser.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/parser.go new file mode 100644 index 000000000..98d5db68c --- /dev/null +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/parser.go @@ -0,0 +1,331 @@ +// +// 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 +} diff --git a/vendor/github.com/cloudwego/iasm/expr/pools.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/pools.go similarity index 76% rename from vendor/github.com/cloudwego/iasm/expr/pools.go rename to vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/pools.go index 869225242..77410b4be 100644 --- a/vendor/github.com/cloudwego/iasm/expr/pools.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/pools.go @@ -17,26 +17,26 @@ package expr import ( - `sync` + "sync" ) var ( - expressionPool sync.Pool + expressionPool sync.Pool ) func newExpression() *Expr { - if v := expressionPool.Get(); v == nil { - return new(Expr) - } else { - return resetExpression(v.(*Expr)) - } + if v := expressionPool.Get(); v == nil { + return new(Expr) + } else { + return resetExpression(v.(*Expr)) + } } func freeExpression(p *Expr) { - expressionPool.Put(p) + expressionPool.Put(p) } func resetExpression(p *Expr) *Expr { - *p = Expr{} - return p + *p = Expr{} + return p } diff --git a/vendor/github.com/cloudwego/iasm/expr/term.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/term.go similarity index 94% rename from vendor/github.com/cloudwego/iasm/expr/term.go rename to vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/term.go index 45042334b..4fe723989 100644 --- a/vendor/github.com/cloudwego/iasm/expr/term.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/term.go @@ -18,6 +18,6 @@ // Term represents a value that can Evaluate() into an integer. type Term interface { - Free() - Evaluate() (int64, error) + Free() + Evaluate() (int64, error) } diff --git a/vendor/github.com/cloudwego/iasm/expr/utils.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/utils.go similarity index 53% rename from vendor/github.com/cloudwego/iasm/expr/utils.go rename to vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/utils.go index 780f406e7..57b4fd842 100644 --- a/vendor/github.com/cloudwego/iasm/expr/utils.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/utils.go @@ -16,62 +16,62 @@ package expr -var op1ch = [...]bool { - '+': true, - '-': true, - '*': true, - '/': true, - '%': true, - '&': true, - '|': true, - '^': true, - '~': true, - '(': true, - ')': true, +var op1ch = [...]bool{ + '+': true, + '-': true, + '*': true, + '/': true, + '%': true, + '&': true, + '|': true, + '^': true, + '~': true, + '(': true, + ')': true, } -var op2ch = [...]bool { - '*': 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 - } + 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 - } + 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] + return ch >= 0 && int(ch) < len(op1ch) && op1ch[ch] } func isop2ch(ch rune) bool { - return ch >= 0 && int(ch) < len(op2ch) && op2ch[ch] + return ch >= 0 && int(ch) < len(op2ch) && op2ch[ch] } func isdigit(ch rune) bool { - return ch >= '0' && ch <= '9' + return ch >= '0' && ch <= '9' } func isident(ch rune) bool { - return isdigit(ch) || isident0(ch) + return isdigit(ch) || isident0(ch) } func isident0(ch rune) bool { - return (ch == '_') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') + 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') + return isdigit(ch) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') } diff --git a/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/arch.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/arch.go new file mode 100644 index 000000000..f33cc9ca6 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/arch.go @@ -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) +} diff --git a/vendor/github.com/cloudwego/iasm/x86_64/asm.s b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/asm.s similarity index 100% rename from vendor/github.com/cloudwego/iasm/x86_64/asm.s rename to vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/asm.s diff --git a/vendor/github.com/cloudwego/iasm/x86_64/eface.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/eface.go similarity index 52% rename from vendor/github.com/cloudwego/iasm/x86_64/eface.go rename to vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/eface.go index ad3967b4f..eb7f3c406 100644 --- a/vendor/github.com/cloudwego/iasm/x86_64/eface.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/eface.go @@ -17,63 +17,63 @@ package x86_64 import ( - `reflect` - `unsafe` + "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 + 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 + _KindMask = (1 << 5) - 1 ) func (self *_GoType) kind() reflect.Kind { - return reflect.Kind(self.kflags & _KindMask) + return reflect.Kind(self.kflags & _KindMask) } type _GoSlice struct { - ptr unsafe.Pointer - len int - cap int + ptr unsafe.Pointer + len int + cap int } type _GoEface struct { - vt *_GoType - ptr unsafe.Pointer + vt *_GoType + ptr unsafe.Pointer } func (self *_GoEface) kind() reflect.Kind { - if self.vt != nil { - return self.vt.kind() - } else { - return reflect.Invalid - } + 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)) - } + 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)) + return *(*_GoEface)(unsafe.Pointer(&v)) } diff --git a/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/encodings.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/encodings.go new file mode 100644 index 000000000..f003be927 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/encodings.go @@ -0,0 +1,836 @@ +// +// 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 +} diff --git a/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions.go new file mode 100644 index 000000000..836e1807f --- /dev/null +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions.go @@ -0,0 +1,1077 @@ +// +// 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. +// + +// Code generated by "mkasm_amd64.py", DO NOT EDIT. + +package x86_64 + +// ADDQ performs "Add". +// +// Mnemonic : ADD +// Supported forms : (8 forms) +// +// - ADDQ imm32, rax +// - ADDQ imm8, r64 +// - ADDQ imm32, r64 +// - ADDQ r64, r64 +// - ADDQ m64, r64 +// - ADDQ imm8, m64 +// - ADDQ imm32, m64 +// - ADDQ r64, m64 +func (self *Program) ADDQ(v0 interface{}, v1 interface{}) *Instruction { + p := self.alloc("ADDQ", 2, Operands{v0, v1}) + // ADDQ imm32, rax + if isImm32(v0) && v1 == RAX { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48) + m.emit(0x05) + m.imm4(toImmAny(v[0])) + }) + } + // ADDQ imm8, r64 + if isImm8Ext(v0, 8) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])) + m.emit(0x83) + m.emit(0xc0 | lcode(v[1])) + m.imm1(toImmAny(v[0])) + }) + } + // ADDQ imm32, r64 + if isImm32Ext(v0, 8) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])) + m.emit(0x81) + m.emit(0xc0 | lcode(v[1])) + m.imm4(toImmAny(v[0])) + }) + } + // ADDQ r64, r64 + if isReg64(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1])) + m.emit(0x01) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0])) + m.emit(0x03) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + } + // ADDQ m64, r64 + if isM64(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[1]), addr(v[0])) + m.emit(0x03) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + // ADDQ imm8, m64 + if isImm8Ext(v0, 8) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, 0, addr(v[1])) + m.emit(0x83) + m.mrsd(0, addr(v[1]), 1) + m.imm1(toImmAny(v[0])) + }) + } + // ADDQ imm32, m64 + if isImm32Ext(v0, 8) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, 0, addr(v[1])) + m.emit(0x81) + m.mrsd(0, addr(v[1]), 1) + m.imm4(toImmAny(v[0])) + }) + } + // ADDQ r64, m64 + if isReg64(v0) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[0]), addr(v[1])) + m.emit(0x01) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for ADDQ") + } + return p +} + +// CALLQ performs "Call Procedure". +// +// Mnemonic : CALL +// Supported forms : (2 forms) +// +// - CALLQ r64 +// - CALLQ m64 +func (self *Program) CALLQ(v0 interface{}) *Instruction { + p := self.alloc("CALLQ", 1, Operands{v0}) + // CALLQ r64 + if isReg64(v0) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(0, v[0], false) + m.emit(0xff) + m.emit(0xd0 | lcode(v[0])) + }) + } + // CALLQ m64 + if isM64(v0) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(0, addr(v[0]), false) + m.emit(0xff) + m.mrsd(2, addr(v[0]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for CALLQ") + } + return p +} + +// CMPQ performs "Compare Two Operands". +// +// Mnemonic : CMP +// Supported forms : (8 forms) +// +// - CMPQ imm32, rax +// - CMPQ imm8, r64 +// - CMPQ imm32, r64 +// - CMPQ r64, r64 +// - CMPQ m64, r64 +// - CMPQ imm8, m64 +// - CMPQ imm32, m64 +// - CMPQ r64, m64 +func (self *Program) CMPQ(v0 interface{}, v1 interface{}) *Instruction { + p := self.alloc("CMPQ", 2, Operands{v0, v1}) + // CMPQ imm32, rax + if isImm32(v0) && v1 == RAX { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48) + m.emit(0x3d) + m.imm4(toImmAny(v[0])) + }) + } + // CMPQ imm8, r64 + if isImm8Ext(v0, 8) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])) + m.emit(0x83) + m.emit(0xf8 | lcode(v[1])) + m.imm1(toImmAny(v[0])) + }) + } + // CMPQ imm32, r64 + if isImm32Ext(v0, 8) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])) + m.emit(0x81) + m.emit(0xf8 | lcode(v[1])) + m.imm4(toImmAny(v[0])) + }) + } + // CMPQ r64, r64 + if isReg64(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1])) + m.emit(0x39) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0])) + m.emit(0x3b) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + } + // CMPQ m64, r64 + if isM64(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[1]), addr(v[0])) + m.emit(0x3b) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + // CMPQ imm8, m64 + if isImm8Ext(v0, 8) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, 0, addr(v[1])) + m.emit(0x83) + m.mrsd(7, addr(v[1]), 1) + m.imm1(toImmAny(v[0])) + }) + } + // CMPQ imm32, m64 + if isImm32Ext(v0, 8) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, 0, addr(v[1])) + m.emit(0x81) + m.mrsd(7, addr(v[1]), 1) + m.imm4(toImmAny(v[0])) + }) + } + // CMPQ r64, m64 + if isReg64(v0) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[0]), addr(v[1])) + m.emit(0x39) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for CMPQ") + } + return p +} + +// JBE performs "Jump if below or equal (CF == 1 or ZF == 1)". +// +// Mnemonic : JBE +// Supported forms : (2 forms) +// +// - JBE rel8 +// - JBE rel32 +func (self *Program) JBE(v0 interface{}) *Instruction { + p := self.alloc("JBE", 1, Operands{v0}) + p.branch = _B_conditional + // JBE rel8 + if isRel8(v0) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x76) + m.imm1(relv(v[0])) + }) + } + // JBE rel32 + if isRel32(v0) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x0f) + m.emit(0x86) + m.imm4(relv(v[0])) + }) + } + // JBE label + if isLabel(v0) { + p.add(_F_rel1, func(m *_Encoding, v []interface{}) { + m.emit(0x76) + m.imm1(relv(v[0])) + }) + p.add(_F_rel4, func(m *_Encoding, v []interface{}) { + m.emit(0x0f) + m.emit(0x86) + m.imm4(relv(v[0])) + }) + } + if p.len == 0 { + panic("invalid operands for JBE") + } + return p +} + +// JMP performs "Jump Unconditionally". +// +// Mnemonic : JMP +// Supported forms : (2 forms) +// +// - JMP rel8 +// - JMP rel32 +func (self *Program) JMP(v0 interface{}) *Instruction { + p := self.alloc("JMP", 1, Operands{v0}) + p.branch = _B_unconditional + // JMP rel8 + if isRel8(v0) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xeb) + m.imm1(relv(v[0])) + }) + } + // JMP rel32 + if isRel32(v0) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xe9) + m.imm4(relv(v[0])) + }) + } + // JMP label + if isLabel(v0) { + p.add(_F_rel1, func(m *_Encoding, v []interface{}) { + m.emit(0xeb) + m.imm1(relv(v[0])) + }) + p.add(_F_rel4, func(m *_Encoding, v []interface{}) { + m.emit(0xe9) + m.imm4(relv(v[0])) + }) + } + if p.len == 0 { + panic("invalid operands for JMP") + } + return p +} + +// JMPQ performs "Jump Unconditionally". +// +// Mnemonic : JMP +// Supported forms : (2 forms) +// +// - JMPQ r64 +// - JMPQ m64 +func (self *Program) JMPQ(v0 interface{}) *Instruction { + p := self.alloc("JMPQ", 1, Operands{v0}) + // JMPQ r64 + if isReg64(v0) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(0, v[0], false) + m.emit(0xff) + m.emit(0xe0 | lcode(v[0])) + }) + } + // JMPQ m64 + if isM64(v0) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(0, addr(v[0]), false) + m.emit(0xff) + m.mrsd(4, addr(v[0]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for JMPQ") + } + return p +} + +// LEAQ performs "Load Effective Address". +// +// Mnemonic : LEA +// Supported forms : (1 form) +// +// - LEAQ m, r64 +func (self *Program) LEAQ(v0 interface{}, v1 interface{}) *Instruction { + p := self.alloc("LEAQ", 2, Operands{v0, v1}) + // LEAQ m, r64 + if isM(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[1]), addr(v[0])) + m.emit(0x8d) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for LEAQ") + } + return p +} + +// MOVQ performs "Move". +// +// Mnemonic : MOV +// Supported forms : (16 forms) +// +// - MOVQ imm32, r64 +// - MOVQ imm64, r64 +// - MOVQ r64, r64 +// - MOVQ m64, r64 +// - MOVQ imm32, m64 +// - MOVQ r64, m64 +// - MOVQ mm, r64 [MMX] +// - MOVQ r64, mm [MMX] +// - MOVQ mm, mm [MMX] +// - MOVQ m64, mm [MMX] +// - MOVQ mm, m64 [MMX] +// - MOVQ xmm, r64 [SSE2] +// - MOVQ r64, xmm [SSE2] +// - MOVQ xmm, xmm [SSE2] +// - MOVQ m64, xmm [SSE2] +// - MOVQ xmm, m64 [SSE2] +func (self *Program) MOVQ(v0 interface{}, v1 interface{}) *Instruction { + p := self.alloc("MOVQ", 2, Operands{v0, v1}) + // MOVQ imm32, r64 + if isImm32Ext(v0, 8) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])) + m.emit(0xc7) + m.emit(0xc0 | lcode(v[1])) + m.imm4(toImmAny(v[0])) + }) + } + // MOVQ imm64, r64 + if isImm64(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])) + m.emit(0xb8 | lcode(v[1])) + m.imm8(toImmAny(v[0])) + }) + } + // MOVQ r64, r64 + if isReg64(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1])) + m.emit(0x89) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0])) + m.emit(0x8b) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + } + // MOVQ m64, r64 + if isM64(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[1]), addr(v[0])) + m.emit(0x8b) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + // MOVQ imm32, m64 + if isImm32Ext(v0, 8) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, 0, addr(v[1])) + m.emit(0xc7) + m.mrsd(0, addr(v[1]), 1) + m.imm4(toImmAny(v[0])) + }) + } + // MOVQ r64, m64 + if isReg64(v0) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[0]), addr(v[1])) + m.emit(0x89) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + } + // MOVQ mm, r64 + if isMM(v0) && isReg64(v1) { + self.require(ISA_MMX) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1])) + m.emit(0x0f) + m.emit(0x7e) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + } + // MOVQ r64, mm + if isReg64(v0) && isMM(v1) { + self.require(ISA_MMX) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0])) + m.emit(0x0f) + m.emit(0x6e) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + } + // MOVQ mm, mm + if isMM(v0) && isMM(v1) { + self.require(ISA_MMX) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(hcode(v[1]), v[0], false) + m.emit(0x0f) + m.emit(0x6f) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(hcode(v[0]), v[1], false) + m.emit(0x0f) + m.emit(0x7f) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + } + // MOVQ m64, mm + if isM64(v0) && isMM(v1) { + self.require(ISA_MMX) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(hcode(v[1]), addr(v[0]), false) + m.emit(0x0f) + m.emit(0x6f) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[1]), addr(v[0])) + m.emit(0x0f) + m.emit(0x6e) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + // MOVQ mm, m64 + if isMM(v0) && isM64(v1) { + self.require(ISA_MMX) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(hcode(v[0]), addr(v[1]), false) + m.emit(0x0f) + m.emit(0x7f) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[0]), addr(v[1])) + m.emit(0x0f) + m.emit(0x7e) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + } + // MOVQ xmm, r64 + if isXMM(v0) && isReg64(v1) { + self.require(ISA_SSE2) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x66) + m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1])) + m.emit(0x0f) + m.emit(0x7e) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + } + // MOVQ r64, xmm + if isReg64(v0) && isXMM(v1) { + self.require(ISA_SSE2) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x66) + m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0])) + m.emit(0x0f) + m.emit(0x6e) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + } + // MOVQ xmm, xmm + if isXMM(v0) && isXMM(v1) { + self.require(ISA_SSE2) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf3) + m.rexo(hcode(v[1]), v[0], false) + m.emit(0x0f) + m.emit(0x7e) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x66) + m.rexo(hcode(v[0]), v[1], false) + m.emit(0x0f) + m.emit(0xd6) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + } + // MOVQ m64, xmm + if isM64(v0) && isXMM(v1) { + self.require(ISA_SSE2) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf3) + m.rexo(hcode(v[1]), addr(v[0]), false) + m.emit(0x0f) + m.emit(0x7e) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x66) + m.rexm(1, hcode(v[1]), addr(v[0])) + m.emit(0x0f) + m.emit(0x6e) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + // MOVQ xmm, m64 + if isXMM(v0) && isM64(v1) { + self.require(ISA_SSE2) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x66) + m.rexo(hcode(v[0]), addr(v[1]), false) + m.emit(0x0f) + m.emit(0xd6) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x66) + m.rexm(1, hcode(v[0]), addr(v[1])) + m.emit(0x0f) + m.emit(0x7e) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for MOVQ") + } + return p +} + +// MOVSD performs "Move Scalar Double-Precision Floating-Point Value". +// +// Mnemonic : MOVSD +// Supported forms : (3 forms) +// +// - MOVSD xmm, xmm [SSE2] +// - MOVSD m64, xmm [SSE2] +// - MOVSD xmm, m64 [SSE2] +func (self *Program) MOVSD(v0 interface{}, v1 interface{}) *Instruction { + p := self.alloc("MOVSD", 2, Operands{v0, v1}) + // MOVSD xmm, xmm + if isXMM(v0) && isXMM(v1) { + self.require(ISA_SSE2) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf2) + m.rexo(hcode(v[1]), v[0], false) + m.emit(0x0f) + m.emit(0x10) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf2) + m.rexo(hcode(v[0]), v[1], false) + m.emit(0x0f) + m.emit(0x11) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + } + // MOVSD m64, xmm + if isM64(v0) && isXMM(v1) { + self.require(ISA_SSE2) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf2) + m.rexo(hcode(v[1]), addr(v[0]), false) + m.emit(0x0f) + m.emit(0x10) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + // MOVSD xmm, m64 + if isXMM(v0) && isM64(v1) { + self.require(ISA_SSE2) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf2) + m.rexo(hcode(v[0]), addr(v[1]), false) + m.emit(0x0f) + m.emit(0x11) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for MOVSD") + } + return p +} + +// MOVSLQ performs "Move Doubleword to Quadword with Sign-Extension". +// +// Mnemonic : MOVSXD +// Supported forms : (2 forms) +// +// - MOVSLQ r32, r64 +// - MOVSLQ m32, r64 +func (self *Program) MOVSLQ(v0 interface{}, v1 interface{}) *Instruction { + p := self.alloc("MOVSLQ", 2, Operands{v0, v1}) + // MOVSLQ r32, r64 + if isReg32(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0])) + m.emit(0x63) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + } + // MOVSLQ m32, r64 + if isM32(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[1]), addr(v[0])) + m.emit(0x63) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for MOVSLQ") + } + return p +} + +// MOVSS performs "Move Scalar Single-Precision Floating-Point Values". +// +// Mnemonic : MOVSS +// Supported forms : (3 forms) +// +// - MOVSS xmm, xmm [SSE] +// - MOVSS m32, xmm [SSE] +// - MOVSS xmm, m32 [SSE] +func (self *Program) MOVSS(v0 interface{}, v1 interface{}) *Instruction { + p := self.alloc("MOVSS", 2, Operands{v0, v1}) + // MOVSS xmm, xmm + if isXMM(v0) && isXMM(v1) { + self.require(ISA_SSE) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf3) + m.rexo(hcode(v[1]), v[0], false) + m.emit(0x0f) + m.emit(0x10) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf3) + m.rexo(hcode(v[0]), v[1], false) + m.emit(0x0f) + m.emit(0x11) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + } + // MOVSS m32, xmm + if isM32(v0) && isXMM(v1) { + self.require(ISA_SSE) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf3) + m.rexo(hcode(v[1]), addr(v[0]), false) + m.emit(0x0f) + m.emit(0x10) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + // MOVSS xmm, m32 + if isXMM(v0) && isM32(v1) { + self.require(ISA_SSE) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xf3) + m.rexo(hcode(v[0]), addr(v[1]), false) + m.emit(0x0f) + m.emit(0x11) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for MOVSS") + } + return p +} + +// RET performs "Return from Procedure". +// +// Mnemonic : RET +// Supported forms : (2 forms) +// +// - RET +// - RET imm16 +func (self *Program) RET(vv ...interface{}) *Instruction { + var p *Instruction + switch len(vv) { + case 0: + p = self.alloc("RET", 0, Operands{}) + case 1: + p = self.alloc("RET", 1, Operands{vv[0]}) + default: + panic("instruction RET takes 0 or 1 operands") + } + // RET + if len(vv) == 0 { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xc3) + }) + } + // RET imm16 + if len(vv) == 1 && isImm16(vv[0]) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xc2) + m.imm2(toImmAny(v[0])) + }) + } + if p.len == 0 { + panic("invalid operands for RET") + } + return p +} + +// SUBQ performs "Subtract". +// +// Mnemonic : SUB +// Supported forms : (8 forms) +// +// - SUBQ imm32, rax +// - SUBQ imm8, r64 +// - SUBQ imm32, r64 +// - SUBQ r64, r64 +// - SUBQ m64, r64 +// - SUBQ imm8, m64 +// - SUBQ imm32, m64 +// - SUBQ r64, m64 +func (self *Program) SUBQ(v0 interface{}, v1 interface{}) *Instruction { + p := self.alloc("SUBQ", 2, Operands{v0, v1}) + // SUBQ imm32, rax + if isImm32(v0) && v1 == RAX { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48) + m.emit(0x2d) + m.imm4(toImmAny(v[0])) + }) + } + // SUBQ imm8, r64 + if isImm8Ext(v0, 8) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])) + m.emit(0x83) + m.emit(0xe8 | lcode(v[1])) + m.imm1(toImmAny(v[0])) + }) + } + // SUBQ imm32, r64 + if isImm32Ext(v0, 8) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])) + m.emit(0x81) + m.emit(0xe8 | lcode(v[1])) + m.imm4(toImmAny(v[0])) + }) + } + // SUBQ r64, r64 + if isReg64(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1])) + m.emit(0x29) + m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0])) + m.emit(0x2b) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + } + // SUBQ m64, r64 + if isM64(v0) && isReg64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[1]), addr(v[0])) + m.emit(0x2b) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + // SUBQ imm8, m64 + if isImm8Ext(v0, 8) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, 0, addr(v[1])) + m.emit(0x83) + m.mrsd(5, addr(v[1]), 1) + m.imm1(toImmAny(v[0])) + }) + } + // SUBQ imm32, m64 + if isImm32Ext(v0, 8) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, 0, addr(v[1])) + m.emit(0x81) + m.mrsd(5, addr(v[1]), 1) + m.imm4(toImmAny(v[0])) + }) + } + // SUBQ r64, m64 + if isReg64(v0) && isM64(v1) { + p.domain = DomainGeneric + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexm(1, hcode(v[0]), addr(v[1])) + m.emit(0x29) + m.mrsd(lcode(v[0]), addr(v[1]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for SUBQ") + } + return p +} + +// VPERMIL2PD performs "Permute Two-Source Double-Precision Floating-Point Vectors". +// +// Mnemonic : VPERMIL2PD +// Supported forms : (6 forms) +// +// - VPERMIL2PD imm4, xmm, xmm, xmm, xmm [XOP] +// - VPERMIL2PD imm4, m128, xmm, xmm, xmm [XOP] +// - VPERMIL2PD imm4, xmm, m128, xmm, xmm [XOP] +// - VPERMIL2PD imm4, ymm, ymm, ymm, ymm [XOP] +// - VPERMIL2PD imm4, m256, ymm, ymm, ymm [XOP] +// - VPERMIL2PD imm4, ymm, m256, ymm, ymm [XOP] +func (self *Program) VPERMIL2PD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, v4 interface{}) *Instruction { + p := self.alloc("VPERMIL2PD", 5, Operands{v0, v1, v2, v3, v4}) + // VPERMIL2PD imm4, xmm, xmm, xmm, xmm + if isImm4(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) && isXMM(v4) { + self.require(ISA_XOP) + p.domain = DomainAMDSpecific + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xc4) + m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[2]) << 5)) + m.emit(0x79 ^ (hlcode(v[3]) << 3)) + m.emit(0x49) + m.emit(0xc0 | lcode(v[4])<<3 | lcode(v[2])) + m.emit((hlcode(v[1]) << 4) | imml(v[0])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xc4) + m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[1]) << 5)) + m.emit(0xf9 ^ (hlcode(v[3]) << 3)) + m.emit(0x49) + m.emit(0xc0 | lcode(v[4])<<3 | lcode(v[1])) + m.emit((hlcode(v[2]) << 4) | imml(v[0])) + }) + } + // VPERMIL2PD imm4, m128, xmm, xmm, xmm + if isImm4(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) && isXMM(v4) { + self.require(ISA_XOP) + p.domain = DomainAMDSpecific + p.add(0, func(m *_Encoding, v []interface{}) { + m.vex3(0xc4, 0b11, 0x81, hcode(v[4]), addr(v[1]), hlcode(v[3])) + m.emit(0x49) + m.mrsd(lcode(v[4]), addr(v[1]), 1) + m.emit((hlcode(v[2]) << 4) | imml(v[0])) + }) + } + // VPERMIL2PD imm4, xmm, m128, xmm, xmm + if isImm4(v0) && isXMM(v1) && isM128(v2) && isXMM(v3) && isXMM(v4) { + self.require(ISA_XOP) + p.domain = DomainAMDSpecific + p.add(0, func(m *_Encoding, v []interface{}) { + m.vex3(0xc4, 0b11, 0x01, hcode(v[4]), addr(v[2]), hlcode(v[3])) + m.emit(0x49) + m.mrsd(lcode(v[4]), addr(v[2]), 1) + m.emit((hlcode(v[1]) << 4) | imml(v[0])) + }) + } + // VPERMIL2PD imm4, ymm, ymm, ymm, ymm + if isImm4(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) && isYMM(v4) { + self.require(ISA_XOP) + p.domain = DomainAMDSpecific + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xc4) + m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[2]) << 5)) + m.emit(0x7d ^ (hlcode(v[3]) << 3)) + m.emit(0x49) + m.emit(0xc0 | lcode(v[4])<<3 | lcode(v[2])) + m.emit((hlcode(v[1]) << 4) | imml(v[0])) + }) + p.add(0, func(m *_Encoding, v []interface{}) { + m.emit(0xc4) + m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[1]) << 5)) + m.emit(0xfd ^ (hlcode(v[3]) << 3)) + m.emit(0x49) + m.emit(0xc0 | lcode(v[4])<<3 | lcode(v[1])) + m.emit((hlcode(v[2]) << 4) | imml(v[0])) + }) + } + // VPERMIL2PD imm4, m256, ymm, ymm, ymm + if isImm4(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) && isYMM(v4) { + self.require(ISA_XOP) + p.domain = DomainAMDSpecific + p.add(0, func(m *_Encoding, v []interface{}) { + m.vex3(0xc4, 0b11, 0x85, hcode(v[4]), addr(v[1]), hlcode(v[3])) + m.emit(0x49) + m.mrsd(lcode(v[4]), addr(v[1]), 1) + m.emit((hlcode(v[2]) << 4) | imml(v[0])) + }) + } + // VPERMIL2PD imm4, ymm, m256, ymm, ymm + if isImm4(v0) && isYMM(v1) && isM256(v2) && isYMM(v3) && isYMM(v4) { + self.require(ISA_XOP) + p.domain = DomainAMDSpecific + p.add(0, func(m *_Encoding, v []interface{}) { + m.vex3(0xc4, 0b11, 0x05, hcode(v[4]), addr(v[2]), hlcode(v[3])) + m.emit(0x49) + m.mrsd(lcode(v[4]), addr(v[2]), 1) + m.emit((hlcode(v[1]) << 4) | imml(v[0])) + }) + } + if p.len == 0 { + panic("invalid operands for VPERMIL2PD") + } + return p +} + +// XORPS performs "Bitwise Logical XOR for Single-Precision Floating-Point Values". +// +// Mnemonic : XORPS +// Supported forms : (2 forms) +// +// - XORPS xmm, xmm [SSE] +// - XORPS m128, xmm [SSE] +func (self *Program) XORPS(v0 interface{}, v1 interface{}) *Instruction { + p := self.alloc("XORPS", 2, Operands{v0, v1}) + // XORPS xmm, xmm + if isXMM(v0) && isXMM(v1) { + self.require(ISA_SSE) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(hcode(v[1]), v[0], false) + m.emit(0x0f) + m.emit(0x57) + m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0])) + }) + } + // XORPS m128, xmm + if isM128(v0) && isXMM(v1) { + self.require(ISA_SSE) + p.domain = DomainMMXSSE + p.add(0, func(m *_Encoding, v []interface{}) { + m.rexo(hcode(v[1]), addr(v[0]), false) + m.emit(0x0f) + m.emit(0x57) + m.mrsd(lcode(v[1]), addr(v[0]), 1) + }) + } + if p.len == 0 { + panic("invalid operands for XORPS") + } + return p +} diff --git a/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions_table.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions_table.go new file mode 100644 index 000000000..2becd9d00 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions_table.go @@ -0,0 +1,24 @@ +// +// 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. +// + +// Code generated by "mkasm_amd64.py", DO NOT EDIT. + +package x86_64 + +const ( + _N_args = 5 + _N_forms = 23 +) diff --git a/vendor/github.com/cloudwego/iasm/x86_64/operands.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/operands.go similarity index 100% rename from vendor/github.com/cloudwego/iasm/x86_64/operands.go rename to vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/operands.go diff --git a/vendor/github.com/cloudwego/iasm/x86_64/pools.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/pools.go similarity index 100% rename from vendor/github.com/cloudwego/iasm/x86_64/pools.go rename to vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/pools.go diff --git a/vendor/github.com/cloudwego/iasm/x86_64/program.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/program.go similarity index 99% rename from vendor/github.com/cloudwego/iasm/x86_64/program.go rename to vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/program.go index f0c9b18c6..bf7d3a1dc 100644 --- a/vendor/github.com/cloudwego/iasm/x86_64/program.go +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/program.go @@ -21,7 +21,7 @@ "math" "math/bits" - "github.com/cloudwego/iasm/expr" + "github.com/bytedance/sonic/loader/internal/iasm/expr" ) type ( diff --git a/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/registers.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/registers.go new file mode 100644 index 000000000..265575a26 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/registers.go @@ -0,0 +1,747 @@ +// +// 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", +} diff --git a/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/utils.go b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/utils.go new file mode 100644 index 000000000..107dfb3cd --- /dev/null +++ b/vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/utils.go @@ -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) diff --git a/vendor/github.com/bytedance/sonic/option/option.go b/vendor/github.com/bytedance/sonic/option/option.go index 4d9965260..1ec6a8528 100644 --- a/vendor/github.com/bytedance/sonic/option/option.go +++ b/vendor/github.com/bytedance/sonic/option/option.go @@ -68,7 +68,7 @@ func DefaultCompileOptions() CompileOptions { // // For deep nested struct (depth exceeds MaxInlineDepth), // try to set more loops to completely compile, -// thus reduce JIT unstability in the first hit. +// thus reduce JIT instability in the first hit. func WithCompileRecursiveDepth(loop int) CompileOption { return func(o *CompileOptions) { if loop < 0 { diff --git a/vendor/github.com/bytedance/sonic/unquote/unquote.go b/vendor/github.com/bytedance/sonic/unquote/unquote.go index d81406b2a..29b2fcde8 100644 --- a/vendor/github.com/bytedance/sonic/unquote/unquote.go +++ b/vendor/github.com/bytedance/sonic/unquote/unquote.go @@ -25,7 +25,7 @@ `github.com/bytedance/sonic/internal/rt` ) -// String unescapes a escaped string (not including `"` at begining and end) +// String unescapes an escaped string (not including `"` at beginning and end) // It validates invalid UTF8 and replace with `\ufffd` func String(s string) (ret string, err types.ParsingError) { mm := make([]byte, 0, len(s)) @@ -43,7 +43,7 @@ func IntoBytes(s string, m *[]byte) types.ParsingError { } } -// String unescapes a escaped string (not including `"` at begining and end) +// String unescapes an escaped string (not including `"` at beginning and end) // - replace enables replacing invalid utf8 escaped char with `\uffd` func _String(s string, replace bool) (ret string, err error) { mm := make([]byte, 0, len(s)) diff --git a/vendor/github.com/bytedance/sonic/utf8/utf8.go b/vendor/github.com/bytedance/sonic/utf8/utf8.go index 573fe2f5b..9d8bcc958 100644 --- a/vendor/github.com/bytedance/sonic/utf8/utf8.go +++ b/vendor/github.com/bytedance/sonic/utf8/utf8.go @@ -29,7 +29,7 @@ func CorrectWith(dst []byte, src []byte, repl string) []byte { sstr := rt.Mem2Str(src) sidx := 0 - /* state machine records the invalid postions */ + /* state machine records the invalid positions */ m := types.NewStateMachine() m.Sp = 0 // invalid utf8 numbers diff --git a/vendor/github.com/cloudwego/iasm/LICENSE-APACHE b/vendor/github.com/cloudwego/iasm/LICENSE-APACHE deleted file mode 100644 index 66a27ec5f..000000000 --- a/vendor/github.com/cloudwego/iasm/LICENSE-APACHE +++ /dev/null @@ -1,177 +0,0 @@ - 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 - diff --git a/vendor/github.com/cloudwego/iasm/expr/ast.go b/vendor/github.com/cloudwego/iasm/expr/ast.go deleted file mode 100644 index a91bb2e25..000000000 --- a/vendor/github.com/cloudwego/iasm/expr/ast.go +++ /dev/null @@ -1,261 +0,0 @@ -// -// 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") - } -} diff --git a/vendor/github.com/cloudwego/iasm/expr/ops.go b/vendor/github.com/cloudwego/iasm/expr/ops.go deleted file mode 100644 index 7f168b902..000000000 --- a/vendor/github.com/cloudwego/iasm/expr/ops.go +++ /dev/null @@ -1,67 +0,0 @@ -// -// 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 -} diff --git a/vendor/github.com/cloudwego/iasm/expr/parser.go b/vendor/github.com/cloudwego/iasm/expr/parser.go deleted file mode 100644 index 1846a58a0..000000000 --- a/vendor/github.com/cloudwego/iasm/expr/parser.go +++ /dev/null @@ -1,329 +0,0 @@ -// -// 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 -} diff --git a/vendor/github.com/cloudwego/iasm/x86_64/arch.go b/vendor/github.com/cloudwego/iasm/x86_64/arch.go deleted file mode 100644 index 26f1a539d..000000000 --- a/vendor/github.com/cloudwego/iasm/x86_64/arch.go +++ /dev/null @@ -1,251 +0,0 @@ -// -// 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) -} diff --git a/vendor/github.com/cloudwego/iasm/x86_64/assembler.go b/vendor/github.com/cloudwego/iasm/x86_64/assembler.go deleted file mode 100644 index bbe19193a..000000000 --- a/vendor/github.com/cloudwego/iasm/x86_64/assembler.go +++ /dev/null @@ -1,1819 +0,0 @@ -// -// 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 ( - `bytes` - `errors` - `fmt` - `math` - `strconv` - `strings` - `unicode` - - `github.com/cloudwego/iasm/expr` -) - -type ( - _TokenKind int - _Punctuation int -) - -const ( - _T_end _TokenKind = iota + 1 - _T_int - _T_name - _T_punc - _T_space -) - -const ( - _P_plus _Punctuation = iota + 1 - _P_minus - _P_star - _P_slash - _P_percent - _P_amp - _P_bar - _P_caret - _P_shl - _P_shr - _P_tilde - _P_lbrk - _P_rbrk - _P_dot - _P_comma - _P_colon - _P_dollar - _P_hash -) - -var _PUNC_NAME = map[_Punctuation]string { - _P_plus : "+", - _P_minus : "-", - _P_star : "*", - _P_slash : "/", - _P_percent : "%", - _P_amp : "&", - _P_bar : "|", - _P_caret : "^", - _P_shl : "<<", - _P_shr : ">>", - _P_tilde : "~", - _P_lbrk : "(", - _P_rbrk : ")", - _P_dot : ".", - _P_comma : ",", - _P_colon : ":", - _P_dollar : "$", - _P_hash : "#", -} - -func (self _Punctuation) String() string { - if v, ok := _PUNC_NAME[self]; ok { - return v - } else { - return fmt.Sprintf("_Punctuation(%d)", self) - } -} - -type _Token struct { - pos int - end int - u64 uint64 - str string - tag _TokenKind -} - -func (self *_Token) punc() _Punctuation { - return _Punctuation(self.u64) -} - -func (self *_Token) String() string { - switch self.tag { - case _T_end : return "" - case _T_int : return fmt.Sprintf("", self.u64) - case _T_punc : return fmt.Sprintf("", _Punctuation(self.u64)) - case _T_name : return fmt.Sprintf("", strconv.QuoteToASCII(self.str)) - case _T_space : return "" - default : return fmt.Sprintf("", self.tag, self.u64, strconv.QuoteToASCII(self.str)) - } -} - -func tokenEnd(p int, end int) _Token { - return _Token { - pos: p, - end: end, - tag: _T_end, - } -} - -func tokenInt(p int, val uint64) _Token { - return _Token { - pos: p, - u64: val, - tag: _T_int, - } -} - -func tokenName(p int, name string) _Token { - return _Token { - pos: p, - str: name, - tag: _T_name, - } -} - -func tokenPunc(p int, punc _Punctuation) _Token { - return _Token { - pos: p, - tag: _T_punc, - u64: uint64(punc), - } -} - -func tokenSpace(p int, end int) _Token { - return _Token { - pos: p, - end: end, - tag: _T_space, - } -} - -// SyntaxError represents an error in the assembly syntax. -type SyntaxError struct { - Pos int - Row int - Src []rune - Reason string -} - -// Error implements the error interface. -func (self *SyntaxError) Error() string { - if self.Pos < 0 { - return fmt.Sprintf("%s at line %d", self.Reason, self.Row) - } else { - return fmt.Sprintf("%s at %d:%d", self.Reason, self.Row, self.Pos + 1) - } -} - -type _Tokenizer struct { - pos int - row int - src []rune -} - -func (self *_Tokenizer) ch() rune { - return self.src[self.pos] -} - -func (self *_Tokenizer) eof() bool { - return self.pos >= len(self.src) -} - -func (self *_Tokenizer) rch() (ret rune) { - ret, self.pos = self.src[self.pos], self.pos + 1 - return -} - -func (self *_Tokenizer) err(pos int, msg string) *SyntaxError { - return &SyntaxError { - Pos : pos, - Row : self.row, - Src : self.src, - Reason : msg, - } -} - -type _TrimState int - -const ( - _TS_normal _TrimState = iota - _TS_slcomm - _TS_hscomm - _TS_string - _TS_escape - _TS_accept - _TS_nolast -) - -func (self *_Tokenizer) init(src string) { - var i int - var ch rune - var st _TrimState - - /* set the source */ - self.pos = 0 - self.src = []rune(src) - - /* remove commends, including "//" and "##" */ - loop: for i, ch = range self.src { - switch { - case st == _TS_normal && ch == '/' : st = _TS_slcomm - case st == _TS_normal && ch == '"' : st = _TS_string - case st == _TS_normal && ch == ';' : st = _TS_accept; break loop - case st == _TS_normal && ch == '#' : st = _TS_hscomm - case st == _TS_slcomm && ch == '/' : st = _TS_nolast; break loop - case st == _TS_slcomm : st = _TS_normal - case st == _TS_hscomm && ch == '#' : st = _TS_nolast; break loop - case st == _TS_hscomm : st = _TS_normal - case st == _TS_string && ch == '"' : st = _TS_normal - case st == _TS_string && ch == '\\' : st = _TS_escape - case st == _TS_escape : st = _TS_string - } - } - - /* check for errors */ - switch st { - case _TS_accept: self.src = self.src[:i] - case _TS_nolast: self.src = self.src[:i - 1] - case _TS_string: panic(self.err(i, "string is not terminated")) - case _TS_escape: panic(self.err(i, "escape sequence is not terminated")) - } -} - -func (self *_Tokenizer) skip(check func(v rune) bool) { - for !self.eof() && check(self.ch()) { - self.pos++ - } -} - -func (self *_Tokenizer) find(pos int, check func(v rune) bool) string { - self.skip(check) - return string(self.src[pos:self.pos]) -} - -func (self *_Tokenizer) chrv(p int) _Token { - var err error - var val uint64 - - /* starting and ending position */ - p0 := p + 1 - p1 := p0 + 1 - - /* find the end of the literal */ - for p1 < len(self.src) && self.src[p1] != '\'' { - if p1++; self.src[p1 - 1] == '\\' { - p1++ - } - } - - /* empty literal */ - if p1 == p0 { - panic(self.err(p1, "empty character constant")) - } - - /* check for EOF */ - if p1 == len(self.src) { - panic(self.err(p1, "unexpected EOF when scanning literals")) - } - - /* parse the literal */ - if val, err = literal64(string(self.src[p0:p1])); err != nil { - panic(self.err(p0, "cannot parse literal: " + err.Error())) - } - - /* skip the closing '\'' */ - self.pos = p1 + 1 - return tokenInt(p, val) -} - -func (self *_Tokenizer) numv(p int) _Token { - if val, err := strconv.ParseUint(self.find(p, isnumber), 0, 64); err != nil { - panic(self.err(p, "invalid immediate value: " + err.Error())) - } else { - return tokenInt(p, val) - } -} - -func (self *_Tokenizer) defv(p int, cc rune) _Token { - if isdigit(cc) { - return self.numv(p) - } else if isident0(cc) { - return tokenName(p, self.find(p, isident)) - } else { - panic(self.err(p, "invalid char: " + strconv.QuoteRune(cc))) - } -} - -func (self *_Tokenizer) rep2(p int, pp _Punctuation, cc rune) _Token { - if self.eof() { - panic(self.err(self.pos, "unexpected EOF when scanning operators")) - } else if c := self.rch(); c != cc { - panic(self.err(p + 1, strconv.QuoteRune(cc) + " expected, got " + strconv.QuoteRune(c))) - } else { - return tokenPunc(p, pp) - } -} - -func (self *_Tokenizer) read() _Token { - var p int - var c rune - var t _Token - - /* check for EOF */ - if self.eof() { - return tokenEnd(self.pos, self.pos) - } - - /* skip spaces as needed */ - if p = self.pos; unicode.IsSpace(self.src[p]) { - self.skip(unicode.IsSpace) - return tokenSpace(p, self.pos) - } - - /* check for line comments */ - if p = self.pos; p < len(self.src) - 1 && self.src[p] == '/' && self.src[p + 1] == '/' { - self.pos = len(self.src) - return tokenEnd(p, self.pos) - } - - /* read the next character */ - p = self.pos - c = self.rch() - - /* parse the next character */ - switch c { - case '+' : t = tokenPunc(p, _P_plus) - case '-' : t = tokenPunc(p, _P_minus) - case '*' : t = tokenPunc(p, _P_star) - case '/' : t = tokenPunc(p, _P_slash) - case '%' : t = tokenPunc(p, _P_percent) - case '&' : t = tokenPunc(p, _P_amp) - case '|' : t = tokenPunc(p, _P_bar) - case '^' : t = tokenPunc(p, _P_caret) - case '<' : t = self.rep2(p, _P_shl, '<') - case '>' : t = self.rep2(p, _P_shr, '>') - case '~' : t = tokenPunc(p, _P_tilde) - case '(' : t = tokenPunc(p, _P_lbrk) - case ')' : t = tokenPunc(p, _P_rbrk) - case '.' : t = tokenPunc(p, _P_dot) - case ',' : t = tokenPunc(p, _P_comma) - case ':' : t = tokenPunc(p, _P_colon) - case '$' : t = tokenPunc(p, _P_dollar) - case '#' : t = tokenPunc(p, _P_hash) - case '\'' : t = self.chrv(p) - default : t = self.defv(p, c) - } - - /* mark the end of token */ - t.end = self.pos - return t -} - -func (self *_Tokenizer) next() (tk _Token) { - for { - if tk = self.read(); tk.tag != _T_space { - return - } - } -} - -// LabelKind indicates the type of label reference. -type LabelKind int - -// OperandKind indicates the type of the operand. -type OperandKind int - -// InstructionPrefix indicates the prefix bytes prepended to the instruction. -type InstructionPrefix byte - -const ( - // OpImm means the operand is an immediate value. - OpImm OperandKind = 1 << iota - - // OpReg means the operand is a register. - OpReg - - // OpMem means the operand is a memory address. - OpMem - - // OpLabel means the operand is a label, specifically for - // branch instructions. - OpLabel -) - -const ( - // Declaration means the label is a declaration. - Declaration LabelKind = iota + 1 - - // BranchTarget means the label should be treated as a branch target. - BranchTarget - - // RelativeAddress means the label should be treated as a reference to - // the code section (e.g. RIP-relative addressing). - RelativeAddress -) - -const ( - // PrefixLock 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. - PrefixLock InstructionPrefix = iota - - // PrefixSegmentCS overrides the memory operation of this instruction to CS (Code Segment). - PrefixSegmentCS - - // PrefixSegmentDS overrides the memory operation of this instruction to DS (Data Segment), - // this is the default section for most instructions if not specified. - PrefixSegmentDS - - // PrefixSegmentES overrides the memory operation of this instruction to ES (Extra Segment). - PrefixSegmentES - - // PrefixSegmentFS overrides the memory operation of this instruction to FS. - PrefixSegmentFS - - // PrefixSegmentGS overrides the memory operation of this instruction to GS. - PrefixSegmentGS - - // PrefixSegmentSS overrides the memory operation of this instruction to SS (Stack Segment). - PrefixSegmentSS -) - -// ParsedLabel represents a label in the source, either a jump target or -// an RIP-relative addressing. -type ParsedLabel struct { - Name string - Kind LabelKind -} - -// ParsedOperand represents an operand of an instruction in the source. -type ParsedOperand struct { - Op OperandKind - Imm int64 - Reg Register - Label ParsedLabel - Memory MemoryAddress -} - -// ParsedInstruction represents an instruction in the source. -type ParsedInstruction struct { - Mnemonic string - Operands []ParsedOperand - Prefixes []InstructionPrefix -} - -func (self *ParsedInstruction) imm(v int64) { - self.Operands = append(self.Operands, ParsedOperand { - Op : OpImm, - Imm : v, - }) -} - -func (self *ParsedInstruction) reg(v Register) { - self.Operands = append(self.Operands, ParsedOperand { - Op : OpReg, - Reg : v, - }) -} - -func (self *ParsedInstruction) mem(v MemoryAddress) { - self.Operands = append(self.Operands, ParsedOperand { - Op : OpMem, - Memory : v, - }) -} - -func (self *ParsedInstruction) target(v string) { - self.Operands = append(self.Operands, ParsedOperand { - Op : OpLabel, - Label : ParsedLabel { - Name: v, - Kind: BranchTarget, - }, - }) -} - -func (self *ParsedInstruction) reference(v string) { - self.Operands = append(self.Operands, ParsedOperand { - Op : OpLabel, - Label : ParsedLabel { - Name: v, - Kind: RelativeAddress, - }, - }) -} - -// LineKind indicates the type of ParsedLine. -type LineKind int - -const ( - // LineLabel means the ParsedLine is a label. - LineLabel LineKind = iota + 1 - - // LineInstr means the ParsedLine is an instruction. - LineInstr - - // LineCommand means the ParsedLine is a ParsedCommand. - LineCommand -) - -// ParsedLine represents a parsed source line. -type ParsedLine struct { - Row int - Src []rune - Kind LineKind - Label ParsedLabel - Command ParsedCommand - Instruction ParsedInstruction -} - -// ParsedCommand represents a parsed assembly directive command. -type ParsedCommand struct { - Cmd string - Args []ParsedCommandArg -} - -// ParsedCommandArg represents an argument of a ParsedCommand. -type ParsedCommandArg struct { - Value string - IsString bool -} - -// Parser parses the source, and generates a sequence of ParsedInstruction's. -type Parser struct { - lex _Tokenizer - exp expr.Parser -} - -const ( - rip Register64 = 0xff -) - -var _RegBranch = map[string]bool { - "jmp" : true, - "jmpq" : true, - "call" : true, - "callq" : true, -} - -var _SegPrefix = map[string]InstructionPrefix { - "cs": PrefixSegmentCS, - "ds": PrefixSegmentDS, - "es": PrefixSegmentES, - "fs": PrefixSegmentFS, - "gs": PrefixSegmentGS, - "ss": PrefixSegmentSS, -} - -func (self *Parser) i32(tk _Token, v int64) int32 { - if v >= math.MinInt32 && v <= math.MaxUint32 { - return int32(v) - } else { - panic(self.err(tk.pos, fmt.Sprintf("32-bit integer out ouf range: %d", v))) - } -} - -func (self *Parser) err(pos int, msg string) *SyntaxError { - return &SyntaxError { - Pos : pos, - Row : self.lex.row, - Src : self.lex.src, - Reason : msg, - } -} - -func (self *Parser) negv() int64 { - tk := self.lex.read() - tt := tk.tag - - /* must be an integer */ - if tt != _T_int { - panic(self.err(tk.pos, "integer expected after '-'")) - } else { - return -int64(tk.u64) - } -} - -func (self *Parser) eval(p int) (r int64) { - var e error - var v *expr.Expr - - /* searching start */ - n := 1 - q := p + 1 - - /* find the end of expression */ - for n > 0 && q < len(self.lex.src) { - switch self.lex.src[q] { - case '(' : q++; n++ - case ')' : q++; n-- - default : q++ - } - } - - /* check for EOF */ - if n != 0 { - panic(self.err(q, "unexpected EOF when parsing expressions")) - } - - /* evaluate the expression */ - if v, e = self.exp.SetSource(string(self.lex.src[p:q - 1])).Parse(nil); e != nil { - panic(self.err(p, "cannot evaluate expression: " + e.Error())) - } - - /* evaluate the expression */ - if r, e = v.Evaluate(); e != nil { - panic(self.err(p, "cannot evaluate expression: " + e.Error())) - } - - /* skip the last ')' */ - v.Free() - self.lex.pos = q - return -} - -func (self *Parser) relx(tk _Token) { - if tk.tag != _T_punc || tk.punc() != _P_lbrk { - panic(self.err(tk.pos, "'(' expected for RIP-relative addressing")) - } else if tk = self.lex.next(); self.regx(tk) != rip { - panic(self.err(tk.pos, "RIP-relative addressing expects %rip as the base register")) - } else if tk = self.lex.next(); tk.tag != _T_punc || tk.punc() != _P_rbrk { - panic(self.err(tk.pos, "RIP-relative addressing does not support indexing or scaling")) - } -} - -func (self *Parser) immx(tk _Token) int64 { - if tk.tag != _T_punc || tk.punc() != _P_dollar { - panic(self.err(tk.pos, "'$' expected for registers")) - } else if tk = self.lex.read(); tk.tag == _T_int { - return int64(tk.u64) - } else if tk.tag == _T_punc && tk.punc() == _P_lbrk { - return self.eval(self.lex.pos) - } else if tk.tag == _T_punc && tk.punc() == _P_minus { - return self.negv() - } else { - panic(self.err(tk.pos, "immediate value expected")) - } -} - -func (self *Parser) regx(tk _Token) Register { - if tk.tag != _T_punc || tk.punc() != _P_percent { - panic(self.err(tk.pos, "'%' expected for registers")) - } else if tk = self.lex.read(); tk.tag != _T_name { - panic(self.err(tk.pos, "register name expected")) - } else if tk.str == "rip" { - return rip - } else if reg, ok := Registers[tk.str]; ok { - return reg - } else { - panic(self.err(tk.pos, "invalid register name: " + strconv.Quote(tk.str))) - } -} - -func (self *Parser) regv(tk _Token) Register { - if reg := self.regx(tk); reg == rip { - panic(self.err(tk.pos, "%rip is not accessable as a dedicated register")) - } else { - return reg - } -} - -func (self *Parser) disp(vv int32) MemoryAddress { - switch tk := self.lex.next(); tk.tag { - case _T_end : return MemoryAddress { Displacement: vv } - case _T_punc : return self.relm(tk, vv) - default : panic(self.err(tk.pos, "',' or '(' expected")) - } -} - -func (self *Parser) relm(tv _Token, disp int32) MemoryAddress { - var tk _Token - var tt _TokenKind - - /* check for absolute addressing */ - if tv.punc() == _P_comma { - self.lex.pos-- - return MemoryAddress { Displacement: disp } - } - - /* must be '(' now */ - if tv.punc() != _P_lbrk { - panic(self.err(tv.pos, "',' or '(' expected")) - } - - /* read the next token */ - tk = self.lex.next() - tt = tk.tag - - /* must be a punctuation */ - if tt != _T_punc { - panic(self.err(tk.pos, "'%' or ',' expected")) - } - - /* check for base */ - switch tk.punc() { - case _P_percent : return self.base(tk, disp) - case _P_comma : return self.index(nil, disp) - default : panic(self.err(tk.pos, "'%' or ',' expected")) - } -} - -func (self *Parser) base(tk _Token, disp int32) MemoryAddress { - rr := self.regx(tk) - nk := self.lex.next() - - /* check for register indirection or base-index addressing */ - if !isReg64(rr) { - panic(self.err(tk.pos, "not a valid base register")) - } else if nk.tag != _T_punc { - panic(self.err(nk.pos, "',' or ')' expected")) - } else if nk.punc() == _P_comma { - return self.index(rr, disp) - } else if nk.punc() == _P_rbrk { - return MemoryAddress { Base: rr, Displacement: disp } - } else { - panic(self.err(nk.pos, "',' or ')' expected")) - } -} - -func (self *Parser) index(base Register, disp int32) MemoryAddress { - tk := self.lex.next() - rr := self.regx(tk) - nk := self.lex.next() - - /* check for scaled indexing */ - if base == rip { - panic(self.err(tk.pos, "RIP-relative addressing does not support indexing or scaling")) - } else if !isIndexable(rr) { - panic(self.err(tk.pos, "not a valid index register")) - } else if nk.tag != _T_punc { - panic(self.err(nk.pos, "',' or ')' expected")) - } else if nk.punc() == _P_comma { - return self.scale(base, rr, disp) - } else if nk.punc() == _P_rbrk { - return MemoryAddress { Base: base, Index: rr, Scale: 1, Displacement: disp } - } else { - panic(self.err(nk.pos, "',' or ')' expected")) - } -} - -func (self *Parser) scale(base Register, index Register, disp int32) MemoryAddress { - tk := self.lex.next() - tt := tk.tag - tv := tk.u64 - - /* must be an integer */ - if tt != _T_int { - panic(self.err(tk.pos, "integer expected")) - } - - /* scale can only be 1, 2, 4 or 8 */ - if tv == 0 || (_Scales & (1 << tv)) == 0 { - panic(self.err(tk.pos, "scale can only be 1, 2, 4 or 8")) - } - - /* read next token */ - tk = self.lex.next() - tt = tk.tag - - /* check for the closing ')' */ - if tt != _T_punc || tk.punc() != _P_rbrk { - panic(self.err(tk.pos, "')' expected")) - } - - /* construct the memory address */ - return MemoryAddress { - Base : base, - Index : index, - Scale : uint8(tv), - Displacement : disp, - } -} - -func (self *Parser) cmds() *ParsedLine { - cmd := "" - pos := self.lex.pos - buf := []ParsedCommandArg(nil) - - /* find the end of command */ - for p := pos; pos < len(self.lex.src); pos++ { - if unicode.IsSpace(self.lex.src[pos]) { - cmd = string(self.lex.src[p:pos]) - break - } - } - - /* parse the arguments */ - loop: for { - switch self.next(&pos) { - case 0 : break loop - case '#' : break loop - case '"' : pos = self.strings(&buf, pos) - default : pos = self.expressions(&buf, pos) - } - } - - /* construct the line */ - return &ParsedLine { - Row : self.lex.row, - Src : self.lex.src, - Kind : LineCommand, - Command : ParsedCommand { - Cmd : cmd, - Args : buf, - }, - } -} - -func (self *Parser) feed(line string) *ParsedLine { - ff := true - rr := false - lk := false - - /* reset the lexer */ - self.lex.row++ - self.lex.init(line) - - /* parse the first token */ - tk := self.lex.next() - tt := tk.tag - - /* it is a directive if it starts with a dot */ - if tk.tag == _T_punc && tk.punc() == _P_dot { - return self.cmds() - } - - /* otherwise it could be labels or instructions */ - if tt != _T_name { - panic(self.err(tk.pos, "identifier expected")) - } - - /* peek the next token */ - lex := self.lex - tkx := lex.next() - - /* check for labels */ - if tkx.tag == _T_punc && tkx.punc() == _P_colon { - tkx = lex.next() - ttx := tkx.tag - - /* the line must end here */ - if ttx != _T_end { - panic(self.err(tkx.pos, "garbage after label definition")) - } - - /* construct the label */ - return &ParsedLine { - Row : self.lex.row, - Src : self.lex.src, - Kind : LineLabel, - Label : ParsedLabel { - Kind: Declaration, - Name: tk.str, - }, - } - } - - /* special case for the "lock" prefix */ - if tk.tag == _T_name && strings.ToLower(tk.str) == "lock" { - lk = true - tk = self.lex.next() - - /* must be an instruction */ - if tk.tag != _T_name { - panic(self.err(tk.pos, "identifier expected")) - } - } - - /* set the line kind and mnemonic */ - ret := &ParsedLine { - Row : self.lex.row, - Src : self.lex.src, - Kind : LineInstr, - Instruction : ParsedInstruction { Mnemonic: strings.ToLower(tk.str) }, - } - - /* check for LOCK prefix */ - if lk { - ret.Instruction.Prefixes = append(ret.Instruction.Prefixes, PrefixLock) - } - - /* parse all the operands */ - for { - tk = self.lex.next() - tt = tk.tag - - /* check for end of line */ - if tt == _T_end { - break - } - - /* expect a comma if not the first operand */ - if !ff { - if tt == _T_punc && tk.punc() == _P_comma { - tk = self.lex.next() - } else { - panic(self.err(tk.pos, "',' expected")) - } - } - - /* not the first operand anymore */ - ff = false - tt = tk.tag - - /* encountered an integer, must be a SIB memory address */ - if tt == _T_int { - ret.Instruction.mem(self.disp(self.i32(tk, int64(tk.u64)))) - continue - } - - /* encountered an identifier, maybe an expression or a jump target, or a segment override prefix */ - if tt == _T_name { - ts := tk.str - tp := self.lex.pos - - /* if the next token is EOF or a comma, it's a jumpt target */ - if tk = self.lex.next(); tk.tag == _T_end || (tk.tag == _T_punc && tk.punc() == _P_comma) { - self.lex.pos = tp - ret.Instruction.target(ts) - continue - } - - /* if it is a colon, it's a segment override prefix, otherwise it must be an RIP-relative addressing operand */ - if tk.tag != _T_punc || tk.punc() != _P_colon { - self.relx(tk) - ret.Instruction.reference(ts) - continue - } - - /* lookup segment prefixes */ - if p, ok := _SegPrefix[strings.ToLower(ts)]; !ok { - panic(self.err(tk.pos, "invalid segment name")) - } else { - ret.Instruction.Prefixes = append(ret.Instruction.Prefixes, p) - } - - /* read the next token */ - tk = self.lex.next() - tt = tk.tag - - /* encountered an integer, must be a SIB memory address */ - if tt == _T_int { - ret.Instruction.mem(self.disp(self.i32(tk, int64(tk.u64)))) - continue - } - } - - /* certain instructions may have a "*" before operands */ - if tt == _T_punc && tk.punc() == _P_star { - tk = self.lex.next() - tt = tk.tag - rr = true - } - - /* ... otherwise it must be a punctuation */ - if tt != _T_punc { - panic(self.err(tk.pos, "'$', '%', '-' or '(' expected")) - } - - /* check the operator */ - switch tk.punc() { - case _P_lbrk : break - case _P_minus : ret.Instruction.mem(self.disp(self.i32(tk, self.negv()))) ; continue - case _P_dollar : ret.Instruction.imm(self.immx(tk)) ; continue - case _P_percent : ret.Instruction.reg(self.regv(tk)) ; continue - default : panic(self.err(tk.pos, "'$', '%', '-' or '(' expected")) - } - - /* special case of '(', might be either `(expr)(SIB)` or just `(SIB)` - * read one more token to confirm */ - tk = self.lex.next() - tt = tk.tag - - /* the next token is '%', it's a memory address, - * or ',' if it's a memory address without base, - * otherwise it must be in `(expr)(SIB)` form */ - if tk.tag == _T_punc && tk.punc() == _P_percent { - ret.Instruction.mem(self.base(tk, 0)) - } else if tk.tag == _T_punc && tk.punc() == _P_comma { - ret.Instruction.mem(self.index(nil, 0)) - } else { - ret.Instruction.mem(self.disp(self.i32(tk, self.eval(tk.pos)))) - } - } - - /* check "jmp" and "call" instructions */ - if !_RegBranch[ret.Instruction.Mnemonic] { - return ret - } else if len(ret.Instruction.Operands) != 1 { - panic(self.err(tk.pos, fmt.Sprintf(`"%s" requires exact 1 argument`, ret.Instruction.Mnemonic))) - } else if !rr && ret.Instruction.Operands[0].Op != OpReg && ret.Instruction.Operands[0].Op != OpLabel { - panic(self.err(tk.pos, fmt.Sprintf(`invalid operand for "%s" instruction`, ret.Instruction.Mnemonic))) - } else { - return ret - } -} - -func (self *Parser) next(p *int) rune { - for { - if *p >= len(self.lex.src) { - return 0 - } else if cc := self.lex.src[*p]; !unicode.IsSpace(cc) { - return cc - } else { - *p++ - } - } -} - -func (self *Parser) delim(p int) int { - if cc := self.next(&p); cc == 0 { - return p - } else if cc == ',' { - return p + 1 - } else { - panic(self.err(p, "',' expected")) - } -} - -func (self *Parser) strings(argv *[]ParsedCommandArg, p int) int { - var i int - var e error - var v string - - /* find the end of string */ - for i = p + 1; i < len(self.lex.src) && self.lex.src[i] != '"'; i++ { - if self.lex.src[i] == '\\' { - i++ - } - } - - /* check for EOF */ - if i == len(self.lex.src) { - panic(self.err(i, "unexpected EOF when scanning strings")) - } - - /* unquote the string */ - if v, e = strconv.Unquote(string(self.lex.src[p:i + 1])); e != nil { - panic(self.err(p, "invalid string: " + e.Error())) - } - - /* add the argument to buffer */ - *argv = append(*argv, ParsedCommandArg { Value: v, IsString: true }) - return self.delim(i + 1) -} - -func (self *Parser) directives(line string) { - self.lex.row++ - self.lex.init(line) - - /* parse the first token */ - tk := self.lex.next() - tt := tk.tag - - /* check for EOF */ - if tt == _T_end { - return - } - - /* must be a directive */ - if tt != _T_punc || tk.punc() != _P_hash { - panic(self.err(tk.pos, "'#' expected")) - } - - /* parse the line number */ - tk = self.lex.next() - tt = tk.tag - - /* must be a line number, if it is, set the row number, and ignore the rest of the line */ - if tt != _T_int { - panic(self.err(tk.pos, "line number expected")) - } else { - self.lex.row = int(tk.u64) - 1 - } -} - -func (self *Parser) expressions(argv *[]ParsedCommandArg, p int) int { - var i int - var n int - var s int - - /* scan until the first standalone ',' or EOF */ - loop: for i = p; i < len(self.lex.src); i++ { - switch self.lex.src[i] { - case ',' : if s == 0 { if n == 0 { break loop } } - case ']', '}', '>' : if s == 0 { if n == 0 { break loop } else { n-- } } - case '[', '{', '<' : if s == 0 { n++ } - case '\\' : if s != 0 { i++ } - case '\'' : if s != 2 { s ^= 1 } - case '"' : if s != 1 { s ^= 2 } - } - } - - /* check for EOF in strings */ - if s != 0 { - panic(self.err(i, "unexpected EOF when scanning strings")) - } - - /* check for bracket matching */ - if n != 0 { - panic(self.err(i, "unbalanced '{' or '[' or '<'")) - } - - /* add the argument to buffer */ - *argv = append(*argv, ParsedCommandArg { Value: string(self.lex.src[p:i]) }) - return self.delim(i) -} - -// Feed feeds the parser with one more line, and the parser -// parses it into a ParsedLine. -// -// NOTE: Feed does not handle empty lines or multiple lines, -// it panics when this happens. Use Parse to parse multiple -// lines of assembly source. -// -func (self *Parser) Feed(src string) (ret *ParsedLine, err error) { - var ok bool - var ss string - var vv interface{} - - /* check for multiple lines */ - if strings.ContainsRune(src, '\n') { - return nil, errors.New("passing multiple lines to Feed()") - } - - /* check for blank lines */ - if ss = strings.TrimSpace(src); ss == "" || ss[0] == '#' || strings.HasPrefix(ss, "//") { - return nil, errors.New("blank line or line with only comments or line-marks") - } - - /* setup error handler */ - defer func() { - if vv = recover(); vv != nil { - if err, ok = vv.(*SyntaxError); !ok { - panic(vv) - } - } - }() - - /* call the actual parser */ - ret = self.feed(src) - return -} - -// Parse parses the entire assembly source (possibly multiple lines) into -// a sequence of *ParsedLine. -func (self *Parser) Parse(src string) (ret []*ParsedLine, err error) { - var ok bool - var ss string - var vv interface{} - - /* setup error handler */ - defer func() { - if vv = recover(); vv != nil { - if err, ok = vv.(*SyntaxError); !ok { - panic(vv) - } - } - }() - - /* feed every line */ - for _, line := range strings.Split(src, "\n") { - if ss = strings.TrimSpace(line); ss == "" || strings.HasPrefix(ss, "//") { - self.lex.row++ - } else if ss[0] == '#' { - self.directives(line) - } else { - ret = append(ret, self.feed(line)) - } - } - - /* all done */ - err = nil - return -} - -// Directive handles the directive. -func (self *Parser) Directive(line string) (err error) { - var ok bool - var ss string - var vv interface{} - - /* check for directives */ - if ss = strings.TrimSpace(line); ss == "" || ss[0] != '#' { - return errors.New("not a directive") - } - - /* setup error handler */ - defer func() { - if vv = recover(); vv != nil { - if err, ok = vv.(*SyntaxError); !ok { - panic(vv) - } - } - }() - - /* call the directive parser */ - self.directives(line) - return -} - -type _TermRepo struct { - terms map[string]expr.Term -} - -func (self *_TermRepo) Get(name string) (expr.Term, error) { - if ret, ok := self.terms[name]; ok { - return ret, nil - } else { - return nil, errors.New("undefined name: " + name) - } -} - -func (self *_TermRepo) label(name string) (*Label, error) { - var ok bool - var lb *Label - var tr expr.Term - - /* check for existing terms */ - if tr, ok = self.terms[name]; ok { - if lb, ok = tr.(*Label); ok { - return lb, nil - } else { - return nil, errors.New("name is not a label: " + name) - } - } - - /* create a new one as needed */ - lb = new(Label) - lb.Name = name - - /* create the map if needed */ - if self.terms == nil { - self.terms = make(map[string]expr.Term, 1) - } - - /* register the label */ - self.terms[name] = lb - return lb, nil -} - -func (self *_TermRepo) define(name string, term expr.Term) { - var ok bool - var tr expr.Term - - /* create the map if needed */ - if self.terms == nil { - self.terms = make(map[string]expr.Term, 1) - } - - /* check for existing terms */ - if tr, ok = self.terms[name]; !ok { - self.terms[name] = term - } else if _, ok = tr.(*Label); !ok { - self.terms[name] = term - } else { - panic("conflicting term types: " + name) - } -} - -// _Command describes an assembler command. -// -// The _Command.args describes both the arity and argument type with characters, -// the length is the number of arguments, the character itself represents the -// argument type. -// -// Possible values are: -// -// s This argument should be a string -// e This argument should be an expression -// ? The next argument is optional, and must be the last argument. -// -type _Command struct { - args string - handler func(*Assembler, *Program, []ParsedCommandArg) error -} - -// Options controls the behavior of Assembler. -type Options struct { - // InstructionAliasing specifies whether to enable instruction aliasing. - // Set to true enables instruction aliasing, and the Assembler will try harder to find instructions. - InstructionAliasing bool - - // IgnoreUnknownDirectives specifies whether to report errors when encountered unknown directives. - // Set to true ignores all unknwon directives silently, useful for parsing generated assembly. - IgnoreUnknownDirectives bool -} - -// Assembler assembles the entire assembly program and generates the corresponding -// machine code representations. -type Assembler struct { - cc int - ps Parser - pc uintptr - buf []byte - main string - opts Options - repo _TermRepo - expr expr.Parser - line *ParsedLine -} - -var asmCommands = map[string]_Command { - "org" : { "e" , (*Assembler).assembleCommandOrg }, - "set" : { "ee" , (*Assembler).assembleCommandSet }, - "byte" : { "e" , (*Assembler).assembleCommandByte }, - "word" : { "e" , (*Assembler).assembleCommandWord }, - "long" : { "e" , (*Assembler).assembleCommandLong }, - "quad" : { "e" , (*Assembler).assembleCommandQuad }, - "fill" : { "e?e" , (*Assembler).assembleCommandFill }, - "space" : { "e?e" , (*Assembler).assembleCommandFill }, - "align" : { "e?e" , (*Assembler).assembleCommandAlign }, - "entry" : { "e" , (*Assembler).assembleCommandEntry }, - "ascii" : { "s" , (*Assembler).assembleCommandAscii }, - "asciz" : { "s" , (*Assembler).assembleCommandAsciz }, - "p2align" : { "e?e" , (*Assembler).assembleCommandP2Align }, -} - -func (self *Assembler) err(msg string) *SyntaxError { - return &SyntaxError { - Pos : -1, - Row : self.line.Row, - Src : self.line.Src, - Reason : msg, - } -} - -func (self *Assembler) eval(expr string) (int64, error) { - if exp, err := self.expr.SetSource(expr).Parse(nil); err != nil { - return 0, err - } else { - return exp.Evaluate() - } -} - -func (self *Assembler) checkArgs(i int, n int, v *ParsedCommand, isString bool) error { - if i >= len(v.Args) { - return self.err(fmt.Sprintf("command %s takes exact %d arguments", strconv.Quote(v.Cmd), n)) - } else if isString && !v.Args[i].IsString { - return self.err(fmt.Sprintf("argument %d of command %s must be a string", i + 1, strconv.Quote(v.Cmd))) - } else if !isString && v.Args[i].IsString { - return self.err(fmt.Sprintf("argument %d of command %s must be an expression", i + 1, strconv.Quote(v.Cmd))) - } else { - return nil - } -} - -func (self *Assembler) assembleLabel(p *Program, lb *ParsedLabel) error { - if v, err := self.repo.label(lb.Name); err != nil { - return err - } else { - p.Link(v) - return nil - } -} - -func (self *Assembler) assembleInstr(p *Program, line *ParsedInstruction) (err error) { - var ok bool - var pfx []byte - var ops []interface{} - var enc _InstructionEncoder - - /* convert to lower-case */ - opts := self.opts - name := strings.ToLower(line.Mnemonic) - - /* fix register-addressing branches if needed */ - if opts.InstructionAliasing && len(line.Operands) == 1 { - switch { - case name == "retq" : name = "ret" - case name == "movabsq" : name = "movq" - case name == "jmp" && line.Operands[0].Op != OpLabel : name = "jmpq" - case name == "jmpq" && line.Operands[0].Op == OpLabel : name = "jmp" - case name == "call" && line.Operands[0].Op != OpLabel : name = "callq" - case name == "callq" && line.Operands[0].Op == OpLabel : name = "call" - } - } - - /* lookup from the alias table if needed */ - if opts.InstructionAliasing { - enc, ok = _InstructionAliases[name] - } - - /* lookup from the instruction table */ - if !ok { - enc, ok = Instructions[name] - } - - /* remove size suffix if possible */ - if !ok && opts.InstructionAliasing { - switch i := len(name) - 1; name[i] { - case 'b', 'w', 'l', 'q': { - enc, ok = Instructions[name[:i]] - } - } - } - - /* check for instruction name */ - if !ok { - return self.err("no such instruction: " + strconv.Quote(name)) - } - - /* allocate memory for prefix if any */ - if len(line.Prefixes) != 0 { - pfx = make([]byte, len(line.Prefixes)) - } - - /* convert the prefixes */ - for i, v := range line.Prefixes { - switch v { - case PrefixLock : pfx[i] = _P_lock - case PrefixSegmentCS : pfx[i] = _P_cs - case PrefixSegmentDS : pfx[i] = _P_ds - case PrefixSegmentES : pfx[i] = _P_es - case PrefixSegmentFS : pfx[i] = _P_fs - case PrefixSegmentGS : pfx[i] = _P_gs - case PrefixSegmentSS : pfx[i] = _P_ss - default : panic("unreachable: invalid segment prefix") - } - } - - /* convert the operands */ - for _, op := range line.Operands { - switch op.Op { - case OpImm : ops = append(ops, op.Imm) - case OpReg : ops = append(ops, op.Reg) - case OpMem : self.assembleInstrMem(&ops, op.Memory) - case OpLabel : self.assembleInstrLabel(&ops, op.Label) - default : panic("parser yields an invalid operand kind") - } - } - - /* catch any exceptions in the encoder */ - defer func() { - if v := recover(); v != nil { - err = self.err(fmt.Sprint(v)) - } - }() - - /* encode the instruction */ - enc(p, ops...).prefix = pfx - return nil -} - -func (self *Assembler) assembleInstrMem(ops *[]interface{}, addr MemoryAddress) { - mem := new(MemoryOperand) - *ops = append(*ops, mem) - - /* check for RIP-relative addressing */ - if addr.Base != rip { - mem.Addr.Type = Memory - mem.Addr.Memory = addr - } else { - mem.Addr.Type = Offset - mem.Addr.Offset = RelativeOffset(addr.Displacement) - } -} - -func (self *Assembler) assembleInstrLabel(ops *[]interface{}, label ParsedLabel) { - vk := label.Kind - tr, err := self.repo.label(label.Name) - - /* check for errors */ - if err != nil { - panic(err) - } - - /* check for branch target */ - if vk == BranchTarget { - *ops = append(*ops, tr) - return - } - - /* add to ops */ - *ops = append(*ops, &MemoryOperand { - Addr: Addressable { - Type : Reference, - Reference : tr, - }, - }) -} - -func (self *Assembler) assembleCommand(p *Program, line *ParsedCommand) error { - var iv int - var cc rune - var ok bool - var va bool - var fn _Command - - /* find the command */ - if fn, ok = asmCommands[line.Cmd]; !ok { - if self.opts.IgnoreUnknownDirectives { - return nil - } else { - return self.err("no such command: " + strconv.Quote(line.Cmd)) - } - } - - /* expected & real argument count */ - argx := len(fn.args) - argc := len(line.Args) - - /* check the arguments */ - loop: for iv, cc = range fn.args { - switch cc { - case '?' : va = true; break loop - case 's' : if err := self.checkArgs(iv, argx, line, true) ; err != nil { return err } - case 'e' : if err := self.checkArgs(iv, argx, line, false) ; err != nil { return err } - default : panic("invalid argument descriptor: " + strconv.Quote(fn.args)) - } - } - - /* simple case: non-variadic command */ - if !va { - if argc == argx { - return fn.handler(self, p, line.Args) - } else { - return self.err(fmt.Sprintf("command %s takes exact %d arguments", strconv.Quote(line.Cmd), argx)) - } - } - - /* check for the descriptor */ - if iv != argx - 2 { - panic("invalid argument descriptor: " + strconv.Quote(fn.args)) - } - - /* variadic command and the final optional argument is set */ - if argc == argx - 1 { - switch fn.args[argx - 1] { - case 's' : if err := self.checkArgs(iv, -1, line, true) ; err != nil { return err } - case 'e' : if err := self.checkArgs(iv, -1, line, false) ; err != nil { return err } - default : panic("invalid argument descriptor: " + strconv.Quote(fn.args)) - } - } - - /* check argument count */ - if argc == argx - 1 || argc == argx - 2 { - return fn.handler(self, p, line.Args) - } else { - return self.err(fmt.Sprintf("command %s takes %d or %d arguments", strconv.Quote(line.Cmd), argx - 2, argx - 1)) - } -} - -func (self *Assembler) assembleCommandInt(p *Program, argv []ParsedCommandArg, addfn func(*Program, *expr.Expr) *Instruction) error { - var err error - var val *expr.Expr - - /* parse the expression */ - if val, err = self.expr.SetSource(argv[0].Value).Parse(&self.repo); err != nil { - return err - } - - /* add to the program */ - addfn(p, val) - return nil -} - -func (self *Assembler) assembleCommandOrg(_ *Program, argv []ParsedCommandArg) error { - var err error - var val int64 - - /* evaluate the expression */ - if val, err = self.eval(argv[0].Value); err != nil { - return err - } - - /* check for origin */ - if val < 0 { - return self.err(fmt.Sprintf("negative origin: %d", val)) - } - - /* ".org" must be the first command if any */ - if self.cc != 1 { - return self.err(".org must be the first command if present") - } - - /* set the initial program counter */ - self.pc = uintptr(val) - return nil -} - -func (self *Assembler) assembleCommandSet(_ *Program, argv []ParsedCommandArg) error { - var err error - var val *expr.Expr - - /* parse the expression */ - if val, err = self.expr.SetSource(argv[1].Value).Parse(&self.repo); err != nil { - return err - } - - /* define the new identifier */ - self.repo.define(argv[0].Value, val) - return nil -} - -func (self *Assembler) assembleCommandByte(p *Program, argv []ParsedCommandArg) error { - return self.assembleCommandInt(p, argv, (*Program).Byte) -} - -func (self *Assembler) assembleCommandWord(p *Program, argv []ParsedCommandArg) error { - return self.assembleCommandInt(p, argv, (*Program).Word) -} - -func (self *Assembler) assembleCommandLong(p *Program, argv []ParsedCommandArg) error { - return self.assembleCommandInt(p, argv, (*Program).Long) -} - -func (self *Assembler) assembleCommandQuad(p *Program, argv []ParsedCommandArg) error { - return self.assembleCommandInt(p, argv, (*Program).Quad) -} - -func (self *Assembler) assembleCommandFill(p *Program, argv []ParsedCommandArg) error { - var fv byte - var nb int64 - var ex error - - /* evaluate the size */ - if nb, ex = self.eval(argv[0].Value); ex != nil { - return ex - } - - /* check for filling size */ - if nb < 0 { - return self.err(fmt.Sprintf("negative filling size: %d", nb)) - } - - /* check for optional filling value */ - if len(argv) == 2 { - if val, err := self.eval(argv[1].Value); err != nil { - return err - } else if val < math.MinInt8 || val > math.MaxUint8 { - return self.err(fmt.Sprintf("value %d cannot be represented with a byte", val)) - } else { - fv = byte(val) - } - } - - /* fill with specified byte */ - p.Data(bytes.Repeat([]byte { fv }, int(nb))) - return nil -} - -func (self *Assembler) assembleCommandAlign(p *Program, argv []ParsedCommandArg) error { - var nb int64 - var ex error - var fv *expr.Expr - - /* evaluate the size */ - if nb, ex = self.eval(argv[0].Value); ex != nil { - return ex - } - - /* check for alignment value */ - if nb <= 0 { - return self.err(fmt.Sprintf("zero or negative alignment: %d", nb)) - } - - /* alignment must be a power of 2 */ - if (nb & (nb - 1)) != 0 { - return self.err(fmt.Sprintf("alignment must be a power of 2: %d", nb)) - } - - /* check for optional filling value */ - if len(argv) == 2 { - if v, err := self.expr.SetSource(argv[1].Value).Parse(&self.repo); err == nil { - fv = v - } else { - return err - } - } - - /* fill with specified byte, default to 0 if not specified */ - p.Align(uint64(nb), fv) - return nil -} - -func (self *Assembler) assembleCommandEntry(_ *Program, argv []ParsedCommandArg) error { - name := argv[0].Value - rbuf := []rune(name) - - /* check all the characters */ - for i, cc := range rbuf { - if !isident0(cc) && (i == 0 || !isident(cc)) { - return self.err("entry point must be a label name") - } - } - - /* set the main entry point */ - self.main = name - return nil -} - -func (self *Assembler) assembleCommandAscii(p *Program, argv []ParsedCommandArg) error { - p.Data([]byte(argv[0].Value)) - return nil -} - -func (self *Assembler) assembleCommandAsciz(p *Program, argv []ParsedCommandArg) error { - p.Data(append([]byte(argv[0].Value), 0)) - return nil -} - -func (self *Assembler) assembleCommandP2Align(p *Program, argv []ParsedCommandArg) error { - var nb int64 - var ex error - var fv *expr.Expr - - /* evaluate the size */ - if nb, ex = self.eval(argv[0].Value); ex != nil { - return ex - } - - /* check for alignment value */ - if nb <= 0 { - return self.err(fmt.Sprintf("zero or negative alignment: %d", nb)) - } - - /* check for optional filling value */ - if len(argv) == 2 { - if v, err := self.expr.SetSource(argv[1].Value).Parse(&self.repo); err == nil { - fv = v - } else { - return err - } - } - - /* fill with specified byte, default to 0 if not specified */ - p.Align(1 << nb, fv) - return nil -} - -// Base returns the origin. -func (self *Assembler) Base() uintptr { - return self.pc -} - -// Code returns the assembled machine code. -func (self *Assembler) Code() []byte { - return self.buf -} - -// Entry returns the address of the specified entry point, or the origin if not specified. -func (self *Assembler) Entry() uintptr { - if self.main == "" { - return self.pc - } else if tr, err := self.repo.Get(self.main); err != nil { - panic(err) - } else if val, err := tr.Evaluate(); err != nil { - panic(err) - } else { - return uintptr(val) - } -} - -// Options returns the internal options reference, changing it WILL affect this Assembler instance. -func (self *Assembler) Options() *Options { - return &self.opts -} - -// WithBase resets the origin to pc. -func (self *Assembler) WithBase(pc uintptr) *Assembler { - self.pc = pc - return self -} - -// Assemble assembles the assembly source and save the machine code to internal buffer. -func (self *Assembler) Assemble(src string) error { - var err error - var buf []*ParsedLine - - /* parse the source */ - if buf, err = self.ps.Parse(src); err != nil { - return err - } - - /* create a new program */ - p := DefaultArch.CreateProgram() - defer p.Free() - - /* process every line */ - for _, self.line = range buf { - switch self.cc++; self.line.Kind { - case LineLabel : if err = self.assembleLabel (p, &self.line.Label) ; err != nil { return err } - case LineInstr : if err = self.assembleInstr (p, &self.line.Instruction) ; err != nil { return err } - case LineCommand : if err = self.assembleCommand (p, &self.line.Command) ; err != nil { return err } - default : panic("parser yields an invalid line kind") - } - } - - /* assemble the program */ - self.buf = p.Assemble(self.pc) - return nil -} diff --git a/vendor/github.com/cloudwego/iasm/x86_64/assembler_alias.go b/vendor/github.com/cloudwego/iasm/x86_64/assembler_alias.go deleted file mode 100644 index e8f1f725c..000000000 --- a/vendor/github.com/cloudwego/iasm/x86_64/assembler_alias.go +++ /dev/null @@ -1,49 +0,0 @@ -// -// 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, -} diff --git a/vendor/github.com/cloudwego/iasm/x86_64/encodings.go b/vendor/github.com/cloudwego/iasm/x86_64/encodings.go deleted file mode 100644 index a0d96db92..000000000 --- a/vendor/github.com/cloudwego/iasm/x86_64/encodings.go +++ /dev/null @@ -1,691 +0,0 @@ -// -// 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 -} diff --git a/vendor/github.com/cloudwego/iasm/x86_64/instructions.go b/vendor/github.com/cloudwego/iasm/x86_64/instructions.go deleted file mode 100644 index d9c069035..000000000 --- a/vendor/github.com/cloudwego/iasm/x86_64/instructions.go +++ /dev/null @@ -1,97210 +0,0 @@ -// -// 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. -// - -// Code generated by "mkasm_amd64.py", DO NOT EDIT. - -package x86_64 - -// ADCB performs "Add with Carry". -// -// Mnemonic : ADC -// Supported forms : (6 forms) -// -// * ADCB imm8, al -// * ADCB imm8, r8 -// * ADCB r8, r8 -// * ADCB m8, r8 -// * ADCB imm8, m8 -// * ADCB r8, m8 -// -func (self *Program) ADCB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADCB", 2, Operands { v0, v1 }) - // ADCB imm8, al - if isImm8(v0) && v1 == AL { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x14) - m.imm1(toImmAny(v[0])) - }) - } - // ADCB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0x80) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ADCB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x10) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADCB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ADCB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x80) - m.mrsd(2, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ADCB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x10) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADCB") - } - return p -} - -// ADCL performs "Add with Carry". -// -// Mnemonic : ADC -// Supported forms : (8 forms) -// -// * ADCL imm32, eax -// * ADCL imm8, r32 -// * ADCL imm32, r32 -// * ADCL r32, r32 -// * ADCL m32, r32 -// * ADCL imm8, m32 -// * ADCL imm32, m32 -// * ADCL r32, m32 -// -func (self *Program) ADCL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADCL", 2, Operands { v0, v1 }) - // ADCL imm32, eax - if isImm32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x15) - m.imm4(toImmAny(v[0])) - }) - } - // ADCL imm8, r32 - if isImm8Ext(v0, 4) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ADCL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xd0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // ADCL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x13) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADCL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x13) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ADCL imm8, m32 - if isImm8Ext(v0, 4) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(2, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ADCL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(2, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // ADCL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADCL") - } - return p -} - -// ADCQ performs "Add with Carry". -// -// Mnemonic : ADC -// Supported forms : (8 forms) -// -// * ADCQ imm32, rax -// * ADCQ imm8, r64 -// * ADCQ imm32, r64 -// * ADCQ r64, r64 -// * ADCQ m64, r64 -// * ADCQ imm8, m64 -// * ADCQ imm32, m64 -// * ADCQ r64, m64 -// -func (self *Program) ADCQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADCQ", 2, Operands { v0, v1 }) - // ADCQ imm32, rax - if isImm32(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x15) - m.imm4(toImmAny(v[0])) - }) - } - // ADCQ imm8, r64 - if isImm8Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x83) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ADCQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x81) - m.emit(0xd0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // ADCQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x13) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADCQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x13) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ADCQ imm8, m64 - if isImm8Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x83) - m.mrsd(2, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ADCQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x81) - m.mrsd(2, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // ADCQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADCQ") - } - return p -} - -// ADCW performs "Add with Carry". -// -// Mnemonic : ADC -// Supported forms : (8 forms) -// -// * ADCW imm16, ax -// * ADCW imm8, r16 -// * ADCW imm16, r16 -// * ADCW r16, r16 -// * ADCW m16, r16 -// * ADCW imm8, m16 -// * ADCW imm16, m16 -// * ADCW r16, m16 -// -func (self *Program) ADCW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADCW", 2, Operands { v0, v1 }) - // ADCW imm16, ax - if isImm16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x15) - m.imm2(toImmAny(v[0])) - }) - } - // ADCW imm8, r16 - if isImm8Ext(v0, 2) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ADCW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xd0 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // ADCW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x13) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADCW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x13) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ADCW imm8, m16 - if isImm8Ext(v0, 2) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(2, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ADCW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(2, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // ADCW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADCW") - } - return p -} - -// ADCXL performs "Unsigned Integer Addition of Two Operands with Carry Flag". -// -// Mnemonic : ADCX -// Supported forms : (2 forms) -// -// * ADCXL r32, r32 [ADX] -// * ADCXL m32, r32 [ADX] -// -func (self *Program) ADCXL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADCXL", 2, Operands { v0, v1 }) - // ADCXL r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_ADX) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADCXL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_ADX) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADCXL") - } - return p -} - -// ADCXQ performs "Unsigned Integer Addition of Two Operands with Carry Flag". -// -// Mnemonic : ADCX -// Supported forms : (2 forms) -// -// * ADCXQ r64, r64 [ADX] -// * ADCXQ m64, r64 [ADX] -// -func (self *Program) ADCXQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADCXQ", 2, Operands { v0, v1 }) - // ADCXQ r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_ADX) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADCXQ m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_ADX) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADCXQ") - } - return p -} - -// ADDB performs "Add". -// -// Mnemonic : ADD -// Supported forms : (6 forms) -// -// * ADDB imm8, al -// * ADDB imm8, r8 -// * ADDB r8, r8 -// * ADDB m8, r8 -// * ADDB imm8, m8 -// * ADDB r8, m8 -// -func (self *Program) ADDB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDB", 2, Operands { v0, v1 }) - // ADDB imm8, al - if isImm8(v0) && v1 == AL { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x04) - m.imm1(toImmAny(v[0])) - }) - } - // ADDB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0x80) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ADDB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x00) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x02) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x02) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ADDB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x80) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ADDB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x00) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDB") - } - return p -} - -// ADDL performs "Add". -// -// Mnemonic : ADD -// Supported forms : (8 forms) -// -// * ADDL imm32, eax -// * ADDL imm8, r32 -// * ADDL imm32, r32 -// * ADDL r32, r32 -// * ADDL m32, r32 -// * ADDL imm8, m32 -// * ADDL imm32, m32 -// * ADDL r32, m32 -// -func (self *Program) ADDL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDL", 2, Operands { v0, v1 }) - // ADDL imm32, eax - if isImm32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x05) - m.imm4(toImmAny(v[0])) - }) - } - // ADDL imm8, r32 - if isImm8Ext(v0, 4) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ADDL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xc0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // ADDL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x01) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x03) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x03) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ADDL imm8, m32 - if isImm8Ext(v0, 4) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ADDL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(0, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // ADDL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x01) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDL") - } - return p -} - -// ADDPD performs "Add Packed Double-Precision Floating-Point Values". -// -// Mnemonic : ADDPD -// Supported forms : (2 forms) -// -// * ADDPD xmm, xmm [SSE2] -// * ADDPD m128, xmm [SSE2] -// -func (self *Program) ADDPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDPD", 2, Operands { v0, v1 }) - // ADDPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x58) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x58) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDPD") - } - return p -} - -// ADDPS performs "Add Packed Single-Precision Floating-Point Values". -// -// Mnemonic : ADDPS -// Supported forms : (2 forms) -// -// * ADDPS xmm, xmm [SSE] -// * ADDPS m128, xmm [SSE] -// -func (self *Program) ADDPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDPS", 2, Operands { v0, v1 }) - // ADDPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x58) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x58) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDPS") - } - return p -} - -// ADDQ performs "Add". -// -// Mnemonic : ADD -// Supported forms : (8 forms) -// -// * ADDQ imm32, rax -// * ADDQ imm8, r64 -// * ADDQ imm32, r64 -// * ADDQ r64, r64 -// * ADDQ m64, r64 -// * ADDQ imm8, m64 -// * ADDQ imm32, m64 -// * ADDQ r64, m64 -// -func (self *Program) ADDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDQ", 2, Operands { v0, v1 }) - // ADDQ imm32, rax - if isImm32(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x05) - m.imm4(toImmAny(v[0])) - }) - } - // ADDQ imm8, r64 - if isImm8Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x83) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ADDQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x81) - m.emit(0xc0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // ADDQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x01) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x03) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x03) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ADDQ imm8, m64 - if isImm8Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x83) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ADDQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x81) - m.mrsd(0, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // ADDQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x01) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDQ") - } - return p -} - -// ADDSD performs "Add Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : ADDSD -// Supported forms : (2 forms) -// -// * ADDSD xmm, xmm [SSE2] -// * ADDSD m64, xmm [SSE2] -// -func (self *Program) ADDSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDSD", 2, Operands { v0, v1 }) - // ADDSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x58) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDSD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x58) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDSD") - } - return p -} - -// ADDSS performs "Add Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : ADDSS -// Supported forms : (2 forms) -// -// * ADDSS xmm, xmm [SSE] -// * ADDSS m32, xmm [SSE] -// -func (self *Program) ADDSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDSS", 2, Operands { v0, v1 }) - // ADDSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x58) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x58) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDSS") - } - return p -} - -// ADDSUBPD performs "Packed Double-FP Add/Subtract". -// -// Mnemonic : ADDSUBPD -// Supported forms : (2 forms) -// -// * ADDSUBPD xmm, xmm [SSE3] -// * ADDSUBPD m128, xmm [SSE3] -// -func (self *Program) ADDSUBPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDSUBPD", 2, Operands { v0, v1 }) - // ADDSUBPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd0) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDSUBPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDSUBPD") - } - return p -} - -// ADDSUBPS performs "Packed Single-FP Add/Subtract". -// -// Mnemonic : ADDSUBPS -// Supported forms : (2 forms) -// -// * ADDSUBPS xmm, xmm [SSE3] -// * ADDSUBPS m128, xmm [SSE3] -// -func (self *Program) ADDSUBPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDSUBPS", 2, Operands { v0, v1 }) - // ADDSUBPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd0) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDSUBPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDSUBPS") - } - return p -} - -// ADDW performs "Add". -// -// Mnemonic : ADD -// Supported forms : (8 forms) -// -// * ADDW imm16, ax -// * ADDW imm8, r16 -// * ADDW imm16, r16 -// * ADDW r16, r16 -// * ADDW m16, r16 -// * ADDW imm8, m16 -// * ADDW imm16, m16 -// * ADDW r16, m16 -// -func (self *Program) ADDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADDW", 2, Operands { v0, v1 }) - // ADDW imm16, ax - if isImm16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x05) - m.imm2(toImmAny(v[0])) - }) - } - // ADDW imm8, r16 - if isImm8Ext(v0, 2) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ADDW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xc0 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // ADDW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x01) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x03) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADDW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x03) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ADDW imm8, m16 - if isImm8Ext(v0, 2) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ADDW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(0, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // ADDW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x01) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADDW") - } - return p -} - -// ADOXL performs "Unsigned Integer Addition of Two Operands with Overflow Flag". -// -// Mnemonic : ADOX -// Supported forms : (2 forms) -// -// * ADOXL r32, r32 [ADX] -// * ADOXL m32, r32 [ADX] -// -func (self *Program) ADOXL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADOXL", 2, Operands { v0, v1 }) - // ADOXL r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_ADX) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADOXL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_ADX) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADOXL") - } - return p -} - -// ADOXQ performs "Unsigned Integer Addition of Two Operands with Overflow Flag". -// -// Mnemonic : ADOX -// Supported forms : (2 forms) -// -// * ADOXQ r64, r64 [ADX] -// * ADOXQ m64, r64 [ADX] -// -func (self *Program) ADOXQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ADOXQ", 2, Operands { v0, v1 }) - // ADOXQ r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_ADX) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ADOXQ m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_ADX) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ADOXQ") - } - return p -} - -// AESDEC performs "Perform One Round of an AES Decryption Flow". -// -// Mnemonic : AESDEC -// Supported forms : (2 forms) -// -// * AESDEC xmm, xmm [AES] -// * AESDEC m128, xmm [AES] -// -func (self *Program) AESDEC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("AESDEC", 2, Operands { v0, v1 }) - // AESDEC xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xde) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // AESDEC m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xde) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for AESDEC") - } - return p -} - -// AESDECLAST performs "Perform Last Round of an AES Decryption Flow". -// -// Mnemonic : AESDECLAST -// Supported forms : (2 forms) -// -// * AESDECLAST xmm, xmm [AES] -// * AESDECLAST m128, xmm [AES] -// -func (self *Program) AESDECLAST(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("AESDECLAST", 2, Operands { v0, v1 }) - // AESDECLAST xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // AESDECLAST m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xdf) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for AESDECLAST") - } - return p -} - -// AESENC performs "Perform One Round of an AES Encryption Flow". -// -// Mnemonic : AESENC -// Supported forms : (2 forms) -// -// * AESENC xmm, xmm [AES] -// * AESENC m128, xmm [AES] -// -func (self *Program) AESENC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("AESENC", 2, Operands { v0, v1 }) - // AESENC xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xdc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // AESENC m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xdc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for AESENC") - } - return p -} - -// AESENCLAST performs "Perform Last Round of an AES Encryption Flow". -// -// Mnemonic : AESENCLAST -// Supported forms : (2 forms) -// -// * AESENCLAST xmm, xmm [AES] -// * AESENCLAST m128, xmm [AES] -// -func (self *Program) AESENCLAST(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("AESENCLAST", 2, Operands { v0, v1 }) - // AESENCLAST xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xdd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // AESENCLAST m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xdd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for AESENCLAST") - } - return p -} - -// AESIMC performs "Perform the AES InvMixColumn Transformation". -// -// Mnemonic : AESIMC -// Supported forms : (2 forms) -// -// * AESIMC xmm, xmm [AES] -// * AESIMC m128, xmm [AES] -// -func (self *Program) AESIMC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("AESIMC", 2, Operands { v0, v1 }) - // AESIMC xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // AESIMC m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xdb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for AESIMC") - } - return p -} - -// AESKEYGENASSIST performs "AES Round Key Generation Assist". -// -// Mnemonic : AESKEYGENASSIST -// Supported forms : (2 forms) -// -// * AESKEYGENASSIST imm8, xmm, xmm [AES] -// * AESKEYGENASSIST imm8, m128, xmm [AES] -// -func (self *Program) AESKEYGENASSIST(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("AESKEYGENASSIST", 3, Operands { v0, v1, v2 }) - // AESKEYGENASSIST imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // AESKEYGENASSIST imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for AESKEYGENASSIST") - } - return p -} - -// ANDB performs "Logical AND". -// -// Mnemonic : AND -// Supported forms : (6 forms) -// -// * ANDB imm8, al -// * ANDB imm8, r8 -// * ANDB r8, r8 -// * ANDB m8, r8 -// * ANDB imm8, m8 -// * ANDB r8, m8 -// -func (self *Program) ANDB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ANDB", 2, Operands { v0, v1 }) - // ANDB imm8, al - if isImm8(v0) && v1 == AL { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x24) - m.imm1(toImmAny(v[0])) - }) - } - // ANDB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0x80) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ANDB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x20) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x22) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ANDB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x22) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ANDB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x80) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ANDB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x20) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDB") - } - return p -} - -// ANDL performs "Logical AND". -// -// Mnemonic : AND -// Supported forms : (8 forms) -// -// * ANDL imm32, eax -// * ANDL imm8, r32 -// * ANDL imm32, r32 -// * ANDL r32, r32 -// * ANDL m32, r32 -// * ANDL imm8, m32 -// * ANDL imm32, m32 -// * ANDL r32, m32 -// -func (self *Program) ANDL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ANDL", 2, Operands { v0, v1 }) - // ANDL imm32, eax - if isImm32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x25) - m.imm4(toImmAny(v[0])) - }) - } - // ANDL imm8, r32 - if isImm8Ext(v0, 4) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ANDL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xe0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // ANDL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x21) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x23) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ANDL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x23) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ANDL imm8, m32 - if isImm8Ext(v0, 4) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ANDL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(4, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // ANDL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x21) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDL") - } - return p -} - -// ANDNL performs "Logical AND NOT". -// -// Mnemonic : ANDN -// Supported forms : (2 forms) -// -// * ANDNL r32, r32, r32 [BMI] -// * ANDNL m32, r32, r32 [BMI] -// -func (self *Program) ANDNL(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("ANDNL", 3, Operands { v0, v1, v2 }) - // ANDNL r32, r32, r32 - if isReg32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0xf2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // ANDNL m32, r32, r32 - if isM32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x00, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf2) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDNL") - } - return p -} - -// ANDNPD performs "Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : ANDNPD -// Supported forms : (2 forms) -// -// * ANDNPD xmm, xmm [SSE2] -// * ANDNPD m128, xmm [SSE2] -// -func (self *Program) ANDNPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ANDNPD", 2, Operands { v0, v1 }) - // ANDNPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x55) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ANDNPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x55) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDNPD") - } - return p -} - -// ANDNPS performs "Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : ANDNPS -// Supported forms : (2 forms) -// -// * ANDNPS xmm, xmm [SSE] -// * ANDNPS m128, xmm [SSE] -// -func (self *Program) ANDNPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ANDNPS", 2, Operands { v0, v1 }) - // ANDNPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x55) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ANDNPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x55) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDNPS") - } - return p -} - -// ANDNQ performs "Logical AND NOT". -// -// Mnemonic : ANDN -// Supported forms : (2 forms) -// -// * ANDNQ r64, r64, r64 [BMI] -// * ANDNQ m64, r64, r64 [BMI] -// -func (self *Program) ANDNQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("ANDNQ", 3, Operands { v0, v1, v2 }) - // ANDNQ r64, r64, r64 - if isReg64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0xf2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // ANDNQ m64, r64, r64 - if isM64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf2) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDNQ") - } - return p -} - -// ANDPD performs "Bitwise Logical AND of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : ANDPD -// Supported forms : (2 forms) -// -// * ANDPD xmm, xmm [SSE2] -// * ANDPD m128, xmm [SSE2] -// -func (self *Program) ANDPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ANDPD", 2, Operands { v0, v1 }) - // ANDPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x54) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ANDPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x54) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDPD") - } - return p -} - -// ANDPS performs "Bitwise Logical AND of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : ANDPS -// Supported forms : (2 forms) -// -// * ANDPS xmm, xmm [SSE] -// * ANDPS m128, xmm [SSE] -// -func (self *Program) ANDPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ANDPS", 2, Operands { v0, v1 }) - // ANDPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x54) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ANDPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x54) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDPS") - } - return p -} - -// ANDQ performs "Logical AND". -// -// Mnemonic : AND -// Supported forms : (8 forms) -// -// * ANDQ imm32, rax -// * ANDQ imm8, r64 -// * ANDQ imm32, r64 -// * ANDQ r64, r64 -// * ANDQ m64, r64 -// * ANDQ imm8, m64 -// * ANDQ imm32, m64 -// * ANDQ r64, m64 -// -func (self *Program) ANDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ANDQ", 2, Operands { v0, v1 }) - // ANDQ imm32, rax - if isImm32(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x25) - m.imm4(toImmAny(v[0])) - }) - } - // ANDQ imm8, r64 - if isImm8Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x83) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ANDQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x81) - m.emit(0xe0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // ANDQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x21) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x23) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ANDQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x23) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ANDQ imm8, m64 - if isImm8Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x83) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ANDQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x81) - m.mrsd(4, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // ANDQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x21) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDQ") - } - return p -} - -// ANDW performs "Logical AND". -// -// Mnemonic : AND -// Supported forms : (8 forms) -// -// * ANDW imm16, ax -// * ANDW imm8, r16 -// * ANDW imm16, r16 -// * ANDW r16, r16 -// * ANDW m16, r16 -// * ANDW imm8, m16 -// * ANDW imm16, m16 -// * ANDW r16, m16 -// -func (self *Program) ANDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ANDW", 2, Operands { v0, v1 }) - // ANDW imm16, ax - if isImm16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x25) - m.imm2(toImmAny(v[0])) - }) - } - // ANDW imm8, r16 - if isImm8Ext(v0, 2) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ANDW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xe0 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // ANDW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x21) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x23) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ANDW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x23) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ANDW imm8, m16 - if isImm8Ext(v0, 2) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ANDW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(4, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // ANDW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x21) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ANDW") - } - return p -} - -// BEXTR performs "Bit Field Extract". -// -// Mnemonic : BEXTR -// Supported forms : (8 forms) -// -// * BEXTR imm32, r32, r32 [TBM] -// * BEXTR imm32, m32, r32 [TBM] -// * BEXTR imm32, r64, r64 [TBM] -// * BEXTR imm32, m64, r64 [TBM] -// * BEXTR r32, r32, r32 [BMI] -// * BEXTR r32, m32, r32 [BMI] -// * BEXTR r64, r64, r64 [BMI] -// * BEXTR r64, m64, r64 [BMI] -// -func (self *Program) BEXTR(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("BEXTR", 3, Operands { v0, v1, v2 }) - // BEXTR imm32, r32, r32 - if isImm32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xea ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // BEXTR imm32, m32, r32 - if isImm32(v0) && isM32(v1) && isReg32(v2) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1010, 0x00, hcode(v[2]), addr(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // BEXTR imm32, r64, r64 - if isImm32(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xea ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xf8) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // BEXTR imm32, m64, r64 - if isImm32(v0) && isM64(v1) && isReg64(v2) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1010, 0x80, hcode(v[2]), addr(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // BEXTR r32, r32, r32 - if isReg32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // BEXTR r32, m32, r32 - if isReg32(v0) && isM32(v1) && isReg32(v2) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf7) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // BEXTR r64, r64, r64 - if isReg64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xf8 ^ (hlcode(v[0]) << 3)) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // BEXTR r64, m64, r64 - if isReg64(v0) && isM64(v1) && isReg64(v2) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x80, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf7) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BEXTR") - } - return p -} - -// BLCFILL performs "Fill From Lowest Clear Bit". -// -// Mnemonic : BLCFILL -// Supported forms : (4 forms) -// -// * BLCFILL r32, r32 [TBM] -// * BLCFILL m32, r32 [TBM] -// * BLCFILL r64, r64 [TBM] -// * BLCFILL m64, r64 [TBM] -// -func (self *Program) BLCFILL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLCFILL", 2, Operands { v0, v1 }) - // BLCFILL r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xc8 | lcode(v[0])) - }) - } - // BLCFILL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(1, addr(v[0]), 1) - }) - } - // BLCFILL r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xc8 | lcode(v[0])) - }) - } - // BLCFILL m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLCFILL") - } - return p -} - -// BLCI performs "Isolate Lowest Clear Bit". -// -// Mnemonic : BLCI -// Supported forms : (4 forms) -// -// * BLCI r32, r32 [TBM] -// * BLCI m32, r32 [TBM] -// * BLCI r64, r64 [TBM] -// * BLCI m64, r64 [TBM] -// -func (self *Program) BLCI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLCI", 2, Operands { v0, v1 }) - // BLCI r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0x02) - m.emit(0xf0 | lcode(v[0])) - }) - } - // BLCI m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x02) - m.mrsd(6, addr(v[0]), 1) - }) - } - // BLCI r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x02) - m.emit(0xf0 | lcode(v[0])) - }) - } - // BLCI m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x02) - m.mrsd(6, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLCI") - } - return p -} - -// BLCIC performs "Isolate Lowest Set Bit and Complement". -// -// Mnemonic : BLCIC -// Supported forms : (4 forms) -// -// * BLCIC r32, r32 [TBM] -// * BLCIC m32, r32 [TBM] -// * BLCIC r64, r64 [TBM] -// * BLCIC m64, r64 [TBM] -// -func (self *Program) BLCIC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLCIC", 2, Operands { v0, v1 }) - // BLCIC r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xe8 | lcode(v[0])) - }) - } - // BLCIC m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(5, addr(v[0]), 1) - }) - } - // BLCIC r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xe8 | lcode(v[0])) - }) - } - // BLCIC m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(5, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLCIC") - } - return p -} - -// BLCMSK performs "Mask From Lowest Clear Bit". -// -// Mnemonic : BLCMSK -// Supported forms : (4 forms) -// -// * BLCMSK r32, r32 [TBM] -// * BLCMSK m32, r32 [TBM] -// * BLCMSK r64, r64 [TBM] -// * BLCMSK m64, r64 [TBM] -// -func (self *Program) BLCMSK(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLCMSK", 2, Operands { v0, v1 }) - // BLCMSK r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0x02) - m.emit(0xc8 | lcode(v[0])) - }) - } - // BLCMSK m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x02) - m.mrsd(1, addr(v[0]), 1) - }) - } - // BLCMSK r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x02) - m.emit(0xc8 | lcode(v[0])) - }) - } - // BLCMSK m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x02) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLCMSK") - } - return p -} - -// BLCS performs "Set Lowest Clear Bit". -// -// Mnemonic : BLCS -// Supported forms : (4 forms) -// -// * BLCS r32, r32 [TBM] -// * BLCS m32, r32 [TBM] -// * BLCS r64, r64 [TBM] -// * BLCS m64, r64 [TBM] -// -func (self *Program) BLCS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLCS", 2, Operands { v0, v1 }) - // BLCS r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xd8 | lcode(v[0])) - }) - } - // BLCS m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(3, addr(v[0]), 1) - }) - } - // BLCS r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xd8 | lcode(v[0])) - }) - } - // BLCS m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(3, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLCS") - } - return p -} - -// BLENDPD performs "Blend Packed Double Precision Floating-Point Values". -// -// Mnemonic : BLENDPD -// Supported forms : (2 forms) -// -// * BLENDPD imm8, xmm, xmm [SSE4.1] -// * BLENDPD imm8, m128, xmm [SSE4.1] -// -func (self *Program) BLENDPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("BLENDPD", 3, Operands { v0, v1, v2 }) - // BLENDPD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BLENDPD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0d) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for BLENDPD") - } - return p -} - -// BLENDPS performs " Blend Packed Single Precision Floating-Point Values". -// -// Mnemonic : BLENDPS -// Supported forms : (2 forms) -// -// * BLENDPS imm8, xmm, xmm [SSE4.1] -// * BLENDPS imm8, m128, xmm [SSE4.1] -// -func (self *Program) BLENDPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("BLENDPS", 3, Operands { v0, v1, v2 }) - // BLENDPS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BLENDPS imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0c) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for BLENDPS") - } - return p -} - -// BLENDVPD performs " Variable Blend Packed Double Precision Floating-Point Values". -// -// Mnemonic : BLENDVPD -// Supported forms : (2 forms) -// -// * BLENDVPD xmm0, xmm, xmm [SSE4.1] -// * BLENDVPD xmm0, m128, xmm [SSE4.1] -// -func (self *Program) BLENDVPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("BLENDVPD", 3, Operands { v0, v1, v2 }) - // BLENDVPD xmm0, xmm, xmm - if v0 == XMM0 && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // BLENDVPD xmm0, m128, xmm - if v0 == XMM0 && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLENDVPD") - } - return p -} - -// BLENDVPS performs " Variable Blend Packed Single Precision Floating-Point Values". -// -// Mnemonic : BLENDVPS -// Supported forms : (2 forms) -// -// * BLENDVPS xmm0, xmm, xmm [SSE4.1] -// * BLENDVPS xmm0, m128, xmm [SSE4.1] -// -func (self *Program) BLENDVPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("BLENDVPS", 3, Operands { v0, v1, v2 }) - // BLENDVPS xmm0, xmm, xmm - if v0 == XMM0 && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // BLENDVPS xmm0, m128, xmm - if v0 == XMM0 && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLENDVPS") - } - return p -} - -// BLSFILL performs "Fill From Lowest Set Bit". -// -// Mnemonic : BLSFILL -// Supported forms : (4 forms) -// -// * BLSFILL r32, r32 [TBM] -// * BLSFILL m32, r32 [TBM] -// * BLSFILL r64, r64 [TBM] -// * BLSFILL m64, r64 [TBM] -// -func (self *Program) BLSFILL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLSFILL", 2, Operands { v0, v1 }) - // BLSFILL r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xd0 | lcode(v[0])) - }) - } - // BLSFILL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(2, addr(v[0]), 1) - }) - } - // BLSFILL r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xd0 | lcode(v[0])) - }) - } - // BLSFILL m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLSFILL") - } - return p -} - -// BLSI performs "Isolate Lowest Set Bit". -// -// Mnemonic : BLSI -// Supported forms : (4 forms) -// -// * BLSI r32, r32 [BMI] -// * BLSI m32, r32 [BMI] -// * BLSI r64, r64 [BMI] -// * BLSI m64, r64 [BMI] -// -func (self *Program) BLSI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLSI", 2, Operands { v0, v1 }) - // BLSI r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0xf3) - m.emit(0xd8 | lcode(v[0])) - }) - } - // BLSI m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0xf3) - m.mrsd(3, addr(v[0]), 1) - }) - } - // BLSI r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0xf3) - m.emit(0xd8 | lcode(v[0])) - }) - } - // BLSI m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0xf3) - m.mrsd(3, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLSI") - } - return p -} - -// BLSIC performs "Isolate Lowest Set Bit and Complement". -// -// Mnemonic : BLSIC -// Supported forms : (4 forms) -// -// * BLSIC r32, r32 [TBM] -// * BLSIC m32, r32 [TBM] -// * BLSIC r64, r64 [TBM] -// * BLSIC m64, r64 [TBM] -// -func (self *Program) BLSIC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLSIC", 2, Operands { v0, v1 }) - // BLSIC r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xf0 | lcode(v[0])) - }) - } - // BLSIC m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(6, addr(v[0]), 1) - }) - } - // BLSIC r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xf0 | lcode(v[0])) - }) - } - // BLSIC m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(6, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLSIC") - } - return p -} - -// BLSMSK performs "Mask From Lowest Set Bit". -// -// Mnemonic : BLSMSK -// Supported forms : (4 forms) -// -// * BLSMSK r32, r32 [BMI] -// * BLSMSK m32, r32 [BMI] -// * BLSMSK r64, r64 [BMI] -// * BLSMSK m64, r64 [BMI] -// -func (self *Program) BLSMSK(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLSMSK", 2, Operands { v0, v1 }) - // BLSMSK r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0xf3) - m.emit(0xd0 | lcode(v[0])) - }) - } - // BLSMSK m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0xf3) - m.mrsd(2, addr(v[0]), 1) - }) - } - // BLSMSK r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0xf3) - m.emit(0xd0 | lcode(v[0])) - }) - } - // BLSMSK m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0xf3) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLSMSK") - } - return p -} - -// BLSR performs "Reset Lowest Set Bit". -// -// Mnemonic : BLSR -// Supported forms : (4 forms) -// -// * BLSR r32, r32 [BMI] -// * BLSR m32, r32 [BMI] -// * BLSR r64, r64 [BMI] -// * BLSR m64, r64 [BMI] -// -func (self *Program) BLSR(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BLSR", 2, Operands { v0, v1 }) - // BLSR r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0xf3) - m.emit(0xc8 | lcode(v[0])) - }) - } - // BLSR m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0xf3) - m.mrsd(1, addr(v[0]), 1) - }) - } - // BLSR r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0xf3) - m.emit(0xc8 | lcode(v[0])) - }) - } - // BLSR m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0xf3) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BLSR") - } - return p -} - -// BSFL performs "Bit Scan Forward". -// -// Mnemonic : BSF -// Supported forms : (2 forms) -// -// * BSFL r32, r32 -// * BSFL m32, r32 -// -func (self *Program) BSFL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BSFL", 2, Operands { v0, v1 }) - // BSFL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // BSFL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BSFL") - } - return p -} - -// BSFQ performs "Bit Scan Forward". -// -// Mnemonic : BSF -// Supported forms : (2 forms) -// -// * BSFQ r64, r64 -// * BSFQ m64, r64 -// -func (self *Program) BSFQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BSFQ", 2, Operands { v0, v1 }) - // BSFQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // BSFQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xbc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BSFQ") - } - return p -} - -// BSFW performs "Bit Scan Forward". -// -// Mnemonic : BSF -// Supported forms : (2 forms) -// -// * BSFW r16, r16 -// * BSFW m16, r16 -// -func (self *Program) BSFW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BSFW", 2, Operands { v0, v1 }) - // BSFW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // BSFW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BSFW") - } - return p -} - -// BSRL performs "Bit Scan Reverse". -// -// Mnemonic : BSR -// Supported forms : (2 forms) -// -// * BSRL r32, r32 -// * BSRL m32, r32 -// -func (self *Program) BSRL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BSRL", 2, Operands { v0, v1 }) - // BSRL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // BSRL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BSRL") - } - return p -} - -// BSRQ performs "Bit Scan Reverse". -// -// Mnemonic : BSR -// Supported forms : (2 forms) -// -// * BSRQ r64, r64 -// * BSRQ m64, r64 -// -func (self *Program) BSRQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BSRQ", 2, Operands { v0, v1 }) - // BSRQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // BSRQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xbd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BSRQ") - } - return p -} - -// BSRW performs "Bit Scan Reverse". -// -// Mnemonic : BSR -// Supported forms : (2 forms) -// -// * BSRW r16, r16 -// * BSRW m16, r16 -// -func (self *Program) BSRW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BSRW", 2, Operands { v0, v1 }) - // BSRW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // BSRW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BSRW") - } - return p -} - -// BSWAPL performs "Byte Swap". -// -// Mnemonic : BSWAP -// Supported forms : (1 form) -// -// * BSWAPL r32 -// -func (self *Program) BSWAPL(v0 interface{}) *Instruction { - p := self.alloc("BSWAPL", 1, Operands { v0 }) - // BSWAPL r32 - if isReg32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0x0f) - m.emit(0xc8 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for BSWAPL") - } - return p -} - -// BSWAPQ performs "Byte Swap". -// -// Mnemonic : BSWAP -// Supported forms : (1 form) -// -// * BSWAPQ r64 -// -func (self *Program) BSWAPQ(v0 interface{}) *Instruction { - p := self.alloc("BSWAPQ", 1, Operands { v0 }) - // BSWAPQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xc8 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for BSWAPQ") - } - return p -} - -// BTCL performs "Bit Test and Complement". -// -// Mnemonic : BTC -// Supported forms : (4 forms) -// -// * BTCL imm8, r32 -// * BTCL r32, r32 -// * BTCL imm8, m32 -// * BTCL r32, m32 -// -func (self *Program) BTCL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTCL", 2, Operands { v0, v1 }) - // BTCL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTCL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xbb) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTCL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTCL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xbb) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTCL") - } - return p -} - -// BTCQ performs "Bit Test and Complement". -// -// Mnemonic : BTC -// Supported forms : (4 forms) -// -// * BTCQ imm8, r64 -// * BTCQ r64, r64 -// * BTCQ imm8, m64 -// * BTCQ r64, m64 -// -func (self *Program) BTCQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTCQ", 2, Operands { v0, v1 }) - // BTCQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTCQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xbb) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTCQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTCQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0xbb) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTCQ") - } - return p -} - -// BTCW performs "Bit Test and Complement". -// -// Mnemonic : BTC -// Supported forms : (4 forms) -// -// * BTCW imm8, r16 -// * BTCW r16, r16 -// * BTCW imm8, m16 -// * BTCW r16, m16 -// -func (self *Program) BTCW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTCW", 2, Operands { v0, v1 }) - // BTCW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTCW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xbb) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTCW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTCW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xbb) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTCW") - } - return p -} - -// BTL performs "Bit Test". -// -// Mnemonic : BT -// Supported forms : (4 forms) -// -// * BTL imm8, r32 -// * BTL r32, r32 -// * BTL imm8, m32 -// * BTL r32, m32 -// -func (self *Program) BTL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTL", 2, Operands { v0, v1 }) - // BTL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xa3) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xa3) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTL") - } - return p -} - -// BTQ performs "Bit Test". -// -// Mnemonic : BT -// Supported forms : (4 forms) -// -// * BTQ imm8, r64 -// * BTQ r64, r64 -// * BTQ imm8, m64 -// * BTQ r64, m64 -// -func (self *Program) BTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTQ", 2, Operands { v0, v1 }) - // BTQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xa3) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0xa3) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTQ") - } - return p -} - -// BTRL performs "Bit Test and Reset". -// -// Mnemonic : BTR -// Supported forms : (4 forms) -// -// * BTRL imm8, r32 -// * BTRL r32, r32 -// * BTRL imm8, m32 -// * BTRL r32, m32 -// -func (self *Program) BTRL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTRL", 2, Operands { v0, v1 }) - // BTRL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTRL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xb3) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTRL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(6, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTRL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xb3) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTRL") - } - return p -} - -// BTRQ performs "Bit Test and Reset". -// -// Mnemonic : BTR -// Supported forms : (4 forms) -// -// * BTRQ imm8, r64 -// * BTRQ r64, r64 -// * BTRQ imm8, m64 -// * BTRQ r64, m64 -// -func (self *Program) BTRQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTRQ", 2, Operands { v0, v1 }) - // BTRQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTRQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xb3) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTRQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(6, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTRQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0xb3) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTRQ") - } - return p -} - -// BTRW performs "Bit Test and Reset". -// -// Mnemonic : BTR -// Supported forms : (4 forms) -// -// * BTRW imm8, r16 -// * BTRW r16, r16 -// * BTRW imm8, m16 -// * BTRW r16, m16 -// -func (self *Program) BTRW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTRW", 2, Operands { v0, v1 }) - // BTRW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTRW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xb3) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTRW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(6, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTRW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xb3) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTRW") - } - return p -} - -// BTSL performs "Bit Test and Set". -// -// Mnemonic : BTS -// Supported forms : (4 forms) -// -// * BTSL imm8, r32 -// * BTSL r32, r32 -// * BTSL imm8, m32 -// * BTSL r32, m32 -// -func (self *Program) BTSL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTSL", 2, Operands { v0, v1 }) - // BTSL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTSL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xab) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTSL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTSL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xab) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTSL") - } - return p -} - -// BTSQ performs "Bit Test and Set". -// -// Mnemonic : BTS -// Supported forms : (4 forms) -// -// * BTSQ imm8, r64 -// * BTSQ r64, r64 -// * BTSQ imm8, m64 -// * BTSQ r64, m64 -// -func (self *Program) BTSQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTSQ", 2, Operands { v0, v1 }) - // BTSQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTSQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xab) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTSQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTSQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0xab) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTSQ") - } - return p -} - -// BTSW performs "Bit Test and Set". -// -// Mnemonic : BTS -// Supported forms : (4 forms) -// -// * BTSW imm8, r16 -// * BTSW r16, r16 -// * BTSW imm8, m16 -// * BTSW r16, m16 -// -func (self *Program) BTSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTSW", 2, Operands { v0, v1 }) - // BTSW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTSW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xab) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTSW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTSW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xab) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTSW") - } - return p -} - -// BTW performs "Bit Test". -// -// Mnemonic : BT -// Supported forms : (4 forms) -// -// * BTW imm8, r16 -// * BTW r16, r16 -// * BTW imm8, m16 -// * BTW r16, m16 -// -func (self *Program) BTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("BTW", 2, Operands { v0, v1 }) - // BTW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0xba) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // BTW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xa3) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // BTW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x0f) - m.emit(0xba) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // BTW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xa3) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BTW") - } - return p -} - -// BZHI performs "Zero High Bits Starting with Specified Bit Position". -// -// Mnemonic : BZHI -// Supported forms : (4 forms) -// -// * BZHI r32, r32, r32 [BMI2] -// * BZHI r32, m32, r32 [BMI2] -// * BZHI r64, r64, r64 [BMI2] -// * BZHI r64, m64, r64 [BMI2] -// -func (self *Program) BZHI(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("BZHI", 3, Operands { v0, v1, v2 }) - // BZHI r32, r32, r32 - if isReg32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // BZHI r32, m32, r32 - if isReg32(v0) && isM32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // BZHI r64, r64, r64 - if isReg64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xf8 ^ (hlcode(v[0]) << 3)) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // BZHI r64, m64, r64 - if isReg64(v0) && isM64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x80, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for BZHI") - } - return p -} - -// CALL performs "Call Procedure". -// -// Mnemonic : CALL -// Supported forms : (1 form) -// -// * CALL rel32 -// -func (self *Program) CALL(v0 interface{}) *Instruction { - p := self.alloc("CALL", 1, Operands { v0 }) - // CALL rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xe8) - m.imm4(relv(v[0])) - }) - } - // CALL label - if isLabel(v0) { - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0xe8) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for CALL") - } - return p -} - -// CALLQ performs "Call Procedure". -// -// Mnemonic : CALL -// Supported forms : (2 forms) -// -// * CALLQ r64 -// * CALLQ m64 -// -func (self *Program) CALLQ(v0 interface{}) *Instruction { - p := self.alloc("CALLQ", 1, Operands { v0 }) - // CALLQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xff) - m.emit(0xd0 | lcode(v[0])) - }) - } - // CALLQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xff) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CALLQ") - } - return p -} - -// CBTW performs "Convert Byte to Word". -// -// Mnemonic : CBW -// Supported forms : (1 form) -// -// * CBTW -// -func (self *Program) CBTW() *Instruction { - p := self.alloc("CBTW", 0, Operands { }) - // CBTW - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x98) - }) - return p -} - -// CLC performs "Clear Carry Flag". -// -// Mnemonic : CLC -// Supported forms : (1 form) -// -// * CLC -// -func (self *Program) CLC() *Instruction { - p := self.alloc("CLC", 0, Operands { }) - // CLC - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf8) - }) - return p -} - -// CLD performs "Clear Direction Flag". -// -// Mnemonic : CLD -// Supported forms : (1 form) -// -// * CLD -// -func (self *Program) CLD() *Instruction { - p := self.alloc("CLD", 0, Operands { }) - // CLD - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xfc) - }) - return p -} - -// CLFLUSH performs "Flush Cache Line". -// -// Mnemonic : CLFLUSH -// Supported forms : (1 form) -// -// * CLFLUSH m8 [CLFLUSH] -// -func (self *Program) CLFLUSH(v0 interface{}) *Instruction { - p := self.alloc("CLFLUSH", 1, Operands { v0 }) - // CLFLUSH m8 - if isM8(v0) { - self.require(ISA_CLFLUSH) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0xae) - m.mrsd(7, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CLFLUSH") - } - return p -} - -// CLFLUSHOPT performs "Flush Cache Line Optimized". -// -// Mnemonic : CLFLUSHOPT -// Supported forms : (1 form) -// -// * CLFLUSHOPT m8 [CLFLUSHOPT] -// -func (self *Program) CLFLUSHOPT(v0 interface{}) *Instruction { - p := self.alloc("CLFLUSHOPT", 1, Operands { v0 }) - // CLFLUSHOPT m8 - if isM8(v0) { - self.require(ISA_CLFLUSHOPT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0xae) - m.mrsd(7, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CLFLUSHOPT") - } - return p -} - -// CLTD performs "Convert Doubleword to Quadword". -// -// Mnemonic : CDQ -// Supported forms : (1 form) -// -// * CLTD -// -func (self *Program) CLTD() *Instruction { - p := self.alloc("CLTD", 0, Operands { }) - // CLTD - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x99) - }) - return p -} - -// CLTQ performs "Convert Doubleword to Quadword". -// -// Mnemonic : CDQE -// Supported forms : (1 form) -// -// * CLTQ -// -func (self *Program) CLTQ() *Instruction { - p := self.alloc("CLTQ", 0, Operands { }) - // CLTQ - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x98) - }) - return p -} - -// CLWB performs "Cache Line Write Back". -// -// Mnemonic : CLWB -// Supported forms : (1 form) -// -// * CLWB m8 [CLWB] -// -func (self *Program) CLWB(v0 interface{}) *Instruction { - p := self.alloc("CLWB", 1, Operands { v0 }) - // CLWB m8 - if isM8(v0) { - self.require(ISA_CLWB) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0xae) - m.mrsd(6, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CLWB") - } - return p -} - -// CLZERO performs "Zero-out 64-bit Cache Line". -// -// Mnemonic : CLZERO -// Supported forms : (1 form) -// -// * CLZERO [CLZERO] -// -func (self *Program) CLZERO() *Instruction { - p := self.alloc("CLZERO", 0, Operands { }) - // CLZERO - self.require(ISA_CLZERO) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x01) - m.emit(0xfc) - }) - return p -} - -// CMC performs "Complement Carry Flag". -// -// Mnemonic : CMC -// Supported forms : (1 form) -// -// * CMC -// -func (self *Program) CMC() *Instruction { - p := self.alloc("CMC", 0, Operands { }) - // CMC - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf5) - }) - return p -} - -// CMOVA performs "Move if above (CF == 0 and ZF == 0)". -// -// Mnemonic : CMOVA -// Supported forms : (6 forms) -// -// * CMOVA r16, r16 [CMOV] -// * CMOVA m16, r16 [CMOV] -// * CMOVA r32, r32 [CMOV] -// * CMOVA m32, r32 [CMOV] -// * CMOVA r64, r64 [CMOV] -// * CMOVA m64, r64 [CMOV] -// -func (self *Program) CMOVA(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVA", 2, Operands { v0, v1 }) - // CMOVA r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x47) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVA m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x47) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVA r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x47) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVA m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x47) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVA r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x47) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVA m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x47) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVA") - } - return p -} - -// CMOVAE performs "Move if above or equal (CF == 0)". -// -// Mnemonic : CMOVAE -// Supported forms : (6 forms) -// -// * CMOVAE r16, r16 [CMOV] -// * CMOVAE m16, r16 [CMOV] -// * CMOVAE r32, r32 [CMOV] -// * CMOVAE m32, r32 [CMOV] -// * CMOVAE r64, r64 [CMOV] -// * CMOVAE m64, r64 [CMOV] -// -func (self *Program) CMOVAE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVAE", 2, Operands { v0, v1 }) - // CMOVAE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x43) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVAE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x43) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVAE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x43) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVAE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x43) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVAE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x43) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVAE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x43) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVAE") - } - return p -} - -// CMOVB performs "Move if below (CF == 1)". -// -// Mnemonic : CMOVB -// Supported forms : (6 forms) -// -// * CMOVB r16, r16 [CMOV] -// * CMOVB m16, r16 [CMOV] -// * CMOVB r32, r32 [CMOV] -// * CMOVB m32, r32 [CMOV] -// * CMOVB r64, r64 [CMOV] -// * CMOVB m64, r64 [CMOV] -// -func (self *Program) CMOVB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVB", 2, Operands { v0, v1 }) - // CMOVB r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVB m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVB r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVB m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVB r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVB m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVB") - } - return p -} - -// CMOVBE performs "Move if below or equal (CF == 1 or ZF == 1)". -// -// Mnemonic : CMOVBE -// Supported forms : (6 forms) -// -// * CMOVBE r16, r16 [CMOV] -// * CMOVBE m16, r16 [CMOV] -// * CMOVBE r32, r32 [CMOV] -// * CMOVBE m32, r32 [CMOV] -// * CMOVBE r64, r64 [CMOV] -// * CMOVBE m64, r64 [CMOV] -// -func (self *Program) CMOVBE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVBE", 2, Operands { v0, v1 }) - // CMOVBE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x46) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVBE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x46) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVBE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x46) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVBE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x46) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVBE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x46) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVBE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x46) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVBE") - } - return p -} - -// CMOVC performs "Move if carry (CF == 1)". -// -// Mnemonic : CMOVC -// Supported forms : (6 forms) -// -// * CMOVC r16, r16 [CMOV] -// * CMOVC m16, r16 [CMOV] -// * CMOVC r32, r32 [CMOV] -// * CMOVC m32, r32 [CMOV] -// * CMOVC r64, r64 [CMOV] -// * CMOVC m64, r64 [CMOV] -// -func (self *Program) CMOVC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVC", 2, Operands { v0, v1 }) - // CMOVC r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVC m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVC r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVC m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVC r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVC m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVC") - } - return p -} - -// CMOVE performs "Move if equal (ZF == 1)". -// -// Mnemonic : CMOVE -// Supported forms : (6 forms) -// -// * CMOVE r16, r16 [CMOV] -// * CMOVE m16, r16 [CMOV] -// * CMOVE r32, r32 [CMOV] -// * CMOVE m32, r32 [CMOV] -// * CMOVE r64, r64 [CMOV] -// * CMOVE m64, r64 [CMOV] -// -func (self *Program) CMOVE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVE", 2, Operands { v0, v1 }) - // CMOVE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVE") - } - return p -} - -// CMOVG performs "Move if greater (ZF == 0 and SF == OF)". -// -// Mnemonic : CMOVG -// Supported forms : (6 forms) -// -// * CMOVG r16, r16 [CMOV] -// * CMOVG m16, r16 [CMOV] -// * CMOVG r32, r32 [CMOV] -// * CMOVG m32, r32 [CMOV] -// * CMOVG r64, r64 [CMOV] -// * CMOVG m64, r64 [CMOV] -// -func (self *Program) CMOVG(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVG", 2, Operands { v0, v1 }) - // CMOVG r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVG m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVG r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVG m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVG r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVG m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVG") - } - return p -} - -// CMOVGE performs "Move if greater or equal (SF == OF)". -// -// Mnemonic : CMOVGE -// Supported forms : (6 forms) -// -// * CMOVGE r16, r16 [CMOV] -// * CMOVGE m16, r16 [CMOV] -// * CMOVGE r32, r32 [CMOV] -// * CMOVGE m32, r32 [CMOV] -// * CMOVGE r64, r64 [CMOV] -// * CMOVGE m64, r64 [CMOV] -// -func (self *Program) CMOVGE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVGE", 2, Operands { v0, v1 }) - // CMOVGE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVGE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVGE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVGE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVGE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVGE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVGE") - } - return p -} - -// CMOVL performs "Move if less (SF != OF)". -// -// Mnemonic : CMOVL -// Supported forms : (6 forms) -// -// * CMOVL r16, r16 [CMOV] -// * CMOVL m16, r16 [CMOV] -// * CMOVL r32, r32 [CMOV] -// * CMOVL m32, r32 [CMOV] -// * CMOVL r64, r64 [CMOV] -// * CMOVL m64, r64 [CMOV] -// -func (self *Program) CMOVL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVL", 2, Operands { v0, v1 }) - // CMOVL r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVL m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVL r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVL r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVL m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVL") - } - return p -} - -// CMOVLE performs "Move if less or equal (ZF == 1 or SF != OF)". -// -// Mnemonic : CMOVLE -// Supported forms : (6 forms) -// -// * CMOVLE r16, r16 [CMOV] -// * CMOVLE m16, r16 [CMOV] -// * CMOVLE r32, r32 [CMOV] -// * CMOVLE m32, r32 [CMOV] -// * CMOVLE r64, r64 [CMOV] -// * CMOVLE m64, r64 [CMOV] -// -func (self *Program) CMOVLE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVLE", 2, Operands { v0, v1 }) - // CMOVLE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVLE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVLE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVLE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVLE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVLE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVLE") - } - return p -} - -// CMOVNA performs "Move if not above (CF == 1 or ZF == 1)". -// -// Mnemonic : CMOVNA -// Supported forms : (6 forms) -// -// * CMOVNA r16, r16 [CMOV] -// * CMOVNA m16, r16 [CMOV] -// * CMOVNA r32, r32 [CMOV] -// * CMOVNA m32, r32 [CMOV] -// * CMOVNA r64, r64 [CMOV] -// * CMOVNA m64, r64 [CMOV] -// -func (self *Program) CMOVNA(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNA", 2, Operands { v0, v1 }) - // CMOVNA r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x46) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNA m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x46) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNA r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x46) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNA m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x46) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNA r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x46) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNA m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x46) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNA") - } - return p -} - -// CMOVNAE performs "Move if not above or equal (CF == 1)". -// -// Mnemonic : CMOVNAE -// Supported forms : (6 forms) -// -// * CMOVNAE r16, r16 [CMOV] -// * CMOVNAE m16, r16 [CMOV] -// * CMOVNAE r32, r32 [CMOV] -// * CMOVNAE m32, r32 [CMOV] -// * CMOVNAE r64, r64 [CMOV] -// * CMOVNAE m64, r64 [CMOV] -// -func (self *Program) CMOVNAE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNAE", 2, Operands { v0, v1 }) - // CMOVNAE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNAE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNAE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNAE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNAE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNAE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNAE") - } - return p -} - -// CMOVNB performs "Move if not below (CF == 0)". -// -// Mnemonic : CMOVNB -// Supported forms : (6 forms) -// -// * CMOVNB r16, r16 [CMOV] -// * CMOVNB m16, r16 [CMOV] -// * CMOVNB r32, r32 [CMOV] -// * CMOVNB m32, r32 [CMOV] -// * CMOVNB r64, r64 [CMOV] -// * CMOVNB m64, r64 [CMOV] -// -func (self *Program) CMOVNB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNB", 2, Operands { v0, v1 }) - // CMOVNB r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x43) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNB m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x43) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNB r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x43) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNB m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x43) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNB r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x43) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNB m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x43) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNB") - } - return p -} - -// CMOVNBE performs "Move if not below or equal (CF == 0 and ZF == 0)". -// -// Mnemonic : CMOVNBE -// Supported forms : (6 forms) -// -// * CMOVNBE r16, r16 [CMOV] -// * CMOVNBE m16, r16 [CMOV] -// * CMOVNBE r32, r32 [CMOV] -// * CMOVNBE m32, r32 [CMOV] -// * CMOVNBE r64, r64 [CMOV] -// * CMOVNBE m64, r64 [CMOV] -// -func (self *Program) CMOVNBE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNBE", 2, Operands { v0, v1 }) - // CMOVNBE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x47) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNBE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x47) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNBE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x47) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNBE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x47) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNBE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x47) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNBE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x47) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNBE") - } - return p -} - -// CMOVNC performs "Move if not carry (CF == 0)". -// -// Mnemonic : CMOVNC -// Supported forms : (6 forms) -// -// * CMOVNC r16, r16 [CMOV] -// * CMOVNC m16, r16 [CMOV] -// * CMOVNC r32, r32 [CMOV] -// * CMOVNC m32, r32 [CMOV] -// * CMOVNC r64, r64 [CMOV] -// * CMOVNC m64, r64 [CMOV] -// -func (self *Program) CMOVNC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNC", 2, Operands { v0, v1 }) - // CMOVNC r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x43) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNC m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x43) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNC r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x43) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNC m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x43) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNC r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x43) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNC m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x43) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNC") - } - return p -} - -// CMOVNE performs "Move if not equal (ZF == 0)". -// -// Mnemonic : CMOVNE -// Supported forms : (6 forms) -// -// * CMOVNE r16, r16 [CMOV] -// * CMOVNE m16, r16 [CMOV] -// * CMOVNE r32, r32 [CMOV] -// * CMOVNE m32, r32 [CMOV] -// * CMOVNE r64, r64 [CMOV] -// * CMOVNE m64, r64 [CMOV] -// -func (self *Program) CMOVNE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNE", 2, Operands { v0, v1 }) - // CMOVNE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x45) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x45) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x45) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x45) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x45) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x45) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNE") - } - return p -} - -// CMOVNG performs "Move if not greater (ZF == 1 or SF != OF)". -// -// Mnemonic : CMOVNG -// Supported forms : (6 forms) -// -// * CMOVNG r16, r16 [CMOV] -// * CMOVNG m16, r16 [CMOV] -// * CMOVNG r32, r32 [CMOV] -// * CMOVNG m32, r32 [CMOV] -// * CMOVNG r64, r64 [CMOV] -// * CMOVNG m64, r64 [CMOV] -// -func (self *Program) CMOVNG(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNG", 2, Operands { v0, v1 }) - // CMOVNG r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNG m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNG r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNG m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNG r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNG m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNG") - } - return p -} - -// CMOVNGE performs "Move if not greater or equal (SF != OF)". -// -// Mnemonic : CMOVNGE -// Supported forms : (6 forms) -// -// * CMOVNGE r16, r16 [CMOV] -// * CMOVNGE m16, r16 [CMOV] -// * CMOVNGE r32, r32 [CMOV] -// * CMOVNGE m32, r32 [CMOV] -// * CMOVNGE r64, r64 [CMOV] -// * CMOVNGE m64, r64 [CMOV] -// -func (self *Program) CMOVNGE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNGE", 2, Operands { v0, v1 }) - // CMOVNGE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNGE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNGE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNGE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNGE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNGE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNGE") - } - return p -} - -// CMOVNL performs "Move if not less (SF == OF)". -// -// Mnemonic : CMOVNL -// Supported forms : (6 forms) -// -// * CMOVNL r16, r16 [CMOV] -// * CMOVNL m16, r16 [CMOV] -// * CMOVNL r32, r32 [CMOV] -// * CMOVNL m32, r32 [CMOV] -// * CMOVNL r64, r64 [CMOV] -// * CMOVNL m64, r64 [CMOV] -// -func (self *Program) CMOVNL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNL", 2, Operands { v0, v1 }) - // CMOVNL r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNL m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNL r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNL r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNL m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNL") - } - return p -} - -// CMOVNLE performs "Move if not less or equal (ZF == 0 and SF == OF)". -// -// Mnemonic : CMOVNLE -// Supported forms : (6 forms) -// -// * CMOVNLE r16, r16 [CMOV] -// * CMOVNLE m16, r16 [CMOV] -// * CMOVNLE r32, r32 [CMOV] -// * CMOVNLE m32, r32 [CMOV] -// * CMOVNLE r64, r64 [CMOV] -// * CMOVNLE m64, r64 [CMOV] -// -func (self *Program) CMOVNLE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNLE", 2, Operands { v0, v1 }) - // CMOVNLE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNLE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNLE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNLE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNLE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNLE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNLE") - } - return p -} - -// CMOVNO performs "Move if not overflow (OF == 0)". -// -// Mnemonic : CMOVNO -// Supported forms : (6 forms) -// -// * CMOVNO r16, r16 [CMOV] -// * CMOVNO m16, r16 [CMOV] -// * CMOVNO r32, r32 [CMOV] -// * CMOVNO m32, r32 [CMOV] -// * CMOVNO r64, r64 [CMOV] -// * CMOVNO m64, r64 [CMOV] -// -func (self *Program) CMOVNO(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNO", 2, Operands { v0, v1 }) - // CMOVNO r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x41) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNO m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x41) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNO r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x41) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNO m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x41) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNO r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x41) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNO m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x41) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNO") - } - return p -} - -// CMOVNP performs "Move if not parity (PF == 0)". -// -// Mnemonic : CMOVNP -// Supported forms : (6 forms) -// -// * CMOVNP r16, r16 [CMOV] -// * CMOVNP m16, r16 [CMOV] -// * CMOVNP r32, r32 [CMOV] -// * CMOVNP m32, r32 [CMOV] -// * CMOVNP r64, r64 [CMOV] -// * CMOVNP m64, r64 [CMOV] -// -func (self *Program) CMOVNP(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNP", 2, Operands { v0, v1 }) - // CMOVNP r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNP m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNP r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNP m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNP r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNP m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNP") - } - return p -} - -// CMOVNS performs "Move if not sign (SF == 0)". -// -// Mnemonic : CMOVNS -// Supported forms : (6 forms) -// -// * CMOVNS r16, r16 [CMOV] -// * CMOVNS m16, r16 [CMOV] -// * CMOVNS r32, r32 [CMOV] -// * CMOVNS m32, r32 [CMOV] -// * CMOVNS r64, r64 [CMOV] -// * CMOVNS m64, r64 [CMOV] -// -func (self *Program) CMOVNS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNS", 2, Operands { v0, v1 }) - // CMOVNS r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x49) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNS m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x49) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNS r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x49) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNS m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x49) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNS r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x49) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNS m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x49) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNS") - } - return p -} - -// CMOVNZ performs "Move if not zero (ZF == 0)". -// -// Mnemonic : CMOVNZ -// Supported forms : (6 forms) -// -// * CMOVNZ r16, r16 [CMOV] -// * CMOVNZ m16, r16 [CMOV] -// * CMOVNZ r32, r32 [CMOV] -// * CMOVNZ m32, r32 [CMOV] -// * CMOVNZ r64, r64 [CMOV] -// * CMOVNZ m64, r64 [CMOV] -// -func (self *Program) CMOVNZ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVNZ", 2, Operands { v0, v1 }) - // CMOVNZ r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x45) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNZ m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x45) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNZ r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x45) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNZ m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x45) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVNZ r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x45) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVNZ m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x45) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVNZ") - } - return p -} - -// CMOVO performs "Move if overflow (OF == 1)". -// -// Mnemonic : CMOVO -// Supported forms : (6 forms) -// -// * CMOVO r16, r16 [CMOV] -// * CMOVO m16, r16 [CMOV] -// * CMOVO r32, r32 [CMOV] -// * CMOVO m32, r32 [CMOV] -// * CMOVO r64, r64 [CMOV] -// * CMOVO m64, r64 [CMOV] -// -func (self *Program) CMOVO(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVO", 2, Operands { v0, v1 }) - // CMOVO r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x40) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVO m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x40) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVO r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x40) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVO m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x40) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVO r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x40) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVO m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x40) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVO") - } - return p -} - -// CMOVP performs "Move if parity (PF == 1)". -// -// Mnemonic : CMOVP -// Supported forms : (6 forms) -// -// * CMOVP r16, r16 [CMOV] -// * CMOVP m16, r16 [CMOV] -// * CMOVP r32, r32 [CMOV] -// * CMOVP m32, r32 [CMOV] -// * CMOVP r64, r64 [CMOV] -// * CMOVP m64, r64 [CMOV] -// -func (self *Program) CMOVP(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVP", 2, Operands { v0, v1 }) - // CMOVP r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVP m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVP r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVP m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVP r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVP m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVP") - } - return p -} - -// CMOVPE performs "Move if parity even (PF == 1)". -// -// Mnemonic : CMOVPE -// Supported forms : (6 forms) -// -// * CMOVPE r16, r16 [CMOV] -// * CMOVPE m16, r16 [CMOV] -// * CMOVPE r32, r32 [CMOV] -// * CMOVPE m32, r32 [CMOV] -// * CMOVPE r64, r64 [CMOV] -// * CMOVPE m64, r64 [CMOV] -// -func (self *Program) CMOVPE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVPE", 2, Operands { v0, v1 }) - // CMOVPE r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVPE m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVPE r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVPE m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVPE r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVPE m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVPE") - } - return p -} - -// CMOVPO performs "Move if parity odd (PF == 0)". -// -// Mnemonic : CMOVPO -// Supported forms : (6 forms) -// -// * CMOVPO r16, r16 [CMOV] -// * CMOVPO m16, r16 [CMOV] -// * CMOVPO r32, r32 [CMOV] -// * CMOVPO m32, r32 [CMOV] -// * CMOVPO r64, r64 [CMOV] -// * CMOVPO m64, r64 [CMOV] -// -func (self *Program) CMOVPO(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVPO", 2, Operands { v0, v1 }) - // CMOVPO r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVPO m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVPO r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVPO m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x4b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVPO r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVPO m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x4b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVPO") - } - return p -} - -// CMOVS performs "Move if sign (SF == 1)". -// -// Mnemonic : CMOVS -// Supported forms : (6 forms) -// -// * CMOVS r16, r16 [CMOV] -// * CMOVS m16, r16 [CMOV] -// * CMOVS r32, r32 [CMOV] -// * CMOVS m32, r32 [CMOV] -// * CMOVS r64, r64 [CMOV] -// * CMOVS m64, r64 [CMOV] -// -func (self *Program) CMOVS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVS", 2, Operands { v0, v1 }) - // CMOVS r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x48) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVS m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x48) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVS r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x48) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVS m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x48) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVS r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x48) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVS m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x48) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVS") - } - return p -} - -// CMOVZ performs "Move if zero (ZF == 1)". -// -// Mnemonic : CMOVZ -// Supported forms : (6 forms) -// -// * CMOVZ r16, r16 [CMOV] -// * CMOVZ m16, r16 [CMOV] -// * CMOVZ r32, r32 [CMOV] -// * CMOVZ m32, r32 [CMOV] -// * CMOVZ r64, r64 [CMOV] -// * CMOVZ m64, r64 [CMOV] -// -func (self *Program) CMOVZ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMOVZ", 2, Operands { v0, v1 }) - // CMOVZ r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVZ m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVZ r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVZ m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMOVZ r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMOVZ m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_CMOV) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMOVZ") - } - return p -} - -// CMPB performs "Compare Two Operands". -// -// Mnemonic : CMP -// Supported forms : (6 forms) -// -// * CMPB imm8, al -// * CMPB imm8, r8 -// * CMPB r8, r8 -// * CMPB m8, r8 -// * CMPB imm8, m8 -// * CMPB r8, m8 -// -func (self *Program) CMPB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMPB", 2, Operands { v0, v1 }) - // CMPB imm8, al - if isImm8(v0) && v1 == AL { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x3c) - m.imm1(toImmAny(v[0])) - }) - } - // CMPB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0x80) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // CMPB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x38) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMPB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x3a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMPB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x80) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // CMPB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x38) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPB") - } - return p -} - -// CMPL performs "Compare Two Operands". -// -// Mnemonic : CMP -// Supported forms : (8 forms) -// -// * CMPL imm32, eax -// * CMPL imm8, r32 -// * CMPL imm32, r32 -// * CMPL r32, r32 -// * CMPL m32, r32 -// * CMPL imm8, m32 -// * CMPL imm32, m32 -// * CMPL r32, m32 -// -func (self *Program) CMPL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMPL", 2, Operands { v0, v1 }) - // CMPL imm32, eax - if isImm32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x3d) - m.imm4(toImmAny(v[0])) - }) - } - // CMPL imm8, r32 - if isImm8Ext(v0, 4) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // CMPL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xf8 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // CMPL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x39) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMPL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x3b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMPL imm8, m32 - if isImm8Ext(v0, 4) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // CMPL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(7, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // CMPL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x39) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPL") - } - return p -} - -// CMPPD performs "Compare Packed Double-Precision Floating-Point Values". -// -// Mnemonic : CMPPD -// Supported forms : (2 forms) -// -// * CMPPD imm8, xmm, xmm [SSE2] -// * CMPPD imm8, m128, xmm [SSE2] -// -func (self *Program) CMPPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("CMPPD", 3, Operands { v0, v1, v2 }) - // CMPPD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // CMPPD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc2) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for CMPPD") - } - return p -} - -// CMPPS performs "Compare Packed Single-Precision Floating-Point Values". -// -// Mnemonic : CMPPS -// Supported forms : (2 forms) -// -// * CMPPS imm8, xmm, xmm [SSE] -// * CMPPS imm8, m128, xmm [SSE] -// -func (self *Program) CMPPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("CMPPS", 3, Operands { v0, v1, v2 }) - // CMPPS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // CMPPS imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc2) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for CMPPS") - } - return p -} - -// CMPQ performs "Compare Two Operands". -// -// Mnemonic : CMP -// Supported forms : (8 forms) -// -// * CMPQ imm32, rax -// * CMPQ imm8, r64 -// * CMPQ imm32, r64 -// * CMPQ r64, r64 -// * CMPQ m64, r64 -// * CMPQ imm8, m64 -// * CMPQ imm32, m64 -// * CMPQ r64, m64 -// -func (self *Program) CMPQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMPQ", 2, Operands { v0, v1 }) - // CMPQ imm32, rax - if isImm32(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x3d) - m.imm4(toImmAny(v[0])) - }) - } - // CMPQ imm8, r64 - if isImm8Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x83) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // CMPQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x81) - m.emit(0xf8 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // CMPQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x39) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMPQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x3b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMPQ imm8, m64 - if isImm8Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x83) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // CMPQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x81) - m.mrsd(7, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // CMPQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x39) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPQ") - } - return p -} - -// CMPSD performs "Compare Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : CMPSD -// Supported forms : (2 forms) -// -// * CMPSD imm8, xmm, xmm [SSE2] -// * CMPSD imm8, m64, xmm [SSE2] -// -func (self *Program) CMPSD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("CMPSD", 3, Operands { v0, v1, v2 }) - // CMPSD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // CMPSD imm8, m64, xmm - if isImm8(v0) && isM64(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc2) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for CMPSD") - } - return p -} - -// CMPSS performs "Compare Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : CMPSS -// Supported forms : (2 forms) -// -// * CMPSS imm8, xmm, xmm [SSE] -// * CMPSS imm8, m32, xmm [SSE] -// -func (self *Program) CMPSS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("CMPSS", 3, Operands { v0, v1, v2 }) - // CMPSS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // CMPSS imm8, m32, xmm - if isImm8(v0) && isM32(v1) && isXMM(v2) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc2) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for CMPSS") - } - return p -} - -// CMPW performs "Compare Two Operands". -// -// Mnemonic : CMP -// Supported forms : (8 forms) -// -// * CMPW imm16, ax -// * CMPW imm8, r16 -// * CMPW imm16, r16 -// * CMPW r16, r16 -// * CMPW m16, r16 -// * CMPW imm8, m16 -// * CMPW imm16, m16 -// * CMPW r16, m16 -// -func (self *Program) CMPW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMPW", 2, Operands { v0, v1 }) - // CMPW imm16, ax - if isImm16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x3d) - m.imm2(toImmAny(v[0])) - }) - } - // CMPW imm8, r16 - if isImm8Ext(v0, 2) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // CMPW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xf8 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // CMPW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x39) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CMPW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x3b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CMPW imm8, m16 - if isImm8Ext(v0, 2) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // CMPW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(7, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // CMPW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x39) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPW") - } - return p -} - -// CMPXCHG16B performs "Compare and Exchange 16 Bytes". -// -// Mnemonic : CMPXCHG16B -// Supported forms : (1 form) -// -// * CMPXCHG16B m128 -// -func (self *Program) CMPXCHG16B(v0 interface{}) *Instruction { - p := self.alloc("CMPXCHG16B", 1, Operands { v0 }) - // CMPXCHG16B m128 - if isM128(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[0])) - m.emit(0x0f) - m.emit(0xc7) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPXCHG16B") - } - return p -} - -// CMPXCHG8B performs "Compare and Exchange 8 Bytes". -// -// Mnemonic : CMPXCHG8B -// Supported forms : (1 form) -// -// * CMPXCHG8B m64 -// -func (self *Program) CMPXCHG8B(v0 interface{}) *Instruction { - p := self.alloc("CMPXCHG8B", 1, Operands { v0 }) - // CMPXCHG8B m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0xc7) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPXCHG8B") - } - return p -} - -// CMPXCHGB performs "Compare and Exchange". -// -// Mnemonic : CMPXCHG -// Supported forms : (2 forms) -// -// * CMPXCHGB r8, r8 -// * CMPXCHGB r8, m8 -// -func (self *Program) CMPXCHGB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMPXCHGB", 2, Operands { v0, v1 }) - // CMPXCHGB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x0f) - m.emit(0xb0) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // CMPXCHGB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0xb0) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPXCHGB") - } - return p -} - -// CMPXCHGL performs "Compare and Exchange". -// -// Mnemonic : CMPXCHG -// Supported forms : (2 forms) -// -// * CMPXCHGL r32, r32 -// * CMPXCHGL r32, m32 -// -func (self *Program) CMPXCHGL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMPXCHGL", 2, Operands { v0, v1 }) - // CMPXCHGL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xb1) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // CMPXCHGL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xb1) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPXCHGL") - } - return p -} - -// CMPXCHGQ performs "Compare and Exchange". -// -// Mnemonic : CMPXCHG -// Supported forms : (2 forms) -// -// * CMPXCHGQ r64, r64 -// * CMPXCHGQ r64, m64 -// -func (self *Program) CMPXCHGQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMPXCHGQ", 2, Operands { v0, v1 }) - // CMPXCHGQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xb1) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // CMPXCHGQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0xb1) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPXCHGQ") - } - return p -} - -// CMPXCHGW performs "Compare and Exchange". -// -// Mnemonic : CMPXCHG -// Supported forms : (2 forms) -// -// * CMPXCHGW r16, r16 -// * CMPXCHGW r16, m16 -// -func (self *Program) CMPXCHGW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CMPXCHGW", 2, Operands { v0, v1 }) - // CMPXCHGW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xb1) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // CMPXCHGW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xb1) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CMPXCHGW") - } - return p -} - -// COMISD performs "Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS". -// -// Mnemonic : COMISD -// Supported forms : (2 forms) -// -// * COMISD xmm, xmm [SSE2] -// * COMISD m64, xmm [SSE2] -// -func (self *Program) COMISD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("COMISD", 2, Operands { v0, v1 }) - // COMISD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // COMISD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for COMISD") - } - return p -} - -// COMISS performs "Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS". -// -// Mnemonic : COMISS -// Supported forms : (2 forms) -// -// * COMISS xmm, xmm [SSE] -// * COMISS m32, xmm [SSE] -// -func (self *Program) COMISS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("COMISS", 2, Operands { v0, v1 }) - // COMISS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // COMISS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for COMISS") - } - return p -} - -// CPUID performs "CPU Identification". -// -// Mnemonic : CPUID -// Supported forms : (1 form) -// -// * CPUID [CPUID] -// -func (self *Program) CPUID() *Instruction { - p := self.alloc("CPUID", 0, Operands { }) - // CPUID - self.require(ISA_CPUID) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0xa2) - }) - return p -} - -// CQTO performs "Convert Quadword to Octaword". -// -// Mnemonic : CQO -// Supported forms : (1 form) -// -// * CQTO -// -func (self *Program) CQTO() *Instruction { - p := self.alloc("CQTO", 0, Operands { }) - // CQTO - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x99) - }) - return p -} - -// CRC32B performs "Accumulate CRC32 Value". -// -// Mnemonic : CRC32 -// Supported forms : (4 forms) -// -// * CRC32B r8, r32 [SSE4.2] -// * CRC32B m8, r32 [SSE4.2] -// * CRC32B r8, r64 [SSE4.2] -// * CRC32B m8, r64 [SSE4.2] -// -func (self *Program) CRC32B(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CRC32B", 2, Operands { v0, v1 }) - // CRC32B r8, r32 - if isReg8(v0) && isReg32(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf0) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CRC32B m8, r32 - if isM8(v0) && isReg32(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CRC32B r8, r64 - if isReg8(v0) && isReg64(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf0) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CRC32B m8, r64 - if isM8(v0) && isReg64(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CRC32B") - } - return p -} - -// CRC32L performs "Accumulate CRC32 Value". -// -// Mnemonic : CRC32 -// Supported forms : (2 forms) -// -// * CRC32L r32, r32 [SSE4.2] -// * CRC32L m32, r32 [SSE4.2] -// -func (self *Program) CRC32L(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CRC32L", 2, Operands { v0, v1 }) - // CRC32L r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CRC32L m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CRC32L") - } - return p -} - -// CRC32Q performs "Accumulate CRC32 Value". -// -// Mnemonic : CRC32 -// Supported forms : (2 forms) -// -// * CRC32Q r64, r64 [SSE4.2] -// * CRC32Q m64, r64 [SSE4.2] -// -func (self *Program) CRC32Q(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CRC32Q", 2, Operands { v0, v1 }) - // CRC32Q r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CRC32Q m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CRC32Q") - } - return p -} - -// CRC32W performs "Accumulate CRC32 Value". -// -// Mnemonic : CRC32 -// Supported forms : (2 forms) -// -// * CRC32W r16, r32 [SSE4.2] -// * CRC32W m16, r32 [SSE4.2] -// -func (self *Program) CRC32W(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CRC32W", 2, Operands { v0, v1 }) - // CRC32W r16, r32 - if isReg16(v0) && isReg32(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CRC32W m16, r32 - if isM16(v0) && isReg32(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CRC32W") - } - return p -} - -// CVTDQ2PD performs "Convert Packed Dword Integers to Packed Double-Precision FP Values". -// -// Mnemonic : CVTDQ2PD -// Supported forms : (2 forms) -// -// * CVTDQ2PD xmm, xmm [SSE2] -// * CVTDQ2PD m64, xmm [SSE2] -// -func (self *Program) CVTDQ2PD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTDQ2PD", 2, Operands { v0, v1 }) - // CVTDQ2PD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTDQ2PD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTDQ2PD") - } - return p -} - -// CVTDQ2PS performs "Convert Packed Dword Integers to Packed Single-Precision FP Values". -// -// Mnemonic : CVTDQ2PS -// Supported forms : (2 forms) -// -// * CVTDQ2PS xmm, xmm [SSE2] -// * CVTDQ2PS m128, xmm [SSE2] -// -func (self *Program) CVTDQ2PS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTDQ2PS", 2, Operands { v0, v1 }) - // CVTDQ2PS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTDQ2PS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTDQ2PS") - } - return p -} - -// CVTPD2DQ performs "Convert Packed Double-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : CVTPD2DQ -// Supported forms : (2 forms) -// -// * CVTPD2DQ xmm, xmm [SSE2] -// * CVTPD2DQ m128, xmm [SSE2] -// -func (self *Program) CVTPD2DQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTPD2DQ", 2, Operands { v0, v1 }) - // CVTPD2DQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTPD2DQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTPD2DQ") - } - return p -} - -// CVTPD2PI performs "Convert Packed Double-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : CVTPD2PI -// Supported forms : (2 forms) -// -// * CVTPD2PI xmm, mm [SSE] -// * CVTPD2PI m128, mm [SSE] -// -func (self *Program) CVTPD2PI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTPD2PI", 2, Operands { v0, v1 }) - // CVTPD2PI xmm, mm - if isXMM(v0) && isMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTPD2PI m128, mm - if isM128(v0) && isMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTPD2PI") - } - return p -} - -// CVTPD2PS performs "Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values". -// -// Mnemonic : CVTPD2PS -// Supported forms : (2 forms) -// -// * CVTPD2PS xmm, xmm [SSE2] -// * CVTPD2PS m128, xmm [SSE2] -// -func (self *Program) CVTPD2PS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTPD2PS", 2, Operands { v0, v1 }) - // CVTPD2PS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTPD2PS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTPD2PS") - } - return p -} - -// CVTPI2PD performs "Convert Packed Dword Integers to Packed Double-Precision FP Values". -// -// Mnemonic : CVTPI2PD -// Supported forms : (2 forms) -// -// * CVTPI2PD mm, xmm [SSE2] -// * CVTPI2PD m64, xmm [SSE2] -// -func (self *Program) CVTPI2PD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTPI2PD", 2, Operands { v0, v1 }) - // CVTPI2PD mm, xmm - if isMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTPI2PD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTPI2PD") - } - return p -} - -// CVTPI2PS performs "Convert Packed Dword Integers to Packed Single-Precision FP Values". -// -// Mnemonic : CVTPI2PS -// Supported forms : (2 forms) -// -// * CVTPI2PS mm, xmm [SSE] -// * CVTPI2PS m64, xmm [SSE] -// -func (self *Program) CVTPI2PS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTPI2PS", 2, Operands { v0, v1 }) - // CVTPI2PS mm, xmm - if isMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTPI2PS m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTPI2PS") - } - return p -} - -// CVTPS2DQ performs "Convert Packed Single-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : CVTPS2DQ -// Supported forms : (2 forms) -// -// * CVTPS2DQ xmm, xmm [SSE2] -// * CVTPS2DQ m128, xmm [SSE2] -// -func (self *Program) CVTPS2DQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTPS2DQ", 2, Operands { v0, v1 }) - // CVTPS2DQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTPS2DQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTPS2DQ") - } - return p -} - -// CVTPS2PD performs "Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values". -// -// Mnemonic : CVTPS2PD -// Supported forms : (2 forms) -// -// * CVTPS2PD xmm, xmm [SSE2] -// * CVTPS2PD m64, xmm [SSE2] -// -func (self *Program) CVTPS2PD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTPS2PD", 2, Operands { v0, v1 }) - // CVTPS2PD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTPS2PD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTPS2PD") - } - return p -} - -// CVTPS2PI performs "Convert Packed Single-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : CVTPS2PI -// Supported forms : (2 forms) -// -// * CVTPS2PI xmm, mm [SSE] -// * CVTPS2PI m64, mm [SSE] -// -func (self *Program) CVTPS2PI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTPS2PI", 2, Operands { v0, v1 }) - // CVTPS2PI xmm, mm - if isXMM(v0) && isMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTPS2PI m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTPS2PI") - } - return p -} - -// CVTSD2SI performs "Convert Scalar Double-Precision FP Value to Integer". -// -// Mnemonic : CVTSD2SI -// Supported forms : (4 forms) -// -// * CVTSD2SI xmm, r32 [SSE2] -// * CVTSD2SI m64, r32 [SSE2] -// * CVTSD2SI xmm, r64 [SSE2] -// * CVTSD2SI m64, r64 [SSE2] -// -func (self *Program) CVTSD2SI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTSD2SI", 2, Operands { v0, v1 }) - // CVTSD2SI xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSD2SI m64, r32 - if isM64(v0) && isReg32(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CVTSD2SI xmm, r64 - if isXMM(v0) && isReg64(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSD2SI m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTSD2SI") - } - return p -} - -// CVTSD2SS performs "Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value". -// -// Mnemonic : CVTSD2SS -// Supported forms : (2 forms) -// -// * CVTSD2SS xmm, xmm [SSE2] -// * CVTSD2SS m64, xmm [SSE2] -// -func (self *Program) CVTSD2SS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTSD2SS", 2, Operands { v0, v1 }) - // CVTSD2SS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSD2SS m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTSD2SS") - } - return p -} - -// CVTSI2SD performs "Convert Dword Integer to Scalar Double-Precision FP Value". -// -// Mnemonic : CVTSI2SD -// Supported forms : (4 forms) -// -// * CVTSI2SD r32, xmm [SSE2] -// * CVTSI2SD r64, xmm [SSE2] -// * CVTSI2SD m32, xmm [SSE2] -// * CVTSI2SD m64, xmm [SSE2] -// -func (self *Program) CVTSI2SD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTSI2SD", 2, Operands { v0, v1 }) - // CVTSI2SD r32, xmm - if isReg32(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSI2SD r64, xmm - if isReg64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSI2SD m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CVTSI2SD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTSI2SD") - } - return p -} - -// CVTSI2SS performs "Convert Dword Integer to Scalar Single-Precision FP Value". -// -// Mnemonic : CVTSI2SS -// Supported forms : (4 forms) -// -// * CVTSI2SS r32, xmm [SSE] -// * CVTSI2SS r64, xmm [SSE] -// * CVTSI2SS m32, xmm [SSE] -// * CVTSI2SS m64, xmm [SSE] -// -func (self *Program) CVTSI2SS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTSI2SS", 2, Operands { v0, v1 }) - // CVTSI2SS r32, xmm - if isReg32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSI2SS r64, xmm - if isReg64(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSI2SS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CVTSI2SS m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTSI2SS") - } - return p -} - -// CVTSS2SD performs "Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value". -// -// Mnemonic : CVTSS2SD -// Supported forms : (2 forms) -// -// * CVTSS2SD xmm, xmm [SSE2] -// * CVTSS2SD m32, xmm [SSE2] -// -func (self *Program) CVTSS2SD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTSS2SD", 2, Operands { v0, v1 }) - // CVTSS2SD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSS2SD m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTSS2SD") - } - return p -} - -// CVTSS2SI performs "Convert Scalar Single-Precision FP Value to Dword Integer". -// -// Mnemonic : CVTSS2SI -// Supported forms : (4 forms) -// -// * CVTSS2SI xmm, r32 [SSE] -// * CVTSS2SI m32, r32 [SSE] -// * CVTSS2SI xmm, r64 [SSE] -// * CVTSS2SI m32, r64 [SSE] -// -func (self *Program) CVTSS2SI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTSS2SI", 2, Operands { v0, v1 }) - // CVTSS2SI xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSS2SI m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CVTSS2SI xmm, r64 - if isXMM(v0) && isReg64(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTSS2SI m32, r64 - if isM32(v0) && isReg64(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTSS2SI") - } - return p -} - -// CVTTPD2DQ performs "Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : CVTTPD2DQ -// Supported forms : (2 forms) -// -// * CVTTPD2DQ xmm, xmm [SSE2] -// * CVTTPD2DQ m128, xmm [SSE2] -// -func (self *Program) CVTTPD2DQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTTPD2DQ", 2, Operands { v0, v1 }) - // CVTTPD2DQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTTPD2DQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTTPD2DQ") - } - return p -} - -// CVTTPD2PI performs "Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : CVTTPD2PI -// Supported forms : (2 forms) -// -// * CVTTPD2PI xmm, mm [SSE2] -// * CVTTPD2PI m128, mm [SSE2] -// -func (self *Program) CVTTPD2PI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTTPD2PI", 2, Operands { v0, v1 }) - // CVTTPD2PI xmm, mm - if isXMM(v0) && isMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTTPD2PI m128, mm - if isM128(v0) && isMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTTPD2PI") - } - return p -} - -// CVTTPS2DQ performs "Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : CVTTPS2DQ -// Supported forms : (2 forms) -// -// * CVTTPS2DQ xmm, xmm [SSE2] -// * CVTTPS2DQ m128, xmm [SSE2] -// -func (self *Program) CVTTPS2DQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTTPS2DQ", 2, Operands { v0, v1 }) - // CVTTPS2DQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTTPS2DQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTTPS2DQ") - } - return p -} - -// CVTTPS2PI performs "Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : CVTTPS2PI -// Supported forms : (2 forms) -// -// * CVTTPS2PI xmm, mm [SSE] -// * CVTTPS2PI m64, mm [SSE] -// -func (self *Program) CVTTPS2PI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTTPS2PI", 2, Operands { v0, v1 }) - // CVTTPS2PI xmm, mm - if isXMM(v0) && isMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTTPS2PI m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTTPS2PI") - } - return p -} - -// CVTTSD2SI performs "Convert with Truncation Scalar Double-Precision FP Value to Signed Integer". -// -// Mnemonic : CVTTSD2SI -// Supported forms : (4 forms) -// -// * CVTTSD2SI xmm, r32 [SSE2] -// * CVTTSD2SI m64, r32 [SSE2] -// * CVTTSD2SI xmm, r64 [SSE2] -// * CVTTSD2SI m64, r64 [SSE2] -// -func (self *Program) CVTTSD2SI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTTSD2SI", 2, Operands { v0, v1 }) - // CVTTSD2SI xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTTSD2SI m64, r32 - if isM64(v0) && isReg32(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CVTTSD2SI xmm, r64 - if isXMM(v0) && isReg64(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTTSD2SI m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTTSD2SI") - } - return p -} - -// CVTTSS2SI performs "Convert with Truncation Scalar Single-Precision FP Value to Dword Integer". -// -// Mnemonic : CVTTSS2SI -// Supported forms : (4 forms) -// -// * CVTTSS2SI xmm, r32 [SSE] -// * CVTTSS2SI m32, r32 [SSE] -// * CVTTSS2SI xmm, r64 [SSE] -// * CVTTSS2SI m32, r64 [SSE] -// -func (self *Program) CVTTSS2SI(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("CVTTSS2SI", 2, Operands { v0, v1 }) - // CVTTSS2SI xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTTSS2SI m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // CVTTSS2SI xmm, r64 - if isXMM(v0) && isReg64(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // CVTTSS2SI m32, r64 - if isM32(v0) && isReg64(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for CVTTSS2SI") - } - return p -} - -// CWTD performs "Convert Word to Doubleword". -// -// Mnemonic : CWD -// Supported forms : (1 form) -// -// * CWTD -// -func (self *Program) CWTD() *Instruction { - p := self.alloc("CWTD", 0, Operands { }) - // CWTD - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x99) - }) - return p -} - -// CWTL performs "Convert Word to Doubleword". -// -// Mnemonic : CWDE -// Supported forms : (1 form) -// -// * CWTL -// -func (self *Program) CWTL() *Instruction { - p := self.alloc("CWTL", 0, Operands { }) - // CWTL - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x98) - }) - return p -} - -// DECB performs "Decrement by 1". -// -// Mnemonic : DEC -// Supported forms : (2 forms) -// -// * DECB r8 -// * DECB m8 -// -func (self *Program) DECB(v0 interface{}) *Instruction { - p := self.alloc("DECB", 1, Operands { v0 }) - // DECB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0xfe) - m.emit(0xc8 | lcode(v[0])) - }) - } - // DECB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xfe) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DECB") - } - return p -} - -// DECL performs "Decrement by 1". -// -// Mnemonic : DEC -// Supported forms : (2 forms) -// -// * DECL r32 -// * DECL m32 -// -func (self *Program) DECL(v0 interface{}) *Instruction { - p := self.alloc("DECL", 1, Operands { v0 }) - // DECL r32 - if isReg32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xff) - m.emit(0xc8 | lcode(v[0])) - }) - } - // DECL m32 - if isM32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xff) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DECL") - } - return p -} - -// DECQ performs "Decrement by 1". -// -// Mnemonic : DEC -// Supported forms : (2 forms) -// -// * DECQ r64 -// * DECQ m64 -// -func (self *Program) DECQ(v0 interface{}) *Instruction { - p := self.alloc("DECQ", 1, Operands { v0 }) - // DECQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0xff) - m.emit(0xc8 | lcode(v[0])) - }) - } - // DECQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[0])) - m.emit(0xff) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DECQ") - } - return p -} - -// DECW performs "Decrement by 1". -// -// Mnemonic : DEC -// Supported forms : (2 forms) -// -// * DECW r16 -// * DECW m16 -// -func (self *Program) DECW(v0 interface{}) *Instruction { - p := self.alloc("DECW", 1, Operands { v0 }) - // DECW r16 - if isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0xff) - m.emit(0xc8 | lcode(v[0])) - }) - } - // DECW m16 - if isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0xff) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DECW") - } - return p -} - -// DIVB performs "Unsigned Divide". -// -// Mnemonic : DIV -// Supported forms : (2 forms) -// -// * DIVB r8 -// * DIVB m8 -// -func (self *Program) DIVB(v0 interface{}) *Instruction { - p := self.alloc("DIVB", 1, Operands { v0 }) - // DIVB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0xf6) - m.emit(0xf0 | lcode(v[0])) - }) - } - // DIVB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf6) - m.mrsd(6, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DIVB") - } - return p -} - -// DIVL performs "Unsigned Divide". -// -// Mnemonic : DIV -// Supported forms : (2 forms) -// -// * DIVL r32 -// * DIVL m32 -// -func (self *Program) DIVL(v0 interface{}) *Instruction { - p := self.alloc("DIVL", 1, Operands { v0 }) - // DIVL r32 - if isReg32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xf0 | lcode(v[0])) - }) - } - // DIVL m32 - if isM32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(6, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DIVL") - } - return p -} - -// DIVPD performs "Divide Packed Double-Precision Floating-Point Values". -// -// Mnemonic : DIVPD -// Supported forms : (2 forms) -// -// * DIVPD xmm, xmm [SSE2] -// * DIVPD m128, xmm [SSE2] -// -func (self *Program) DIVPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("DIVPD", 2, Operands { v0, v1 }) - // DIVPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // DIVPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DIVPD") - } - return p -} - -// DIVPS performs "Divide Packed Single-Precision Floating-Point Values". -// -// Mnemonic : DIVPS -// Supported forms : (2 forms) -// -// * DIVPS xmm, xmm [SSE] -// * DIVPS m128, xmm [SSE] -// -func (self *Program) DIVPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("DIVPS", 2, Operands { v0, v1 }) - // DIVPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // DIVPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DIVPS") - } - return p -} - -// DIVQ performs "Unsigned Divide". -// -// Mnemonic : DIV -// Supported forms : (2 forms) -// -// * DIVQ r64 -// * DIVQ m64 -// -func (self *Program) DIVQ(v0 interface{}) *Instruction { - p := self.alloc("DIVQ", 1, Operands { v0 }) - // DIVQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0xf7) - m.emit(0xf0 | lcode(v[0])) - }) - } - // DIVQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[0])) - m.emit(0xf7) - m.mrsd(6, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DIVQ") - } - return p -} - -// DIVSD performs "Divide Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : DIVSD -// Supported forms : (2 forms) -// -// * DIVSD xmm, xmm [SSE2] -// * DIVSD m64, xmm [SSE2] -// -func (self *Program) DIVSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("DIVSD", 2, Operands { v0, v1 }) - // DIVSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // DIVSD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DIVSD") - } - return p -} - -// DIVSS performs "Divide Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : DIVSS -// Supported forms : (2 forms) -// -// * DIVSS xmm, xmm [SSE] -// * DIVSS m32, xmm [SSE] -// -func (self *Program) DIVSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("DIVSS", 2, Operands { v0, v1 }) - // DIVSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // DIVSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DIVSS") - } - return p -} - -// DIVW performs "Unsigned Divide". -// -// Mnemonic : DIV -// Supported forms : (2 forms) -// -// * DIVW r16 -// * DIVW m16 -// -func (self *Program) DIVW(v0 interface{}) *Instruction { - p := self.alloc("DIVW", 1, Operands { v0 }) - // DIVW r16 - if isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xf0 | lcode(v[0])) - }) - } - // DIVW m16 - if isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(6, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for DIVW") - } - return p -} - -// DPPD performs "Dot Product of Packed Double Precision Floating-Point Values". -// -// Mnemonic : DPPD -// Supported forms : (2 forms) -// -// * DPPD imm8, xmm, xmm [SSE4.1] -// * DPPD imm8, m128, xmm [SSE4.1] -// -func (self *Program) DPPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("DPPD", 3, Operands { v0, v1, v2 }) - // DPPD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x41) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // DPPD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x41) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for DPPD") - } - return p -} - -// DPPS performs "Dot Product of Packed Single Precision Floating-Point Values". -// -// Mnemonic : DPPS -// Supported forms : (2 forms) -// -// * DPPS imm8, xmm, xmm [SSE4.1] -// * DPPS imm8, m128, xmm [SSE4.1] -// -func (self *Program) DPPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("DPPS", 3, Operands { v0, v1, v2 }) - // DPPS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x40) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // DPPS imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x40) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for DPPS") - } - return p -} - -// EMMS performs "Exit MMX State". -// -// Mnemonic : EMMS -// Supported forms : (1 form) -// -// * EMMS [MMX] -// -func (self *Program) EMMS() *Instruction { - p := self.alloc("EMMS", 0, Operands { }) - // EMMS - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x77) - }) - return p -} - -// EXTRACTPS performs "Extract Packed Single Precision Floating-Point Value". -// -// Mnemonic : EXTRACTPS -// Supported forms : (2 forms) -// -// * EXTRACTPS imm8, xmm, r32 [SSE4.1] -// * EXTRACTPS imm8, xmm, m32 [SSE4.1] -// -func (self *Program) EXTRACTPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("EXTRACTPS", 3, Operands { v0, v1, v2 }) - // EXTRACTPS imm8, xmm, r32 - if isImm8(v0) && isXMM(v1) && isReg32(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x17) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // EXTRACTPS imm8, xmm, m32 - if isImm8(v0) && isXMM(v1) && isM32(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x17) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for EXTRACTPS") - } - return p -} - -// EXTRQ performs "Extract Field". -// -// Mnemonic : EXTRQ -// Supported forms : (2 forms) -// -// * EXTRQ xmm, xmm [SSE4A] -// * EXTRQ imm8, imm8, xmm [SSE4A] -// -func (self *Program) EXTRQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("EXTRQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("EXTRQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction EXTRQ takes 2 or 3 operands") - } - // EXTRQ xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4A) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // EXTRQ imm8, imm8, xmm - if len(vv) == 1 && isImm8(v0) && isImm8(v1) && isXMM(vv[0]) { - self.require(ISA_SSE4A) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[2], false) - m.emit(0x0f) - m.emit(0x78) - m.emit(0xc0 | lcode(v[2])) - m.imm1(toImmAny(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for EXTRQ") - } - return p -} - -// FEMMS performs "Fast Exit Multimedia State". -// -// Mnemonic : FEMMS -// Supported forms : (1 form) -// -// * FEMMS [FEMMS] -// -func (self *Program) FEMMS() *Instruction { - p := self.alloc("FEMMS", 0, Operands { }) - // FEMMS - self.require(ISA_FEMMS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x0e) - }) - return p -} - -// HADDPD performs "Packed Double-FP Horizontal Add". -// -// Mnemonic : HADDPD -// Supported forms : (2 forms) -// -// * HADDPD xmm, xmm [SSE3] -// * HADDPD m128, xmm [SSE3] -// -func (self *Program) HADDPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("HADDPD", 2, Operands { v0, v1 }) - // HADDPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // HADDPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x7c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for HADDPD") - } - return p -} - -// HADDPS performs "Packed Single-FP Horizontal Add". -// -// Mnemonic : HADDPS -// Supported forms : (2 forms) -// -// * HADDPS xmm, xmm [SSE3] -// * HADDPS m128, xmm [SSE3] -// -func (self *Program) HADDPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("HADDPS", 2, Operands { v0, v1 }) - // HADDPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // HADDPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x7c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for HADDPS") - } - return p -} - -// HSUBPD performs "Packed Double-FP Horizontal Subtract". -// -// Mnemonic : HSUBPD -// Supported forms : (2 forms) -// -// * HSUBPD xmm, xmm [SSE3] -// * HSUBPD m128, xmm [SSE3] -// -func (self *Program) HSUBPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("HSUBPD", 2, Operands { v0, v1 }) - // HSUBPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // HSUBPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x7d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for HSUBPD") - } - return p -} - -// HSUBPS performs "Packed Single-FP Horizontal Subtract". -// -// Mnemonic : HSUBPS -// Supported forms : (2 forms) -// -// * HSUBPS xmm, xmm [SSE3] -// * HSUBPS m128, xmm [SSE3] -// -func (self *Program) HSUBPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("HSUBPS", 2, Operands { v0, v1 }) - // HSUBPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // HSUBPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x7d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for HSUBPS") - } - return p -} - -// IDIVB performs "Signed Divide". -// -// Mnemonic : IDIV -// Supported forms : (2 forms) -// -// * IDIVB r8 -// * IDIVB m8 -// -func (self *Program) IDIVB(v0 interface{}) *Instruction { - p := self.alloc("IDIVB", 1, Operands { v0 }) - // IDIVB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0xf6) - m.emit(0xf8 | lcode(v[0])) - }) - } - // IDIVB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf6) - m.mrsd(7, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for IDIVB") - } - return p -} - -// IDIVL performs "Signed Divide". -// -// Mnemonic : IDIV -// Supported forms : (2 forms) -// -// * IDIVL r32 -// * IDIVL m32 -// -func (self *Program) IDIVL(v0 interface{}) *Instruction { - p := self.alloc("IDIVL", 1, Operands { v0 }) - // IDIVL r32 - if isReg32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xf8 | lcode(v[0])) - }) - } - // IDIVL m32 - if isM32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(7, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for IDIVL") - } - return p -} - -// IDIVQ performs "Signed Divide". -// -// Mnemonic : IDIV -// Supported forms : (2 forms) -// -// * IDIVQ r64 -// * IDIVQ m64 -// -func (self *Program) IDIVQ(v0 interface{}) *Instruction { - p := self.alloc("IDIVQ", 1, Operands { v0 }) - // IDIVQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0xf7) - m.emit(0xf8 | lcode(v[0])) - }) - } - // IDIVQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[0])) - m.emit(0xf7) - m.mrsd(7, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for IDIVQ") - } - return p -} - -// IDIVW performs "Signed Divide". -// -// Mnemonic : IDIV -// Supported forms : (2 forms) -// -// * IDIVW r16 -// * IDIVW m16 -// -func (self *Program) IDIVW(v0 interface{}) *Instruction { - p := self.alloc("IDIVW", 1, Operands { v0 }) - // IDIVW r16 - if isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xf8 | lcode(v[0])) - }) - } - // IDIVW m16 - if isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(7, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for IDIVW") - } - return p -} - -// IMULB performs "Signed Multiply". -// -// Mnemonic : IMUL -// Supported forms : (2 forms) -// -// * IMULB r8 -// * IMULB m8 -// -func (self *Program) IMULB(v0 interface{}) *Instruction { - p := self.alloc("IMULB", 1, Operands { v0 }) - // IMULB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0xf6) - m.emit(0xe8 | lcode(v[0])) - }) - } - // IMULB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf6) - m.mrsd(5, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for IMULB") - } - return p -} - -// IMULL performs "Signed Multiply". -// -// Mnemonic : IMUL -// Supported forms : (8 forms) -// -// * IMULL r32 -// * IMULL m32 -// * IMULL r32, r32 -// * IMULL m32, r32 -// * IMULL imm8, r32, r32 -// * IMULL imm32, r32, r32 -// * IMULL imm8, m32, r32 -// * IMULL imm32, m32, r32 -// -func (self *Program) IMULL(v0 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("IMULL", 1, Operands { v0 }) - case 1 : p = self.alloc("IMULL", 2, Operands { v0, vv[0] }) - case 2 : p = self.alloc("IMULL", 3, Operands { v0, vv[0], vv[1] }) - default : panic("instruction IMULL takes 1 or 2 or 3 operands") - } - // IMULL r32 - if len(vv) == 0 && isReg32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xe8 | lcode(v[0])) - }) - } - // IMULL m32 - if len(vv) == 0 && isM32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(5, addr(v[0]), 1) - }) - } - // IMULL r32, r32 - if len(vv) == 1 && isReg32(v0) && isReg32(vv[0]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xaf) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // IMULL m32, r32 - if len(vv) == 1 && isM32(v0) && isReg32(vv[0]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xaf) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // IMULL imm8, r32, r32 - if len(vv) == 2 && isImm8(v0) && isReg32(vv[0]) && isReg32(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // IMULL imm32, r32, r32 - if len(vv) == 2 && isImm32(v0) && isReg32(vv[0]) && isReg32(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x69) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // IMULL imm8, m32, r32 - if len(vv) == 2 && isImm8(v0) && isM32(vv[0]) && isReg32(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x6b) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // IMULL imm32, m32, r32 - if len(vv) == 2 && isImm32(v0) && isM32(vv[0]) && isReg32(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x69) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for IMULL") - } - return p -} - -// IMULQ performs "Signed Multiply". -// -// Mnemonic : IMUL -// Supported forms : (8 forms) -// -// * IMULQ r64 -// * IMULQ m64 -// * IMULQ r64, r64 -// * IMULQ m64, r64 -// * IMULQ imm8, r64, r64 -// * IMULQ imm32, r64, r64 -// * IMULQ imm8, m64, r64 -// * IMULQ imm32, m64, r64 -// -func (self *Program) IMULQ(v0 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("IMULQ", 1, Operands { v0 }) - case 1 : p = self.alloc("IMULQ", 2, Operands { v0, vv[0] }) - case 2 : p = self.alloc("IMULQ", 3, Operands { v0, vv[0], vv[1] }) - default : panic("instruction IMULQ takes 1 or 2 or 3 operands") - } - // IMULQ r64 - if len(vv) == 0 && isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0xf7) - m.emit(0xe8 | lcode(v[0])) - }) - } - // IMULQ m64 - if len(vv) == 0 && isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[0])) - m.emit(0xf7) - m.mrsd(5, addr(v[0]), 1) - }) - } - // IMULQ r64, r64 - if len(vv) == 1 && isReg64(v0) && isReg64(vv[0]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xaf) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // IMULQ m64, r64 - if len(vv) == 1 && isM64(v0) && isReg64(vv[0]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xaf) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // IMULQ imm8, r64, r64 - if len(vv) == 2 && isImm8(v0) && isReg64(vv[0]) && isReg64(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[2]) << 2 | hcode(v[1])) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // IMULQ imm32, r64, r64 - if len(vv) == 2 && isImm32(v0) && isReg64(vv[0]) && isReg64(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[2]) << 2 | hcode(v[1])) - m.emit(0x69) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // IMULQ imm8, m64, r64 - if len(vv) == 2 && isImm8(v0) && isM64(vv[0]) && isReg64(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[2]), addr(v[1])) - m.emit(0x6b) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // IMULQ imm32, m64, r64 - if len(vv) == 2 && isImm32(v0) && isM64(vv[0]) && isReg64(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[2]), addr(v[1])) - m.emit(0x69) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for IMULQ") - } - return p -} - -// IMULW performs "Signed Multiply". -// -// Mnemonic : IMUL -// Supported forms : (8 forms) -// -// * IMULW r16 -// * IMULW m16 -// * IMULW r16, r16 -// * IMULW m16, r16 -// * IMULW imm8, r16, r16 -// * IMULW imm16, r16, r16 -// * IMULW imm8, m16, r16 -// * IMULW imm16, m16, r16 -// -func (self *Program) IMULW(v0 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("IMULW", 1, Operands { v0 }) - case 1 : p = self.alloc("IMULW", 2, Operands { v0, vv[0] }) - case 2 : p = self.alloc("IMULW", 3, Operands { v0, vv[0], vv[1] }) - default : panic("instruction IMULW takes 1 or 2 or 3 operands") - } - // IMULW r16 - if len(vv) == 0 && isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xe8 | lcode(v[0])) - }) - } - // IMULW m16 - if len(vv) == 0 && isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(5, addr(v[0]), 1) - }) - } - // IMULW r16, r16 - if len(vv) == 1 && isReg16(v0) && isReg16(vv[0]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xaf) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // IMULW m16, r16 - if len(vv) == 1 && isM16(v0) && isReg16(vv[0]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xaf) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // IMULW imm8, r16, r16 - if len(vv) == 2 && isImm8(v0) && isReg16(vv[0]) && isReg16(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // IMULW imm16, r16, r16 - if len(vv) == 2 && isImm16(v0) && isReg16(vv[0]) && isReg16(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x69) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // IMULW imm8, m16, r16 - if len(vv) == 2 && isImm8(v0) && isM16(vv[0]) && isReg16(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x6b) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // IMULW imm16, m16, r16 - if len(vv) == 2 && isImm16(v0) && isM16(vv[0]) && isReg16(vv[1]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x69) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for IMULW") - } - return p -} - -// INCB performs "Increment by 1". -// -// Mnemonic : INC -// Supported forms : (2 forms) -// -// * INCB r8 -// * INCB m8 -// -func (self *Program) INCB(v0 interface{}) *Instruction { - p := self.alloc("INCB", 1, Operands { v0 }) - // INCB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0xfe) - m.emit(0xc0 | lcode(v[0])) - }) - } - // INCB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xfe) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for INCB") - } - return p -} - -// INCL performs "Increment by 1". -// -// Mnemonic : INC -// Supported forms : (2 forms) -// -// * INCL r32 -// * INCL m32 -// -func (self *Program) INCL(v0 interface{}) *Instruction { - p := self.alloc("INCL", 1, Operands { v0 }) - // INCL r32 - if isReg32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xff) - m.emit(0xc0 | lcode(v[0])) - }) - } - // INCL m32 - if isM32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xff) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for INCL") - } - return p -} - -// INCQ performs "Increment by 1". -// -// Mnemonic : INC -// Supported forms : (2 forms) -// -// * INCQ r64 -// * INCQ m64 -// -func (self *Program) INCQ(v0 interface{}) *Instruction { - p := self.alloc("INCQ", 1, Operands { v0 }) - // INCQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0xff) - m.emit(0xc0 | lcode(v[0])) - }) - } - // INCQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[0])) - m.emit(0xff) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for INCQ") - } - return p -} - -// INCW performs "Increment by 1". -// -// Mnemonic : INC -// Supported forms : (2 forms) -// -// * INCW r16 -// * INCW m16 -// -func (self *Program) INCW(v0 interface{}) *Instruction { - p := self.alloc("INCW", 1, Operands { v0 }) - // INCW r16 - if isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0xff) - m.emit(0xc0 | lcode(v[0])) - }) - } - // INCW m16 - if isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0xff) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for INCW") - } - return p -} - -// INSERTPS performs "Insert Packed Single Precision Floating-Point Value". -// -// Mnemonic : INSERTPS -// Supported forms : (2 forms) -// -// * INSERTPS imm8, xmm, xmm [SSE4.1] -// * INSERTPS imm8, m32, xmm [SSE4.1] -// -func (self *Program) INSERTPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("INSERTPS", 3, Operands { v0, v1, v2 }) - // INSERTPS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x21) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // INSERTPS imm8, m32, xmm - if isImm8(v0) && isM32(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x21) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for INSERTPS") - } - return p -} - -// INSERTQ performs "Insert Field". -// -// Mnemonic : INSERTQ -// Supported forms : (2 forms) -// -// * INSERTQ xmm, xmm [SSE4A] -// * INSERTQ imm8, imm8, xmm, xmm [SSE4A] -// -func (self *Program) INSERTQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("INSERTQ", 2, Operands { v0, v1 }) - case 2 : p = self.alloc("INSERTQ", 4, Operands { v0, v1, vv[0], vv[1] }) - default : panic("instruction INSERTQ takes 2 or 4 operands") - } - // INSERTQ xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4A) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // INSERTQ imm8, imm8, xmm, xmm - if len(vv) == 2 && isImm8(v0) && isImm8(v1) && isXMM(vv[0]) && isXMM(vv[1]) { - self.require(ISA_SSE4A) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[3]), v[2], false) - m.emit(0x0f) - m.emit(0x78) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for INSERTQ") - } - return p -} - -// INT performs "Call to Interrupt Procedure". -// -// Mnemonic : INT -// Supported forms : (2 forms) -// -// * INT 3 -// * INT imm8 -// -func (self *Program) INT(v0 interface{}) *Instruction { - p := self.alloc("INT", 1, Operands { v0 }) - // INT 3 - if isConst3(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xcc) - }) - } - // INT imm8 - if isImm8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xcd) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for INT") - } - return p -} - -// JA performs "Jump if above (CF == 0 and ZF == 0)". -// -// Mnemonic : JA -// Supported forms : (2 forms) -// -// * JA rel8 -// * JA rel32 -// -func (self *Program) JA(v0 interface{}) *Instruction { - p := self.alloc("JA", 1, Operands { v0 }) - p.branch = _B_conditional - // JA rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x77) - m.imm1(relv(v[0])) - }) - } - // JA rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x87) - m.imm4(relv(v[0])) - }) - } - // JA label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x77) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x87) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JA") - } - return p -} - -// JAE performs "Jump if above or equal (CF == 0)". -// -// Mnemonic : JAE -// Supported forms : (2 forms) -// -// * JAE rel8 -// * JAE rel32 -// -func (self *Program) JAE(v0 interface{}) *Instruction { - p := self.alloc("JAE", 1, Operands { v0 }) - p.branch = _B_conditional - // JAE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x73) - m.imm1(relv(v[0])) - }) - } - // JAE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x83) - m.imm4(relv(v[0])) - }) - } - // JAE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x73) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x83) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JAE") - } - return p -} - -// JB performs "Jump if below (CF == 1)". -// -// Mnemonic : JB -// Supported forms : (2 forms) -// -// * JB rel8 -// * JB rel32 -// -func (self *Program) JB(v0 interface{}) *Instruction { - p := self.alloc("JB", 1, Operands { v0 }) - p.branch = _B_conditional - // JB rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x72) - m.imm1(relv(v[0])) - }) - } - // JB rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x82) - m.imm4(relv(v[0])) - }) - } - // JB label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x72) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x82) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JB") - } - return p -} - -// JBE performs "Jump if below or equal (CF == 1 or ZF == 1)". -// -// Mnemonic : JBE -// Supported forms : (2 forms) -// -// * JBE rel8 -// * JBE rel32 -// -func (self *Program) JBE(v0 interface{}) *Instruction { - p := self.alloc("JBE", 1, Operands { v0 }) - p.branch = _B_conditional - // JBE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x76) - m.imm1(relv(v[0])) - }) - } - // JBE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x86) - m.imm4(relv(v[0])) - }) - } - // JBE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x76) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x86) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JBE") - } - return p -} - -// JC performs "Jump if carry (CF == 1)". -// -// Mnemonic : JC -// Supported forms : (2 forms) -// -// * JC rel8 -// * JC rel32 -// -func (self *Program) JC(v0 interface{}) *Instruction { - p := self.alloc("JC", 1, Operands { v0 }) - p.branch = _B_conditional - // JC rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x72) - m.imm1(relv(v[0])) - }) - } - // JC rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x82) - m.imm4(relv(v[0])) - }) - } - // JC label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x72) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x82) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JC") - } - return p -} - -// JE performs "Jump if equal (ZF == 1)". -// -// Mnemonic : JE -// Supported forms : (2 forms) -// -// * JE rel8 -// * JE rel32 -// -func (self *Program) JE(v0 interface{}) *Instruction { - p := self.alloc("JE", 1, Operands { v0 }) - p.branch = _B_conditional - // JE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x74) - m.imm1(relv(v[0])) - }) - } - // JE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x84) - m.imm4(relv(v[0])) - }) - } - // JE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x74) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x84) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JE") - } - return p -} - -// JECXZ performs "Jump if ECX register is 0". -// -// Mnemonic : JECXZ -// Supported forms : (1 form) -// -// * JECXZ rel8 -// -func (self *Program) JECXZ(v0 interface{}) *Instruction { - p := self.alloc("JECXZ", 1, Operands { v0 }) - p.branch = _B_conditional - // JECXZ rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xe3) - m.imm1(relv(v[0])) - }) - } - // JECXZ label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0xe3) - m.imm1(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JECXZ") - } - return p -} - -// JG performs "Jump if greater (ZF == 0 and SF == OF)". -// -// Mnemonic : JG -// Supported forms : (2 forms) -// -// * JG rel8 -// * JG rel32 -// -func (self *Program) JG(v0 interface{}) *Instruction { - p := self.alloc("JG", 1, Operands { v0 }) - p.branch = _B_conditional - // JG rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7f) - m.imm1(relv(v[0])) - }) - } - // JG rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8f) - m.imm4(relv(v[0])) - }) - } - // JG label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7f) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8f) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JG") - } - return p -} - -// JGE performs "Jump if greater or equal (SF == OF)". -// -// Mnemonic : JGE -// Supported forms : (2 forms) -// -// * JGE rel8 -// * JGE rel32 -// -func (self *Program) JGE(v0 interface{}) *Instruction { - p := self.alloc("JGE", 1, Operands { v0 }) - p.branch = _B_conditional - // JGE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7d) - m.imm1(relv(v[0])) - }) - } - // JGE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8d) - m.imm4(relv(v[0])) - }) - } - // JGE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7d) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8d) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JGE") - } - return p -} - -// JL performs "Jump if less (SF != OF)". -// -// Mnemonic : JL -// Supported forms : (2 forms) -// -// * JL rel8 -// * JL rel32 -// -func (self *Program) JL(v0 interface{}) *Instruction { - p := self.alloc("JL", 1, Operands { v0 }) - p.branch = _B_conditional - // JL rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7c) - m.imm1(relv(v[0])) - }) - } - // JL rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8c) - m.imm4(relv(v[0])) - }) - } - // JL label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7c) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8c) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JL") - } - return p -} - -// JLE performs "Jump if less or equal (ZF == 1 or SF != OF)". -// -// Mnemonic : JLE -// Supported forms : (2 forms) -// -// * JLE rel8 -// * JLE rel32 -// -func (self *Program) JLE(v0 interface{}) *Instruction { - p := self.alloc("JLE", 1, Operands { v0 }) - p.branch = _B_conditional - // JLE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7e) - m.imm1(relv(v[0])) - }) - } - // JLE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8e) - m.imm4(relv(v[0])) - }) - } - // JLE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7e) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8e) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JLE") - } - return p -} - -// JMP performs "Jump Unconditionally". -// -// Mnemonic : JMP -// Supported forms : (2 forms) -// -// * JMP rel8 -// * JMP rel32 -// -func (self *Program) JMP(v0 interface{}) *Instruction { - p := self.alloc("JMP", 1, Operands { v0 }) - p.branch = _B_unconditional - // JMP rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xeb) - m.imm1(relv(v[0])) - }) - } - // JMP rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xe9) - m.imm4(relv(v[0])) - }) - } - // JMP label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0xeb) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0xe9) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JMP") - } - return p -} - -// JMPQ performs "Jump Unconditionally". -// -// Mnemonic : JMP -// Supported forms : (2 forms) -// -// * JMPQ r64 -// * JMPQ m64 -// -func (self *Program) JMPQ(v0 interface{}) *Instruction { - p := self.alloc("JMPQ", 1, Operands { v0 }) - // JMPQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xff) - m.emit(0xe0 | lcode(v[0])) - }) - } - // JMPQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xff) - m.mrsd(4, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for JMPQ") - } - return p -} - -// JNA performs "Jump if not above (CF == 1 or ZF == 1)". -// -// Mnemonic : JNA -// Supported forms : (2 forms) -// -// * JNA rel8 -// * JNA rel32 -// -func (self *Program) JNA(v0 interface{}) *Instruction { - p := self.alloc("JNA", 1, Operands { v0 }) - p.branch = _B_conditional - // JNA rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x76) - m.imm1(relv(v[0])) - }) - } - // JNA rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x86) - m.imm4(relv(v[0])) - }) - } - // JNA label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x76) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x86) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNA") - } - return p -} - -// JNAE performs "Jump if not above or equal (CF == 1)". -// -// Mnemonic : JNAE -// Supported forms : (2 forms) -// -// * JNAE rel8 -// * JNAE rel32 -// -func (self *Program) JNAE(v0 interface{}) *Instruction { - p := self.alloc("JNAE", 1, Operands { v0 }) - p.branch = _B_conditional - // JNAE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x72) - m.imm1(relv(v[0])) - }) - } - // JNAE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x82) - m.imm4(relv(v[0])) - }) - } - // JNAE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x72) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x82) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNAE") - } - return p -} - -// JNB performs "Jump if not below (CF == 0)". -// -// Mnemonic : JNB -// Supported forms : (2 forms) -// -// * JNB rel8 -// * JNB rel32 -// -func (self *Program) JNB(v0 interface{}) *Instruction { - p := self.alloc("JNB", 1, Operands { v0 }) - p.branch = _B_conditional - // JNB rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x73) - m.imm1(relv(v[0])) - }) - } - // JNB rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x83) - m.imm4(relv(v[0])) - }) - } - // JNB label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x73) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x83) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNB") - } - return p -} - -// JNBE performs "Jump if not below or equal (CF == 0 and ZF == 0)". -// -// Mnemonic : JNBE -// Supported forms : (2 forms) -// -// * JNBE rel8 -// * JNBE rel32 -// -func (self *Program) JNBE(v0 interface{}) *Instruction { - p := self.alloc("JNBE", 1, Operands { v0 }) - p.branch = _B_conditional - // JNBE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x77) - m.imm1(relv(v[0])) - }) - } - // JNBE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x87) - m.imm4(relv(v[0])) - }) - } - // JNBE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x77) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x87) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNBE") - } - return p -} - -// JNC performs "Jump if not carry (CF == 0)". -// -// Mnemonic : JNC -// Supported forms : (2 forms) -// -// * JNC rel8 -// * JNC rel32 -// -func (self *Program) JNC(v0 interface{}) *Instruction { - p := self.alloc("JNC", 1, Operands { v0 }) - p.branch = _B_conditional - // JNC rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x73) - m.imm1(relv(v[0])) - }) - } - // JNC rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x83) - m.imm4(relv(v[0])) - }) - } - // JNC label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x73) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x83) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNC") - } - return p -} - -// JNE performs "Jump if not equal (ZF == 0)". -// -// Mnemonic : JNE -// Supported forms : (2 forms) -// -// * JNE rel8 -// * JNE rel32 -// -func (self *Program) JNE(v0 interface{}) *Instruction { - p := self.alloc("JNE", 1, Operands { v0 }) - p.branch = _B_conditional - // JNE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x75) - m.imm1(relv(v[0])) - }) - } - // JNE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x85) - m.imm4(relv(v[0])) - }) - } - // JNE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x75) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x85) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNE") - } - return p -} - -// JNG performs "Jump if not greater (ZF == 1 or SF != OF)". -// -// Mnemonic : JNG -// Supported forms : (2 forms) -// -// * JNG rel8 -// * JNG rel32 -// -func (self *Program) JNG(v0 interface{}) *Instruction { - p := self.alloc("JNG", 1, Operands { v0 }) - p.branch = _B_conditional - // JNG rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7e) - m.imm1(relv(v[0])) - }) - } - // JNG rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8e) - m.imm4(relv(v[0])) - }) - } - // JNG label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7e) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8e) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNG") - } - return p -} - -// JNGE performs "Jump if not greater or equal (SF != OF)". -// -// Mnemonic : JNGE -// Supported forms : (2 forms) -// -// * JNGE rel8 -// * JNGE rel32 -// -func (self *Program) JNGE(v0 interface{}) *Instruction { - p := self.alloc("JNGE", 1, Operands { v0 }) - p.branch = _B_conditional - // JNGE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7c) - m.imm1(relv(v[0])) - }) - } - // JNGE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8c) - m.imm4(relv(v[0])) - }) - } - // JNGE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7c) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8c) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNGE") - } - return p -} - -// JNL performs "Jump if not less (SF == OF)". -// -// Mnemonic : JNL -// Supported forms : (2 forms) -// -// * JNL rel8 -// * JNL rel32 -// -func (self *Program) JNL(v0 interface{}) *Instruction { - p := self.alloc("JNL", 1, Operands { v0 }) - p.branch = _B_conditional - // JNL rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7d) - m.imm1(relv(v[0])) - }) - } - // JNL rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8d) - m.imm4(relv(v[0])) - }) - } - // JNL label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7d) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8d) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNL") - } - return p -} - -// JNLE performs "Jump if not less or equal (ZF == 0 and SF == OF)". -// -// Mnemonic : JNLE -// Supported forms : (2 forms) -// -// * JNLE rel8 -// * JNLE rel32 -// -func (self *Program) JNLE(v0 interface{}) *Instruction { - p := self.alloc("JNLE", 1, Operands { v0 }) - p.branch = _B_conditional - // JNLE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7f) - m.imm1(relv(v[0])) - }) - } - // JNLE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8f) - m.imm4(relv(v[0])) - }) - } - // JNLE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7f) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8f) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNLE") - } - return p -} - -// JNO performs "Jump if not overflow (OF == 0)". -// -// Mnemonic : JNO -// Supported forms : (2 forms) -// -// * JNO rel8 -// * JNO rel32 -// -func (self *Program) JNO(v0 interface{}) *Instruction { - p := self.alloc("JNO", 1, Operands { v0 }) - p.branch = _B_conditional - // JNO rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x71) - m.imm1(relv(v[0])) - }) - } - // JNO rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x81) - m.imm4(relv(v[0])) - }) - } - // JNO label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x71) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x81) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNO") - } - return p -} - -// JNP performs "Jump if not parity (PF == 0)". -// -// Mnemonic : JNP -// Supported forms : (2 forms) -// -// * JNP rel8 -// * JNP rel32 -// -func (self *Program) JNP(v0 interface{}) *Instruction { - p := self.alloc("JNP", 1, Operands { v0 }) - p.branch = _B_conditional - // JNP rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7b) - m.imm1(relv(v[0])) - }) - } - // JNP rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8b) - m.imm4(relv(v[0])) - }) - } - // JNP label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7b) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8b) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNP") - } - return p -} - -// JNS performs "Jump if not sign (SF == 0)". -// -// Mnemonic : JNS -// Supported forms : (2 forms) -// -// * JNS rel8 -// * JNS rel32 -// -func (self *Program) JNS(v0 interface{}) *Instruction { - p := self.alloc("JNS", 1, Operands { v0 }) - p.branch = _B_conditional - // JNS rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x79) - m.imm1(relv(v[0])) - }) - } - // JNS rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x89) - m.imm4(relv(v[0])) - }) - } - // JNS label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x79) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x89) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNS") - } - return p -} - -// JNZ performs "Jump if not zero (ZF == 0)". -// -// Mnemonic : JNZ -// Supported forms : (2 forms) -// -// * JNZ rel8 -// * JNZ rel32 -// -func (self *Program) JNZ(v0 interface{}) *Instruction { - p := self.alloc("JNZ", 1, Operands { v0 }) - p.branch = _B_conditional - // JNZ rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x75) - m.imm1(relv(v[0])) - }) - } - // JNZ rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x85) - m.imm4(relv(v[0])) - }) - } - // JNZ label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x75) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x85) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JNZ") - } - return p -} - -// JO performs "Jump if overflow (OF == 1)". -// -// Mnemonic : JO -// Supported forms : (2 forms) -// -// * JO rel8 -// * JO rel32 -// -func (self *Program) JO(v0 interface{}) *Instruction { - p := self.alloc("JO", 1, Operands { v0 }) - p.branch = _B_conditional - // JO rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x70) - m.imm1(relv(v[0])) - }) - } - // JO rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x80) - m.imm4(relv(v[0])) - }) - } - // JO label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x70) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x80) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JO") - } - return p -} - -// JP performs "Jump if parity (PF == 1)". -// -// Mnemonic : JP -// Supported forms : (2 forms) -// -// * JP rel8 -// * JP rel32 -// -func (self *Program) JP(v0 interface{}) *Instruction { - p := self.alloc("JP", 1, Operands { v0 }) - p.branch = _B_conditional - // JP rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7a) - m.imm1(relv(v[0])) - }) - } - // JP rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8a) - m.imm4(relv(v[0])) - }) - } - // JP label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7a) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8a) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JP") - } - return p -} - -// JPE performs "Jump if parity even (PF == 1)". -// -// Mnemonic : JPE -// Supported forms : (2 forms) -// -// * JPE rel8 -// * JPE rel32 -// -func (self *Program) JPE(v0 interface{}) *Instruction { - p := self.alloc("JPE", 1, Operands { v0 }) - p.branch = _B_conditional - // JPE rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7a) - m.imm1(relv(v[0])) - }) - } - // JPE rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8a) - m.imm4(relv(v[0])) - }) - } - // JPE label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7a) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8a) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JPE") - } - return p -} - -// JPO performs "Jump if parity odd (PF == 0)". -// -// Mnemonic : JPO -// Supported forms : (2 forms) -// -// * JPO rel8 -// * JPO rel32 -// -func (self *Program) JPO(v0 interface{}) *Instruction { - p := self.alloc("JPO", 1, Operands { v0 }) - p.branch = _B_conditional - // JPO rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x7b) - m.imm1(relv(v[0])) - }) - } - // JPO rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8b) - m.imm4(relv(v[0])) - }) - } - // JPO label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x7b) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x8b) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JPO") - } - return p -} - -// JRCXZ performs "Jump if RCX register is 0". -// -// Mnemonic : JRCXZ -// Supported forms : (1 form) -// -// * JRCXZ rel8 -// -func (self *Program) JRCXZ(v0 interface{}) *Instruction { - p := self.alloc("JRCXZ", 1, Operands { v0 }) - p.branch = _B_conditional - // JRCXZ rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xe3) - m.imm1(relv(v[0])) - }) - } - // JRCXZ label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0xe3) - m.imm1(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JRCXZ") - } - return p -} - -// JS performs "Jump if sign (SF == 1)". -// -// Mnemonic : JS -// Supported forms : (2 forms) -// -// * JS rel8 -// * JS rel32 -// -func (self *Program) JS(v0 interface{}) *Instruction { - p := self.alloc("JS", 1, Operands { v0 }) - p.branch = _B_conditional - // JS rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x78) - m.imm1(relv(v[0])) - }) - } - // JS rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x88) - m.imm4(relv(v[0])) - }) - } - // JS label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x78) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x88) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JS") - } - return p -} - -// JZ performs "Jump if zero (ZF == 1)". -// -// Mnemonic : JZ -// Supported forms : (2 forms) -// -// * JZ rel8 -// * JZ rel32 -// -func (self *Program) JZ(v0 interface{}) *Instruction { - p := self.alloc("JZ", 1, Operands { v0 }) - p.branch = _B_conditional - // JZ rel8 - if isRel8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x74) - m.imm1(relv(v[0])) - }) - } - // JZ rel32 - if isRel32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x84) - m.imm4(relv(v[0])) - }) - } - // JZ label - if isLabel(v0) { - p.add(_F_rel1, func(m *_Encoding, v []interface{}) { - m.emit(0x74) - m.imm1(relv(v[0])) - }) - p.add(_F_rel4, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x84) - m.imm4(relv(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for JZ") - } - return p -} - -// KADDB performs "ADD Two 8-bit Masks". -// -// Mnemonic : KADDB -// Supported forms : (1 form) -// -// * KADDB k, k, k [AVX512DQ] -// -func (self *Program) KADDB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KADDB", 3, Operands { v0, v1, v2 }) - // KADDB k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, nil, hlcode(v[1])) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KADDB") - } - return p -} - -// KADDD performs "ADD Two 32-bit Masks". -// -// Mnemonic : KADDD -// Supported forms : (1 form) -// -// * KADDD k, k, k [AVX512BW] -// -func (self *Program) KADDD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KADDD", 3, Operands { v0, v1, v2 }) - // KADDD k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KADDD") - } - return p -} - -// KADDQ performs "ADD Two 64-bit Masks". -// -// Mnemonic : KADDQ -// Supported forms : (1 form) -// -// * KADDQ k, k, k [AVX512BW] -// -func (self *Program) KADDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KADDQ", 3, Operands { v0, v1, v2 }) - // KADDQ k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfc ^ (hlcode(v[1]) << 3)) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KADDQ") - } - return p -} - -// KADDW performs "ADD Two 16-bit Masks". -// -// Mnemonic : KADDW -// Supported forms : (1 form) -// -// * KADDW k, k, k [AVX512DQ] -// -func (self *Program) KADDW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KADDW", 3, Operands { v0, v1, v2 }) - // KADDW k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, 0, nil, hlcode(v[1])) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KADDW") - } - return p -} - -// KANDB performs "Bitwise Logical AND 8-bit Masks". -// -// Mnemonic : KANDB -// Supported forms : (1 form) -// -// * KANDB k, k, k [AVX512DQ] -// -func (self *Program) KANDB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KANDB", 3, Operands { v0, v1, v2 }) - // KANDB k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, nil, hlcode(v[1])) - m.emit(0x41) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KANDB") - } - return p -} - -// KANDD performs "Bitwise Logical AND 32-bit Masks". -// -// Mnemonic : KANDD -// Supported forms : (1 form) -// -// * KANDD k, k, k [AVX512BW] -// -func (self *Program) KANDD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KANDD", 3, Operands { v0, v1, v2 }) - // KANDD k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x41) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KANDD") - } - return p -} - -// KANDNB performs "Bitwise Logical AND NOT 8-bit Masks". -// -// Mnemonic : KANDNB -// Supported forms : (1 form) -// -// * KANDNB k, k, k [AVX512DQ] -// -func (self *Program) KANDNB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KANDNB", 3, Operands { v0, v1, v2 }) - // KANDNB k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, nil, hlcode(v[1])) - m.emit(0x42) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KANDNB") - } - return p -} - -// KANDND performs "Bitwise Logical AND NOT 32-bit Masks". -// -// Mnemonic : KANDND -// Supported forms : (1 form) -// -// * KANDND k, k, k [AVX512BW] -// -func (self *Program) KANDND(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KANDND", 3, Operands { v0, v1, v2 }) - // KANDND k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x42) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KANDND") - } - return p -} - -// KANDNQ performs "Bitwise Logical AND NOT 64-bit Masks". -// -// Mnemonic : KANDNQ -// Supported forms : (1 form) -// -// * KANDNQ k, k, k [AVX512BW] -// -func (self *Program) KANDNQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KANDNQ", 3, Operands { v0, v1, v2 }) - // KANDNQ k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfc ^ (hlcode(v[1]) << 3)) - m.emit(0x42) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KANDNQ") - } - return p -} - -// KANDNW performs "Bitwise Logical AND NOT 16-bit Masks". -// -// Mnemonic : KANDNW -// Supported forms : (1 form) -// -// * KANDNW k, k, k [AVX512F] -// -func (self *Program) KANDNW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KANDNW", 3, Operands { v0, v1, v2 }) - // KANDNW k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, 0, nil, hlcode(v[1])) - m.emit(0x42) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KANDNW") - } - return p -} - -// KANDQ performs "Bitwise Logical AND 64-bit Masks". -// -// Mnemonic : KANDQ -// Supported forms : (1 form) -// -// * KANDQ k, k, k [AVX512BW] -// -func (self *Program) KANDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KANDQ", 3, Operands { v0, v1, v2 }) - // KANDQ k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfc ^ (hlcode(v[1]) << 3)) - m.emit(0x41) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KANDQ") - } - return p -} - -// KANDW performs "Bitwise Logical AND 16-bit Masks". -// -// Mnemonic : KANDW -// Supported forms : (1 form) -// -// * KANDW k, k, k [AVX512F] -// -func (self *Program) KANDW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KANDW", 3, Operands { v0, v1, v2 }) - // KANDW k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, 0, nil, hlcode(v[1])) - m.emit(0x41) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KANDW") - } - return p -} - -// KMOVB performs "Move 8-bit Mask". -// -// Mnemonic : KMOVB -// Supported forms : (5 forms) -// -// * KMOVB k, k [AVX512DQ] -// * KMOVB r32, k [AVX512DQ] -// * KMOVB m8, k [AVX512DQ] -// * KMOVB k, r32 [AVX512DQ] -// * KMOVB k, m8 [AVX512DQ] -// -func (self *Program) KMOVB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KMOVB", 2, Operands { v0, v1 }) - // KMOVB k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, nil, 0) - m.emit(0x90) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVB r32, k - if isReg32(v0) && isK(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[0], 0) - m.emit(0x92) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVB m8, k - if isM8(v0) && isK(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, addr(v[0]), 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // KMOVB k, r32 - if isK(v0) && isReg32(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), nil, 0) - m.emit(0x93) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVB k, m8 - if isK(v0) && isM8(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, addr(v[1]), 0) - m.emit(0x91) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for KMOVB") - } - return p -} - -// KMOVD performs "Move 32-bit Mask". -// -// Mnemonic : KMOVD -// Supported forms : (5 forms) -// -// * KMOVD k, k [AVX512BW] -// * KMOVD r32, k [AVX512BW] -// * KMOVD m32, k [AVX512BW] -// * KMOVD k, r32 [AVX512BW] -// * KMOVD k, m32 [AVX512BW] -// -func (self *Program) KMOVD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KMOVD", 2, Operands { v0, v1 }) - // KMOVD k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xf9) - m.emit(0x90) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVD r32, k - if isReg32(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, 0, v[0], 0) - m.emit(0x92) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVD m32, k - if isM32(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x81, 0, addr(v[0]), 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // KMOVD k, r32 - if isK(v0) && isReg32(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), nil, 0) - m.emit(0x93) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVD k, m32 - if isK(v0) && isM32(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x81, 0, addr(v[1]), 0) - m.emit(0x91) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for KMOVD") - } - return p -} - -// KMOVQ performs "Move 64-bit Mask". -// -// Mnemonic : KMOVQ -// Supported forms : (5 forms) -// -// * KMOVQ k, k [AVX512BW] -// * KMOVQ r64, k [AVX512BW] -// * KMOVQ m64, k [AVX512BW] -// * KMOVQ k, r64 [AVX512BW] -// * KMOVQ k, m64 [AVX512BW] -// -func (self *Program) KMOVQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KMOVQ", 2, Operands { v0, v1 }) - // KMOVQ k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xf8) - m.emit(0x90) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVQ r64, k - if isReg64(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[0]) << 5)) - m.emit(0xfb) - m.emit(0x92) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVQ m64, k - if isM64(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x80, 0, addr(v[0]), 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // KMOVQ k, r64 - if isK(v0) && isReg64(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[1]) << 7)) - m.emit(0xfb) - m.emit(0x93) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVQ k, m64 - if isK(v0) && isM64(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x80, 0, addr(v[1]), 0) - m.emit(0x91) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for KMOVQ") - } - return p -} - -// KMOVW performs "Move 16-bit Mask". -// -// Mnemonic : KMOVW -// Supported forms : (5 forms) -// -// * KMOVW k, k [AVX512F] -// * KMOVW r32, k [AVX512F] -// * KMOVW m16, k [AVX512F] -// * KMOVW k, r32 [AVX512F] -// * KMOVW k, m16 [AVX512F] -// -func (self *Program) KMOVW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KMOVW", 2, Operands { v0, v1 }) - // KMOVW k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, nil, 0) - m.emit(0x90) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVW r32, k - if isReg32(v0) && isK(v1) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, v[0], 0) - m.emit(0x92) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVW m16, k - if isM16(v0) && isK(v1) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, addr(v[0]), 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // KMOVW k, r32 - if isK(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), nil, 0) - m.emit(0x93) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // KMOVW k, m16 - if isK(v0) && isM16(v1) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, addr(v[1]), 0) - m.emit(0x91) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for KMOVW") - } - return p -} - -// KNOTB performs "NOT 8-bit Mask Register". -// -// Mnemonic : KNOTB -// Supported forms : (1 form) -// -// * KNOTB k, k [AVX512DQ] -// -func (self *Program) KNOTB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KNOTB", 2, Operands { v0, v1 }) - // KNOTB k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, nil, 0) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KNOTB") - } - return p -} - -// KNOTD performs "NOT 32-bit Mask Register". -// -// Mnemonic : KNOTD -// Supported forms : (1 form) -// -// * KNOTD k, k [AVX512BW] -// -func (self *Program) KNOTD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KNOTD", 2, Operands { v0, v1 }) - // KNOTD k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xf9) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KNOTD") - } - return p -} - -// KNOTQ performs "NOT 64-bit Mask Register". -// -// Mnemonic : KNOTQ -// Supported forms : (1 form) -// -// * KNOTQ k, k [AVX512BW] -// -func (self *Program) KNOTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KNOTQ", 2, Operands { v0, v1 }) - // KNOTQ k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xf8) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KNOTQ") - } - return p -} - -// KNOTW performs "NOT 16-bit Mask Register". -// -// Mnemonic : KNOTW -// Supported forms : (1 form) -// -// * KNOTW k, k [AVX512F] -// -func (self *Program) KNOTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KNOTW", 2, Operands { v0, v1 }) - // KNOTW k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, nil, 0) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KNOTW") - } - return p -} - -// KORB performs "Bitwise Logical OR 8-bit Masks". -// -// Mnemonic : KORB -// Supported forms : (1 form) -// -// * KORB k, k, k [AVX512DQ] -// -func (self *Program) KORB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KORB", 3, Operands { v0, v1, v2 }) - // KORB k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, nil, hlcode(v[1])) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KORB") - } - return p -} - -// KORD performs "Bitwise Logical OR 32-bit Masks". -// -// Mnemonic : KORD -// Supported forms : (1 form) -// -// * KORD k, k, k [AVX512BW] -// -func (self *Program) KORD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KORD", 3, Operands { v0, v1, v2 }) - // KORD k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KORD") - } - return p -} - -// KORQ performs "Bitwise Logical OR 64-bit Masks". -// -// Mnemonic : KORQ -// Supported forms : (1 form) -// -// * KORQ k, k, k [AVX512BW] -// -func (self *Program) KORQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KORQ", 3, Operands { v0, v1, v2 }) - // KORQ k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfc ^ (hlcode(v[1]) << 3)) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KORQ") - } - return p -} - -// KORTESTB performs "OR 8-bit Masks and Set Flags". -// -// Mnemonic : KORTESTB -// Supported forms : (1 form) -// -// * KORTESTB k, k [AVX512DQ] -// -func (self *Program) KORTESTB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KORTESTB", 2, Operands { v0, v1 }) - // KORTESTB k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, nil, 0) - m.emit(0x98) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KORTESTB") - } - return p -} - -// KORTESTD performs "OR 32-bit Masks and Set Flags". -// -// Mnemonic : KORTESTD -// Supported forms : (1 form) -// -// * KORTESTD k, k [AVX512BW] -// -func (self *Program) KORTESTD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KORTESTD", 2, Operands { v0, v1 }) - // KORTESTD k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xf9) - m.emit(0x98) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KORTESTD") - } - return p -} - -// KORTESTQ performs "OR 64-bit Masks and Set Flags". -// -// Mnemonic : KORTESTQ -// Supported forms : (1 form) -// -// * KORTESTQ k, k [AVX512BW] -// -func (self *Program) KORTESTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KORTESTQ", 2, Operands { v0, v1 }) - // KORTESTQ k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xf8) - m.emit(0x98) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KORTESTQ") - } - return p -} - -// KORTESTW performs "OR 16-bit Masks and Set Flags". -// -// Mnemonic : KORTESTW -// Supported forms : (1 form) -// -// * KORTESTW k, k [AVX512F] -// -func (self *Program) KORTESTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KORTESTW", 2, Operands { v0, v1 }) - // KORTESTW k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, nil, 0) - m.emit(0x98) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KORTESTW") - } - return p -} - -// KORW performs "Bitwise Logical OR 16-bit Masks". -// -// Mnemonic : KORW -// Supported forms : (1 form) -// -// * KORW k, k, k [AVX512F] -// -func (self *Program) KORW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KORW", 3, Operands { v0, v1, v2 }) - // KORW k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, 0, nil, hlcode(v[1])) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KORW") - } - return p -} - -// KSHIFTLB performs "Shift Left 8-bit Masks". -// -// Mnemonic : KSHIFTLB -// Supported forms : (1 form) -// -// * KSHIFTLB imm8, k, k [AVX512DQ] -// -func (self *Program) KSHIFTLB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KSHIFTLB", 3, Operands { v0, v1, v2 }) - // KSHIFTLB imm8, k, k - if isImm8(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3) - m.emit(0x79) - m.emit(0x32) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KSHIFTLB") - } - return p -} - -// KSHIFTLD performs "Shift Left 32-bit Masks". -// -// Mnemonic : KSHIFTLD -// Supported forms : (1 form) -// -// * KSHIFTLD imm8, k, k [AVX512BW] -// -func (self *Program) KSHIFTLD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KSHIFTLD", 3, Operands { v0, v1, v2 }) - // KSHIFTLD imm8, k, k - if isImm8(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3) - m.emit(0x79) - m.emit(0x33) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KSHIFTLD") - } - return p -} - -// KSHIFTLQ performs "Shift Left 64-bit Masks". -// -// Mnemonic : KSHIFTLQ -// Supported forms : (1 form) -// -// * KSHIFTLQ imm8, k, k [AVX512BW] -// -func (self *Program) KSHIFTLQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KSHIFTLQ", 3, Operands { v0, v1, v2 }) - // KSHIFTLQ imm8, k, k - if isImm8(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3) - m.emit(0xf9) - m.emit(0x33) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KSHIFTLQ") - } - return p -} - -// KSHIFTLW performs "Shift Left 16-bit Masks". -// -// Mnemonic : KSHIFTLW -// Supported forms : (1 form) -// -// * KSHIFTLW imm8, k, k [AVX512F] -// -func (self *Program) KSHIFTLW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KSHIFTLW", 3, Operands { v0, v1, v2 }) - // KSHIFTLW imm8, k, k - if isImm8(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3) - m.emit(0xf9) - m.emit(0x32) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KSHIFTLW") - } - return p -} - -// KSHIFTRB performs "Shift Right 8-bit Masks". -// -// Mnemonic : KSHIFTRB -// Supported forms : (1 form) -// -// * KSHIFTRB imm8, k, k [AVX512DQ] -// -func (self *Program) KSHIFTRB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KSHIFTRB", 3, Operands { v0, v1, v2 }) - // KSHIFTRB imm8, k, k - if isImm8(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3) - m.emit(0x79) - m.emit(0x30) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KSHIFTRB") - } - return p -} - -// KSHIFTRD performs "Shift Right 32-bit Masks". -// -// Mnemonic : KSHIFTRD -// Supported forms : (1 form) -// -// * KSHIFTRD imm8, k, k [AVX512BW] -// -func (self *Program) KSHIFTRD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KSHIFTRD", 3, Operands { v0, v1, v2 }) - // KSHIFTRD imm8, k, k - if isImm8(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3) - m.emit(0x79) - m.emit(0x31) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KSHIFTRD") - } - return p -} - -// KSHIFTRQ performs "Shift Right 64-bit Masks". -// -// Mnemonic : KSHIFTRQ -// Supported forms : (1 form) -// -// * KSHIFTRQ imm8, k, k [AVX512BW] -// -func (self *Program) KSHIFTRQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KSHIFTRQ", 3, Operands { v0, v1, v2 }) - // KSHIFTRQ imm8, k, k - if isImm8(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3) - m.emit(0xf9) - m.emit(0x31) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KSHIFTRQ") - } - return p -} - -// KSHIFTRW performs "Shift Right 16-bit Masks". -// -// Mnemonic : KSHIFTRW -// Supported forms : (1 form) -// -// * KSHIFTRW imm8, k, k [AVX512F] -// -func (self *Program) KSHIFTRW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KSHIFTRW", 3, Operands { v0, v1, v2 }) - // KSHIFTRW imm8, k, k - if isImm8(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3) - m.emit(0xf9) - m.emit(0x30) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KSHIFTRW") - } - return p -} - -// KTESTB performs "Bit Test 8-bit Masks and Set Flags". -// -// Mnemonic : KTESTB -// Supported forms : (1 form) -// -// * KTESTB k, k [AVX512DQ] -// -func (self *Program) KTESTB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KTESTB", 2, Operands { v0, v1 }) - // KTESTB k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, nil, 0) - m.emit(0x99) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KTESTB") - } - return p -} - -// KTESTD performs "Bit Test 32-bit Masks and Set Flags". -// -// Mnemonic : KTESTD -// Supported forms : (1 form) -// -// * KTESTD k, k [AVX512BW] -// -func (self *Program) KTESTD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KTESTD", 2, Operands { v0, v1 }) - // KTESTD k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xf9) - m.emit(0x99) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KTESTD") - } - return p -} - -// KTESTQ performs "Bit Test 64-bit Masks and Set Flags". -// -// Mnemonic : KTESTQ -// Supported forms : (1 form) -// -// * KTESTQ k, k [AVX512BW] -// -func (self *Program) KTESTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KTESTQ", 2, Operands { v0, v1 }) - // KTESTQ k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xf8) - m.emit(0x99) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KTESTQ") - } - return p -} - -// KTESTW performs "Bit Test 16-bit Masks and Set Flags". -// -// Mnemonic : KTESTW -// Supported forms : (1 form) -// -// * KTESTW k, k [AVX512DQ] -// -func (self *Program) KTESTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("KTESTW", 2, Operands { v0, v1 }) - // KTESTW k, k - if isK(v0) && isK(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, nil, 0) - m.emit(0x99) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KTESTW") - } - return p -} - -// KUNPCKBW performs "Unpack and Interleave 8-bit Masks". -// -// Mnemonic : KUNPCKBW -// Supported forms : (1 form) -// -// * KUNPCKBW k, k, k [AVX512F] -// -func (self *Program) KUNPCKBW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KUNPCKBW", 3, Operands { v0, v1, v2 }) - // KUNPCKBW k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, nil, hlcode(v[1])) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KUNPCKBW") - } - return p -} - -// KUNPCKDQ performs "Unpack and Interleave 32-bit Masks". -// -// Mnemonic : KUNPCKDQ -// Supported forms : (1 form) -// -// * KUNPCKDQ k, k, k [AVX512BW] -// -func (self *Program) KUNPCKDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KUNPCKDQ", 3, Operands { v0, v1, v2 }) - // KUNPCKDQ k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfc ^ (hlcode(v[1]) << 3)) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KUNPCKDQ") - } - return p -} - -// KUNPCKWD performs "Unpack and Interleave 16-bit Masks". -// -// Mnemonic : KUNPCKWD -// Supported forms : (1 form) -// -// * KUNPCKWD k, k, k [AVX512BW] -// -func (self *Program) KUNPCKWD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KUNPCKWD", 3, Operands { v0, v1, v2 }) - // KUNPCKWD k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, 0, nil, hlcode(v[1])) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KUNPCKWD") - } - return p -} - -// KXNORB performs "Bitwise Logical XNOR 8-bit Masks". -// -// Mnemonic : KXNORB -// Supported forms : (1 form) -// -// * KXNORB k, k, k [AVX512DQ] -// -func (self *Program) KXNORB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KXNORB", 3, Operands { v0, v1, v2 }) - // KXNORB k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, nil, hlcode(v[1])) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KXNORB") - } - return p -} - -// KXNORD performs "Bitwise Logical XNOR 32-bit Masks". -// -// Mnemonic : KXNORD -// Supported forms : (1 form) -// -// * KXNORD k, k, k [AVX512BW] -// -func (self *Program) KXNORD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KXNORD", 3, Operands { v0, v1, v2 }) - // KXNORD k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KXNORD") - } - return p -} - -// KXNORQ performs "Bitwise Logical XNOR 64-bit Masks". -// -// Mnemonic : KXNORQ -// Supported forms : (1 form) -// -// * KXNORQ k, k, k [AVX512BW] -// -func (self *Program) KXNORQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KXNORQ", 3, Operands { v0, v1, v2 }) - // KXNORQ k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfc ^ (hlcode(v[1]) << 3)) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KXNORQ") - } - return p -} - -// KXNORW performs "Bitwise Logical XNOR 16-bit Masks". -// -// Mnemonic : KXNORW -// Supported forms : (1 form) -// -// * KXNORW k, k, k [AVX512F] -// -func (self *Program) KXNORW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KXNORW", 3, Operands { v0, v1, v2 }) - // KXNORW k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, 0, nil, hlcode(v[1])) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KXNORW") - } - return p -} - -// KXORB performs "Bitwise Logical XOR 8-bit Masks". -// -// Mnemonic : KXORB -// Supported forms : (1 form) -// -// * KXORB k, k, k [AVX512DQ] -// -func (self *Program) KXORB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KXORB", 3, Operands { v0, v1, v2 }) - // KXORB k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, nil, hlcode(v[1])) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KXORB") - } - return p -} - -// KXORD performs "Bitwise Logical XOR 32-bit Masks". -// -// Mnemonic : KXORD -// Supported forms : (1 form) -// -// * KXORD k, k, k [AVX512BW] -// -func (self *Program) KXORD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KXORD", 3, Operands { v0, v1, v2 }) - // KXORD k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KXORD") - } - return p -} - -// KXORQ performs "Bitwise Logical XOR 64-bit Masks". -// -// Mnemonic : KXORQ -// Supported forms : (1 form) -// -// * KXORQ k, k, k [AVX512BW] -// -func (self *Program) KXORQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KXORQ", 3, Operands { v0, v1, v2 }) - // KXORQ k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1) - m.emit(0xfc ^ (hlcode(v[1]) << 3)) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KXORQ") - } - return p -} - -// KXORW performs "Bitwise Logical XOR 16-bit Masks". -// -// Mnemonic : KXORW -// Supported forms : (1 form) -// -// * KXORW k, k, k [AVX512F] -// -func (self *Program) KXORW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("KXORW", 3, Operands { v0, v1, v2 }) - // KXORW k, k, k - if isK(v0) && isK(v1) && isK(v2) { - self.require(ISA_AVX512F) - p.domain = DomainMask - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, 0, nil, hlcode(v[1])) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for KXORW") - } - return p -} - -// LDDQU performs "Load Unaligned Integer 128 Bits". -// -// Mnemonic : LDDQU -// Supported forms : (1 form) -// -// * LDDQU m128, xmm [SSE3] -// -func (self *Program) LDDQU(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("LDDQU", 2, Operands { v0, v1 }) - // LDDQU m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for LDDQU") - } - return p -} - -// LDMXCSR performs "Load MXCSR Register". -// -// Mnemonic : LDMXCSR -// Supported forms : (1 form) -// -// * LDMXCSR m32 [SSE] -// -func (self *Program) LDMXCSR(v0 interface{}) *Instruction { - p := self.alloc("LDMXCSR", 1, Operands { v0 }) - // LDMXCSR m32 - if isM32(v0) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0xae) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for LDMXCSR") - } - return p -} - -// LEAL performs "Load Effective Address". -// -// Mnemonic : LEA -// Supported forms : (1 form) -// -// * LEAL m, r32 -// -func (self *Program) LEAL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("LEAL", 2, Operands { v0, v1 }) - // LEAL m, r32 - if isM(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x8d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for LEAL") - } - return p -} - -// LEAQ performs "Load Effective Address". -// -// Mnemonic : LEA -// Supported forms : (1 form) -// -// * LEAQ m, r64 -// -func (self *Program) LEAQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("LEAQ", 2, Operands { v0, v1 }) - // LEAQ m, r64 - if isM(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x8d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for LEAQ") - } - return p -} - -// LEAW performs "Load Effective Address". -// -// Mnemonic : LEA -// Supported forms : (1 form) -// -// * LEAW m, r16 -// -func (self *Program) LEAW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("LEAW", 2, Operands { v0, v1 }) - // LEAW m, r16 - if isM(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x8d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for LEAW") - } - return p -} - -// LFENCE performs "Load Fence". -// -// Mnemonic : LFENCE -// Supported forms : (1 form) -// -// * LFENCE [SSE2] -// -func (self *Program) LFENCE() *Instruction { - p := self.alloc("LFENCE", 0, Operands { }) - // LFENCE - self.require(ISA_SSE2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0xae) - m.emit(0xe8) - }) - return p -} - -// LZCNTL performs "Count the Number of Leading Zero Bits". -// -// Mnemonic : LZCNT -// Supported forms : (2 forms) -// -// * LZCNTL r32, r32 [LZCNT] -// * LZCNTL m32, r32 [LZCNT] -// -func (self *Program) LZCNTL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("LZCNTL", 2, Operands { v0, v1 }) - // LZCNTL r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_LZCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // LZCNTL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_LZCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for LZCNTL") - } - return p -} - -// LZCNTQ performs "Count the Number of Leading Zero Bits". -// -// Mnemonic : LZCNT -// Supported forms : (2 forms) -// -// * LZCNTQ r64, r64 [LZCNT] -// * LZCNTQ m64, r64 [LZCNT] -// -func (self *Program) LZCNTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("LZCNTQ", 2, Operands { v0, v1 }) - // LZCNTQ r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_LZCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // LZCNTQ m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_LZCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xbd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for LZCNTQ") - } - return p -} - -// LZCNTW performs "Count the Number of Leading Zero Bits". -// -// Mnemonic : LZCNT -// Supported forms : (2 forms) -// -// * LZCNTW r16, r16 [LZCNT] -// * LZCNTW m16, r16 [LZCNT] -// -func (self *Program) LZCNTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("LZCNTW", 2, Operands { v0, v1 }) - // LZCNTW r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_LZCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // LZCNTW m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_LZCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for LZCNTW") - } - return p -} - -// MASKMOVDQU performs "Store Selected Bytes of Double Quadword". -// -// Mnemonic : MASKMOVDQU -// Supported forms : (1 form) -// -// * MASKMOVDQU xmm, xmm [SSE2] -// -func (self *Program) MASKMOVDQU(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MASKMOVDQU", 2, Operands { v0, v1 }) - // MASKMOVDQU xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for MASKMOVDQU") - } - return p -} - -// MASKMOVQ performs "Store Selected Bytes of Quadword". -// -// Mnemonic : MASKMOVQ -// Supported forms : (1 form) -// -// * MASKMOVQ mm, mm [MMX+] -// -func (self *Program) MASKMOVQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MASKMOVQ", 2, Operands { v0, v1 }) - // MASKMOVQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for MASKMOVQ") - } - return p -} - -// MAXPD performs "Return Maximum Packed Double-Precision Floating-Point Values". -// -// Mnemonic : MAXPD -// Supported forms : (2 forms) -// -// * MAXPD xmm, xmm [SSE2] -// * MAXPD m128, xmm [SSE2] -// -func (self *Program) MAXPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MAXPD", 2, Operands { v0, v1 }) - // MAXPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MAXPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MAXPD") - } - return p -} - -// MAXPS performs "Return Maximum Packed Single-Precision Floating-Point Values". -// -// Mnemonic : MAXPS -// Supported forms : (2 forms) -// -// * MAXPS xmm, xmm [SSE] -// * MAXPS m128, xmm [SSE] -// -func (self *Program) MAXPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MAXPS", 2, Operands { v0, v1 }) - // MAXPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MAXPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MAXPS") - } - return p -} - -// MAXSD performs "Return Maximum Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : MAXSD -// Supported forms : (2 forms) -// -// * MAXSD xmm, xmm [SSE2] -// * MAXSD m64, xmm [SSE2] -// -func (self *Program) MAXSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MAXSD", 2, Operands { v0, v1 }) - // MAXSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MAXSD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MAXSD") - } - return p -} - -// MAXSS performs "Return Maximum Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : MAXSS -// Supported forms : (2 forms) -// -// * MAXSS xmm, xmm [SSE] -// * MAXSS m32, xmm [SSE] -// -func (self *Program) MAXSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MAXSS", 2, Operands { v0, v1 }) - // MAXSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MAXSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MAXSS") - } - return p -} - -// MFENCE performs "Memory Fence". -// -// Mnemonic : MFENCE -// Supported forms : (1 form) -// -// * MFENCE [SSE2] -// -func (self *Program) MFENCE() *Instruction { - p := self.alloc("MFENCE", 0, Operands { }) - // MFENCE - self.require(ISA_SSE2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0xae) - m.emit(0xf0) - }) - return p -} - -// MINPD performs "Return Minimum Packed Double-Precision Floating-Point Values". -// -// Mnemonic : MINPD -// Supported forms : (2 forms) -// -// * MINPD xmm, xmm [SSE2] -// * MINPD m128, xmm [SSE2] -// -func (self *Program) MINPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MINPD", 2, Operands { v0, v1 }) - // MINPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MINPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MINPD") - } - return p -} - -// MINPS performs "Return Minimum Packed Single-Precision Floating-Point Values". -// -// Mnemonic : MINPS -// Supported forms : (2 forms) -// -// * MINPS xmm, xmm [SSE] -// * MINPS m128, xmm [SSE] -// -func (self *Program) MINPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MINPS", 2, Operands { v0, v1 }) - // MINPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MINPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MINPS") - } - return p -} - -// MINSD performs "Return Minimum Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : MINSD -// Supported forms : (2 forms) -// -// * MINSD xmm, xmm [SSE2] -// * MINSD m64, xmm [SSE2] -// -func (self *Program) MINSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MINSD", 2, Operands { v0, v1 }) - // MINSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MINSD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MINSD") - } - return p -} - -// MINSS performs "Return Minimum Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : MINSS -// Supported forms : (2 forms) -// -// * MINSS xmm, xmm [SSE] -// * MINSS m32, xmm [SSE] -// -func (self *Program) MINSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MINSS", 2, Operands { v0, v1 }) - // MINSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MINSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MINSS") - } - return p -} - -// MONITOR performs "Monitor a Linear Address Range". -// -// Mnemonic : MONITOR -// Supported forms : (1 form) -// -// * MONITOR [MONITOR] -// -func (self *Program) MONITOR() *Instruction { - p := self.alloc("MONITOR", 0, Operands { }) - // MONITOR - self.require(ISA_MONITOR) - p.domain = DomainMisc - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x01) - m.emit(0xc8) - }) - return p -} - -// MONITORX performs "Monitor a Linear Address Range with Timeout". -// -// Mnemonic : MONITORX -// Supported forms : (1 form) -// -// * MONITORX [MONITORX] -// -func (self *Program) MONITORX() *Instruction { - p := self.alloc("MONITORX", 0, Operands { }) - // MONITORX - self.require(ISA_MONITORX) - p.domain = DomainMisc - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x01) - m.emit(0xfa) - }) - return p -} - -// MOVAPD performs "Move Aligned Packed Double-Precision Floating-Point Values". -// -// Mnemonic : MOVAPD -// Supported forms : (3 forms) -// -// * MOVAPD xmm, xmm [SSE2] -// * MOVAPD m128, xmm [SSE2] -// * MOVAPD xmm, m128 [SSE2] -// -func (self *Program) MOVAPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVAPD", 2, Operands { v0, v1 }) - // MOVAPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVAPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVAPD xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVAPD") - } - return p -} - -// MOVAPS performs "Move Aligned Packed Single-Precision Floating-Point Values". -// -// Mnemonic : MOVAPS -// Supported forms : (3 forms) -// -// * MOVAPS xmm, xmm [SSE] -// * MOVAPS m128, xmm [SSE] -// * MOVAPS xmm, m128 [SSE] -// -func (self *Program) MOVAPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVAPS", 2, Operands { v0, v1 }) - // MOVAPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVAPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVAPS xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVAPS") - } - return p -} - -// MOVB performs "Move". -// -// Mnemonic : MOV -// Supported forms : (5 forms) -// -// * MOVB imm8, r8 -// * MOVB r8, r8 -// * MOVB m8, r8 -// * MOVB imm8, m8 -// * MOVB r8, m8 -// -func (self *Program) MOVB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVB", 2, Operands { v0, v1 }) - // MOVB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xb0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // MOVB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x88) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x8a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x8a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc6) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // MOVB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x88) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVB") - } - return p -} - -// MOVBEL performs "Move Data After Swapping Bytes". -// -// Mnemonic : MOVBE -// Supported forms : (2 forms) -// -// * MOVBEL m32, r32 [MOVBE] -// * MOVBEL r32, m32 [MOVBE] -// -func (self *Program) MOVBEL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVBEL", 2, Operands { v0, v1 }) - // MOVBEL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_MOVBE) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVBEL r32, m32 - if isReg32(v0) && isM32(v1) { - self.require(ISA_MOVBE) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf1) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVBEL") - } - return p -} - -// MOVBEQ performs "Move Data After Swapping Bytes". -// -// Mnemonic : MOVBE -// Supported forms : (2 forms) -// -// * MOVBEQ m64, r64 [MOVBE] -// * MOVBEQ r64, m64 [MOVBE] -// -func (self *Program) MOVBEQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVBEQ", 2, Operands { v0, v1 }) - // MOVBEQ m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_MOVBE) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVBEQ r64, m64 - if isReg64(v0) && isM64(v1) { - self.require(ISA_MOVBE) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf1) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVBEQ") - } - return p -} - -// MOVBEW performs "Move Data After Swapping Bytes". -// -// Mnemonic : MOVBE -// Supported forms : (2 forms) -// -// * MOVBEW m16, r16 [MOVBE] -// * MOVBEW r16, m16 [MOVBE] -// -func (self *Program) MOVBEW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVBEW", 2, Operands { v0, v1 }) - // MOVBEW m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_MOVBE) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVBEW r16, m16 - if isReg16(v0) && isM16(v1) { - self.require(ISA_MOVBE) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xf1) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVBEW") - } - return p -} - -// MOVD performs "Move Doubleword". -// -// Mnemonic : MOVD -// Supported forms : (8 forms) -// -// * MOVD mm, r32 [MMX] -// * MOVD r32, mm [MMX] -// * MOVD m32, mm [MMX] -// * MOVD mm, m32 [MMX] -// * MOVD xmm, r32 [SSE2] -// * MOVD r32, xmm [SSE2] -// * MOVD m32, xmm [SSE2] -// * MOVD xmm, m32 [SSE2] -// -func (self *Program) MOVD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVD", 2, Operands { v0, v1 }) - // MOVD mm, r32 - if isMM(v0) && isReg32(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVD r32, mm - if isReg32(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVD m32, mm - if isM32(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVD mm, m32 - if isMM(v0) && isM32(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x7e) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // MOVD xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVD r32, xmm - if isReg32(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVD m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVD xmm, m32 - if isXMM(v0) && isM32(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x7e) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVD") - } - return p -} - -// MOVDDUP performs "Move One Double-FP and Duplicate". -// -// Mnemonic : MOVDDUP -// Supported forms : (2 forms) -// -// * MOVDDUP xmm, xmm [SSE3] -// * MOVDDUP m64, xmm [SSE3] -// -func (self *Program) MOVDDUP(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVDDUP", 2, Operands { v0, v1 }) - // MOVDDUP xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVDDUP m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVDDUP") - } - return p -} - -// MOVDQ2Q performs "Move Quadword from XMM to MMX Technology Register". -// -// Mnemonic : MOVDQ2Q -// Supported forms : (1 form) -// -// * MOVDQ2Q xmm, mm [SSE2] -// -func (self *Program) MOVDQ2Q(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVDQ2Q", 2, Operands { v0, v1 }) - // MOVDQ2Q xmm, mm - if isXMM(v0) && isMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for MOVDQ2Q") - } - return p -} - -// MOVDQA performs "Move Aligned Double Quadword". -// -// Mnemonic : MOVDQA -// Supported forms : (3 forms) -// -// * MOVDQA xmm, xmm [SSE2] -// * MOVDQA m128, xmm [SSE2] -// * MOVDQA xmm, m128 [SSE2] -// -func (self *Program) MOVDQA(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVDQA", 2, Operands { v0, v1 }) - // MOVDQA xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVDQA m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVDQA xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVDQA") - } - return p -} - -// MOVDQU performs "Move Unaligned Double Quadword". -// -// Mnemonic : MOVDQU -// Supported forms : (3 forms) -// -// * MOVDQU xmm, xmm [SSE2] -// * MOVDQU m128, xmm [SSE2] -// * MOVDQU xmm, m128 [SSE2] -// -func (self *Program) MOVDQU(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVDQU", 2, Operands { v0, v1 }) - // MOVDQU xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVDQU m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVDQU xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVDQU") - } - return p -} - -// MOVHLPS performs "Move Packed Single-Precision Floating-Point Values High to Low". -// -// Mnemonic : MOVHLPS -// Supported forms : (1 form) -// -// * MOVHLPS xmm, xmm [SSE] -// -func (self *Program) MOVHLPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVHLPS", 2, Operands { v0, v1 }) - // MOVHLPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for MOVHLPS") - } - return p -} - -// MOVHPD performs "Move High Packed Double-Precision Floating-Point Value". -// -// Mnemonic : MOVHPD -// Supported forms : (2 forms) -// -// * MOVHPD m64, xmm [SSE2] -// * MOVHPD xmm, m64 [SSE2] -// -func (self *Program) MOVHPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVHPD", 2, Operands { v0, v1 }) - // MOVHPD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVHPD xmm, m64 - if isXMM(v0) && isM64(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x17) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVHPD") - } - return p -} - -// MOVHPS performs "Move High Packed Single-Precision Floating-Point Values". -// -// Mnemonic : MOVHPS -// Supported forms : (2 forms) -// -// * MOVHPS m64, xmm [SSE] -// * MOVHPS xmm, m64 [SSE] -// -func (self *Program) MOVHPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVHPS", 2, Operands { v0, v1 }) - // MOVHPS m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVHPS xmm, m64 - if isXMM(v0) && isM64(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x17) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVHPS") - } - return p -} - -// MOVL performs "Move". -// -// Mnemonic : MOV -// Supported forms : (5 forms) -// -// * MOVL imm32, r32 -// * MOVL r32, r32 -// * MOVL m32, r32 -// * MOVL imm32, m32 -// * MOVL r32, m32 -// -func (self *Program) MOVL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVL", 2, Operands { v0, v1 }) - // MOVL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xc7) - m.emit(0xc0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xb8 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // MOVL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x89) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x8b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x8b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc7) - m.mrsd(0, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // MOVL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x89) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVL") - } - return p -} - -// MOVLHPS performs "Move Packed Single-Precision Floating-Point Values Low to High". -// -// Mnemonic : MOVLHPS -// Supported forms : (1 form) -// -// * MOVLHPS xmm, xmm [SSE] -// -func (self *Program) MOVLHPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVLHPS", 2, Operands { v0, v1 }) - // MOVLHPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for MOVLHPS") - } - return p -} - -// MOVLPD performs "Move Low Packed Double-Precision Floating-Point Value". -// -// Mnemonic : MOVLPD -// Supported forms : (2 forms) -// -// * MOVLPD m64, xmm [SSE2] -// * MOVLPD xmm, m64 [SSE2] -// -func (self *Program) MOVLPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVLPD", 2, Operands { v0, v1 }) - // MOVLPD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVLPD xmm, m64 - if isXMM(v0) && isM64(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x13) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVLPD") - } - return p -} - -// MOVLPS performs "Move Low Packed Single-Precision Floating-Point Values". -// -// Mnemonic : MOVLPS -// Supported forms : (2 forms) -// -// * MOVLPS m64, xmm [SSE] -// * MOVLPS xmm, m64 [SSE] -// -func (self *Program) MOVLPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVLPS", 2, Operands { v0, v1 }) - // MOVLPS m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVLPS xmm, m64 - if isXMM(v0) && isM64(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x13) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVLPS") - } - return p -} - -// MOVMSKPD performs "Extract Packed Double-Precision Floating-Point Sign Mask". -// -// Mnemonic : MOVMSKPD -// Supported forms : (1 form) -// -// * MOVMSKPD xmm, r32 [SSE2] -// -func (self *Program) MOVMSKPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVMSKPD", 2, Operands { v0, v1 }) - // MOVMSKPD xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x50) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for MOVMSKPD") - } - return p -} - -// MOVMSKPS performs "Extract Packed Single-Precision Floating-Point Sign Mask". -// -// Mnemonic : MOVMSKPS -// Supported forms : (1 form) -// -// * MOVMSKPS xmm, r32 [SSE] -// -func (self *Program) MOVMSKPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVMSKPS", 2, Operands { v0, v1 }) - // MOVMSKPS xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x50) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for MOVMSKPS") - } - return p -} - -// MOVNTDQ performs "Store Double Quadword Using Non-Temporal Hint". -// -// Mnemonic : MOVNTDQ -// Supported forms : (1 form) -// -// * MOVNTDQ xmm, m128 [SSE2] -// -func (self *Program) MOVNTDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVNTDQ", 2, Operands { v0, v1 }) - // MOVNTDQ xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xe7) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVNTDQ") - } - return p -} - -// MOVNTDQA performs "Load Double Quadword Non-Temporal Aligned Hint". -// -// Mnemonic : MOVNTDQA -// Supported forms : (1 form) -// -// * MOVNTDQA m128, xmm [SSE4.1] -// -func (self *Program) MOVNTDQA(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVNTDQA", 2, Operands { v0, v1 }) - // MOVNTDQA m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVNTDQA") - } - return p -} - -// MOVNTIL performs "Store Doubleword Using Non-Temporal Hint". -// -// Mnemonic : MOVNTI -// Supported forms : (1 form) -// -// * MOVNTIL r32, m32 [SSE2] -// -func (self *Program) MOVNTIL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVNTIL", 2, Operands { v0, v1 }) - // MOVNTIL r32, m32 - if isReg32(v0) && isM32(v1) { - self.require(ISA_SSE2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc3) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVNTIL") - } - return p -} - -// MOVNTIQ performs "Store Doubleword Using Non-Temporal Hint". -// -// Mnemonic : MOVNTI -// Supported forms : (1 form) -// -// * MOVNTIQ r64, m64 [SSE2] -// -func (self *Program) MOVNTIQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVNTIQ", 2, Operands { v0, v1 }) - // MOVNTIQ r64, m64 - if isReg64(v0) && isM64(v1) { - self.require(ISA_SSE2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0xc3) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVNTIQ") - } - return p -} - -// MOVNTPD performs "Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint". -// -// Mnemonic : MOVNTPD -// Supported forms : (1 form) -// -// * MOVNTPD xmm, m128 [SSE2] -// -func (self *Program) MOVNTPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVNTPD", 2, Operands { v0, v1 }) - // MOVNTPD xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVNTPD") - } - return p -} - -// MOVNTPS performs "Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint". -// -// Mnemonic : MOVNTPS -// Supported forms : (1 form) -// -// * MOVNTPS xmm, m128 [SSE] -// -func (self *Program) MOVNTPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVNTPS", 2, Operands { v0, v1 }) - // MOVNTPS xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVNTPS") - } - return p -} - -// MOVNTQ performs "Store of Quadword Using Non-Temporal Hint". -// -// Mnemonic : MOVNTQ -// Supported forms : (1 form) -// -// * MOVNTQ mm, m64 [MMX+] -// -func (self *Program) MOVNTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVNTQ", 2, Operands { v0, v1 }) - // MOVNTQ mm, m64 - if isMM(v0) && isM64(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xe7) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVNTQ") - } - return p -} - -// MOVNTSD performs "Store Scalar Double-Precision Floating-Point Values Using Non-Temporal Hint". -// -// Mnemonic : MOVNTSD -// Supported forms : (1 form) -// -// * MOVNTSD xmm, m64 [SSE4A] -// -func (self *Program) MOVNTSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVNTSD", 2, Operands { v0, v1 }) - // MOVNTSD xmm, m64 - if isXMM(v0) && isM64(v1) { - self.require(ISA_SSE4A) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVNTSD") - } - return p -} - -// MOVNTSS performs "Store Scalar Single-Precision Floating-Point Values Using Non-Temporal Hint". -// -// Mnemonic : MOVNTSS -// Supported forms : (1 form) -// -// * MOVNTSS xmm, m32 [SSE4A] -// -func (self *Program) MOVNTSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVNTSS", 2, Operands { v0, v1 }) - // MOVNTSS xmm, m32 - if isXMM(v0) && isM32(v1) { - self.require(ISA_SSE4A) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVNTSS") - } - return p -} - -// MOVQ performs "Move". -// -// Mnemonic : MOV -// Supported forms : (16 forms) -// -// * MOVQ imm32, r64 -// * MOVQ imm64, r64 -// * MOVQ r64, r64 -// * MOVQ m64, r64 -// * MOVQ imm32, m64 -// * MOVQ r64, m64 -// * MOVQ mm, r64 [MMX] -// * MOVQ r64, mm [MMX] -// * MOVQ mm, mm [MMX] -// * MOVQ m64, mm [MMX] -// * MOVQ mm, m64 [MMX] -// * MOVQ xmm, r64 [SSE2] -// * MOVQ r64, xmm [SSE2] -// * MOVQ xmm, xmm [SSE2] -// * MOVQ m64, xmm [SSE2] -// * MOVQ xmm, m64 [SSE2] -// -func (self *Program) MOVQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVQ", 2, Operands { v0, v1 }) - // MOVQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xc7) - m.emit(0xc0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // MOVQ imm64, r64 - if isImm64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xb8 | lcode(v[1])) - m.imm8(toImmAny(v[0])) - }) - } - // MOVQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x89) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x8b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x8b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xc7) - m.mrsd(0, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // MOVQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x89) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // MOVQ mm, r64 - if isMM(v0) && isReg64(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x0f) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVQ r64, mm - if isReg64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVQ m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x6e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVQ mm, m64 - if isMM(v0) && isM64(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0x7e) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // MOVQ xmm, r64 - if isXMM(v0) && isReg64(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x0f) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVQ r64, xmm - if isReg64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xd6) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVQ m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x7e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0x6e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVQ xmm, m64 - if isXMM(v0) && isM64(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xd6) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0x7e) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVQ") - } - return p -} - -// MOVQ2DQ performs "Move Quadword from MMX Technology to XMM Register". -// -// Mnemonic : MOVQ2DQ -// Supported forms : (1 form) -// -// * MOVQ2DQ mm, xmm [SSE2] -// -func (self *Program) MOVQ2DQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVQ2DQ", 2, Operands { v0, v1 }) - // MOVQ2DQ mm, xmm - if isMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for MOVQ2DQ") - } - return p -} - -// MOVSBL performs "Move with Sign-Extension". -// -// Mnemonic : MOVSX -// Supported forms : (2 forms) -// -// * MOVSBL r8, r32 -// * MOVSBL m8, r32 -// -func (self *Program) MOVSBL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSBL", 2, Operands { v0, v1 }) - // MOVSBL r8, r32 - if isReg8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVSBL m8, r32 - if isM8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbe) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSBL") - } - return p -} - -// MOVSBQ performs "Move with Sign-Extension". -// -// Mnemonic : MOVSX -// Supported forms : (2 forms) -// -// * MOVSBQ r8, r64 -// * MOVSBQ m8, r64 -// -func (self *Program) MOVSBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSBQ", 2, Operands { v0, v1 }) - // MOVSBQ r8, r64 - if isReg8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVSBQ m8, r64 - if isM8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xbe) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSBQ") - } - return p -} - -// MOVSBW performs "Move with Sign-Extension". -// -// Mnemonic : MOVSX -// Supported forms : (2 forms) -// -// * MOVSBW r8, r16 -// * MOVSBW m8, r16 -// -func (self *Program) MOVSBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSBW", 2, Operands { v0, v1 }) - // MOVSBW r8, r16 - if isReg8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVSBW m8, r16 - if isM8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbe) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSBW") - } - return p -} - -// MOVSD performs "Move Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : MOVSD -// Supported forms : (3 forms) -// -// * MOVSD xmm, xmm [SSE2] -// * MOVSD m64, xmm [SSE2] -// * MOVSD xmm, m64 [SSE2] -// -func (self *Program) MOVSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSD", 2, Operands { v0, v1 }) - // MOVSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVSD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVSD xmm, m64 - if isXMM(v0) && isM64(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSD") - } - return p -} - -// MOVSHDUP performs "Move Packed Single-FP High and Duplicate". -// -// Mnemonic : MOVSHDUP -// Supported forms : (2 forms) -// -// * MOVSHDUP xmm, xmm [SSE3] -// * MOVSHDUP m128, xmm [SSE3] -// -func (self *Program) MOVSHDUP(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSHDUP", 2, Operands { v0, v1 }) - // MOVSHDUP xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVSHDUP m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSHDUP") - } - return p -} - -// MOVSLDUP performs "Move Packed Single-FP Low and Duplicate". -// -// Mnemonic : MOVSLDUP -// Supported forms : (2 forms) -// -// * MOVSLDUP xmm, xmm [SSE3] -// * MOVSLDUP m128, xmm [SSE3] -// -func (self *Program) MOVSLDUP(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSLDUP", 2, Operands { v0, v1 }) - // MOVSLDUP xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVSLDUP m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSLDUP") - } - return p -} - -// MOVSLQ performs "Move Doubleword to Quadword with Sign-Extension". -// -// Mnemonic : MOVSXD -// Supported forms : (2 forms) -// -// * MOVSLQ r32, r64 -// * MOVSLQ m32, r64 -// -func (self *Program) MOVSLQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSLQ", 2, Operands { v0, v1 }) - // MOVSLQ r32, r64 - if isReg32(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x63) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVSLQ m32, r64 - if isM32(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x63) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSLQ") - } - return p -} - -// MOVSS performs "Move Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : MOVSS -// Supported forms : (3 forms) -// -// * MOVSS xmm, xmm [SSE] -// * MOVSS m32, xmm [SSE] -// * MOVSS xmm, m32 [SSE] -// -func (self *Program) MOVSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSS", 2, Operands { v0, v1 }) - // MOVSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVSS xmm, m32 - if isXMM(v0) && isM32(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSS") - } - return p -} - -// MOVSWL performs "Move with Sign-Extension". -// -// Mnemonic : MOVSX -// Supported forms : (2 forms) -// -// * MOVSWL r16, r32 -// * MOVSWL m16, r32 -// -func (self *Program) MOVSWL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSWL", 2, Operands { v0, v1 }) - // MOVSWL r16, r32 - if isReg16(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xbf) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVSWL m16, r32 - if isM16(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbf) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSWL") - } - return p -} - -// MOVSWQ performs "Move with Sign-Extension". -// -// Mnemonic : MOVSX -// Supported forms : (2 forms) -// -// * MOVSWQ r16, r64 -// * MOVSWQ m16, r64 -// -func (self *Program) MOVSWQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVSWQ", 2, Operands { v0, v1 }) - // MOVSWQ r16, r64 - if isReg16(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xbf) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVSWQ m16, r64 - if isM16(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xbf) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVSWQ") - } - return p -} - -// MOVUPD performs "Move Unaligned Packed Double-Precision Floating-Point Values". -// -// Mnemonic : MOVUPD -// Supported forms : (3 forms) -// -// * MOVUPD xmm, xmm [SSE2] -// * MOVUPD m128, xmm [SSE2] -// * MOVUPD xmm, m128 [SSE2] -// -func (self *Program) MOVUPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVUPD", 2, Operands { v0, v1 }) - // MOVUPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVUPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVUPD xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVUPD") - } - return p -} - -// MOVUPS performs "Move Unaligned Packed Single-Precision Floating-Point Values". -// -// Mnemonic : MOVUPS -// Supported forms : (3 forms) -// -// * MOVUPS xmm, xmm [SSE] -// * MOVUPS m128, xmm [SSE] -// * MOVUPS xmm, m128 [SSE] -// -func (self *Program) MOVUPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVUPS", 2, Operands { v0, v1 }) - // MOVUPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // MOVUPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVUPS xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVUPS") - } - return p -} - -// MOVW performs "Move". -// -// Mnemonic : MOV -// Supported forms : (5 forms) -// -// * MOVW imm16, r16 -// * MOVW r16, r16 -// * MOVW m16, r16 -// * MOVW imm16, m16 -// * MOVW r16, m16 -// -func (self *Program) MOVW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVW", 2, Operands { v0, v1 }) - // MOVW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xc7) - m.emit(0xc0 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xb8 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // MOVW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x89) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x8b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x8b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // MOVW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xc7) - m.mrsd(0, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // MOVW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x89) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVW") - } - return p -} - -// MOVZBL performs "Move with Zero-Extend". -// -// Mnemonic : MOVZX -// Supported forms : (2 forms) -// -// * MOVZBL r8, r32 -// * MOVZBL m8, r32 -// -func (self *Program) MOVZBL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVZBL", 2, Operands { v0, v1 }) - // MOVZBL r8, r32 - if isReg8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVZBL m8, r32 - if isM8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xb6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVZBL") - } - return p -} - -// MOVZBQ performs "Move with Zero-Extend". -// -// Mnemonic : MOVZX -// Supported forms : (2 forms) -// -// * MOVZBQ r8, r64 -// * MOVZBQ m8, r64 -// -func (self *Program) MOVZBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVZBQ", 2, Operands { v0, v1 }) - // MOVZBQ r8, r64 - if isReg8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVZBQ m8, r64 - if isM8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xb6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVZBQ") - } - return p -} - -// MOVZBW performs "Move with Zero-Extend". -// -// Mnemonic : MOVZX -// Supported forms : (2 forms) -// -// * MOVZBW r8, r16 -// * MOVZBW m8, r16 -// -func (self *Program) MOVZBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVZBW", 2, Operands { v0, v1 }) - // MOVZBW r8, r16 - if isReg8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVZBW m8, r16 - if isM8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xb6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVZBW") - } - return p -} - -// MOVZWL performs "Move with Zero-Extend". -// -// Mnemonic : MOVZX -// Supported forms : (2 forms) -// -// * MOVZWL r16, r32 -// * MOVZWL m16, r32 -// -func (self *Program) MOVZWL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVZWL", 2, Operands { v0, v1 }) - // MOVZWL r16, r32 - if isReg16(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVZWL m16, r32 - if isM16(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xb7) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVZWL") - } - return p -} - -// MOVZWQ performs "Move with Zero-Extend". -// -// Mnemonic : MOVZX -// Supported forms : (2 forms) -// -// * MOVZWQ r16, r64 -// * MOVZWQ m16, r64 -// -func (self *Program) MOVZWQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MOVZWQ", 2, Operands { v0, v1 }) - // MOVZWQ r16, r64 - if isReg16(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MOVZWQ m16, r64 - if isM16(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xb7) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MOVZWQ") - } - return p -} - -// MPSADBW performs "Compute Multiple Packed Sums of Absolute Difference". -// -// Mnemonic : MPSADBW -// Supported forms : (2 forms) -// -// * MPSADBW imm8, xmm, xmm [SSE4.1] -// * MPSADBW imm8, m128, xmm [SSE4.1] -// -func (self *Program) MPSADBW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("MPSADBW", 3, Operands { v0, v1, v2 }) - // MPSADBW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x42) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // MPSADBW imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x42) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for MPSADBW") - } - return p -} - -// MULB performs "Unsigned Multiply". -// -// Mnemonic : MUL -// Supported forms : (2 forms) -// -// * MULB r8 -// * MULB m8 -// -func (self *Program) MULB(v0 interface{}) *Instruction { - p := self.alloc("MULB", 1, Operands { v0 }) - // MULB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0xf6) - m.emit(0xe0 | lcode(v[0])) - }) - } - // MULB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf6) - m.mrsd(4, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULB") - } - return p -} - -// MULL performs "Unsigned Multiply". -// -// Mnemonic : MUL -// Supported forms : (2 forms) -// -// * MULL r32 -// * MULL m32 -// -func (self *Program) MULL(v0 interface{}) *Instruction { - p := self.alloc("MULL", 1, Operands { v0 }) - // MULL r32 - if isReg32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xe0 | lcode(v[0])) - }) - } - // MULL m32 - if isM32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(4, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULL") - } - return p -} - -// MULPD performs "Multiply Packed Double-Precision Floating-Point Values". -// -// Mnemonic : MULPD -// Supported forms : (2 forms) -// -// * MULPD xmm, xmm [SSE2] -// * MULPD m128, xmm [SSE2] -// -func (self *Program) MULPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MULPD", 2, Operands { v0, v1 }) - // MULPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MULPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULPD") - } - return p -} - -// MULPS performs "Multiply Packed Single-Precision Floating-Point Values". -// -// Mnemonic : MULPS -// Supported forms : (2 forms) -// -// * MULPS xmm, xmm [SSE] -// * MULPS m128, xmm [SSE] -// -func (self *Program) MULPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MULPS", 2, Operands { v0, v1 }) - // MULPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MULPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULPS") - } - return p -} - -// MULQ performs "Unsigned Multiply". -// -// Mnemonic : MUL -// Supported forms : (2 forms) -// -// * MULQ r64 -// * MULQ m64 -// -func (self *Program) MULQ(v0 interface{}) *Instruction { - p := self.alloc("MULQ", 1, Operands { v0 }) - // MULQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0xf7) - m.emit(0xe0 | lcode(v[0])) - }) - } - // MULQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[0])) - m.emit(0xf7) - m.mrsd(4, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULQ") - } - return p -} - -// MULSD performs "Multiply Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : MULSD -// Supported forms : (2 forms) -// -// * MULSD xmm, xmm [SSE2] -// * MULSD m64, xmm [SSE2] -// -func (self *Program) MULSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MULSD", 2, Operands { v0, v1 }) - // MULSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MULSD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULSD") - } - return p -} - -// MULSS performs "Multiply Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : MULSS -// Supported forms : (2 forms) -// -// * MULSS xmm, xmm [SSE] -// * MULSS m32, xmm [SSE] -// -func (self *Program) MULSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("MULSS", 2, Operands { v0, v1 }) - // MULSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // MULSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULSS") - } - return p -} - -// MULW performs "Unsigned Multiply". -// -// Mnemonic : MUL -// Supported forms : (2 forms) -// -// * MULW r16 -// * MULW m16 -// -func (self *Program) MULW(v0 interface{}) *Instruction { - p := self.alloc("MULW", 1, Operands { v0 }) - // MULW r16 - if isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xe0 | lcode(v[0])) - }) - } - // MULW m16 - if isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(4, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULW") - } - return p -} - -// MULXL performs "Unsigned Multiply Without Affecting Flags". -// -// Mnemonic : MULX -// Supported forms : (2 forms) -// -// * MULXL r32, r32, r32 [BMI2] -// * MULXL m32, r32, r32 [BMI2] -// -func (self *Program) MULXL(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("MULXL", 3, Operands { v0, v1, v2 }) - // MULXL r32, r32, r32 - if isReg32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7b ^ (hlcode(v[1]) << 3)) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // MULXL m32, r32, r32 - if isM32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x03, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULXL") - } - return p -} - -// MULXQ performs "Unsigned Multiply Without Affecting Flags". -// -// Mnemonic : MULX -// Supported forms : (2 forms) -// -// * MULXQ r64, r64, r64 [BMI2] -// * MULXQ m64, r64, r64 [BMI2] -// -func (self *Program) MULXQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("MULXQ", 3, Operands { v0, v1, v2 }) - // MULXQ r64, r64, r64 - if isReg64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfb ^ (hlcode(v[1]) << 3)) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // MULXQ m64, r64, r64 - if isM64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x83, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for MULXQ") - } - return p -} - -// MWAIT performs "Monitor Wait". -// -// Mnemonic : MWAIT -// Supported forms : (1 form) -// -// * MWAIT [MONITOR] -// -func (self *Program) MWAIT() *Instruction { - p := self.alloc("MWAIT", 0, Operands { }) - // MWAIT - self.require(ISA_MONITOR) - p.domain = DomainMisc - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x01) - m.emit(0xc9) - }) - return p -} - -// MWAITX performs "Monitor Wait with Timeout". -// -// Mnemonic : MWAITX -// Supported forms : (1 form) -// -// * MWAITX [MONITORX] -// -func (self *Program) MWAITX() *Instruction { - p := self.alloc("MWAITX", 0, Operands { }) - // MWAITX - self.require(ISA_MONITORX) - p.domain = DomainMisc - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x01) - m.emit(0xfb) - }) - return p -} - -// NEGB performs "Two's Complement Negation". -// -// Mnemonic : NEG -// Supported forms : (2 forms) -// -// * NEGB r8 -// * NEGB m8 -// -func (self *Program) NEGB(v0 interface{}) *Instruction { - p := self.alloc("NEGB", 1, Operands { v0 }) - // NEGB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0xf6) - m.emit(0xd8 | lcode(v[0])) - }) - } - // NEGB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf6) - m.mrsd(3, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for NEGB") - } - return p -} - -// NEGL performs "Two's Complement Negation". -// -// Mnemonic : NEG -// Supported forms : (2 forms) -// -// * NEGL r32 -// * NEGL m32 -// -func (self *Program) NEGL(v0 interface{}) *Instruction { - p := self.alloc("NEGL", 1, Operands { v0 }) - // NEGL r32 - if isReg32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xd8 | lcode(v[0])) - }) - } - // NEGL m32 - if isM32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(3, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for NEGL") - } - return p -} - -// NEGQ performs "Two's Complement Negation". -// -// Mnemonic : NEG -// Supported forms : (2 forms) -// -// * NEGQ r64 -// * NEGQ m64 -// -func (self *Program) NEGQ(v0 interface{}) *Instruction { - p := self.alloc("NEGQ", 1, Operands { v0 }) - // NEGQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0xf7) - m.emit(0xd8 | lcode(v[0])) - }) - } - // NEGQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[0])) - m.emit(0xf7) - m.mrsd(3, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for NEGQ") - } - return p -} - -// NEGW performs "Two's Complement Negation". -// -// Mnemonic : NEG -// Supported forms : (2 forms) -// -// * NEGW r16 -// * NEGW m16 -// -func (self *Program) NEGW(v0 interface{}) *Instruction { - p := self.alloc("NEGW", 1, Operands { v0 }) - // NEGW r16 - if isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xd8 | lcode(v[0])) - }) - } - // NEGW m16 - if isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(3, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for NEGW") - } - return p -} - -// NOP performs "No Operation". -// -// Mnemonic : NOP -// Supported forms : (1 form) -// -// * NOP -// -func (self *Program) NOP() *Instruction { - p := self.alloc("NOP", 0, Operands { }) - // NOP - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x90) - }) - return p -} - -// NOTB performs "One's Complement Negation". -// -// Mnemonic : NOT -// Supported forms : (2 forms) -// -// * NOTB r8 -// * NOTB m8 -// -func (self *Program) NOTB(v0 interface{}) *Instruction { - p := self.alloc("NOTB", 1, Operands { v0 }) - // NOTB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0xf6) - m.emit(0xd0 | lcode(v[0])) - }) - } - // NOTB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf6) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for NOTB") - } - return p -} - -// NOTL performs "One's Complement Negation". -// -// Mnemonic : NOT -// Supported forms : (2 forms) -// -// * NOTL r32 -// * NOTL m32 -// -func (self *Program) NOTL(v0 interface{}) *Instruction { - p := self.alloc("NOTL", 1, Operands { v0 }) - // NOTL r32 - if isReg32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xd0 | lcode(v[0])) - }) - } - // NOTL m32 - if isM32(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for NOTL") - } - return p -} - -// NOTQ performs "One's Complement Negation". -// -// Mnemonic : NOT -// Supported forms : (2 forms) -// -// * NOTQ r64 -// * NOTQ m64 -// -func (self *Program) NOTQ(v0 interface{}) *Instruction { - p := self.alloc("NOTQ", 1, Operands { v0 }) - // NOTQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0xf7) - m.emit(0xd0 | lcode(v[0])) - }) - } - // NOTQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[0])) - m.emit(0xf7) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for NOTQ") - } - return p -} - -// NOTW performs "One's Complement Negation". -// -// Mnemonic : NOT -// Supported forms : (2 forms) -// -// * NOTW r16 -// * NOTW m16 -// -func (self *Program) NOTW(v0 interface{}) *Instruction { - p := self.alloc("NOTW", 1, Operands { v0 }) - // NOTW r16 - if isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0xf7) - m.emit(0xd0 | lcode(v[0])) - }) - } - // NOTW m16 - if isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0xf7) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for NOTW") - } - return p -} - -// ORB performs "Logical Inclusive OR". -// -// Mnemonic : OR -// Supported forms : (6 forms) -// -// * ORB imm8, al -// * ORB imm8, r8 -// * ORB r8, r8 -// * ORB m8, r8 -// * ORB imm8, m8 -// * ORB r8, m8 -// -func (self *Program) ORB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ORB", 2, Operands { v0, v1 }) - // ORB imm8, al - if isImm8(v0) && v1 == AL { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0c) - m.imm1(toImmAny(v[0])) - }) - } - // ORB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0x80) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ORB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x08) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x0a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ORB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x0a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ORB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x80) - m.mrsd(1, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ORB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x08) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ORB") - } - return p -} - -// ORL performs "Logical Inclusive OR". -// -// Mnemonic : OR -// Supported forms : (8 forms) -// -// * ORL imm32, eax -// * ORL imm8, r32 -// * ORL imm32, r32 -// * ORL r32, r32 -// * ORL m32, r32 -// * ORL imm8, m32 -// * ORL imm32, m32 -// * ORL r32, m32 -// -func (self *Program) ORL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ORL", 2, Operands { v0, v1 }) - // ORL imm32, eax - if isImm32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0d) - m.imm4(toImmAny(v[0])) - }) - } - // ORL imm8, r32 - if isImm8Ext(v0, 4) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ORL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xc8 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // ORL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x09) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ORL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ORL imm8, m32 - if isImm8Ext(v0, 4) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(1, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ORL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(1, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // ORL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x09) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ORL") - } - return p -} - -// ORPD performs "Bitwise Logical OR of Double-Precision Floating-Point Values". -// -// Mnemonic : ORPD -// Supported forms : (2 forms) -// -// * ORPD xmm, xmm [SSE2] -// * ORPD m128, xmm [SSE2] -// -func (self *Program) ORPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ORPD", 2, Operands { v0, v1 }) - // ORPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x56) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ORPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x56) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ORPD") - } - return p -} - -// ORPS performs "Bitwise Logical OR of Single-Precision Floating-Point Values". -// -// Mnemonic : ORPS -// Supported forms : (2 forms) -// -// * ORPS xmm, xmm [SSE] -// * ORPS m128, xmm [SSE] -// -func (self *Program) ORPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ORPS", 2, Operands { v0, v1 }) - // ORPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x56) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ORPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x56) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ORPS") - } - return p -} - -// ORQ performs "Logical Inclusive OR". -// -// Mnemonic : OR -// Supported forms : (8 forms) -// -// * ORQ imm32, rax -// * ORQ imm8, r64 -// * ORQ imm32, r64 -// * ORQ r64, r64 -// * ORQ m64, r64 -// * ORQ imm8, m64 -// * ORQ imm32, m64 -// * ORQ r64, m64 -// -func (self *Program) ORQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ORQ", 2, Operands { v0, v1 }) - // ORQ imm32, rax - if isImm32(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x0d) - m.imm4(toImmAny(v[0])) - }) - } - // ORQ imm8, r64 - if isImm8Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x83) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ORQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x81) - m.emit(0xc8 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // ORQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x09) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ORQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ORQ imm8, m64 - if isImm8Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x83) - m.mrsd(1, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ORQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x81) - m.mrsd(1, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // ORQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x09) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ORQ") - } - return p -} - -// ORW performs "Logical Inclusive OR". -// -// Mnemonic : OR -// Supported forms : (8 forms) -// -// * ORW imm16, ax -// * ORW imm8, r16 -// * ORW imm16, r16 -// * ORW r16, r16 -// * ORW m16, r16 -// * ORW imm8, m16 -// * ORW imm16, m16 -// * ORW r16, m16 -// -func (self *Program) ORW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ORW", 2, Operands { v0, v1 }) - // ORW imm16, ax - if isImm16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x0d) - m.imm2(toImmAny(v[0])) - }) - } - // ORW imm8, r16 - if isImm8Ext(v0, 2) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ORW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xc8 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // ORW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x09) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // ORW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // ORW imm8, m16 - if isImm8Ext(v0, 2) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(1, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ORW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(1, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // ORW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x09) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ORW") - } - return p -} - -// PABSB performs "Packed Absolute Value of Byte Integers". -// -// Mnemonic : PABSB -// Supported forms : (4 forms) -// -// * PABSB mm, mm [SSSE3] -// * PABSB m64, mm [SSSE3] -// * PABSB xmm, xmm [SSSE3] -// * PABSB m128, xmm [SSSE3] -// -func (self *Program) PABSB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PABSB", 2, Operands { v0, v1 }) - // PABSB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PABSB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PABSB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PABSB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PABSB") - } - return p -} - -// PABSD performs "Packed Absolute Value of Doubleword Integers". -// -// Mnemonic : PABSD -// Supported forms : (4 forms) -// -// * PABSD mm, mm [SSSE3] -// * PABSD m64, mm [SSSE3] -// * PABSD xmm, xmm [SSSE3] -// * PABSD m128, xmm [SSSE3] -// -func (self *Program) PABSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PABSD", 2, Operands { v0, v1 }) - // PABSD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PABSD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PABSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PABSD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PABSD") - } - return p -} - -// PABSW performs "Packed Absolute Value of Word Integers". -// -// Mnemonic : PABSW -// Supported forms : (4 forms) -// -// * PABSW mm, mm [SSSE3] -// * PABSW m64, mm [SSSE3] -// * PABSW xmm, xmm [SSSE3] -// * PABSW m128, xmm [SSSE3] -// -func (self *Program) PABSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PABSW", 2, Operands { v0, v1 }) - // PABSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PABSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PABSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PABSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PABSW") - } - return p -} - -// PACKSSDW performs "Pack Doublewords into Words with Signed Saturation". -// -// Mnemonic : PACKSSDW -// Supported forms : (4 forms) -// -// * PACKSSDW mm, mm [MMX] -// * PACKSSDW m64, mm [MMX] -// * PACKSSDW xmm, xmm [SSE2] -// * PACKSSDW m128, xmm [SSE2] -// -func (self *Program) PACKSSDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PACKSSDW", 2, Operands { v0, v1 }) - // PACKSSDW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PACKSSDW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PACKSSDW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PACKSSDW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PACKSSDW") - } - return p -} - -// PACKSSWB performs "Pack Words into Bytes with Signed Saturation". -// -// Mnemonic : PACKSSWB -// Supported forms : (4 forms) -// -// * PACKSSWB mm, mm [MMX] -// * PACKSSWB m64, mm [MMX] -// * PACKSSWB xmm, xmm [SSE2] -// * PACKSSWB m128, xmm [SSE2] -// -func (self *Program) PACKSSWB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PACKSSWB", 2, Operands { v0, v1 }) - // PACKSSWB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x63) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PACKSSWB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x63) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PACKSSWB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x63) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PACKSSWB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x63) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PACKSSWB") - } - return p -} - -// PACKUSDW performs "Pack Doublewords into Words with Unsigned Saturation". -// -// Mnemonic : PACKUSDW -// Supported forms : (2 forms) -// -// * PACKUSDW xmm, xmm [SSE4.1] -// * PACKUSDW m128, xmm [SSE4.1] -// -func (self *Program) PACKUSDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PACKUSDW", 2, Operands { v0, v1 }) - // PACKUSDW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x2b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PACKUSDW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x2b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PACKUSDW") - } - return p -} - -// PACKUSWB performs "Pack Words into Bytes with Unsigned Saturation". -// -// Mnemonic : PACKUSWB -// Supported forms : (4 forms) -// -// * PACKUSWB mm, mm [MMX] -// * PACKUSWB m64, mm [MMX] -// * PACKUSWB xmm, xmm [SSE2] -// * PACKUSWB m128, xmm [SSE2] -// -func (self *Program) PACKUSWB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PACKUSWB", 2, Operands { v0, v1 }) - // PACKUSWB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x67) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PACKUSWB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x67) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PACKUSWB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x67) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PACKUSWB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x67) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PACKUSWB") - } - return p -} - -// PADDB performs "Add Packed Byte Integers". -// -// Mnemonic : PADDB -// Supported forms : (4 forms) -// -// * PADDB mm, mm [MMX] -// * PADDB m64, mm [MMX] -// * PADDB xmm, xmm [SSE2] -// * PADDB m128, xmm [SSE2] -// -func (self *Program) PADDB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PADDB", 2, Operands { v0, v1 }) - // PADDB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PADDB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PADDB") - } - return p -} - -// PADDD performs "Add Packed Doubleword Integers". -// -// Mnemonic : PADDD -// Supported forms : (4 forms) -// -// * PADDD mm, mm [MMX] -// * PADDD m64, mm [MMX] -// * PADDD xmm, xmm [SSE2] -// * PADDD m128, xmm [SSE2] -// -func (self *Program) PADDD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PADDD", 2, Operands { v0, v1 }) - // PADDD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfe) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfe) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PADDD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfe) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfe) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PADDD") - } - return p -} - -// PADDQ performs "Add Packed Quadword Integers". -// -// Mnemonic : PADDQ -// Supported forms : (4 forms) -// -// * PADDQ mm, mm [SSE2] -// * PADDQ m64, mm [SSE2] -// * PADDQ xmm, xmm [SSE2] -// * PADDQ m128, xmm [SSE2] -// -func (self *Program) PADDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PADDQ", 2, Operands { v0, v1 }) - // PADDQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDQ m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd4) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PADDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd4) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PADDQ") - } - return p -} - -// PADDSB performs "Add Packed Signed Byte Integers with Signed Saturation". -// -// Mnemonic : PADDSB -// Supported forms : (4 forms) -// -// * PADDSB mm, mm [MMX] -// * PADDSB m64, mm [MMX] -// * PADDSB xmm, xmm [SSE2] -// * PADDSB m128, xmm [SSE2] -// -func (self *Program) PADDSB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PADDSB", 2, Operands { v0, v1 }) - // PADDSB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xec) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDSB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xec) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PADDSB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xec) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDSB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xec) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PADDSB") - } - return p -} - -// PADDSW performs "Add Packed Signed Word Integers with Signed Saturation". -// -// Mnemonic : PADDSW -// Supported forms : (4 forms) -// -// * PADDSW mm, mm [MMX] -// * PADDSW m64, mm [MMX] -// * PADDSW xmm, xmm [SSE2] -// * PADDSW m128, xmm [SSE2] -// -func (self *Program) PADDSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PADDSW", 2, Operands { v0, v1 }) - // PADDSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xed) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xed) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PADDSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xed) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xed) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PADDSW") - } - return p -} - -// PADDUSB performs "Add Packed Unsigned Byte Integers with Unsigned Saturation". -// -// Mnemonic : PADDUSB -// Supported forms : (4 forms) -// -// * PADDUSB mm, mm [MMX] -// * PADDUSB m64, mm [MMX] -// * PADDUSB xmm, xmm [SSE2] -// * PADDUSB m128, xmm [SSE2] -// -func (self *Program) PADDUSB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PADDUSB", 2, Operands { v0, v1 }) - // PADDUSB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xdc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDUSB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xdc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PADDUSB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xdc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDUSB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xdc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PADDUSB") - } - return p -} - -// PADDUSW performs "Add Packed Unsigned Word Integers with Unsigned Saturation". -// -// Mnemonic : PADDUSW -// Supported forms : (4 forms) -// -// * PADDUSW mm, mm [MMX] -// * PADDUSW m64, mm [MMX] -// * PADDUSW xmm, xmm [SSE2] -// * PADDUSW m128, xmm [SSE2] -// -func (self *Program) PADDUSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PADDUSW", 2, Operands { v0, v1 }) - // PADDUSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xdd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDUSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xdd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PADDUSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xdd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDUSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xdd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PADDUSW") - } - return p -} - -// PADDW performs "Add Packed Word Integers". -// -// Mnemonic : PADDW -// Supported forms : (4 forms) -// -// * PADDW mm, mm [MMX] -// * PADDW m64, mm [MMX] -// * PADDW xmm, xmm [SSE2] -// * PADDW m128, xmm [SSE2] -// -func (self *Program) PADDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PADDW", 2, Operands { v0, v1 }) - // PADDW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PADDW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PADDW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PADDW") - } - return p -} - -// PALIGNR performs "Packed Align Right". -// -// Mnemonic : PALIGNR -// Supported forms : (4 forms) -// -// * PALIGNR imm8, mm, mm [SSSE3] -// * PALIGNR imm8, m64, mm [SSSE3] -// * PALIGNR imm8, xmm, xmm [SSSE3] -// * PALIGNR imm8, m128, xmm [SSSE3] -// -func (self *Program) PALIGNR(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PALIGNR", 3, Operands { v0, v1, v2 }) - // PALIGNR imm8, mm, mm - if isImm8(v0) && isMM(v1) && isMM(v2) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PALIGNR imm8, m64, mm - if isImm8(v0) && isM64(v1) && isMM(v2) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0f) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // PALIGNR imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PALIGNR imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0f) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PALIGNR") - } - return p -} - -// PAND performs "Packed Bitwise Logical AND". -// -// Mnemonic : PAND -// Supported forms : (4 forms) -// -// * PAND mm, mm [MMX] -// * PAND m64, mm [MMX] -// * PAND xmm, xmm [SSE2] -// * PAND m128, xmm [SSE2] -// -func (self *Program) PAND(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PAND", 2, Operands { v0, v1 }) - // PAND mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PAND m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xdb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PAND xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PAND m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xdb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PAND") - } - return p -} - -// PANDN performs "Packed Bitwise Logical AND NOT". -// -// Mnemonic : PANDN -// Supported forms : (4 forms) -// -// * PANDN mm, mm [MMX] -// * PANDN m64, mm [MMX] -// * PANDN xmm, xmm [SSE2] -// * PANDN m128, xmm [SSE2] -// -func (self *Program) PANDN(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PANDN", 2, Operands { v0, v1 }) - // PANDN mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PANDN m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xdf) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PANDN xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PANDN m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xdf) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PANDN") - } - return p -} - -// PAUSE performs "Spin Loop Hint". -// -// Mnemonic : PAUSE -// Supported forms : (1 form) -// -// * PAUSE -// -func (self *Program) PAUSE() *Instruction { - p := self.alloc("PAUSE", 0, Operands { }) - // PAUSE - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.emit(0x90) - }) - return p -} - -// PAVGB performs "Average Packed Byte Integers". -// -// Mnemonic : PAVGB -// Supported forms : (4 forms) -// -// * PAVGB mm, mm [MMX+] -// * PAVGB m64, mm [MMX+] -// * PAVGB xmm, xmm [SSE2] -// * PAVGB m128, xmm [SSE2] -// -func (self *Program) PAVGB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PAVGB", 2, Operands { v0, v1 }) - // PAVGB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe0) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PAVGB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PAVGB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe0) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PAVGB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PAVGB") - } - return p -} - -// PAVGUSB performs "Average Packed Byte Integers". -// -// Mnemonic : PAVGUSB -// Supported forms : (2 forms) -// -// * PAVGUSB mm, mm [3dnow!] -// * PAVGUSB m64, mm [3dnow!] -// -func (self *Program) PAVGUSB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PAVGUSB", 2, Operands { v0, v1 }) - // PAVGUSB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xbf) - }) - } - // PAVGUSB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xbf) - }) - } - if p.len == 0 { - panic("invalid operands for PAVGUSB") - } - return p -} - -// PAVGW performs "Average Packed Word Integers". -// -// Mnemonic : PAVGW -// Supported forms : (4 forms) -// -// * PAVGW mm, mm [MMX+] -// * PAVGW m64, mm [MMX+] -// * PAVGW xmm, xmm [SSE2] -// * PAVGW m128, xmm [SSE2] -// -func (self *Program) PAVGW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PAVGW", 2, Operands { v0, v1 }) - // PAVGW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe3) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PAVGW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe3) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PAVGW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe3) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PAVGW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe3) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PAVGW") - } - return p -} - -// PBLENDVB performs "Variable Blend Packed Bytes". -// -// Mnemonic : PBLENDVB -// Supported forms : (2 forms) -// -// * PBLENDVB xmm0, xmm, xmm [SSE4.1] -// * PBLENDVB xmm0, m128, xmm [SSE4.1] -// -func (self *Program) PBLENDVB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PBLENDVB", 3, Operands { v0, v1, v2 }) - // PBLENDVB xmm0, xmm, xmm - if v0 == XMM0 && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // PBLENDVB xmm0, m128, xmm - if v0 == XMM0 && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x10) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PBLENDVB") - } - return p -} - -// PBLENDW performs "Blend Packed Words". -// -// Mnemonic : PBLENDW -// Supported forms : (2 forms) -// -// * PBLENDW imm8, xmm, xmm [SSE4.1] -// * PBLENDW imm8, m128, xmm [SSE4.1] -// -func (self *Program) PBLENDW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PBLENDW", 3, Operands { v0, v1, v2 }) - // PBLENDW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PBLENDW imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0e) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PBLENDW") - } - return p -} - -// PCLMULQDQ performs "Carry-Less Quadword Multiplication". -// -// Mnemonic : PCLMULQDQ -// Supported forms : (2 forms) -// -// * PCLMULQDQ imm8, xmm, xmm [PCLMULQDQ] -// * PCLMULQDQ imm8, m128, xmm [PCLMULQDQ] -// -func (self *Program) PCLMULQDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PCLMULQDQ", 3, Operands { v0, v1, v2 }) - // PCLMULQDQ imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_PCLMULQDQ) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x44) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PCLMULQDQ imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_PCLMULQDQ) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x44) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PCLMULQDQ") - } - return p -} - -// PCMPEQB performs "Compare Packed Byte Data for Equality". -// -// Mnemonic : PCMPEQB -// Supported forms : (4 forms) -// -// * PCMPEQB mm, mm [MMX] -// * PCMPEQB m64, mm [MMX] -// * PCMPEQB xmm, xmm [SSE2] -// * PCMPEQB m128, xmm [SSE2] -// -func (self *Program) PCMPEQB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PCMPEQB", 2, Operands { v0, v1 }) - // PCMPEQB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x74) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPEQB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x74) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PCMPEQB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x74) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPEQB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x74) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPEQB") - } - return p -} - -// PCMPEQD performs "Compare Packed Doubleword Data for Equality". -// -// Mnemonic : PCMPEQD -// Supported forms : (4 forms) -// -// * PCMPEQD mm, mm [MMX] -// * PCMPEQD m64, mm [MMX] -// * PCMPEQD xmm, xmm [SSE2] -// * PCMPEQD m128, xmm [SSE2] -// -func (self *Program) PCMPEQD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PCMPEQD", 2, Operands { v0, v1 }) - // PCMPEQD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x76) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPEQD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x76) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PCMPEQD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x76) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPEQD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x76) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPEQD") - } - return p -} - -// PCMPEQQ performs "Compare Packed Quadword Data for Equality". -// -// Mnemonic : PCMPEQQ -// Supported forms : (2 forms) -// -// * PCMPEQQ xmm, xmm [SSE4.1] -// * PCMPEQQ m128, xmm [SSE4.1] -// -func (self *Program) PCMPEQQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PCMPEQQ", 2, Operands { v0, v1 }) - // PCMPEQQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x29) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPEQQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x29) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPEQQ") - } - return p -} - -// PCMPEQW performs "Compare Packed Word Data for Equality". -// -// Mnemonic : PCMPEQW -// Supported forms : (4 forms) -// -// * PCMPEQW mm, mm [MMX] -// * PCMPEQW m64, mm [MMX] -// * PCMPEQW xmm, xmm [SSE2] -// * PCMPEQW m128, xmm [SSE2] -// -func (self *Program) PCMPEQW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PCMPEQW", 2, Operands { v0, v1 }) - // PCMPEQW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x75) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPEQW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x75) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PCMPEQW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x75) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPEQW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x75) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPEQW") - } - return p -} - -// PCMPESTRI performs "Packed Compare Explicit Length Strings, Return Index". -// -// Mnemonic : PCMPESTRI -// Supported forms : (2 forms) -// -// * PCMPESTRI imm8, xmm, xmm [SSE4.2] -// * PCMPESTRI imm8, m128, xmm [SSE4.2] -// -func (self *Program) PCMPESTRI(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PCMPESTRI", 3, Operands { v0, v1, v2 }) - // PCMPESTRI imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x61) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PCMPESTRI imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x61) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPESTRI") - } - return p -} - -// PCMPESTRM performs "Packed Compare Explicit Length Strings, Return Mask". -// -// Mnemonic : PCMPESTRM -// Supported forms : (2 forms) -// -// * PCMPESTRM imm8, xmm, xmm [SSE4.2] -// * PCMPESTRM imm8, m128, xmm [SSE4.2] -// -func (self *Program) PCMPESTRM(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PCMPESTRM", 3, Operands { v0, v1, v2 }) - // PCMPESTRM imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x60) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PCMPESTRM imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x60) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPESTRM") - } - return p -} - -// PCMPGTB performs "Compare Packed Signed Byte Integers for Greater Than". -// -// Mnemonic : PCMPGTB -// Supported forms : (4 forms) -// -// * PCMPGTB mm, mm [MMX] -// * PCMPGTB m64, mm [MMX] -// * PCMPGTB xmm, xmm [SSE2] -// * PCMPGTB m128, xmm [SSE2] -// -func (self *Program) PCMPGTB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PCMPGTB", 2, Operands { v0, v1 }) - // PCMPGTB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x64) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPGTB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x64) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PCMPGTB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x64) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPGTB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x64) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPGTB") - } - return p -} - -// PCMPGTD performs "Compare Packed Signed Doubleword Integers for Greater Than". -// -// Mnemonic : PCMPGTD -// Supported forms : (4 forms) -// -// * PCMPGTD mm, mm [MMX] -// * PCMPGTD m64, mm [MMX] -// * PCMPGTD xmm, xmm [SSE2] -// * PCMPGTD m128, xmm [SSE2] -// -func (self *Program) PCMPGTD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PCMPGTD", 2, Operands { v0, v1 }) - // PCMPGTD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x66) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPGTD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x66) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PCMPGTD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x66) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPGTD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x66) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPGTD") - } - return p -} - -// PCMPGTQ performs "Compare Packed Data for Greater Than". -// -// Mnemonic : PCMPGTQ -// Supported forms : (2 forms) -// -// * PCMPGTQ xmm, xmm [SSE4.2] -// * PCMPGTQ m128, xmm [SSE4.2] -// -func (self *Program) PCMPGTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PCMPGTQ", 2, Operands { v0, v1 }) - // PCMPGTQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x37) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPGTQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x37) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPGTQ") - } - return p -} - -// PCMPGTW performs "Compare Packed Signed Word Integers for Greater Than". -// -// Mnemonic : PCMPGTW -// Supported forms : (4 forms) -// -// * PCMPGTW mm, mm [MMX] -// * PCMPGTW m64, mm [MMX] -// * PCMPGTW xmm, xmm [SSE2] -// * PCMPGTW m128, xmm [SSE2] -// -func (self *Program) PCMPGTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PCMPGTW", 2, Operands { v0, v1 }) - // PCMPGTW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x65) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPGTW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x65) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PCMPGTW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x65) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PCMPGTW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x65) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPGTW") - } - return p -} - -// PCMPISTRI performs "Packed Compare Implicit Length Strings, Return Index". -// -// Mnemonic : PCMPISTRI -// Supported forms : (2 forms) -// -// * PCMPISTRI imm8, xmm, xmm [SSE4.2] -// * PCMPISTRI imm8, m128, xmm [SSE4.2] -// -func (self *Program) PCMPISTRI(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PCMPISTRI", 3, Operands { v0, v1, v2 }) - // PCMPISTRI imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x63) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PCMPISTRI imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x63) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPISTRI") - } - return p -} - -// PCMPISTRM performs "Packed Compare Implicit Length Strings, Return Mask". -// -// Mnemonic : PCMPISTRM -// Supported forms : (2 forms) -// -// * PCMPISTRM imm8, xmm, xmm [SSE4.2] -// * PCMPISTRM imm8, m128, xmm [SSE4.2] -// -func (self *Program) PCMPISTRM(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PCMPISTRM", 3, Operands { v0, v1, v2 }) - // PCMPISTRM imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x62) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PCMPISTRM imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x62) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PCMPISTRM") - } - return p -} - -// PDEP performs "Parallel Bits Deposit". -// -// Mnemonic : PDEP -// Supported forms : (4 forms) -// -// * PDEP r32, r32, r32 [BMI2] -// * PDEP m32, r32, r32 [BMI2] -// * PDEP r64, r64, r64 [BMI2] -// * PDEP m64, r64, r64 [BMI2] -// -func (self *Program) PDEP(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PDEP", 3, Operands { v0, v1, v2 }) - // PDEP r32, r32, r32 - if isReg32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7b ^ (hlcode(v[1]) << 3)) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // PDEP m32, r32, r32 - if isM32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x03, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // PDEP r64, r64, r64 - if isReg64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfb ^ (hlcode(v[1]) << 3)) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // PDEP m64, r64, r64 - if isM64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x83, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PDEP") - } - return p -} - -// PEXT performs "Parallel Bits Extract". -// -// Mnemonic : PEXT -// Supported forms : (4 forms) -// -// * PEXT r32, r32, r32 [BMI2] -// * PEXT m32, r32, r32 [BMI2] -// * PEXT r64, r64, r64 [BMI2] -// * PEXT m64, r64, r64 [BMI2] -// -func (self *Program) PEXT(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PEXT", 3, Operands { v0, v1, v2 }) - // PEXT r32, r32, r32 - if isReg32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7a ^ (hlcode(v[1]) << 3)) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // PEXT m32, r32, r32 - if isM32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x02, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // PEXT r64, r64, r64 - if isReg64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfa ^ (hlcode(v[1]) << 3)) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // PEXT m64, r64, r64 - if isM64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x82, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PEXT") - } - return p -} - -// PEXTRB performs "Extract Byte". -// -// Mnemonic : PEXTRB -// Supported forms : (2 forms) -// -// * PEXTRB imm8, xmm, r32 [SSE4.1] -// * PEXTRB imm8, xmm, m8 [SSE4.1] -// -func (self *Program) PEXTRB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PEXTRB", 3, Operands { v0, v1, v2 }) - // PEXTRB imm8, xmm, r32 - if isImm8(v0) && isXMM(v1) && isReg32(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x14) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // PEXTRB imm8, xmm, m8 - if isImm8(v0) && isXMM(v1) && isM8(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x14) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PEXTRB") - } - return p -} - -// PEXTRD performs "Extract Doubleword". -// -// Mnemonic : PEXTRD -// Supported forms : (2 forms) -// -// * PEXTRD imm8, xmm, r32 [SSE4.1] -// * PEXTRD imm8, xmm, m32 [SSE4.1] -// -func (self *Program) PEXTRD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PEXTRD", 3, Operands { v0, v1, v2 }) - // PEXTRD imm8, xmm, r32 - if isImm8(v0) && isXMM(v1) && isReg32(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // PEXTRD imm8, xmm, m32 - if isImm8(v0) && isXMM(v1) && isM32(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PEXTRD") - } - return p -} - -// PEXTRQ performs "Extract Quadword". -// -// Mnemonic : PEXTRQ -// Supported forms : (2 forms) -// -// * PEXTRQ imm8, xmm, r64 [SSE4.1] -// * PEXTRQ imm8, xmm, m64 [SSE4.1] -// -func (self *Program) PEXTRQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PEXTRQ", 3, Operands { v0, v1, v2 }) - // PEXTRQ imm8, xmm, r64 - if isImm8(v0) && isXMM(v1) && isReg64(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[2])) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // PEXTRQ imm8, xmm, m64 - if isImm8(v0) && isXMM(v1) && isM64(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexm(1, hcode(v[1]), addr(v[2])) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PEXTRQ") - } - return p -} - -// PEXTRW performs "Extract Word". -// -// Mnemonic : PEXTRW -// Supported forms : (3 forms) -// -// * PEXTRW imm8, mm, r32 [MMX+] -// * PEXTRW imm8, xmm, r32 [SSE4.1] -// * PEXTRW imm8, xmm, m16 [SSE4.1] -// -func (self *Program) PEXTRW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PEXTRW", 3, Operands { v0, v1, v2 }) - // PEXTRW imm8, mm, r32 - if isImm8(v0) && isMM(v1) && isReg32(v2) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PEXTRW imm8, xmm, r32 - if isImm8(v0) && isXMM(v1) && isReg32(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x15) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PEXTRW imm8, xmm, m16 - if isImm8(v0) && isXMM(v1) && isM16(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x15) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PEXTRW") - } - return p -} - -// PF2ID performs "Packed Floating-Point to Integer Doubleword Converson". -// -// Mnemonic : PF2ID -// Supported forms : (2 forms) -// -// * PF2ID mm, mm [3dnow!] -// * PF2ID m64, mm [3dnow!] -// -func (self *Program) PF2ID(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PF2ID", 2, Operands { v0, v1 }) - // PF2ID mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x1d) - }) - } - // PF2ID m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x1d) - }) - } - if p.len == 0 { - panic("invalid operands for PF2ID") - } - return p -} - -// PF2IW performs "Packed Floating-Point to Integer Word Conversion". -// -// Mnemonic : PF2IW -// Supported forms : (2 forms) -// -// * PF2IW mm, mm [3dnow!+] -// * PF2IW m64, mm [3dnow!+] -// -func (self *Program) PF2IW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PF2IW", 2, Operands { v0, v1 }) - // PF2IW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x1c) - }) - } - // PF2IW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x1c) - }) - } - if p.len == 0 { - panic("invalid operands for PF2IW") - } - return p -} - -// PFACC performs "Packed Floating-Point Accumulate". -// -// Mnemonic : PFACC -// Supported forms : (2 forms) -// -// * PFACC mm, mm [3dnow!] -// * PFACC m64, mm [3dnow!] -// -func (self *Program) PFACC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFACC", 2, Operands { v0, v1 }) - // PFACC mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xae) - }) - } - // PFACC m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xae) - }) - } - if p.len == 0 { - panic("invalid operands for PFACC") - } - return p -} - -// PFADD performs "Packed Floating-Point Add". -// -// Mnemonic : PFADD -// Supported forms : (2 forms) -// -// * PFADD mm, mm [3dnow!] -// * PFADD m64, mm [3dnow!] -// -func (self *Program) PFADD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFADD", 2, Operands { v0, v1 }) - // PFADD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x9e) - }) - } - // PFADD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x9e) - }) - } - if p.len == 0 { - panic("invalid operands for PFADD") - } - return p -} - -// PFCMPEQ performs "Packed Floating-Point Compare for Equal". -// -// Mnemonic : PFCMPEQ -// Supported forms : (2 forms) -// -// * PFCMPEQ mm, mm [3dnow!] -// * PFCMPEQ m64, mm [3dnow!] -// -func (self *Program) PFCMPEQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFCMPEQ", 2, Operands { v0, v1 }) - // PFCMPEQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xb0) - }) - } - // PFCMPEQ m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xb0) - }) - } - if p.len == 0 { - panic("invalid operands for PFCMPEQ") - } - return p -} - -// PFCMPGE performs "Packed Floating-Point Compare for Greater or Equal". -// -// Mnemonic : PFCMPGE -// Supported forms : (2 forms) -// -// * PFCMPGE mm, mm [3dnow!] -// * PFCMPGE m64, mm [3dnow!] -// -func (self *Program) PFCMPGE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFCMPGE", 2, Operands { v0, v1 }) - // PFCMPGE mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x90) - }) - } - // PFCMPGE m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x90) - }) - } - if p.len == 0 { - panic("invalid operands for PFCMPGE") - } - return p -} - -// PFCMPGT performs "Packed Floating-Point Compare for Greater Than". -// -// Mnemonic : PFCMPGT -// Supported forms : (2 forms) -// -// * PFCMPGT mm, mm [3dnow!] -// * PFCMPGT m64, mm [3dnow!] -// -func (self *Program) PFCMPGT(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFCMPGT", 2, Operands { v0, v1 }) - // PFCMPGT mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xa0) - }) - } - // PFCMPGT m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xa0) - }) - } - if p.len == 0 { - panic("invalid operands for PFCMPGT") - } - return p -} - -// PFMAX performs "Packed Floating-Point Maximum". -// -// Mnemonic : PFMAX -// Supported forms : (2 forms) -// -// * PFMAX mm, mm [3dnow!] -// * PFMAX m64, mm [3dnow!] -// -func (self *Program) PFMAX(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFMAX", 2, Operands { v0, v1 }) - // PFMAX mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xa4) - }) - } - // PFMAX m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xa4) - }) - } - if p.len == 0 { - panic("invalid operands for PFMAX") - } - return p -} - -// PFMIN performs "Packed Floating-Point Minimum". -// -// Mnemonic : PFMIN -// Supported forms : (2 forms) -// -// * PFMIN mm, mm [3dnow!] -// * PFMIN m64, mm [3dnow!] -// -func (self *Program) PFMIN(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFMIN", 2, Operands { v0, v1 }) - // PFMIN mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x94) - }) - } - // PFMIN m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x94) - }) - } - if p.len == 0 { - panic("invalid operands for PFMIN") - } - return p -} - -// PFMUL performs "Packed Floating-Point Multiply". -// -// Mnemonic : PFMUL -// Supported forms : (2 forms) -// -// * PFMUL mm, mm [3dnow!] -// * PFMUL m64, mm [3dnow!] -// -func (self *Program) PFMUL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFMUL", 2, Operands { v0, v1 }) - // PFMUL mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xb4) - }) - } - // PFMUL m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xb4) - }) - } - if p.len == 0 { - panic("invalid operands for PFMUL") - } - return p -} - -// PFNACC performs "Packed Floating-Point Negative Accumulate". -// -// Mnemonic : PFNACC -// Supported forms : (2 forms) -// -// * PFNACC mm, mm [3dnow!+] -// * PFNACC m64, mm [3dnow!+] -// -func (self *Program) PFNACC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFNACC", 2, Operands { v0, v1 }) - // PFNACC mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x8a) - }) - } - // PFNACC m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x8a) - }) - } - if p.len == 0 { - panic("invalid operands for PFNACC") - } - return p -} - -// PFPNACC performs "Packed Floating-Point Positive-Negative Accumulate". -// -// Mnemonic : PFPNACC -// Supported forms : (2 forms) -// -// * PFPNACC mm, mm [3dnow!+] -// * PFPNACC m64, mm [3dnow!+] -// -func (self *Program) PFPNACC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFPNACC", 2, Operands { v0, v1 }) - // PFPNACC mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x8e) - }) - } - // PFPNACC m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x8e) - }) - } - if p.len == 0 { - panic("invalid operands for PFPNACC") - } - return p -} - -// PFRCP performs "Packed Floating-Point Reciprocal Approximation". -// -// Mnemonic : PFRCP -// Supported forms : (2 forms) -// -// * PFRCP mm, mm [3dnow!] -// * PFRCP m64, mm [3dnow!] -// -func (self *Program) PFRCP(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFRCP", 2, Operands { v0, v1 }) - // PFRCP mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x96) - }) - } - // PFRCP m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x96) - }) - } - if p.len == 0 { - panic("invalid operands for PFRCP") - } - return p -} - -// PFRCPIT1 performs "Packed Floating-Point Reciprocal Iteration 1". -// -// Mnemonic : PFRCPIT1 -// Supported forms : (2 forms) -// -// * PFRCPIT1 mm, mm [3dnow!] -// * PFRCPIT1 m64, mm [3dnow!] -// -func (self *Program) PFRCPIT1(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFRCPIT1", 2, Operands { v0, v1 }) - // PFRCPIT1 mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xa6) - }) - } - // PFRCPIT1 m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xa6) - }) - } - if p.len == 0 { - panic("invalid operands for PFRCPIT1") - } - return p -} - -// PFRCPIT2 performs "Packed Floating-Point Reciprocal Iteration 2". -// -// Mnemonic : PFRCPIT2 -// Supported forms : (2 forms) -// -// * PFRCPIT2 mm, mm [3dnow!] -// * PFRCPIT2 m64, mm [3dnow!] -// -func (self *Program) PFRCPIT2(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFRCPIT2", 2, Operands { v0, v1 }) - // PFRCPIT2 mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xb6) - }) - } - // PFRCPIT2 m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xb6) - }) - } - if p.len == 0 { - panic("invalid operands for PFRCPIT2") - } - return p -} - -// PFRSQIT1 performs "Packed Floating-Point Reciprocal Square Root Iteration 1". -// -// Mnemonic : PFRSQIT1 -// Supported forms : (2 forms) -// -// * PFRSQIT1 mm, mm [3dnow!] -// * PFRSQIT1 m64, mm [3dnow!] -// -func (self *Program) PFRSQIT1(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFRSQIT1", 2, Operands { v0, v1 }) - // PFRSQIT1 mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xa7) - }) - } - // PFRSQIT1 m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xa7) - }) - } - if p.len == 0 { - panic("invalid operands for PFRSQIT1") - } - return p -} - -// PFRSQRT performs "Packed Floating-Point Reciprocal Square Root Approximation". -// -// Mnemonic : PFRSQRT -// Supported forms : (2 forms) -// -// * PFRSQRT mm, mm [3dnow!] -// * PFRSQRT m64, mm [3dnow!] -// -func (self *Program) PFRSQRT(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFRSQRT", 2, Operands { v0, v1 }) - // PFRSQRT mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x97) - }) - } - // PFRSQRT m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x97) - }) - } - if p.len == 0 { - panic("invalid operands for PFRSQRT") - } - return p -} - -// PFSUB performs "Packed Floating-Point Subtract". -// -// Mnemonic : PFSUB -// Supported forms : (2 forms) -// -// * PFSUB mm, mm [3dnow!] -// * PFSUB m64, mm [3dnow!] -// -func (self *Program) PFSUB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFSUB", 2, Operands { v0, v1 }) - // PFSUB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x9a) - }) - } - // PFSUB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x9a) - }) - } - if p.len == 0 { - panic("invalid operands for PFSUB") - } - return p -} - -// PFSUBR performs "Packed Floating-Point Subtract Reverse". -// -// Mnemonic : PFSUBR -// Supported forms : (2 forms) -// -// * PFSUBR mm, mm [3dnow!] -// * PFSUBR m64, mm [3dnow!] -// -func (self *Program) PFSUBR(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PFSUBR", 2, Operands { v0, v1 }) - // PFSUBR mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xaa) - }) - } - // PFSUBR m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xaa) - }) - } - if p.len == 0 { - panic("invalid operands for PFSUBR") - } - return p -} - -// PHADDD performs "Packed Horizontal Add Doubleword Integer". -// -// Mnemonic : PHADDD -// Supported forms : (4 forms) -// -// * PHADDD mm, mm [SSSE3] -// * PHADDD m64, mm [SSSE3] -// * PHADDD xmm, xmm [SSSE3] -// * PHADDD m128, xmm [SSSE3] -// -func (self *Program) PHADDD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PHADDD", 2, Operands { v0, v1 }) - // PHADDD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x02) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHADDD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x02) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PHADDD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x02) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHADDD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x02) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PHADDD") - } - return p -} - -// PHADDSW performs "Packed Horizontal Add Signed Word Integers with Signed Saturation". -// -// Mnemonic : PHADDSW -// Supported forms : (4 forms) -// -// * PHADDSW mm, mm [SSSE3] -// * PHADDSW m64, mm [SSSE3] -// * PHADDSW xmm, xmm [SSSE3] -// * PHADDSW m128, xmm [SSSE3] -// -func (self *Program) PHADDSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PHADDSW", 2, Operands { v0, v1 }) - // PHADDSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x03) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHADDSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x03) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PHADDSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x03) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHADDSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x03) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PHADDSW") - } - return p -} - -// PHADDW performs "Packed Horizontal Add Word Integers". -// -// Mnemonic : PHADDW -// Supported forms : (4 forms) -// -// * PHADDW mm, mm [SSSE3] -// * PHADDW m64, mm [SSSE3] -// * PHADDW xmm, xmm [SSSE3] -// * PHADDW m128, xmm [SSSE3] -// -func (self *Program) PHADDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PHADDW", 2, Operands { v0, v1 }) - // PHADDW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x01) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHADDW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x01) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PHADDW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x01) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHADDW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x01) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PHADDW") - } - return p -} - -// PHMINPOSUW performs "Packed Horizontal Minimum of Unsigned Word Integers". -// -// Mnemonic : PHMINPOSUW -// Supported forms : (2 forms) -// -// * PHMINPOSUW xmm, xmm [SSE4.1] -// * PHMINPOSUW m128, xmm [SSE4.1] -// -func (self *Program) PHMINPOSUW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PHMINPOSUW", 2, Operands { v0, v1 }) - // PHMINPOSUW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x41) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHMINPOSUW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x41) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PHMINPOSUW") - } - return p -} - -// PHSUBD performs "Packed Horizontal Subtract Doubleword Integers". -// -// Mnemonic : PHSUBD -// Supported forms : (4 forms) -// -// * PHSUBD mm, mm [SSSE3] -// * PHSUBD m64, mm [SSSE3] -// * PHSUBD xmm, xmm [SSSE3] -// * PHSUBD m128, xmm [SSSE3] -// -func (self *Program) PHSUBD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PHSUBD", 2, Operands { v0, v1 }) - // PHSUBD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x06) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHSUBD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x06) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PHSUBD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x06) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHSUBD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x06) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PHSUBD") - } - return p -} - -// PHSUBSW performs "Packed Horizontal Subtract Signed Word Integers with Signed Saturation". -// -// Mnemonic : PHSUBSW -// Supported forms : (4 forms) -// -// * PHSUBSW mm, mm [SSSE3] -// * PHSUBSW m64, mm [SSSE3] -// * PHSUBSW xmm, xmm [SSSE3] -// * PHSUBSW m128, xmm [SSSE3] -// -func (self *Program) PHSUBSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PHSUBSW", 2, Operands { v0, v1 }) - // PHSUBSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x07) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHSUBSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x07) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PHSUBSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x07) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHSUBSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x07) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PHSUBSW") - } - return p -} - -// PHSUBW performs "Packed Horizontal Subtract Word Integers". -// -// Mnemonic : PHSUBW -// Supported forms : (4 forms) -// -// * PHSUBW mm, mm [SSSE3] -// * PHSUBW m64, mm [SSSE3] -// * PHSUBW xmm, xmm [SSSE3] -// * PHSUBW m128, xmm [SSSE3] -// -func (self *Program) PHSUBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PHSUBW", 2, Operands { v0, v1 }) - // PHSUBW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x05) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHSUBW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x05) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PHSUBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x05) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PHSUBW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x05) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PHSUBW") - } - return p -} - -// PI2FD performs "Packed Integer to Floating-Point Doubleword Conversion". -// -// Mnemonic : PI2FD -// Supported forms : (2 forms) -// -// * PI2FD mm, mm [3dnow!] -// * PI2FD m64, mm [3dnow!] -// -func (self *Program) PI2FD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PI2FD", 2, Operands { v0, v1 }) - // PI2FD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x0d) - }) - } - // PI2FD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x0d) - }) - } - if p.len == 0 { - panic("invalid operands for PI2FD") - } - return p -} - -// PI2FW performs "Packed Integer to Floating-Point Word Conversion". -// -// Mnemonic : PI2FW -// Supported forms : (2 forms) -// -// * PI2FW mm, mm [3dnow!+] -// * PI2FW m64, mm [3dnow!+] -// -func (self *Program) PI2FW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PI2FW", 2, Operands { v0, v1 }) - // PI2FW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0x0c) - }) - } - // PI2FW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0x0c) - }) - } - if p.len == 0 { - panic("invalid operands for PI2FW") - } - return p -} - -// PINSRB performs "Insert Byte". -// -// Mnemonic : PINSRB -// Supported forms : (2 forms) -// -// * PINSRB imm8, r32, xmm [SSE4.1] -// * PINSRB imm8, m8, xmm [SSE4.1] -// -func (self *Program) PINSRB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PINSRB", 3, Operands { v0, v1, v2 }) - // PINSRB imm8, r32, xmm - if isImm8(v0) && isReg32(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x20) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PINSRB imm8, m8, xmm - if isImm8(v0) && isM8(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x20) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PINSRB") - } - return p -} - -// PINSRD performs "Insert Doubleword". -// -// Mnemonic : PINSRD -// Supported forms : (2 forms) -// -// * PINSRD imm8, r32, xmm [SSE4.1] -// * PINSRD imm8, m32, xmm [SSE4.1] -// -func (self *Program) PINSRD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PINSRD", 3, Operands { v0, v1, v2 }) - // PINSRD imm8, r32, xmm - if isImm8(v0) && isReg32(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x22) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PINSRD imm8, m32, xmm - if isImm8(v0) && isM32(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x22) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PINSRD") - } - return p -} - -// PINSRQ performs "Insert Quadword". -// -// Mnemonic : PINSRQ -// Supported forms : (2 forms) -// -// * PINSRQ imm8, r64, xmm [SSE4.1] -// * PINSRQ imm8, m64, xmm [SSE4.1] -// -func (self *Program) PINSRQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PINSRQ", 3, Operands { v0, v1, v2 }) - // PINSRQ imm8, r64, xmm - if isImm8(v0) && isReg64(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x48 | hcode(v[2]) << 2 | hcode(v[1])) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x22) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PINSRQ imm8, m64, xmm - if isImm8(v0) && isM64(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexm(1, hcode(v[2]), addr(v[1])) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x22) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PINSRQ") - } - return p -} - -// PINSRW performs "Insert Word". -// -// Mnemonic : PINSRW -// Supported forms : (4 forms) -// -// * PINSRW imm8, r32, mm [MMX+] -// * PINSRW imm8, m16, mm [MMX+] -// * PINSRW imm8, r32, xmm [SSE2] -// * PINSRW imm8, m16, xmm [SSE2] -// -func (self *Program) PINSRW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PINSRW", 3, Operands { v0, v1, v2 }) - // PINSRW imm8, r32, mm - if isImm8(v0) && isReg32(v1) && isMM(v2) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PINSRW imm8, m16, mm - if isImm8(v0) && isM16(v1) && isMM(v2) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc4) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // PINSRW imm8, r32, xmm - if isImm8(v0) && isReg32(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PINSRW imm8, m16, xmm - if isImm8(v0) && isM16(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc4) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PINSRW") - } - return p -} - -// PMADDUBSW performs "Multiply and Add Packed Signed and Unsigned Byte Integers". -// -// Mnemonic : PMADDUBSW -// Supported forms : (4 forms) -// -// * PMADDUBSW mm, mm [SSSE3] -// * PMADDUBSW m64, mm [SSSE3] -// * PMADDUBSW xmm, xmm [SSSE3] -// * PMADDUBSW m128, xmm [SSSE3] -// -func (self *Program) PMADDUBSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMADDUBSW", 2, Operands { v0, v1 }) - // PMADDUBSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x04) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMADDUBSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x04) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMADDUBSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x04) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMADDUBSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x04) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMADDUBSW") - } - return p -} - -// PMADDWD performs "Multiply and Add Packed Signed Word Integers". -// -// Mnemonic : PMADDWD -// Supported forms : (4 forms) -// -// * PMADDWD mm, mm [MMX] -// * PMADDWD m64, mm [MMX] -// * PMADDWD xmm, xmm [SSE2] -// * PMADDWD m128, xmm [SSE2] -// -func (self *Program) PMADDWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMADDWD", 2, Operands { v0, v1 }) - // PMADDWD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMADDWD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf5) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMADDWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMADDWD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf5) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMADDWD") - } - return p -} - -// PMAXSB performs "Maximum of Packed Signed Byte Integers". -// -// Mnemonic : PMAXSB -// Supported forms : (2 forms) -// -// * PMAXSB xmm, xmm [SSE4.1] -// * PMAXSB m128, xmm [SSE4.1] -// -func (self *Program) PMAXSB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMAXSB", 2, Operands { v0, v1 }) - // PMAXSB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMAXSB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMAXSB") - } - return p -} - -// PMAXSD performs "Maximum of Packed Signed Doubleword Integers". -// -// Mnemonic : PMAXSD -// Supported forms : (2 forms) -// -// * PMAXSD xmm, xmm [SSE4.1] -// * PMAXSD m128, xmm [SSE4.1] -// -func (self *Program) PMAXSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMAXSD", 2, Operands { v0, v1 }) - // PMAXSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMAXSD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMAXSD") - } - return p -} - -// PMAXSW performs "Maximum of Packed Signed Word Integers". -// -// Mnemonic : PMAXSW -// Supported forms : (4 forms) -// -// * PMAXSW mm, mm [MMX+] -// * PMAXSW m64, mm [MMX+] -// * PMAXSW xmm, xmm [SSE2] -// * PMAXSW m128, xmm [SSE2] -// -func (self *Program) PMAXSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMAXSW", 2, Operands { v0, v1 }) - // PMAXSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xee) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMAXSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xee) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMAXSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xee) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMAXSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xee) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMAXSW") - } - return p -} - -// PMAXUB performs "Maximum of Packed Unsigned Byte Integers". -// -// Mnemonic : PMAXUB -// Supported forms : (4 forms) -// -// * PMAXUB mm, mm [MMX+] -// * PMAXUB m64, mm [MMX+] -// * PMAXUB xmm, xmm [SSE2] -// * PMAXUB m128, xmm [SSE2] -// -func (self *Program) PMAXUB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMAXUB", 2, Operands { v0, v1 }) - // PMAXUB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xde) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMAXUB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xde) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMAXUB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xde) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMAXUB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xde) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMAXUB") - } - return p -} - -// PMAXUD performs "Maximum of Packed Unsigned Doubleword Integers". -// -// Mnemonic : PMAXUD -// Supported forms : (2 forms) -// -// * PMAXUD xmm, xmm [SSE4.1] -// * PMAXUD m128, xmm [SSE4.1] -// -func (self *Program) PMAXUD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMAXUD", 2, Operands { v0, v1 }) - // PMAXUD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMAXUD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMAXUD") - } - return p -} - -// PMAXUW performs "Maximum of Packed Unsigned Word Integers". -// -// Mnemonic : PMAXUW -// Supported forms : (2 forms) -// -// * PMAXUW xmm, xmm [SSE4.1] -// * PMAXUW m128, xmm [SSE4.1] -// -func (self *Program) PMAXUW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMAXUW", 2, Operands { v0, v1 }) - // PMAXUW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMAXUW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMAXUW") - } - return p -} - -// PMINSB performs "Minimum of Packed Signed Byte Integers". -// -// Mnemonic : PMINSB -// Supported forms : (2 forms) -// -// * PMINSB xmm, xmm [SSE4.1] -// * PMINSB m128, xmm [SSE4.1] -// -func (self *Program) PMINSB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMINSB", 2, Operands { v0, v1 }) - // PMINSB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x38) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMINSB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x38) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMINSB") - } - return p -} - -// PMINSD performs "Minimum of Packed Signed Doubleword Integers". -// -// Mnemonic : PMINSD -// Supported forms : (2 forms) -// -// * PMINSD xmm, xmm [SSE4.1] -// * PMINSD m128, xmm [SSE4.1] -// -func (self *Program) PMINSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMINSD", 2, Operands { v0, v1 }) - // PMINSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMINSD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x39) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMINSD") - } - return p -} - -// PMINSW performs "Minimum of Packed Signed Word Integers". -// -// Mnemonic : PMINSW -// Supported forms : (4 forms) -// -// * PMINSW mm, mm [MMX+] -// * PMINSW m64, mm [MMX+] -// * PMINSW xmm, xmm [SSE2] -// * PMINSW m128, xmm [SSE2] -// -func (self *Program) PMINSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMINSW", 2, Operands { v0, v1 }) - // PMINSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xea) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMINSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xea) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMINSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xea) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMINSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xea) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMINSW") - } - return p -} - -// PMINUB performs "Minimum of Packed Unsigned Byte Integers". -// -// Mnemonic : PMINUB -// Supported forms : (4 forms) -// -// * PMINUB mm, mm [MMX+] -// * PMINUB m64, mm [MMX+] -// * PMINUB xmm, xmm [SSE2] -// * PMINUB m128, xmm [SSE2] -// -func (self *Program) PMINUB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMINUB", 2, Operands { v0, v1 }) - // PMINUB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xda) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMINUB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xda) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMINUB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xda) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMINUB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xda) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMINUB") - } - return p -} - -// PMINUD performs "Minimum of Packed Unsigned Doubleword Integers". -// -// Mnemonic : PMINUD -// Supported forms : (2 forms) -// -// * PMINUD xmm, xmm [SSE4.1] -// * PMINUD m128, xmm [SSE4.1] -// -func (self *Program) PMINUD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMINUD", 2, Operands { v0, v1 }) - // PMINUD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMINUD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMINUD") - } - return p -} - -// PMINUW performs "Minimum of Packed Unsigned Word Integers". -// -// Mnemonic : PMINUW -// Supported forms : (2 forms) -// -// * PMINUW xmm, xmm [SSE4.1] -// * PMINUW m128, xmm [SSE4.1] -// -func (self *Program) PMINUW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMINUW", 2, Operands { v0, v1 }) - // PMINUW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMINUW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x3a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMINUW") - } - return p -} - -// PMOVMSKB performs "Move Byte Mask". -// -// Mnemonic : PMOVMSKB -// Supported forms : (2 forms) -// -// * PMOVMSKB mm, r32 [MMX+] -// * PMOVMSKB xmm, r32 [SSE2] -// -func (self *Program) PMOVMSKB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVMSKB", 2, Operands { v0, v1 }) - // PMOVMSKB mm, r32 - if isMM(v0) && isReg32(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVMSKB xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVMSKB") - } - return p -} - -// PMOVSXBD performs "Move Packed Byte Integers to Doubleword Integers with Sign Extension". -// -// Mnemonic : PMOVSXBD -// Supported forms : (2 forms) -// -// * PMOVSXBD xmm, xmm [SSE4.1] -// * PMOVSXBD m32, xmm [SSE4.1] -// -func (self *Program) PMOVSXBD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVSXBD", 2, Operands { v0, v1 }) - // PMOVSXBD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x21) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVSXBD m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x21) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVSXBD") - } - return p -} - -// PMOVSXBQ performs "Move Packed Byte Integers to Quadword Integers with Sign Extension". -// -// Mnemonic : PMOVSXBQ -// Supported forms : (2 forms) -// -// * PMOVSXBQ xmm, xmm [SSE4.1] -// * PMOVSXBQ m16, xmm [SSE4.1] -// -func (self *Program) PMOVSXBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVSXBQ", 2, Operands { v0, v1 }) - // PMOVSXBQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x22) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVSXBQ m16, xmm - if isM16(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x22) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVSXBQ") - } - return p -} - -// PMOVSXBW performs "Move Packed Byte Integers to Word Integers with Sign Extension". -// -// Mnemonic : PMOVSXBW -// Supported forms : (2 forms) -// -// * PMOVSXBW xmm, xmm [SSE4.1] -// * PMOVSXBW m64, xmm [SSE4.1] -// -func (self *Program) PMOVSXBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVSXBW", 2, Operands { v0, v1 }) - // PMOVSXBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x20) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVSXBW m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x20) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVSXBW") - } - return p -} - -// PMOVSXDQ performs "Move Packed Doubleword Integers to Quadword Integers with Sign Extension". -// -// Mnemonic : PMOVSXDQ -// Supported forms : (2 forms) -// -// * PMOVSXDQ xmm, xmm [SSE4.1] -// * PMOVSXDQ m64, xmm [SSE4.1] -// -func (self *Program) PMOVSXDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVSXDQ", 2, Operands { v0, v1 }) - // PMOVSXDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x25) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVSXDQ m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x25) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVSXDQ") - } - return p -} - -// PMOVSXWD performs "Move Packed Word Integers to Doubleword Integers with Sign Extension". -// -// Mnemonic : PMOVSXWD -// Supported forms : (2 forms) -// -// * PMOVSXWD xmm, xmm [SSE4.1] -// * PMOVSXWD m64, xmm [SSE4.1] -// -func (self *Program) PMOVSXWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVSXWD", 2, Operands { v0, v1 }) - // PMOVSXWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x23) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVSXWD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x23) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVSXWD") - } - return p -} - -// PMOVSXWQ performs "Move Packed Word Integers to Quadword Integers with Sign Extension". -// -// Mnemonic : PMOVSXWQ -// Supported forms : (2 forms) -// -// * PMOVSXWQ xmm, xmm [SSE4.1] -// * PMOVSXWQ m32, xmm [SSE4.1] -// -func (self *Program) PMOVSXWQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVSXWQ", 2, Operands { v0, v1 }) - // PMOVSXWQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x24) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVSXWQ m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x24) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVSXWQ") - } - return p -} - -// PMOVZXBD performs "Move Packed Byte Integers to Doubleword Integers with Zero Extension". -// -// Mnemonic : PMOVZXBD -// Supported forms : (2 forms) -// -// * PMOVZXBD xmm, xmm [SSE4.1] -// * PMOVZXBD m32, xmm [SSE4.1] -// -func (self *Program) PMOVZXBD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVZXBD", 2, Operands { v0, v1 }) - // PMOVZXBD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x31) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVZXBD m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x31) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVZXBD") - } - return p -} - -// PMOVZXBQ performs "Move Packed Byte Integers to Quadword Integers with Zero Extension". -// -// Mnemonic : PMOVZXBQ -// Supported forms : (2 forms) -// -// * PMOVZXBQ xmm, xmm [SSE4.1] -// * PMOVZXBQ m16, xmm [SSE4.1] -// -func (self *Program) PMOVZXBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVZXBQ", 2, Operands { v0, v1 }) - // PMOVZXBQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x32) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVZXBQ m16, xmm - if isM16(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x32) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVZXBQ") - } - return p -} - -// PMOVZXBW performs "Move Packed Byte Integers to Word Integers with Zero Extension". -// -// Mnemonic : PMOVZXBW -// Supported forms : (2 forms) -// -// * PMOVZXBW xmm, xmm [SSE4.1] -// * PMOVZXBW m64, xmm [SSE4.1] -// -func (self *Program) PMOVZXBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVZXBW", 2, Operands { v0, v1 }) - // PMOVZXBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x30) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVZXBW m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x30) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVZXBW") - } - return p -} - -// PMOVZXDQ performs "Move Packed Doubleword Integers to Quadword Integers with Zero Extension". -// -// Mnemonic : PMOVZXDQ -// Supported forms : (2 forms) -// -// * PMOVZXDQ xmm, xmm [SSE4.1] -// * PMOVZXDQ m64, xmm [SSE4.1] -// -func (self *Program) PMOVZXDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVZXDQ", 2, Operands { v0, v1 }) - // PMOVZXDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x35) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVZXDQ m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x35) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVZXDQ") - } - return p -} - -// PMOVZXWD performs "Move Packed Word Integers to Doubleword Integers with Zero Extension". -// -// Mnemonic : PMOVZXWD -// Supported forms : (2 forms) -// -// * PMOVZXWD xmm, xmm [SSE4.1] -// * PMOVZXWD m64, xmm [SSE4.1] -// -func (self *Program) PMOVZXWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVZXWD", 2, Operands { v0, v1 }) - // PMOVZXWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x33) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVZXWD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x33) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVZXWD") - } - return p -} - -// PMOVZXWQ performs "Move Packed Word Integers to Quadword Integers with Zero Extension". -// -// Mnemonic : PMOVZXWQ -// Supported forms : (2 forms) -// -// * PMOVZXWQ xmm, xmm [SSE4.1] -// * PMOVZXWQ m32, xmm [SSE4.1] -// -func (self *Program) PMOVZXWQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMOVZXWQ", 2, Operands { v0, v1 }) - // PMOVZXWQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x34) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMOVZXWQ m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x34) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMOVZXWQ") - } - return p -} - -// PMULDQ performs "Multiply Packed Signed Doubleword Integers and Store Quadword Result". -// -// Mnemonic : PMULDQ -// Supported forms : (2 forms) -// -// * PMULDQ xmm, xmm [SSE4.1] -// * PMULDQ m128, xmm [SSE4.1] -// -func (self *Program) PMULDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMULDQ", 2, Operands { v0, v1 }) - // PMULDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMULDQ") - } - return p -} - -// PMULHRSW performs "Packed Multiply Signed Word Integers and Store High Result with Round and Scale". -// -// Mnemonic : PMULHRSW -// Supported forms : (4 forms) -// -// * PMULHRSW mm, mm [SSSE3] -// * PMULHRSW m64, mm [SSSE3] -// * PMULHRSW xmm, xmm [SSSE3] -// * PMULHRSW m128, xmm [SSSE3] -// -func (self *Program) PMULHRSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMULHRSW", 2, Operands { v0, v1 }) - // PMULHRSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULHRSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x0b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMULHRSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULHRSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x0b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMULHRSW") - } - return p -} - -// PMULHRW performs "Packed Multiply High Rounded Word". -// -// Mnemonic : PMULHRW -// Supported forms : (2 forms) -// -// * PMULHRW mm, mm [3dnow!] -// * PMULHRW m64, mm [3dnow!] -// -func (self *Program) PMULHRW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMULHRW", 2, Operands { v0, v1 }) - // PMULHRW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xb7) - }) - } - // PMULHRW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xb7) - }) - } - if p.len == 0 { - panic("invalid operands for PMULHRW") - } - return p -} - -// PMULHUW performs "Multiply Packed Unsigned Word Integers and Store High Result". -// -// Mnemonic : PMULHUW -// Supported forms : (4 forms) -// -// * PMULHUW mm, mm [MMX+] -// * PMULHUW m64, mm [MMX+] -// * PMULHUW xmm, xmm [SSE2] -// * PMULHUW m128, xmm [SSE2] -// -func (self *Program) PMULHUW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMULHUW", 2, Operands { v0, v1 }) - // PMULHUW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULHUW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe4) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMULHUW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULHUW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe4) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMULHUW") - } - return p -} - -// PMULHW performs "Multiply Packed Signed Word Integers and Store High Result". -// -// Mnemonic : PMULHW -// Supported forms : (4 forms) -// -// * PMULHW mm, mm [MMX] -// * PMULHW m64, mm [MMX] -// * PMULHW xmm, xmm [SSE2] -// * PMULHW m128, xmm [SSE2] -// -func (self *Program) PMULHW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMULHW", 2, Operands { v0, v1 }) - // PMULHW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe5) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULHW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe5) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMULHW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe5) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULHW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe5) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMULHW") - } - return p -} - -// PMULLD performs "Multiply Packed Signed Doubleword Integers and Store Low Result". -// -// Mnemonic : PMULLD -// Supported forms : (2 forms) -// -// * PMULLD xmm, xmm [SSE4.1] -// * PMULLD m128, xmm [SSE4.1] -// -func (self *Program) PMULLD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMULLD", 2, Operands { v0, v1 }) - // PMULLD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x40) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULLD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x40) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMULLD") - } - return p -} - -// PMULLW performs "Multiply Packed Signed Word Integers and Store Low Result". -// -// Mnemonic : PMULLW -// Supported forms : (4 forms) -// -// * PMULLW mm, mm [MMX] -// * PMULLW m64, mm [MMX] -// * PMULLW xmm, xmm [SSE2] -// * PMULLW m128, xmm [SSE2] -// -func (self *Program) PMULLW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMULLW", 2, Operands { v0, v1 }) - // PMULLW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd5) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULLW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd5) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMULLW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd5) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULLW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd5) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMULLW") - } - return p -} - -// PMULUDQ performs "Multiply Packed Unsigned Doubleword Integers". -// -// Mnemonic : PMULUDQ -// Supported forms : (4 forms) -// -// * PMULUDQ mm, mm [SSE2] -// * PMULUDQ m64, mm [SSE2] -// * PMULUDQ xmm, xmm [SSE2] -// * PMULUDQ m128, xmm [SSE2] -// -func (self *Program) PMULUDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PMULUDQ", 2, Operands { v0, v1 }) - // PMULUDQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULUDQ m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf4) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PMULUDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PMULUDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf4) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PMULUDQ") - } - return p -} - -// POPCNTL performs "Count of Number of Bits Set to 1". -// -// Mnemonic : POPCNT -// Supported forms : (2 forms) -// -// * POPCNTL r32, r32 [POPCNT] -// * POPCNTL m32, r32 [POPCNT] -// -func (self *Program) POPCNTL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("POPCNTL", 2, Operands { v0, v1 }) - // POPCNTL r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_POPCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // POPCNTL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_POPCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xb8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for POPCNTL") - } - return p -} - -// POPCNTQ performs "Count of Number of Bits Set to 1". -// -// Mnemonic : POPCNT -// Supported forms : (2 forms) -// -// * POPCNTQ r64, r64 [POPCNT] -// * POPCNTQ m64, r64 [POPCNT] -// -func (self *Program) POPCNTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("POPCNTQ", 2, Operands { v0, v1 }) - // POPCNTQ r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_POPCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // POPCNTQ m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_POPCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xb8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for POPCNTQ") - } - return p -} - -// POPCNTW performs "Count of Number of Bits Set to 1". -// -// Mnemonic : POPCNT -// Supported forms : (2 forms) -// -// * POPCNTW r16, r16 [POPCNT] -// * POPCNTW m16, r16 [POPCNT] -// -func (self *Program) POPCNTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("POPCNTW", 2, Operands { v0, v1 }) - // POPCNTW r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_POPCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // POPCNTW m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_POPCNT) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xb8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for POPCNTW") - } - return p -} - -// POPQ performs "Pop a Value from the Stack". -// -// Mnemonic : POP -// Supported forms : (2 forms) -// -// * POPQ r64 -// * POPQ m64 -// -func (self *Program) POPQ(v0 interface{}) *Instruction { - p := self.alloc("POPQ", 1, Operands { v0 }) - // POPQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0x58 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0x8f) - m.emit(0xc0 | lcode(v[0])) - }) - } - // POPQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x8f) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for POPQ") - } - return p -} - -// POPW performs "Pop a Value from the Stack". -// -// Mnemonic : POP -// Supported forms : (2 forms) -// -// * POPW r16 -// * POPW m16 -// -func (self *Program) POPW(v0 interface{}) *Instruction { - p := self.alloc("POPW", 1, Operands { v0 }) - // POPW r16 - if isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0x58 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0x8f) - m.emit(0xc0 | lcode(v[0])) - }) - } - // POPW m16 - if isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0x8f) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for POPW") - } - return p -} - -// POR performs "Packed Bitwise Logical OR". -// -// Mnemonic : POR -// Supported forms : (4 forms) -// -// * POR mm, mm [MMX] -// * POR m64, mm [MMX] -// * POR xmm, xmm [SSE2] -// * POR m128, xmm [SSE2] -// -func (self *Program) POR(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("POR", 2, Operands { v0, v1 }) - // POR mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // POR m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xeb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // POR xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // POR m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xeb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for POR") - } - return p -} - -// PREFETCH performs "Prefetch Data into Caches". -// -// Mnemonic : PREFETCH -// Supported forms : (1 form) -// -// * PREFETCH m8 [PREFETCH] -// -func (self *Program) PREFETCH(v0 interface{}) *Instruction { - p := self.alloc("PREFETCH", 1, Operands { v0 }) - // PREFETCH m8 - if isM8(v0) { - self.require(ISA_PREFETCH) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0d) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PREFETCH") - } - return p -} - -// PREFETCHNTA performs "Prefetch Data Into Caches using NTA Hint". -// -// Mnemonic : PREFETCHNTA -// Supported forms : (1 form) -// -// * PREFETCHNTA m8 [MMX+] -// -func (self *Program) PREFETCHNTA(v0 interface{}) *Instruction { - p := self.alloc("PREFETCHNTA", 1, Operands { v0 }) - // PREFETCHNTA m8 - if isM8(v0) { - self.require(ISA_MMX_PLUS) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x18) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PREFETCHNTA") - } - return p -} - -// PREFETCHT0 performs "Prefetch Data Into Caches using T0 Hint". -// -// Mnemonic : PREFETCHT0 -// Supported forms : (1 form) -// -// * PREFETCHT0 m8 [MMX+] -// -func (self *Program) PREFETCHT0(v0 interface{}) *Instruction { - p := self.alloc("PREFETCHT0", 1, Operands { v0 }) - // PREFETCHT0 m8 - if isM8(v0) { - self.require(ISA_MMX_PLUS) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x18) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PREFETCHT0") - } - return p -} - -// PREFETCHT1 performs "Prefetch Data Into Caches using T1 Hint". -// -// Mnemonic : PREFETCHT1 -// Supported forms : (1 form) -// -// * PREFETCHT1 m8 [MMX+] -// -func (self *Program) PREFETCHT1(v0 interface{}) *Instruction { - p := self.alloc("PREFETCHT1", 1, Operands { v0 }) - // PREFETCHT1 m8 - if isM8(v0) { - self.require(ISA_MMX_PLUS) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x18) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PREFETCHT1") - } - return p -} - -// PREFETCHT2 performs "Prefetch Data Into Caches using T2 Hint". -// -// Mnemonic : PREFETCHT2 -// Supported forms : (1 form) -// -// * PREFETCHT2 m8 [MMX+] -// -func (self *Program) PREFETCHT2(v0 interface{}) *Instruction { - p := self.alloc("PREFETCHT2", 1, Operands { v0 }) - // PREFETCHT2 m8 - if isM8(v0) { - self.require(ISA_MMX_PLUS) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x18) - m.mrsd(3, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PREFETCHT2") - } - return p -} - -// PREFETCHW performs "Prefetch Data into Caches in Anticipation of a Write". -// -// Mnemonic : PREFETCHW -// Supported forms : (1 form) -// -// * PREFETCHW m8 [PREFETCHW] -// -func (self *Program) PREFETCHW(v0 interface{}) *Instruction { - p := self.alloc("PREFETCHW", 1, Operands { v0 }) - // PREFETCHW m8 - if isM8(v0) { - self.require(ISA_PREFETCHW) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0d) - m.mrsd(1, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PREFETCHW") - } - return p -} - -// PREFETCHWT1 performs "Prefetch Vector Data Into Caches with Intent to Write and T1 Hint". -// -// Mnemonic : PREFETCHWT1 -// Supported forms : (1 form) -// -// * PREFETCHWT1 m8 [PREFETCHWT1] -// -func (self *Program) PREFETCHWT1(v0 interface{}) *Instruction { - p := self.alloc("PREFETCHWT1", 1, Operands { v0 }) - // PREFETCHWT1 m8 - if isM8(v0) { - self.require(ISA_PREFETCHWT1) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0d) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PREFETCHWT1") - } - return p -} - -// PSADBW performs "Compute Sum of Absolute Differences". -// -// Mnemonic : PSADBW -// Supported forms : (4 forms) -// -// * PSADBW mm, mm [MMX+] -// * PSADBW m64, mm [MMX+] -// * PSADBW xmm, xmm [SSE2] -// * PSADBW m128, xmm [SSE2] -// -func (self *Program) PSADBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSADBW", 2, Operands { v0, v1 }) - // PSADBW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSADBW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSADBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSADBW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSADBW") - } - return p -} - -// PSHUFB performs "Packed Shuffle Bytes". -// -// Mnemonic : PSHUFB -// Supported forms : (4 forms) -// -// * PSHUFB mm, mm [SSSE3] -// * PSHUFB m64, mm [SSSE3] -// * PSHUFB xmm, xmm [SSSE3] -// * PSHUFB m128, xmm [SSSE3] -// -func (self *Program) PSHUFB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSHUFB", 2, Operands { v0, v1 }) - // PSHUFB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x00) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSHUFB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x00) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSHUFB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x00) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSHUFB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x00) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSHUFB") - } - return p -} - -// PSHUFD performs "Shuffle Packed Doublewords". -// -// Mnemonic : PSHUFD -// Supported forms : (2 forms) -// -// * PSHUFD imm8, xmm, xmm [SSE2] -// * PSHUFD imm8, m128, xmm [SSE2] -// -func (self *Program) PSHUFD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PSHUFD", 3, Operands { v0, v1, v2 }) - // PSHUFD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSHUFD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PSHUFD") - } - return p -} - -// PSHUFHW performs "Shuffle Packed High Words". -// -// Mnemonic : PSHUFHW -// Supported forms : (2 forms) -// -// * PSHUFHW imm8, xmm, xmm [SSE2] -// * PSHUFHW imm8, m128, xmm [SSE2] -// -func (self *Program) PSHUFHW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PSHUFHW", 3, Operands { v0, v1, v2 }) - // PSHUFHW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSHUFHW imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PSHUFHW") - } - return p -} - -// PSHUFLW performs "Shuffle Packed Low Words". -// -// Mnemonic : PSHUFLW -// Supported forms : (2 forms) -// -// * PSHUFLW imm8, xmm, xmm [SSE2] -// * PSHUFLW imm8, m128, xmm [SSE2] -// -func (self *Program) PSHUFLW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PSHUFLW", 3, Operands { v0, v1, v2 }) - // PSHUFLW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSHUFLW imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PSHUFLW") - } - return p -} - -// PSHUFW performs "Shuffle Packed Words". -// -// Mnemonic : PSHUFW -// Supported forms : (2 forms) -// -// * PSHUFW imm8, mm, mm [MMX+] -// * PSHUFW imm8, m64, mm [MMX+] -// -func (self *Program) PSHUFW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("PSHUFW", 3, Operands { v0, v1, v2 }) - // PSHUFW imm8, mm, mm - if isImm8(v0) && isMM(v1) && isMM(v2) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSHUFW imm8, m64, mm - if isImm8(v0) && isM64(v1) && isMM(v2) { - self.require(ISA_MMX_PLUS) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PSHUFW") - } - return p -} - -// PSIGNB performs "Packed Sign of Byte Integers". -// -// Mnemonic : PSIGNB -// Supported forms : (4 forms) -// -// * PSIGNB mm, mm [SSSE3] -// * PSIGNB m64, mm [SSSE3] -// * PSIGNB xmm, xmm [SSSE3] -// * PSIGNB m128, xmm [SSSE3] -// -func (self *Program) PSIGNB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSIGNB", 2, Operands { v0, v1 }) - // PSIGNB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x08) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSIGNB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x08) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSIGNB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x08) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSIGNB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x08) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSIGNB") - } - return p -} - -// PSIGND performs "Packed Sign of Doubleword Integers". -// -// Mnemonic : PSIGND -// Supported forms : (4 forms) -// -// * PSIGND mm, mm [SSSE3] -// * PSIGND m64, mm [SSSE3] -// * PSIGND xmm, xmm [SSSE3] -// * PSIGND m128, xmm [SSSE3] -// -func (self *Program) PSIGND(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSIGND", 2, Operands { v0, v1 }) - // PSIGND mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x0a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSIGND m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x0a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSIGND xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x0a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSIGND m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x0a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSIGND") - } - return p -} - -// PSIGNW performs "Packed Sign of Word Integers". -// -// Mnemonic : PSIGNW -// Supported forms : (4 forms) -// -// * PSIGNW mm, mm [SSSE3] -// * PSIGNW m64, mm [SSSE3] -// * PSIGNW xmm, xmm [SSSE3] -// * PSIGNW m128, xmm [SSSE3] -// -func (self *Program) PSIGNW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSIGNW", 2, Operands { v0, v1 }) - // PSIGNW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x09) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSIGNW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x09) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSIGNW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x09) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSIGNW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSSE3) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x09) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSIGNW") - } - return p -} - -// PSLLD performs "Shift Packed Doubleword Data Left Logical". -// -// Mnemonic : PSLLD -// Supported forms : (6 forms) -// -// * PSLLD imm8, mm [MMX] -// * PSLLD mm, mm [MMX] -// * PSLLD m64, mm [MMX] -// * PSLLD imm8, xmm [SSE2] -// * PSLLD xmm, xmm [SSE2] -// * PSLLD m128, xmm [SSE2] -// -func (self *Program) PSLLD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSLLD", 2, Operands { v0, v1 }) - // PSLLD imm8, mm - if isImm8(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x72) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSLLD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf2) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSLLD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf2) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSLLD imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x72) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSLLD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf2) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSLLD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf2) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSLLD") - } - return p -} - -// PSLLDQ performs "Shift Packed Double Quadword Left Logical". -// -// Mnemonic : PSLLDQ -// Supported forms : (1 form) -// -// * PSLLDQ imm8, xmm [SSE2] -// -func (self *Program) PSLLDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSLLDQ", 2, Operands { v0, v1 }) - // PSLLDQ imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x73) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PSLLDQ") - } - return p -} - -// PSLLQ performs "Shift Packed Quadword Data Left Logical". -// -// Mnemonic : PSLLQ -// Supported forms : (6 forms) -// -// * PSLLQ imm8, mm [MMX] -// * PSLLQ mm, mm [MMX] -// * PSLLQ m64, mm [MMX] -// * PSLLQ imm8, xmm [SSE2] -// * PSLLQ xmm, xmm [SSE2] -// * PSLLQ m128, xmm [SSE2] -// -func (self *Program) PSLLQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSLLQ", 2, Operands { v0, v1 }) - // PSLLQ imm8, mm - if isImm8(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x73) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSLLQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf3) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSLLQ m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf3) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSLLQ imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x73) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSLLQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf3) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSLLQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf3) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSLLQ") - } - return p -} - -// PSLLW performs "Shift Packed Word Data Left Logical". -// -// Mnemonic : PSLLW -// Supported forms : (6 forms) -// -// * PSLLW imm8, mm [MMX] -// * PSLLW mm, mm [MMX] -// * PSLLW m64, mm [MMX] -// * PSLLW imm8, xmm [SSE2] -// * PSLLW xmm, xmm [SSE2] -// * PSLLW m128, xmm [SSE2] -// -func (self *Program) PSLLW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSLLW", 2, Operands { v0, v1 }) - // PSLLW imm8, mm - if isImm8(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x71) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSLLW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSLLW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSLLW imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x71) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSLLW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSLLW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSLLW") - } - return p -} - -// PSRAD performs "Shift Packed Doubleword Data Right Arithmetic". -// -// Mnemonic : PSRAD -// Supported forms : (6 forms) -// -// * PSRAD imm8, mm [MMX] -// * PSRAD mm, mm [MMX] -// * PSRAD m64, mm [MMX] -// * PSRAD imm8, xmm [SSE2] -// * PSRAD xmm, xmm [SSE2] -// * PSRAD m128, xmm [SSE2] -// -func (self *Program) PSRAD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSRAD", 2, Operands { v0, v1 }) - // PSRAD imm8, mm - if isImm8(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRAD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRAD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe2) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSRAD imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRAD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRAD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe2) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSRAD") - } - return p -} - -// PSRAW performs "Shift Packed Word Data Right Arithmetic". -// -// Mnemonic : PSRAW -// Supported forms : (6 forms) -// -// * PSRAW imm8, mm [MMX] -// * PSRAW mm, mm [MMX] -// * PSRAW m64, mm [MMX] -// * PSRAW imm8, xmm [SSE2] -// * PSRAW xmm, xmm [SSE2] -// * PSRAW m128, xmm [SSE2] -// -func (self *Program) PSRAW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSRAW", 2, Operands { v0, v1 }) - // PSRAW imm8, mm - if isImm8(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x71) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRAW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRAW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSRAW imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x71) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRAW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRAW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSRAW") - } - return p -} - -// PSRLD performs "Shift Packed Doubleword Data Right Logical". -// -// Mnemonic : PSRLD -// Supported forms : (6 forms) -// -// * PSRLD imm8, mm [MMX] -// * PSRLD mm, mm [MMX] -// * PSRLD m64, mm [MMX] -// * PSRLD imm8, xmm [SSE2] -// * PSRLD xmm, xmm [SSE2] -// * PSRLD m128, xmm [SSE2] -// -func (self *Program) PSRLD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSRLD", 2, Operands { v0, v1 }) - // PSRLD imm8, mm - if isImm8(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x72) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRLD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd2) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRLD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd2) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSRLD imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x72) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRLD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd2) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRLD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd2) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSRLD") - } - return p -} - -// PSRLDQ performs "Shift Packed Double Quadword Right Logical". -// -// Mnemonic : PSRLDQ -// Supported forms : (1 form) -// -// * PSRLDQ imm8, xmm [SSE2] -// -func (self *Program) PSRLDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSRLDQ", 2, Operands { v0, v1 }) - // PSRLDQ imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x73) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for PSRLDQ") - } - return p -} - -// PSRLQ performs "Shift Packed Quadword Data Right Logical". -// -// Mnemonic : PSRLQ -// Supported forms : (6 forms) -// -// * PSRLQ imm8, mm [MMX] -// * PSRLQ mm, mm [MMX] -// * PSRLQ m64, mm [MMX] -// * PSRLQ imm8, xmm [SSE2] -// * PSRLQ xmm, xmm [SSE2] -// * PSRLQ m128, xmm [SSE2] -// -func (self *Program) PSRLQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSRLQ", 2, Operands { v0, v1 }) - // PSRLQ imm8, mm - if isImm8(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x73) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRLQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRLQ m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd3) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSRLQ imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x73) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRLQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRLQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd3) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSRLQ") - } - return p -} - -// PSRLW performs "Shift Packed Word Data Right Logical". -// -// Mnemonic : PSRLW -// Supported forms : (6 forms) -// -// * PSRLW imm8, mm [MMX] -// * PSRLW mm, mm [MMX] -// * PSRLW m64, mm [MMX] -// * PSRLW imm8, xmm [SSE2] -// * PSRLW xmm, xmm [SSE2] -// * PSRLW m128, xmm [SSE2] -// -func (self *Program) PSRLW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSRLW", 2, Operands { v0, v1 }) - // PSRLW imm8, mm - if isImm8(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x71) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRLW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRLW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSRLW imm8, xmm - if isImm8(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x0f) - m.emit(0x71) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // PSRLW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSRLW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSRLW") - } - return p -} - -// PSUBB performs "Subtract Packed Byte Integers". -// -// Mnemonic : PSUBB -// Supported forms : (4 forms) -// -// * PSUBB mm, mm [MMX] -// * PSUBB m64, mm [MMX] -// * PSUBB xmm, xmm [SSE2] -// * PSUBB m128, xmm [SSE2] -// -func (self *Program) PSUBB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSUBB", 2, Operands { v0, v1 }) - // PSUBB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSUBB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSUBB") - } - return p -} - -// PSUBD performs "Subtract Packed Doubleword Integers". -// -// Mnemonic : PSUBD -// Supported forms : (4 forms) -// -// * PSUBD mm, mm [MMX] -// * PSUBD m64, mm [MMX] -// * PSUBD xmm, xmm [SSE2] -// * PSUBD m128, xmm [SSE2] -// -func (self *Program) PSUBD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSUBD", 2, Operands { v0, v1 }) - // PSUBD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfa) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfa) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSUBD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfa) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfa) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSUBD") - } - return p -} - -// PSUBQ performs "Subtract Packed Quadword Integers". -// -// Mnemonic : PSUBQ -// Supported forms : (4 forms) -// -// * PSUBQ mm, mm [SSE2] -// * PSUBQ m64, mm [SSE2] -// * PSUBQ xmm, xmm [SSE2] -// * PSUBQ m128, xmm [SSE2] -// -func (self *Program) PSUBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSUBQ", 2, Operands { v0, v1 }) - // PSUBQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBQ m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSUBQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xfb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xfb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSUBQ") - } - return p -} - -// PSUBSB performs "Subtract Packed Signed Byte Integers with Signed Saturation". -// -// Mnemonic : PSUBSB -// Supported forms : (4 forms) -// -// * PSUBSB mm, mm [MMX] -// * PSUBSB m64, mm [MMX] -// * PSUBSB xmm, xmm [SSE2] -// * PSUBSB m128, xmm [SSE2] -// -func (self *Program) PSUBSB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSUBSB", 2, Operands { v0, v1 }) - // PSUBSB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBSB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSUBSB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBSB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSUBSB") - } - return p -} - -// PSUBSW performs "Subtract Packed Signed Word Integers with Signed Saturation". -// -// Mnemonic : PSUBSW -// Supported forms : (4 forms) -// -// * PSUBSW mm, mm [MMX] -// * PSUBSW m64, mm [MMX] -// * PSUBSW xmm, xmm [SSE2] -// * PSUBSW m128, xmm [SSE2] -// -func (self *Program) PSUBSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSUBSW", 2, Operands { v0, v1 }) - // PSUBSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe9) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe9) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSUBSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xe9) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xe9) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSUBSW") - } - return p -} - -// PSUBUSB performs "Subtract Packed Unsigned Byte Integers with Unsigned Saturation". -// -// Mnemonic : PSUBUSB -// Supported forms : (4 forms) -// -// * PSUBUSB mm, mm [MMX] -// * PSUBUSB m64, mm [MMX] -// * PSUBUSB xmm, xmm [SSE2] -// * PSUBUSB m128, xmm [SSE2] -// -func (self *Program) PSUBUSB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSUBUSB", 2, Operands { v0, v1 }) - // PSUBUSB mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBUSB m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSUBUSB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBUSB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSUBUSB") - } - return p -} - -// PSUBUSW performs "Subtract Packed Unsigned Word Integers with Unsigned Saturation". -// -// Mnemonic : PSUBUSW -// Supported forms : (4 forms) -// -// * PSUBUSW mm, mm [MMX] -// * PSUBUSW m64, mm [MMX] -// * PSUBUSW xmm, xmm [SSE2] -// * PSUBUSW m128, xmm [SSE2] -// -func (self *Program) PSUBUSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSUBUSW", 2, Operands { v0, v1 }) - // PSUBUSW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd9) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBUSW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd9) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSUBUSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xd9) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBUSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xd9) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSUBUSW") - } - return p -} - -// PSUBW performs "Subtract Packed Word Integers". -// -// Mnemonic : PSUBW -// Supported forms : (4 forms) -// -// * PSUBW mm, mm [MMX] -// * PSUBW m64, mm [MMX] -// * PSUBW xmm, xmm [SSE2] -// * PSUBW m128, xmm [SSE2] -// -func (self *Program) PSUBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSUBW", 2, Operands { v0, v1 }) - // PSUBW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf9) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf9) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PSUBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xf9) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PSUBW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xf9) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PSUBW") - } - return p -} - -// PSWAPD performs "Packed Swap Doubleword". -// -// Mnemonic : PSWAPD -// Supported forms : (2 forms) -// -// * PSWAPD mm, mm [3dnow!+] -// * PSWAPD m64, mm [3dnow!+] -// -func (self *Program) PSWAPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PSWAPD", 2, Operands { v0, v1 }) - // PSWAPD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - m.emit(0xbb) - }) - } - // PSWAPD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_3DNOW_PLUS) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - m.emit(0xbb) - }) - } - if p.len == 0 { - panic("invalid operands for PSWAPD") - } - return p -} - -// PTEST performs "Packed Logical Compare". -// -// Mnemonic : PTEST -// Supported forms : (2 forms) -// -// * PTEST xmm, xmm [SSE4.1] -// * PTEST m128, xmm [SSE4.1] -// -func (self *Program) PTEST(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PTEST", 2, Operands { v0, v1 }) - // PTEST xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x17) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PTEST m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0x17) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PTEST") - } - return p -} - -// PUNPCKHBW performs "Unpack and Interleave High-Order Bytes into Words". -// -// Mnemonic : PUNPCKHBW -// Supported forms : (4 forms) -// -// * PUNPCKHBW mm, mm [MMX] -// * PUNPCKHBW m64, mm [MMX] -// * PUNPCKHBW xmm, xmm [SSE2] -// * PUNPCKHBW m128, xmm [SSE2] -// -func (self *Program) PUNPCKHBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PUNPCKHBW", 2, Operands { v0, v1 }) - // PUNPCKHBW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x68) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKHBW m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x68) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PUNPCKHBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x68) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKHBW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x68) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUNPCKHBW") - } - return p -} - -// PUNPCKHDQ performs "Unpack and Interleave High-Order Doublewords into Quadwords". -// -// Mnemonic : PUNPCKHDQ -// Supported forms : (4 forms) -// -// * PUNPCKHDQ mm, mm [MMX] -// * PUNPCKHDQ m64, mm [MMX] -// * PUNPCKHDQ xmm, xmm [SSE2] -// * PUNPCKHDQ m128, xmm [SSE2] -// -func (self *Program) PUNPCKHDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PUNPCKHDQ", 2, Operands { v0, v1 }) - // PUNPCKHDQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKHDQ m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PUNPCKHDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKHDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUNPCKHDQ") - } - return p -} - -// PUNPCKHQDQ performs "Unpack and Interleave High-Order Quadwords into Double Quadwords". -// -// Mnemonic : PUNPCKHQDQ -// Supported forms : (2 forms) -// -// * PUNPCKHQDQ xmm, xmm [SSE2] -// * PUNPCKHQDQ m128, xmm [SSE2] -// -func (self *Program) PUNPCKHQDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PUNPCKHQDQ", 2, Operands { v0, v1 }) - // PUNPCKHQDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKHQDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUNPCKHQDQ") - } - return p -} - -// PUNPCKHWD performs "Unpack and Interleave High-Order Words into Doublewords". -// -// Mnemonic : PUNPCKHWD -// Supported forms : (4 forms) -// -// * PUNPCKHWD mm, mm [MMX] -// * PUNPCKHWD m64, mm [MMX] -// * PUNPCKHWD xmm, xmm [SSE2] -// * PUNPCKHWD m128, xmm [SSE2] -// -func (self *Program) PUNPCKHWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PUNPCKHWD", 2, Operands { v0, v1 }) - // PUNPCKHWD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x69) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKHWD m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x69) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PUNPCKHWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x69) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKHWD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x69) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUNPCKHWD") - } - return p -} - -// PUNPCKLBW performs "Unpack and Interleave Low-Order Bytes into Words". -// -// Mnemonic : PUNPCKLBW -// Supported forms : (4 forms) -// -// * PUNPCKLBW mm, mm [MMX] -// * PUNPCKLBW m32, mm [MMX] -// * PUNPCKLBW xmm, xmm [SSE2] -// * PUNPCKLBW m128, xmm [SSE2] -// -func (self *Program) PUNPCKLBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PUNPCKLBW", 2, Operands { v0, v1 }) - // PUNPCKLBW mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x60) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKLBW m32, mm - if isM32(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x60) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PUNPCKLBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x60) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKLBW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x60) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUNPCKLBW") - } - return p -} - -// PUNPCKLDQ performs "Unpack and Interleave Low-Order Doublewords into Quadwords". -// -// Mnemonic : PUNPCKLDQ -// Supported forms : (4 forms) -// -// * PUNPCKLDQ mm, mm [MMX] -// * PUNPCKLDQ m32, mm [MMX] -// * PUNPCKLDQ xmm, xmm [SSE2] -// * PUNPCKLDQ m128, xmm [SSE2] -// -func (self *Program) PUNPCKLDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PUNPCKLDQ", 2, Operands { v0, v1 }) - // PUNPCKLDQ mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x62) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKLDQ m32, mm - if isM32(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x62) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PUNPCKLDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x62) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKLDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x62) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUNPCKLDQ") - } - return p -} - -// PUNPCKLQDQ performs "Unpack and Interleave Low-Order Quadwords into Double Quadwords". -// -// Mnemonic : PUNPCKLQDQ -// Supported forms : (2 forms) -// -// * PUNPCKLQDQ xmm, xmm [SSE2] -// * PUNPCKLQDQ m128, xmm [SSE2] -// -func (self *Program) PUNPCKLQDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PUNPCKLQDQ", 2, Operands { v0, v1 }) - // PUNPCKLQDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKLQDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x6c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUNPCKLQDQ") - } - return p -} - -// PUNPCKLWD performs "Unpack and Interleave Low-Order Words into Doublewords". -// -// Mnemonic : PUNPCKLWD -// Supported forms : (4 forms) -// -// * PUNPCKLWD mm, mm [MMX] -// * PUNPCKLWD m32, mm [MMX] -// * PUNPCKLWD xmm, xmm [SSE2] -// * PUNPCKLWD m128, xmm [SSE2] -// -func (self *Program) PUNPCKLWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PUNPCKLWD", 2, Operands { v0, v1 }) - // PUNPCKLWD mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x61) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKLWD m32, mm - if isM32(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x61) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PUNPCKLWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x61) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PUNPCKLWD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x61) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUNPCKLWD") - } - return p -} - -// PUSHQ performs "Push Value Onto the Stack". -// -// Mnemonic : PUSH -// Supported forms : (4 forms) -// -// * PUSHQ imm8 -// * PUSHQ imm32 -// * PUSHQ r64 -// * PUSHQ m64 -// -func (self *Program) PUSHQ(v0 interface{}) *Instruction { - p := self.alloc("PUSHQ", 1, Operands { v0 }) - // PUSHQ imm8 - if isImm8Ext(v0, 8) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x6a) - m.imm1(toImmAny(v[0])) - }) - } - // PUSHQ imm32 - if isImm32Ext(v0, 8) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x68) - m.imm4(toImmAny(v[0])) - }) - } - // PUSHQ r64 - if isReg64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0x50 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0xff) - m.emit(0xf0 | lcode(v[0])) - }) - } - // PUSHQ m64 - if isM64(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0xff) - m.mrsd(6, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUSHQ") - } - return p -} - -// PUSHW performs "Push Value Onto the Stack". -// -// Mnemonic : PUSH -// Supported forms : (2 forms) -// -// * PUSHW r16 -// * PUSHW m16 -// -func (self *Program) PUSHW(v0 interface{}) *Instruction { - p := self.alloc("PUSHW", 1, Operands { v0 }) - // PUSHW r16 - if isReg16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0x50 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0xff) - m.emit(0xf0 | lcode(v[0])) - }) - } - // PUSHW m16 - if isM16(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[0]), false) - m.emit(0xff) - m.mrsd(6, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PUSHW") - } - return p -} - -// PXOR performs "Packed Bitwise Logical Exclusive OR". -// -// Mnemonic : PXOR -// Supported forms : (4 forms) -// -// * PXOR mm, mm [MMX] -// * PXOR m64, mm [MMX] -// * PXOR xmm, xmm [SSE2] -// * PXOR m128, xmm [SSE2] -// -func (self *Program) PXOR(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("PXOR", 2, Operands { v0, v1 }) - // PXOR mm, mm - if isMM(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xef) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PXOR m64, mm - if isM64(v0) && isMM(v1) { - self.require(ISA_MMX) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xef) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // PXOR xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xef) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // PXOR m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xef) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for PXOR") - } - return p -} - -// RCLB performs "Rotate Left through Carry Flag". -// -// Mnemonic : RCL -// Supported forms : (6 forms) -// -// * RCLB 1, r8 -// * RCLB imm8, r8 -// * RCLB cl, r8 -// * RCLB 1, m8 -// * RCLB imm8, m8 -// * RCLB cl, m8 -// -func (self *Program) RCLB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCLB", 2, Operands { v0, v1 }) - // RCLB 1, r8 - if isConst1(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd0) - m.emit(0xd0 | lcode(v[1])) - }) - } - // RCLB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xc0) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RCLB cl, r8 - if v0 == CL && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd2) - m.emit(0xd0 | lcode(v[1])) - }) - } - // RCLB 1, m8 - if isConst1(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd0) - m.mrsd(2, addr(v[1]), 1) - }) - } - // RCLB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc0) - m.mrsd(2, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RCLB cl, m8 - if v0 == CL && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd2) - m.mrsd(2, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCLB") - } - return p -} - -// RCLL performs "Rotate Left through Carry Flag". -// -// Mnemonic : RCL -// Supported forms : (6 forms) -// -// * RCLL 1, r32 -// * RCLL imm8, r32 -// * RCLL cl, r32 -// * RCLL 1, m32 -// * RCLL imm8, m32 -// * RCLL cl, m32 -// -func (self *Program) RCLL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCLL", 2, Operands { v0, v1 }) - // RCLL 1, r32 - if isConst1(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xd0 | lcode(v[1])) - }) - } - // RCLL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RCLL cl, r32 - if v0 == CL && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xd0 | lcode(v[1])) - }) - } - // RCLL 1, m32 - if isConst1(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(2, addr(v[1]), 1) - }) - } - // RCLL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(2, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RCLL cl, m32 - if v0 == CL && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(2, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCLL") - } - return p -} - -// RCLQ performs "Rotate Left through Carry Flag". -// -// Mnemonic : RCL -// Supported forms : (6 forms) -// -// * RCLQ 1, r64 -// * RCLQ imm8, r64 -// * RCLQ cl, r64 -// * RCLQ 1, m64 -// * RCLQ imm8, m64 -// * RCLQ cl, m64 -// -func (self *Program) RCLQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCLQ", 2, Operands { v0, v1 }) - // RCLQ 1, r64 - if isConst1(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd1) - m.emit(0xd0 | lcode(v[1])) - }) - } - // RCLQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xc1) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RCLQ cl, r64 - if v0 == CL && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd3) - m.emit(0xd0 | lcode(v[1])) - }) - } - // RCLQ 1, m64 - if isConst1(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd1) - m.mrsd(2, addr(v[1]), 1) - }) - } - // RCLQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xc1) - m.mrsd(2, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RCLQ cl, m64 - if v0 == CL && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd3) - m.mrsd(2, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCLQ") - } - return p -} - -// RCLW performs "Rotate Left through Carry Flag". -// -// Mnemonic : RCL -// Supported forms : (6 forms) -// -// * RCLW 1, r16 -// * RCLW imm8, r16 -// * RCLW cl, r16 -// * RCLW 1, m16 -// * RCLW imm8, m16 -// * RCLW cl, m16 -// -func (self *Program) RCLW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCLW", 2, Operands { v0, v1 }) - // RCLW 1, r16 - if isConst1(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xd0 | lcode(v[1])) - }) - } - // RCLW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RCLW cl, r16 - if v0 == CL && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xd0 | lcode(v[1])) - }) - } - // RCLW 1, m16 - if isConst1(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(2, addr(v[1]), 1) - }) - } - // RCLW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(2, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RCLW cl, m16 - if v0 == CL && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(2, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCLW") - } - return p -} - -// RCPPS performs "Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : RCPPS -// Supported forms : (2 forms) -// -// * RCPPS xmm, xmm [SSE] -// * RCPPS m128, xmm [SSE] -// -func (self *Program) RCPPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCPPS", 2, Operands { v0, v1 }) - // RCPPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x53) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // RCPPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x53) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCPPS") - } - return p -} - -// RCPSS performs "Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : RCPSS -// Supported forms : (2 forms) -// -// * RCPSS xmm, xmm [SSE] -// * RCPSS m32, xmm [SSE] -// -func (self *Program) RCPSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCPSS", 2, Operands { v0, v1 }) - // RCPSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x53) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // RCPSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x53) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCPSS") - } - return p -} - -// RCRB performs "Rotate Right through Carry Flag". -// -// Mnemonic : RCR -// Supported forms : (6 forms) -// -// * RCRB 1, r8 -// * RCRB imm8, r8 -// * RCRB cl, r8 -// * RCRB 1, m8 -// * RCRB imm8, m8 -// * RCRB cl, m8 -// -func (self *Program) RCRB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCRB", 2, Operands { v0, v1 }) - // RCRB 1, r8 - if isConst1(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd0) - m.emit(0xd8 | lcode(v[1])) - }) - } - // RCRB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xc0) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RCRB cl, r8 - if v0 == CL && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd2) - m.emit(0xd8 | lcode(v[1])) - }) - } - // RCRB 1, m8 - if isConst1(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd0) - m.mrsd(3, addr(v[1]), 1) - }) - } - // RCRB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc0) - m.mrsd(3, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RCRB cl, m8 - if v0 == CL && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd2) - m.mrsd(3, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCRB") - } - return p -} - -// RCRL performs "Rotate Right through Carry Flag". -// -// Mnemonic : RCR -// Supported forms : (6 forms) -// -// * RCRL 1, r32 -// * RCRL imm8, r32 -// * RCRL cl, r32 -// * RCRL 1, m32 -// * RCRL imm8, m32 -// * RCRL cl, m32 -// -func (self *Program) RCRL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCRL", 2, Operands { v0, v1 }) - // RCRL 1, r32 - if isConst1(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xd8 | lcode(v[1])) - }) - } - // RCRL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RCRL cl, r32 - if v0 == CL && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xd8 | lcode(v[1])) - }) - } - // RCRL 1, m32 - if isConst1(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(3, addr(v[1]), 1) - }) - } - // RCRL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(3, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RCRL cl, m32 - if v0 == CL && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(3, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCRL") - } - return p -} - -// RCRQ performs "Rotate Right through Carry Flag". -// -// Mnemonic : RCR -// Supported forms : (6 forms) -// -// * RCRQ 1, r64 -// * RCRQ imm8, r64 -// * RCRQ cl, r64 -// * RCRQ 1, m64 -// * RCRQ imm8, m64 -// * RCRQ cl, m64 -// -func (self *Program) RCRQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCRQ", 2, Operands { v0, v1 }) - // RCRQ 1, r64 - if isConst1(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd1) - m.emit(0xd8 | lcode(v[1])) - }) - } - // RCRQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xc1) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RCRQ cl, r64 - if v0 == CL && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd3) - m.emit(0xd8 | lcode(v[1])) - }) - } - // RCRQ 1, m64 - if isConst1(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd1) - m.mrsd(3, addr(v[1]), 1) - }) - } - // RCRQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xc1) - m.mrsd(3, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RCRQ cl, m64 - if v0 == CL && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd3) - m.mrsd(3, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCRQ") - } - return p -} - -// RCRW performs "Rotate Right through Carry Flag". -// -// Mnemonic : RCR -// Supported forms : (6 forms) -// -// * RCRW 1, r16 -// * RCRW imm8, r16 -// * RCRW cl, r16 -// * RCRW 1, m16 -// * RCRW imm8, m16 -// * RCRW cl, m16 -// -func (self *Program) RCRW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RCRW", 2, Operands { v0, v1 }) - // RCRW 1, r16 - if isConst1(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xd8 | lcode(v[1])) - }) - } - // RCRW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RCRW cl, r16 - if v0 == CL && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xd8 | lcode(v[1])) - }) - } - // RCRW 1, m16 - if isConst1(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(3, addr(v[1]), 1) - }) - } - // RCRW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(3, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RCRW cl, m16 - if v0 == CL && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(3, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RCRW") - } - return p -} - -// RDRAND performs "Read Random Number". -// -// Mnemonic : RDRAND -// Supported forms : (3 forms) -// -// * RDRAND r16 [RDRAND] -// * RDRAND r32 [RDRAND] -// * RDRAND r64 [RDRAND] -// -func (self *Program) RDRAND(v0 interface{}) *Instruction { - p := self.alloc("RDRAND", 1, Operands { v0 }) - // RDRAND r16 - if isReg16(v0) { - self.require(ISA_RDRAND) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0x0f) - m.emit(0xc7) - m.emit(0xf0 | lcode(v[0])) - }) - } - // RDRAND r32 - if isReg32(v0) { - self.require(ISA_RDRAND) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0x0f) - m.emit(0xc7) - m.emit(0xf0 | lcode(v[0])) - }) - } - // RDRAND r64 - if isReg64(v0) { - self.require(ISA_RDRAND) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xc7) - m.emit(0xf0 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for RDRAND") - } - return p -} - -// RDSEED performs "Read Random SEED". -// -// Mnemonic : RDSEED -// Supported forms : (3 forms) -// -// * RDSEED r16 [RDSEED] -// * RDSEED r32 [RDSEED] -// * RDSEED r64 [RDSEED] -// -func (self *Program) RDSEED(v0 interface{}) *Instruction { - p := self.alloc("RDSEED", 1, Operands { v0 }) - // RDSEED r16 - if isReg16(v0) { - self.require(ISA_RDSEED) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0x0f) - m.emit(0xc7) - m.emit(0xf8 | lcode(v[0])) - }) - } - // RDSEED r32 - if isReg32(v0) { - self.require(ISA_RDSEED) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0x0f) - m.emit(0xc7) - m.emit(0xf8 | lcode(v[0])) - }) - } - // RDSEED r64 - if isReg64(v0) { - self.require(ISA_RDSEED) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xc7) - m.emit(0xf8 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for RDSEED") - } - return p -} - -// RDTSC performs "Read Time-Stamp Counter". -// -// Mnemonic : RDTSC -// Supported forms : (1 form) -// -// * RDTSC [RDTSC] -// -func (self *Program) RDTSC() *Instruction { - p := self.alloc("RDTSC", 0, Operands { }) - // RDTSC - self.require(ISA_RDTSC) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x31) - }) - return p -} - -// RDTSCP performs "Read Time-Stamp Counter and Processor ID". -// -// Mnemonic : RDTSCP -// Supported forms : (1 form) -// -// * RDTSCP [RDTSCP] -// -func (self *Program) RDTSCP() *Instruction { - p := self.alloc("RDTSCP", 0, Operands { }) - // RDTSCP - self.require(ISA_RDTSCP) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x01) - m.emit(0xf9) - }) - return p -} - -// RET performs "Return from Procedure". -// -// Mnemonic : RET -// Supported forms : (2 forms) -// -// * RET -// * RET imm16 -// -func (self *Program) RET(vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("RET", 0, Operands { }) - case 1 : p = self.alloc("RET", 1, Operands { vv[0] }) - default : panic("instruction RET takes 0 or 1 operands") - } - // RET - if len(vv) == 0 { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc3) - }) - } - // RET imm16 - if len(vv) == 1 && isImm16(vv[0]) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc2) - m.imm2(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for RET") - } - return p -} - -// ROLB performs "Rotate Left". -// -// Mnemonic : ROL -// Supported forms : (6 forms) -// -// * ROLB 1, r8 -// * ROLB imm8, r8 -// * ROLB cl, r8 -// * ROLB 1, m8 -// * ROLB imm8, m8 -// * ROLB cl, m8 -// -func (self *Program) ROLB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ROLB", 2, Operands { v0, v1 }) - // ROLB 1, r8 - if isConst1(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd0) - m.emit(0xc0 | lcode(v[1])) - }) - } - // ROLB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xc0) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ROLB cl, r8 - if v0 == CL && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd2) - m.emit(0xc0 | lcode(v[1])) - }) - } - // ROLB 1, m8 - if isConst1(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd0) - m.mrsd(0, addr(v[1]), 1) - }) - } - // ROLB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc0) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ROLB cl, m8 - if v0 == CL && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd2) - m.mrsd(0, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ROLB") - } - return p -} - -// ROLL performs "Rotate Left". -// -// Mnemonic : ROL -// Supported forms : (6 forms) -// -// * ROLL 1, r32 -// * ROLL imm8, r32 -// * ROLL cl, r32 -// * ROLL 1, m32 -// * ROLL imm8, m32 -// * ROLL cl, m32 -// -func (self *Program) ROLL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ROLL", 2, Operands { v0, v1 }) - // ROLL 1, r32 - if isConst1(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[1])) - }) - } - // ROLL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ROLL cl, r32 - if v0 == CL && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[1])) - }) - } - // ROLL 1, m32 - if isConst1(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(0, addr(v[1]), 1) - }) - } - // ROLL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ROLL cl, m32 - if v0 == CL && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(0, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ROLL") - } - return p -} - -// ROLQ performs "Rotate Left". -// -// Mnemonic : ROL -// Supported forms : (6 forms) -// -// * ROLQ 1, r64 -// * ROLQ imm8, r64 -// * ROLQ cl, r64 -// * ROLQ 1, m64 -// * ROLQ imm8, m64 -// * ROLQ cl, m64 -// -func (self *Program) ROLQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ROLQ", 2, Operands { v0, v1 }) - // ROLQ 1, r64 - if isConst1(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[1])) - }) - } - // ROLQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xc1) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ROLQ cl, r64 - if v0 == CL && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[1])) - }) - } - // ROLQ 1, m64 - if isConst1(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd1) - m.mrsd(0, addr(v[1]), 1) - }) - } - // ROLQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xc1) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ROLQ cl, m64 - if v0 == CL && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd3) - m.mrsd(0, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ROLQ") - } - return p -} - -// ROLW performs "Rotate Left". -// -// Mnemonic : ROL -// Supported forms : (6 forms) -// -// * ROLW 1, r16 -// * ROLW imm8, r16 -// * ROLW cl, r16 -// * ROLW 1, m16 -// * ROLW imm8, m16 -// * ROLW cl, m16 -// -func (self *Program) ROLW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("ROLW", 2, Operands { v0, v1 }) - // ROLW 1, r16 - if isConst1(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[1])) - }) - } - // ROLW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ROLW cl, r16 - if v0 == CL && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[1])) - }) - } - // ROLW 1, m16 - if isConst1(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(0, addr(v[1]), 1) - }) - } - // ROLW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // ROLW cl, m16 - if v0 == CL && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(0, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for ROLW") - } - return p -} - -// RORB performs "Rotate Right". -// -// Mnemonic : ROR -// Supported forms : (6 forms) -// -// * RORB 1, r8 -// * RORB imm8, r8 -// * RORB cl, r8 -// * RORB 1, m8 -// * RORB imm8, m8 -// * RORB cl, m8 -// -func (self *Program) RORB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RORB", 2, Operands { v0, v1 }) - // RORB 1, r8 - if isConst1(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd0) - m.emit(0xc8 | lcode(v[1])) - }) - } - // RORB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xc0) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RORB cl, r8 - if v0 == CL && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd2) - m.emit(0xc8 | lcode(v[1])) - }) - } - // RORB 1, m8 - if isConst1(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd0) - m.mrsd(1, addr(v[1]), 1) - }) - } - // RORB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc0) - m.mrsd(1, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RORB cl, m8 - if v0 == CL && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd2) - m.mrsd(1, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RORB") - } - return p -} - -// RORL performs "Rotate Right". -// -// Mnemonic : ROR -// Supported forms : (6 forms) -// -// * RORL 1, r32 -// * RORL imm8, r32 -// * RORL cl, r32 -// * RORL 1, m32 -// * RORL imm8, m32 -// * RORL cl, m32 -// -func (self *Program) RORL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RORL", 2, Operands { v0, v1 }) - // RORL 1, r32 - if isConst1(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xc8 | lcode(v[1])) - }) - } - // RORL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RORL cl, r32 - if v0 == CL && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xc8 | lcode(v[1])) - }) - } - // RORL 1, m32 - if isConst1(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(1, addr(v[1]), 1) - }) - } - // RORL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(1, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RORL cl, m32 - if v0 == CL && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(1, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RORL") - } - return p -} - -// RORQ performs "Rotate Right". -// -// Mnemonic : ROR -// Supported forms : (6 forms) -// -// * RORQ 1, r64 -// * RORQ imm8, r64 -// * RORQ cl, r64 -// * RORQ 1, m64 -// * RORQ imm8, m64 -// * RORQ cl, m64 -// -func (self *Program) RORQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RORQ", 2, Operands { v0, v1 }) - // RORQ 1, r64 - if isConst1(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd1) - m.emit(0xc8 | lcode(v[1])) - }) - } - // RORQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xc1) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RORQ cl, r64 - if v0 == CL && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd3) - m.emit(0xc8 | lcode(v[1])) - }) - } - // RORQ 1, m64 - if isConst1(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd1) - m.mrsd(1, addr(v[1]), 1) - }) - } - // RORQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xc1) - m.mrsd(1, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RORQ cl, m64 - if v0 == CL && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd3) - m.mrsd(1, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RORQ") - } - return p -} - -// RORW performs "Rotate Right". -// -// Mnemonic : ROR -// Supported forms : (6 forms) -// -// * RORW 1, r16 -// * RORW imm8, r16 -// * RORW cl, r16 -// * RORW 1, m16 -// * RORW imm8, m16 -// * RORW cl, m16 -// -func (self *Program) RORW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RORW", 2, Operands { v0, v1 }) - // RORW 1, r16 - if isConst1(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xc8 | lcode(v[1])) - }) - } - // RORW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RORW cl, r16 - if v0 == CL && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xc8 | lcode(v[1])) - }) - } - // RORW 1, m16 - if isConst1(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(1, addr(v[1]), 1) - }) - } - // RORW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(1, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // RORW cl, m16 - if v0 == CL && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(1, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RORW") - } - return p -} - -// RORXL performs "Rotate Right Logical Without Affecting Flags". -// -// Mnemonic : RORX -// Supported forms : (2 forms) -// -// * RORXL imm8, r32, r32 [BMI2] -// * RORXL imm8, m32, r32 [BMI2] -// -func (self *Program) RORXL(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("RORXL", 3, Operands { v0, v1, v2 }) - // RORXL imm8, r32, r32 - if isImm8(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7b) - m.emit(0xf0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RORXL imm8, m32, r32 - if isImm8(v0) && isM32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x03, hcode(v[2]), addr(v[1]), 0) - m.emit(0xf0) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for RORXL") - } - return p -} - -// RORXQ performs "Rotate Right Logical Without Affecting Flags". -// -// Mnemonic : RORX -// Supported forms : (2 forms) -// -// * RORXQ imm8, r64, r64 [BMI2] -// * RORXQ imm8, m64, r64 [BMI2] -// -func (self *Program) RORXQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("RORXQ", 3, Operands { v0, v1, v2 }) - // RORXQ imm8, r64, r64 - if isImm8(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xfb) - m.emit(0xf0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // RORXQ imm8, m64, r64 - if isImm8(v0) && isM64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x83, hcode(v[2]), addr(v[1]), 0) - m.emit(0xf0) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for RORXQ") - } - return p -} - -// ROUNDPD performs "Round Packed Double Precision Floating-Point Values". -// -// Mnemonic : ROUNDPD -// Supported forms : (2 forms) -// -// * ROUNDPD imm8, xmm, xmm [SSE4.1] -// * ROUNDPD imm8, m128, xmm [SSE4.1] -// -func (self *Program) ROUNDPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("ROUNDPD", 3, Operands { v0, v1, v2 }) - // ROUNDPD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x09) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ROUNDPD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x09) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for ROUNDPD") - } - return p -} - -// ROUNDPS performs "Round Packed Single Precision Floating-Point Values". -// -// Mnemonic : ROUNDPS -// Supported forms : (2 forms) -// -// * ROUNDPS imm8, xmm, xmm [SSE4.1] -// * ROUNDPS imm8, m128, xmm [SSE4.1] -// -func (self *Program) ROUNDPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("ROUNDPS", 3, Operands { v0, v1, v2 }) - // ROUNDPS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x08) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ROUNDPS imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x08) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for ROUNDPS") - } - return p -} - -// ROUNDSD performs "Round Scalar Double Precision Floating-Point Values". -// -// Mnemonic : ROUNDSD -// Supported forms : (2 forms) -// -// * ROUNDSD imm8, xmm, xmm [SSE4.1] -// * ROUNDSD imm8, m64, xmm [SSE4.1] -// -func (self *Program) ROUNDSD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("ROUNDSD", 3, Operands { v0, v1, v2 }) - // ROUNDSD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ROUNDSD imm8, m64, xmm - if isImm8(v0) && isM64(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0b) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for ROUNDSD") - } - return p -} - -// ROUNDSS performs "Round Scalar Single Precision Floating-Point Values". -// -// Mnemonic : ROUNDSS -// Supported forms : (2 forms) -// -// * ROUNDSS imm8, xmm, xmm [SSE4.1] -// * ROUNDSS imm8, m32, xmm [SSE4.1] -// -func (self *Program) ROUNDSS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("ROUNDSS", 3, Operands { v0, v1, v2 }) - // ROUNDSS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // ROUNDSS imm8, m32, xmm - if isImm8(v0) && isM32(v1) && isXMM(v2) { - self.require(ISA_SSE4_1) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0x0a) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for ROUNDSS") - } - return p -} - -// RSQRTPS performs "Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : RSQRTPS -// Supported forms : (2 forms) -// -// * RSQRTPS xmm, xmm [SSE] -// * RSQRTPS m128, xmm [SSE] -// -func (self *Program) RSQRTPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RSQRTPS", 2, Operands { v0, v1 }) - // RSQRTPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x52) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // RSQRTPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x52) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RSQRTPS") - } - return p -} - -// RSQRTSS performs "Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : RSQRTSS -// Supported forms : (2 forms) -// -// * RSQRTSS xmm, xmm [SSE] -// * RSQRTSS m32, xmm [SSE] -// -func (self *Program) RSQRTSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("RSQRTSS", 2, Operands { v0, v1 }) - // RSQRTSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x52) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // RSQRTSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x52) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for RSQRTSS") - } - return p -} - -// SALB performs "Arithmetic Shift Left". -// -// Mnemonic : SAL -// Supported forms : (6 forms) -// -// * SALB 1, r8 -// * SALB imm8, r8 -// * SALB cl, r8 -// * SALB 1, m8 -// * SALB imm8, m8 -// * SALB cl, m8 -// -func (self *Program) SALB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SALB", 2, Operands { v0, v1 }) - // SALB 1, r8 - if isConst1(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd0) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SALB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xc0) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SALB cl, r8 - if v0 == CL && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd2) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SALB 1, m8 - if isConst1(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd0) - m.mrsd(4, addr(v[1]), 1) - }) - } - // SALB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc0) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SALB cl, m8 - if v0 == CL && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd2) - m.mrsd(4, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SALB") - } - return p -} - -// SALL performs "Arithmetic Shift Left". -// -// Mnemonic : SAL -// Supported forms : (6 forms) -// -// * SALL 1, r32 -// * SALL imm8, r32 -// * SALL cl, r32 -// * SALL 1, m32 -// * SALL imm8, m32 -// * SALL cl, m32 -// -func (self *Program) SALL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SALL", 2, Operands { v0, v1 }) - // SALL 1, r32 - if isConst1(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SALL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SALL cl, r32 - if v0 == CL && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SALL 1, m32 - if isConst1(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(4, addr(v[1]), 1) - }) - } - // SALL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SALL cl, m32 - if v0 == CL && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(4, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SALL") - } - return p -} - -// SALQ performs "Arithmetic Shift Left". -// -// Mnemonic : SAL -// Supported forms : (6 forms) -// -// * SALQ 1, r64 -// * SALQ imm8, r64 -// * SALQ cl, r64 -// * SALQ 1, m64 -// * SALQ imm8, m64 -// * SALQ cl, m64 -// -func (self *Program) SALQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SALQ", 2, Operands { v0, v1 }) - // SALQ 1, r64 - if isConst1(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd1) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SALQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xc1) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SALQ cl, r64 - if v0 == CL && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd3) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SALQ 1, m64 - if isConst1(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd1) - m.mrsd(4, addr(v[1]), 1) - }) - } - // SALQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xc1) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SALQ cl, m64 - if v0 == CL && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd3) - m.mrsd(4, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SALQ") - } - return p -} - -// SALW performs "Arithmetic Shift Left". -// -// Mnemonic : SAL -// Supported forms : (6 forms) -// -// * SALW 1, r16 -// * SALW imm8, r16 -// * SALW cl, r16 -// * SALW 1, m16 -// * SALW imm8, m16 -// * SALW cl, m16 -// -func (self *Program) SALW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SALW", 2, Operands { v0, v1 }) - // SALW 1, r16 - if isConst1(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SALW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SALW cl, r16 - if v0 == CL && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SALW 1, m16 - if isConst1(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(4, addr(v[1]), 1) - }) - } - // SALW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SALW cl, m16 - if v0 == CL && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(4, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SALW") - } - return p -} - -// SARB performs "Arithmetic Shift Right". -// -// Mnemonic : SAR -// Supported forms : (6 forms) -// -// * SARB 1, r8 -// * SARB imm8, r8 -// * SARB cl, r8 -// * SARB 1, m8 -// * SARB imm8, m8 -// * SARB cl, m8 -// -func (self *Program) SARB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SARB", 2, Operands { v0, v1 }) - // SARB 1, r8 - if isConst1(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd0) - m.emit(0xf8 | lcode(v[1])) - }) - } - // SARB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xc0) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SARB cl, r8 - if v0 == CL && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd2) - m.emit(0xf8 | lcode(v[1])) - }) - } - // SARB 1, m8 - if isConst1(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd0) - m.mrsd(7, addr(v[1]), 1) - }) - } - // SARB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc0) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SARB cl, m8 - if v0 == CL && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd2) - m.mrsd(7, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SARB") - } - return p -} - -// SARL performs "Arithmetic Shift Right". -// -// Mnemonic : SAR -// Supported forms : (6 forms) -// -// * SARL 1, r32 -// * SARL imm8, r32 -// * SARL cl, r32 -// * SARL 1, m32 -// * SARL imm8, m32 -// * SARL cl, m32 -// -func (self *Program) SARL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SARL", 2, Operands { v0, v1 }) - // SARL 1, r32 - if isConst1(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xf8 | lcode(v[1])) - }) - } - // SARL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SARL cl, r32 - if v0 == CL && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xf8 | lcode(v[1])) - }) - } - // SARL 1, m32 - if isConst1(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(7, addr(v[1]), 1) - }) - } - // SARL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SARL cl, m32 - if v0 == CL && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(7, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SARL") - } - return p -} - -// SARQ performs "Arithmetic Shift Right". -// -// Mnemonic : SAR -// Supported forms : (6 forms) -// -// * SARQ 1, r64 -// * SARQ imm8, r64 -// * SARQ cl, r64 -// * SARQ 1, m64 -// * SARQ imm8, m64 -// * SARQ cl, m64 -// -func (self *Program) SARQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SARQ", 2, Operands { v0, v1 }) - // SARQ 1, r64 - if isConst1(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd1) - m.emit(0xf8 | lcode(v[1])) - }) - } - // SARQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xc1) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SARQ cl, r64 - if v0 == CL && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd3) - m.emit(0xf8 | lcode(v[1])) - }) - } - // SARQ 1, m64 - if isConst1(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd1) - m.mrsd(7, addr(v[1]), 1) - }) - } - // SARQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xc1) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SARQ cl, m64 - if v0 == CL && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd3) - m.mrsd(7, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SARQ") - } - return p -} - -// SARW performs "Arithmetic Shift Right". -// -// Mnemonic : SAR -// Supported forms : (6 forms) -// -// * SARW 1, r16 -// * SARW imm8, r16 -// * SARW cl, r16 -// * SARW 1, m16 -// * SARW imm8, m16 -// * SARW cl, m16 -// -func (self *Program) SARW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SARW", 2, Operands { v0, v1 }) - // SARW 1, r16 - if isConst1(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xf8 | lcode(v[1])) - }) - } - // SARW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SARW cl, r16 - if v0 == CL && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xf8 | lcode(v[1])) - }) - } - // SARW 1, m16 - if isConst1(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(7, addr(v[1]), 1) - }) - } - // SARW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(7, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SARW cl, m16 - if v0 == CL && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(7, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SARW") - } - return p -} - -// SARXL performs "Arithmetic Shift Right Without Affecting Flags". -// -// Mnemonic : SARX -// Supported forms : (2 forms) -// -// * SARXL r32, r32, r32 [BMI2] -// * SARXL r32, m32, r32 [BMI2] -// -func (self *Program) SARXL(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SARXL", 3, Operands { v0, v1, v2 }) - // SARXL r32, r32, r32 - if isReg32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7a ^ (hlcode(v[0]) << 3)) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // SARXL r32, m32, r32 - if isReg32(v0) && isM32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x02, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf7) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SARXL") - } - return p -} - -// SARXQ performs "Arithmetic Shift Right Without Affecting Flags". -// -// Mnemonic : SARX -// Supported forms : (2 forms) -// -// * SARXQ r64, r64, r64 [BMI2] -// * SARXQ r64, m64, r64 [BMI2] -// -func (self *Program) SARXQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SARXQ", 3, Operands { v0, v1, v2 }) - // SARXQ r64, r64, r64 - if isReg64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xfa ^ (hlcode(v[0]) << 3)) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // SARXQ r64, m64, r64 - if isReg64(v0) && isM64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x82, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf7) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SARXQ") - } - return p -} - -// SBBB performs "Subtract with Borrow". -// -// Mnemonic : SBB -// Supported forms : (6 forms) -// -// * SBBB imm8, al -// * SBBB imm8, r8 -// * SBBB r8, r8 -// * SBBB m8, r8 -// * SBBB imm8, m8 -// * SBBB r8, m8 -// -func (self *Program) SBBB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SBBB", 2, Operands { v0, v1 }) - // SBBB imm8, al - if isImm8(v0) && v1 == AL { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x1c) - m.imm1(toImmAny(v[0])) - }) - } - // SBBB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0x80) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SBBB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x18) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x1a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SBBB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x1a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // SBBB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x80) - m.mrsd(3, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SBBB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x18) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SBBB") - } - return p -} - -// SBBL performs "Subtract with Borrow". -// -// Mnemonic : SBB -// Supported forms : (8 forms) -// -// * SBBL imm32, eax -// * SBBL imm8, r32 -// * SBBL imm32, r32 -// * SBBL r32, r32 -// * SBBL m32, r32 -// * SBBL imm8, m32 -// * SBBL imm32, m32 -// * SBBL r32, m32 -// -func (self *Program) SBBL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SBBL", 2, Operands { v0, v1 }) - // SBBL imm32, eax - if isImm32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x1d) - m.imm4(toImmAny(v[0])) - }) - } - // SBBL imm8, r32 - if isImm8Ext(v0, 4) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SBBL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xd8 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // SBBL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x19) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x1b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SBBL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x1b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // SBBL imm8, m32 - if isImm8Ext(v0, 4) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(3, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SBBL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(3, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // SBBL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x19) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SBBL") - } - return p -} - -// SBBQ performs "Subtract with Borrow". -// -// Mnemonic : SBB -// Supported forms : (8 forms) -// -// * SBBQ imm32, rax -// * SBBQ imm8, r64 -// * SBBQ imm32, r64 -// * SBBQ r64, r64 -// * SBBQ m64, r64 -// * SBBQ imm8, m64 -// * SBBQ imm32, m64 -// * SBBQ r64, m64 -// -func (self *Program) SBBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SBBQ", 2, Operands { v0, v1 }) - // SBBQ imm32, rax - if isImm32(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x1d) - m.imm4(toImmAny(v[0])) - }) - } - // SBBQ imm8, r64 - if isImm8Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x83) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SBBQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x81) - m.emit(0xd8 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // SBBQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x19) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x1b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SBBQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x1b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // SBBQ imm8, m64 - if isImm8Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x83) - m.mrsd(3, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SBBQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x81) - m.mrsd(3, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // SBBQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x19) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SBBQ") - } - return p -} - -// SBBW performs "Subtract with Borrow". -// -// Mnemonic : SBB -// Supported forms : (8 forms) -// -// * SBBW imm16, ax -// * SBBW imm8, r16 -// * SBBW imm16, r16 -// * SBBW r16, r16 -// * SBBW m16, r16 -// * SBBW imm8, m16 -// * SBBW imm16, m16 -// * SBBW r16, m16 -// -func (self *Program) SBBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SBBW", 2, Operands { v0, v1 }) - // SBBW imm16, ax - if isImm16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x1d) - m.imm2(toImmAny(v[0])) - }) - } - // SBBW imm8, r16 - if isImm8Ext(v0, 2) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SBBW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xd8 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // SBBW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x19) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x1b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SBBW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x1b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // SBBW imm8, m16 - if isImm8Ext(v0, 2) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(3, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SBBW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(3, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // SBBW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x19) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SBBW") - } - return p -} - -// SETA performs "Set byte if above (CF == 0 and ZF == 0)". -// -// Mnemonic : SETA -// Supported forms : (2 forms) -// -// * SETA r8 -// * SETA m8 -// -func (self *Program) SETA(v0 interface{}) *Instruction { - p := self.alloc("SETA", 1, Operands { v0 }) - // SETA r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x97) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETA m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x97) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETA") - } - return p -} - -// SETAE performs "Set byte if above or equal (CF == 0)". -// -// Mnemonic : SETAE -// Supported forms : (2 forms) -// -// * SETAE r8 -// * SETAE m8 -// -func (self *Program) SETAE(v0 interface{}) *Instruction { - p := self.alloc("SETAE", 1, Operands { v0 }) - // SETAE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x93) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETAE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x93) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETAE") - } - return p -} - -// SETB performs "Set byte if below (CF == 1)". -// -// Mnemonic : SETB -// Supported forms : (2 forms) -// -// * SETB r8 -// * SETB m8 -// -func (self *Program) SETB(v0 interface{}) *Instruction { - p := self.alloc("SETB", 1, Operands { v0 }) - // SETB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x92) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x92) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETB") - } - return p -} - -// SETBE performs "Set byte if below or equal (CF == 1 or ZF == 1)". -// -// Mnemonic : SETBE -// Supported forms : (2 forms) -// -// * SETBE r8 -// * SETBE m8 -// -func (self *Program) SETBE(v0 interface{}) *Instruction { - p := self.alloc("SETBE", 1, Operands { v0 }) - // SETBE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x96) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETBE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x96) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETBE") - } - return p -} - -// SETC performs "Set byte if carry (CF == 1)". -// -// Mnemonic : SETC -// Supported forms : (2 forms) -// -// * SETC r8 -// * SETC m8 -// -func (self *Program) SETC(v0 interface{}) *Instruction { - p := self.alloc("SETC", 1, Operands { v0 }) - // SETC r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x92) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETC m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x92) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETC") - } - return p -} - -// SETE performs "Set byte if equal (ZF == 1)". -// -// Mnemonic : SETE -// Supported forms : (2 forms) -// -// * SETE r8 -// * SETE m8 -// -func (self *Program) SETE(v0 interface{}) *Instruction { - p := self.alloc("SETE", 1, Operands { v0 }) - // SETE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x94) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x94) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETE") - } - return p -} - -// SETG performs "Set byte if greater (ZF == 0 and SF == OF)". -// -// Mnemonic : SETG -// Supported forms : (2 forms) -// -// * SETG r8 -// * SETG m8 -// -func (self *Program) SETG(v0 interface{}) *Instruction { - p := self.alloc("SETG", 1, Operands { v0 }) - // SETG r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9f) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETG m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9f) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETG") - } - return p -} - -// SETGE performs "Set byte if greater or equal (SF == OF)". -// -// Mnemonic : SETGE -// Supported forms : (2 forms) -// -// * SETGE r8 -// * SETGE m8 -// -func (self *Program) SETGE(v0 interface{}) *Instruction { - p := self.alloc("SETGE", 1, Operands { v0 }) - // SETGE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9d) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETGE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9d) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETGE") - } - return p -} - -// SETL performs "Set byte if less (SF != OF)". -// -// Mnemonic : SETL -// Supported forms : (2 forms) -// -// * SETL r8 -// * SETL m8 -// -func (self *Program) SETL(v0 interface{}) *Instruction { - p := self.alloc("SETL", 1, Operands { v0 }) - // SETL r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETL m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9c) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETL") - } - return p -} - -// SETLE performs "Set byte if less or equal (ZF == 1 or SF != OF)". -// -// Mnemonic : SETLE -// Supported forms : (2 forms) -// -// * SETLE r8 -// * SETLE m8 -// -func (self *Program) SETLE(v0 interface{}) *Instruction { - p := self.alloc("SETLE", 1, Operands { v0 }) - // SETLE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETLE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9e) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETLE") - } - return p -} - -// SETNA performs "Set byte if not above (CF == 1 or ZF == 1)". -// -// Mnemonic : SETNA -// Supported forms : (2 forms) -// -// * SETNA r8 -// * SETNA m8 -// -func (self *Program) SETNA(v0 interface{}) *Instruction { - p := self.alloc("SETNA", 1, Operands { v0 }) - // SETNA r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x96) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNA m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x96) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNA") - } - return p -} - -// SETNAE performs "Set byte if not above or equal (CF == 1)". -// -// Mnemonic : SETNAE -// Supported forms : (2 forms) -// -// * SETNAE r8 -// * SETNAE m8 -// -func (self *Program) SETNAE(v0 interface{}) *Instruction { - p := self.alloc("SETNAE", 1, Operands { v0 }) - // SETNAE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x92) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNAE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x92) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNAE") - } - return p -} - -// SETNB performs "Set byte if not below (CF == 0)". -// -// Mnemonic : SETNB -// Supported forms : (2 forms) -// -// * SETNB r8 -// * SETNB m8 -// -func (self *Program) SETNB(v0 interface{}) *Instruction { - p := self.alloc("SETNB", 1, Operands { v0 }) - // SETNB r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x93) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNB m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x93) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNB") - } - return p -} - -// SETNBE performs "Set byte if not below or equal (CF == 0 and ZF == 0)". -// -// Mnemonic : SETNBE -// Supported forms : (2 forms) -// -// * SETNBE r8 -// * SETNBE m8 -// -func (self *Program) SETNBE(v0 interface{}) *Instruction { - p := self.alloc("SETNBE", 1, Operands { v0 }) - // SETNBE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x97) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNBE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x97) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNBE") - } - return p -} - -// SETNC performs "Set byte if not carry (CF == 0)". -// -// Mnemonic : SETNC -// Supported forms : (2 forms) -// -// * SETNC r8 -// * SETNC m8 -// -func (self *Program) SETNC(v0 interface{}) *Instruction { - p := self.alloc("SETNC", 1, Operands { v0 }) - // SETNC r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x93) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNC m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x93) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNC") - } - return p -} - -// SETNE performs "Set byte if not equal (ZF == 0)". -// -// Mnemonic : SETNE -// Supported forms : (2 forms) -// -// * SETNE r8 -// * SETNE m8 -// -func (self *Program) SETNE(v0 interface{}) *Instruction { - p := self.alloc("SETNE", 1, Operands { v0 }) - // SETNE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x95) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x95) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNE") - } - return p -} - -// SETNG performs "Set byte if not greater (ZF == 1 or SF != OF)". -// -// Mnemonic : SETNG -// Supported forms : (2 forms) -// -// * SETNG r8 -// * SETNG m8 -// -func (self *Program) SETNG(v0 interface{}) *Instruction { - p := self.alloc("SETNG", 1, Operands { v0 }) - // SETNG r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNG m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9e) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNG") - } - return p -} - -// SETNGE performs "Set byte if not greater or equal (SF != OF)". -// -// Mnemonic : SETNGE -// Supported forms : (2 forms) -// -// * SETNGE r8 -// * SETNGE m8 -// -func (self *Program) SETNGE(v0 interface{}) *Instruction { - p := self.alloc("SETNGE", 1, Operands { v0 }) - // SETNGE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNGE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9c) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNGE") - } - return p -} - -// SETNL performs "Set byte if not less (SF == OF)". -// -// Mnemonic : SETNL -// Supported forms : (2 forms) -// -// * SETNL r8 -// * SETNL m8 -// -func (self *Program) SETNL(v0 interface{}) *Instruction { - p := self.alloc("SETNL", 1, Operands { v0 }) - // SETNL r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9d) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNL m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9d) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNL") - } - return p -} - -// SETNLE performs "Set byte if not less or equal (ZF == 0 and SF == OF)". -// -// Mnemonic : SETNLE -// Supported forms : (2 forms) -// -// * SETNLE r8 -// * SETNLE m8 -// -func (self *Program) SETNLE(v0 interface{}) *Instruction { - p := self.alloc("SETNLE", 1, Operands { v0 }) - // SETNLE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9f) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNLE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9f) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNLE") - } - return p -} - -// SETNO performs "Set byte if not overflow (OF == 0)". -// -// Mnemonic : SETNO -// Supported forms : (2 forms) -// -// * SETNO r8 -// * SETNO m8 -// -func (self *Program) SETNO(v0 interface{}) *Instruction { - p := self.alloc("SETNO", 1, Operands { v0 }) - // SETNO r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x91) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNO m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x91) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNO") - } - return p -} - -// SETNP performs "Set byte if not parity (PF == 0)". -// -// Mnemonic : SETNP -// Supported forms : (2 forms) -// -// * SETNP r8 -// * SETNP m8 -// -func (self *Program) SETNP(v0 interface{}) *Instruction { - p := self.alloc("SETNP", 1, Operands { v0 }) - // SETNP r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNP m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9b) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNP") - } - return p -} - -// SETNS performs "Set byte if not sign (SF == 0)". -// -// Mnemonic : SETNS -// Supported forms : (2 forms) -// -// * SETNS r8 -// * SETNS m8 -// -func (self *Program) SETNS(v0 interface{}) *Instruction { - p := self.alloc("SETNS", 1, Operands { v0 }) - // SETNS r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x99) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNS m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x99) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNS") - } - return p -} - -// SETNZ performs "Set byte if not zero (ZF == 0)". -// -// Mnemonic : SETNZ -// Supported forms : (2 forms) -// -// * SETNZ r8 -// * SETNZ m8 -// -func (self *Program) SETNZ(v0 interface{}) *Instruction { - p := self.alloc("SETNZ", 1, Operands { v0 }) - // SETNZ r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x95) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETNZ m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x95) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETNZ") - } - return p -} - -// SETO performs "Set byte if overflow (OF == 1)". -// -// Mnemonic : SETO -// Supported forms : (2 forms) -// -// * SETO r8 -// * SETO m8 -// -func (self *Program) SETO(v0 interface{}) *Instruction { - p := self.alloc("SETO", 1, Operands { v0 }) - // SETO r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x90) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETO m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x90) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETO") - } - return p -} - -// SETP performs "Set byte if parity (PF == 1)". -// -// Mnemonic : SETP -// Supported forms : (2 forms) -// -// * SETP r8 -// * SETP m8 -// -func (self *Program) SETP(v0 interface{}) *Instruction { - p := self.alloc("SETP", 1, Operands { v0 }) - // SETP r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETP m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9a) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETP") - } - return p -} - -// SETPE performs "Set byte if parity even (PF == 1)". -// -// Mnemonic : SETPE -// Supported forms : (2 forms) -// -// * SETPE r8 -// * SETPE m8 -// -func (self *Program) SETPE(v0 interface{}) *Instruction { - p := self.alloc("SETPE", 1, Operands { v0 }) - // SETPE r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETPE m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9a) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETPE") - } - return p -} - -// SETPO performs "Set byte if parity odd (PF == 0)". -// -// Mnemonic : SETPO -// Supported forms : (2 forms) -// -// * SETPO r8 -// * SETPO m8 -// -func (self *Program) SETPO(v0 interface{}) *Instruction { - p := self.alloc("SETPO", 1, Operands { v0 }) - // SETPO r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETPO m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x9b) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETPO") - } - return p -} - -// SETS performs "Set byte if sign (SF == 1)". -// -// Mnemonic : SETS -// Supported forms : (2 forms) -// -// * SETS r8 -// * SETS m8 -// -func (self *Program) SETS(v0 interface{}) *Instruction { - p := self.alloc("SETS", 1, Operands { v0 }) - // SETS r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x98) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETS m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x98) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETS") - } - return p -} - -// SETZ performs "Set byte if zero (ZF == 1)". -// -// Mnemonic : SETZ -// Supported forms : (2 forms) -// -// * SETZ r8 -// * SETZ m8 -// -func (self *Program) SETZ(v0 interface{}) *Instruction { - p := self.alloc("SETZ", 1, Operands { v0 }) - // SETZ r8 - if isReg8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0x94) - m.emit(0xc0 | lcode(v[0])) - }) - } - // SETZ m8 - if isM8(v0) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0x94) - m.mrsd(0, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SETZ") - } - return p -} - -// SFENCE performs "Store Fence". -// -// Mnemonic : SFENCE -// Supported forms : (1 form) -// -// * SFENCE [MMX+] -// -func (self *Program) SFENCE() *Instruction { - p := self.alloc("SFENCE", 0, Operands { }) - // SFENCE - self.require(ISA_MMX_PLUS) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0xae) - m.emit(0xf8) - }) - return p -} - -// SHA1MSG1 performs "Perform an Intermediate Calculation for the Next Four SHA1 Message Doublewords". -// -// Mnemonic : SHA1MSG1 -// Supported forms : (2 forms) -// -// * SHA1MSG1 xmm, xmm [SHA] -// * SHA1MSG1 m128, xmm [SHA] -// -func (self *Program) SHA1MSG1(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHA1MSG1", 2, Operands { v0, v1 }) - // SHA1MSG1 xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xc9) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SHA1MSG1 m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xc9) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHA1MSG1") - } - return p -} - -// SHA1MSG2 performs "Perform a Final Calculation for the Next Four SHA1 Message Doublewords". -// -// Mnemonic : SHA1MSG2 -// Supported forms : (2 forms) -// -// * SHA1MSG2 xmm, xmm [SHA] -// * SHA1MSG2 m128, xmm [SHA] -// -func (self *Program) SHA1MSG2(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHA1MSG2", 2, Operands { v0, v1 }) - // SHA1MSG2 xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xca) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SHA1MSG2 m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xca) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHA1MSG2") - } - return p -} - -// SHA1NEXTE performs "Calculate SHA1 State Variable E after Four Rounds". -// -// Mnemonic : SHA1NEXTE -// Supported forms : (2 forms) -// -// * SHA1NEXTE xmm, xmm [SHA] -// * SHA1NEXTE m128, xmm [SHA] -// -func (self *Program) SHA1NEXTE(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHA1NEXTE", 2, Operands { v0, v1 }) - // SHA1NEXTE xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xc8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SHA1NEXTE m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xc8) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHA1NEXTE") - } - return p -} - -// SHA1RNDS4 performs "Perform Four Rounds of SHA1 Operation". -// -// Mnemonic : SHA1RNDS4 -// Supported forms : (2 forms) -// -// * SHA1RNDS4 imm8, xmm, xmm [SHA] -// * SHA1RNDS4 imm8, m128, xmm [SHA] -// -func (self *Program) SHA1RNDS4(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHA1RNDS4", 3, Operands { v0, v1, v2 }) - // SHA1RNDS4 imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0xcc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHA1RNDS4 imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x3a) - m.emit(0xcc) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for SHA1RNDS4") - } - return p -} - -// SHA256MSG1 performs "Perform an Intermediate Calculation for the Next Four SHA256 Message Doublewords". -// -// Mnemonic : SHA256MSG1 -// Supported forms : (2 forms) -// -// * SHA256MSG1 xmm, xmm [SHA] -// * SHA256MSG1 m128, xmm [SHA] -// -func (self *Program) SHA256MSG1(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHA256MSG1", 2, Operands { v0, v1 }) - // SHA256MSG1 xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xcc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SHA256MSG1 m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xcc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHA256MSG1") - } - return p -} - -// SHA256MSG2 performs "Perform a Final Calculation for the Next Four SHA256 Message Doublewords". -// -// Mnemonic : SHA256MSG2 -// Supported forms : (2 forms) -// -// * SHA256MSG2 xmm, xmm [SHA] -// * SHA256MSG2 m128, xmm [SHA] -// -func (self *Program) SHA256MSG2(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHA256MSG2", 2, Operands { v0, v1 }) - // SHA256MSG2 xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xcd) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SHA256MSG2 m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xcd) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHA256MSG2") - } - return p -} - -// SHA256RNDS2 performs "Perform Two Rounds of SHA256 Operation". -// -// Mnemonic : SHA256RNDS2 -// Supported forms : (2 forms) -// -// * SHA256RNDS2 xmm0, xmm, xmm [SHA] -// * SHA256RNDS2 xmm0, m128, xmm [SHA] -// -func (self *Program) SHA256RNDS2(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHA256RNDS2", 3, Operands { v0, v1, v2 }) - // SHA256RNDS2 xmm0, xmm, xmm - if v0 == XMM0 && isXMM(v1) && isXMM(v2) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xcb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // SHA256RNDS2 xmm0, m128, xmm - if v0 == XMM0 && isM128(v1) && isXMM(v2) { - self.require(ISA_SHA) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0x38) - m.emit(0xcb) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHA256RNDS2") - } - return p -} - -// SHLB performs "Logical Shift Left". -// -// Mnemonic : SHL -// Supported forms : (6 forms) -// -// * SHLB 1, r8 -// * SHLB imm8, r8 -// * SHLB cl, r8 -// * SHLB 1, m8 -// * SHLB imm8, m8 -// * SHLB cl, m8 -// -func (self *Program) SHLB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHLB", 2, Operands { v0, v1 }) - // SHLB 1, r8 - if isConst1(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd0) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SHLB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xc0) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHLB cl, r8 - if v0 == CL && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd2) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SHLB 1, m8 - if isConst1(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd0) - m.mrsd(4, addr(v[1]), 1) - }) - } - // SHLB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc0) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHLB cl, m8 - if v0 == CL && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd2) - m.mrsd(4, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHLB") - } - return p -} - -// SHLDL performs "Integer Double Precision Shift Left". -// -// Mnemonic : SHLD -// Supported forms : (4 forms) -// -// * SHLDL imm8, r32, r32 -// * SHLDL cl, r32, r32 -// * SHLDL imm8, r32, m32 -// * SHLDL cl, r32, m32 -// -func (self *Program) SHLDL(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHLDL", 3, Operands { v0, v1, v2 }) - // SHLDL imm8, r32, r32 - if isImm8(v0) && isReg32(v1) && isReg32(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0xa4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // SHLDL cl, r32, r32 - if v0 == CL && isReg32(v1) && isReg32(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0xa5) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - }) - } - // SHLDL imm8, r32, m32 - if isImm8(v0) && isReg32(v1) && isM32(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0xa4) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHLDL cl, r32, m32 - if v0 == CL && isReg32(v1) && isM32(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0xa5) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHLDL") - } - return p -} - -// SHLDQ performs "Integer Double Precision Shift Left". -// -// Mnemonic : SHLD -// Supported forms : (4 forms) -// -// * SHLDQ imm8, r64, r64 -// * SHLDQ cl, r64, r64 -// * SHLDQ imm8, r64, m64 -// * SHLDQ cl, r64, m64 -// -func (self *Program) SHLDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHLDQ", 3, Operands { v0, v1, v2 }) - // SHLDQ imm8, r64, r64 - if isImm8(v0) && isReg64(v1) && isReg64(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[2])) - m.emit(0x0f) - m.emit(0xa4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // SHLDQ cl, r64, r64 - if v0 == CL && isReg64(v1) && isReg64(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[2])) - m.emit(0x0f) - m.emit(0xa5) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - }) - } - // SHLDQ imm8, r64, m64 - if isImm8(v0) && isReg64(v1) && isM64(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[2])) - m.emit(0x0f) - m.emit(0xa4) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHLDQ cl, r64, m64 - if v0 == CL && isReg64(v1) && isM64(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[2])) - m.emit(0x0f) - m.emit(0xa5) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHLDQ") - } - return p -} - -// SHLDW performs "Integer Double Precision Shift Left". -// -// Mnemonic : SHLD -// Supported forms : (4 forms) -// -// * SHLDW imm8, r16, r16 -// * SHLDW cl, r16, r16 -// * SHLDW imm8, r16, m16 -// * SHLDW cl, r16, m16 -// -func (self *Program) SHLDW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHLDW", 3, Operands { v0, v1, v2 }) - // SHLDW imm8, r16, r16 - if isImm8(v0) && isReg16(v1) && isReg16(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0xa4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // SHLDW cl, r16, r16 - if v0 == CL && isReg16(v1) && isReg16(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0xa5) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - }) - } - // SHLDW imm8, r16, m16 - if isImm8(v0) && isReg16(v1) && isM16(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0xa4) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHLDW cl, r16, m16 - if v0 == CL && isReg16(v1) && isM16(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0xa5) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHLDW") - } - return p -} - -// SHLL performs "Logical Shift Left". -// -// Mnemonic : SHL -// Supported forms : (6 forms) -// -// * SHLL 1, r32 -// * SHLL imm8, r32 -// * SHLL cl, r32 -// * SHLL 1, m32 -// * SHLL imm8, m32 -// * SHLL cl, m32 -// -func (self *Program) SHLL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHLL", 2, Operands { v0, v1 }) - // SHLL 1, r32 - if isConst1(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SHLL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHLL cl, r32 - if v0 == CL && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SHLL 1, m32 - if isConst1(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(4, addr(v[1]), 1) - }) - } - // SHLL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHLL cl, m32 - if v0 == CL && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(4, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHLL") - } - return p -} - -// SHLQ performs "Logical Shift Left". -// -// Mnemonic : SHL -// Supported forms : (6 forms) -// -// * SHLQ 1, r64 -// * SHLQ imm8, r64 -// * SHLQ cl, r64 -// * SHLQ 1, m64 -// * SHLQ imm8, m64 -// * SHLQ cl, m64 -// -func (self *Program) SHLQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHLQ", 2, Operands { v0, v1 }) - // SHLQ 1, r64 - if isConst1(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd1) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SHLQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xc1) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHLQ cl, r64 - if v0 == CL && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd3) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SHLQ 1, m64 - if isConst1(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd1) - m.mrsd(4, addr(v[1]), 1) - }) - } - // SHLQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xc1) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHLQ cl, m64 - if v0 == CL && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd3) - m.mrsd(4, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHLQ") - } - return p -} - -// SHLW performs "Logical Shift Left". -// -// Mnemonic : SHL -// Supported forms : (6 forms) -// -// * SHLW 1, r16 -// * SHLW imm8, r16 -// * SHLW cl, r16 -// * SHLW 1, m16 -// * SHLW imm8, m16 -// * SHLW cl, m16 -// -func (self *Program) SHLW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHLW", 2, Operands { v0, v1 }) - // SHLW 1, r16 - if isConst1(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SHLW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHLW cl, r16 - if v0 == CL && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xe0 | lcode(v[1])) - }) - } - // SHLW 1, m16 - if isConst1(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(4, addr(v[1]), 1) - }) - } - // SHLW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(4, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHLW cl, m16 - if v0 == CL && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(4, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHLW") - } - return p -} - -// SHLXL performs "Logical Shift Left Without Affecting Flags". -// -// Mnemonic : SHLX -// Supported forms : (2 forms) -// -// * SHLXL r32, r32, r32 [BMI2] -// * SHLXL r32, m32, r32 [BMI2] -// -func (self *Program) SHLXL(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHLXL", 3, Operands { v0, v1, v2 }) - // SHLXL r32, r32, r32 - if isReg32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[0]) << 3)) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // SHLXL r32, m32, r32 - if isReg32(v0) && isM32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf7) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHLXL") - } - return p -} - -// SHLXQ performs "Logical Shift Left Without Affecting Flags". -// -// Mnemonic : SHLX -// Supported forms : (2 forms) -// -// * SHLXQ r64, r64, r64 [BMI2] -// * SHLXQ r64, m64, r64 [BMI2] -// -func (self *Program) SHLXQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHLXQ", 3, Operands { v0, v1, v2 }) - // SHLXQ r64, r64, r64 - if isReg64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xf9 ^ (hlcode(v[0]) << 3)) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // SHLXQ r64, m64, r64 - if isReg64(v0) && isM64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf7) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHLXQ") - } - return p -} - -// SHRB performs "Logical Shift Right". -// -// Mnemonic : SHR -// Supported forms : (6 forms) -// -// * SHRB 1, r8 -// * SHRB imm8, r8 -// * SHRB cl, r8 -// * SHRB 1, m8 -// * SHRB imm8, m8 -// * SHRB cl, m8 -// -func (self *Program) SHRB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHRB", 2, Operands { v0, v1 }) - // SHRB 1, r8 - if isConst1(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd0) - m.emit(0xe8 | lcode(v[1])) - }) - } - // SHRB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xc0) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHRB cl, r8 - if v0 == CL && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xd2) - m.emit(0xe8 | lcode(v[1])) - }) - } - // SHRB 1, m8 - if isConst1(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd0) - m.mrsd(5, addr(v[1]), 1) - }) - } - // SHRB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc0) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHRB cl, m8 - if v0 == CL && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd2) - m.mrsd(5, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHRB") - } - return p -} - -// SHRDL performs "Integer Double Precision Shift Right". -// -// Mnemonic : SHRD -// Supported forms : (4 forms) -// -// * SHRDL imm8, r32, r32 -// * SHRDL cl, r32, r32 -// * SHRDL imm8, r32, m32 -// * SHRDL cl, r32, m32 -// -func (self *Program) SHRDL(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHRDL", 3, Operands { v0, v1, v2 }) - // SHRDL imm8, r32, r32 - if isImm8(v0) && isReg32(v1) && isReg32(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0xac) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // SHRDL cl, r32, r32 - if v0 == CL && isReg32(v1) && isReg32(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0xad) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - }) - } - // SHRDL imm8, r32, m32 - if isImm8(v0) && isReg32(v1) && isM32(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0xac) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHRDL cl, r32, m32 - if v0 == CL && isReg32(v1) && isM32(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0xad) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHRDL") - } - return p -} - -// SHRDQ performs "Integer Double Precision Shift Right". -// -// Mnemonic : SHRD -// Supported forms : (4 forms) -// -// * SHRDQ imm8, r64, r64 -// * SHRDQ cl, r64, r64 -// * SHRDQ imm8, r64, m64 -// * SHRDQ cl, r64, m64 -// -func (self *Program) SHRDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHRDQ", 3, Operands { v0, v1, v2 }) - // SHRDQ imm8, r64, r64 - if isImm8(v0) && isReg64(v1) && isReg64(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[2])) - m.emit(0x0f) - m.emit(0xac) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // SHRDQ cl, r64, r64 - if v0 == CL && isReg64(v1) && isReg64(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[2])) - m.emit(0x0f) - m.emit(0xad) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - }) - } - // SHRDQ imm8, r64, m64 - if isImm8(v0) && isReg64(v1) && isM64(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[2])) - m.emit(0x0f) - m.emit(0xac) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHRDQ cl, r64, m64 - if v0 == CL && isReg64(v1) && isM64(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[2])) - m.emit(0x0f) - m.emit(0xad) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHRDQ") - } - return p -} - -// SHRDW performs "Integer Double Precision Shift Right". -// -// Mnemonic : SHRD -// Supported forms : (4 forms) -// -// * SHRDW imm8, r16, r16 -// * SHRDW cl, r16, r16 -// * SHRDW imm8, r16, m16 -// * SHRDW cl, r16, m16 -// -func (self *Program) SHRDW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHRDW", 3, Operands { v0, v1, v2 }) - // SHRDW imm8, r16, r16 - if isImm8(v0) && isReg16(v1) && isReg16(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0xac) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // SHRDW cl, r16, r16 - if v0 == CL && isReg16(v1) && isReg16(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[2], false) - m.emit(0x0f) - m.emit(0xad) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - }) - } - // SHRDW imm8, r16, m16 - if isImm8(v0) && isReg16(v1) && isM16(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0xac) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHRDW cl, r16, m16 - if v0 == CL && isReg16(v1) && isM16(v2) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[2]), false) - m.emit(0x0f) - m.emit(0xad) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHRDW") - } - return p -} - -// SHRL performs "Logical Shift Right". -// -// Mnemonic : SHR -// Supported forms : (6 forms) -// -// * SHRL 1, r32 -// * SHRL imm8, r32 -// * SHRL cl, r32 -// * SHRL 1, m32 -// * SHRL imm8, m32 -// * SHRL cl, m32 -// -func (self *Program) SHRL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHRL", 2, Operands { v0, v1 }) - // SHRL 1, r32 - if isConst1(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xe8 | lcode(v[1])) - }) - } - // SHRL imm8, r32 - if isImm8(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHRL cl, r32 - if v0 == CL && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xe8 | lcode(v[1])) - }) - } - // SHRL 1, m32 - if isConst1(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(5, addr(v[1]), 1) - }) - } - // SHRL imm8, m32 - if isImm8(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHRL cl, m32 - if v0 == CL && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(5, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHRL") - } - return p -} - -// SHRQ performs "Logical Shift Right". -// -// Mnemonic : SHR -// Supported forms : (6 forms) -// -// * SHRQ 1, r64 -// * SHRQ imm8, r64 -// * SHRQ cl, r64 -// * SHRQ 1, m64 -// * SHRQ imm8, m64 -// * SHRQ cl, m64 -// -func (self *Program) SHRQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHRQ", 2, Operands { v0, v1 }) - // SHRQ 1, r64 - if isConst1(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd1) - m.emit(0xe8 | lcode(v[1])) - }) - } - // SHRQ imm8, r64 - if isImm8(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xc1) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHRQ cl, r64 - if v0 == CL && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xd3) - m.emit(0xe8 | lcode(v[1])) - }) - } - // SHRQ 1, m64 - if isConst1(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd1) - m.mrsd(5, addr(v[1]), 1) - }) - } - // SHRQ imm8, m64 - if isImm8(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xc1) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHRQ cl, m64 - if v0 == CL && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xd3) - m.mrsd(5, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHRQ") - } - return p -} - -// SHRW performs "Logical Shift Right". -// -// Mnemonic : SHR -// Supported forms : (6 forms) -// -// * SHRW 1, r16 -// * SHRW imm8, r16 -// * SHRW cl, r16 -// * SHRW 1, m16 -// * SHRW imm8, m16 -// * SHRW cl, m16 -// -func (self *Program) SHRW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SHRW", 2, Operands { v0, v1 }) - // SHRW 1, r16 - if isConst1(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd1) - m.emit(0xe8 | lcode(v[1])) - }) - } - // SHRW imm8, r16 - if isImm8(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xc1) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHRW cl, r16 - if v0 == CL && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xd3) - m.emit(0xe8 | lcode(v[1])) - }) - } - // SHRW 1, m16 - if isConst1(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd1) - m.mrsd(5, addr(v[1]), 1) - }) - } - // SHRW imm8, m16 - if isImm8(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xc1) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SHRW cl, m16 - if v0 == CL && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xd3) - m.mrsd(5, addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHRW") - } - return p -} - -// SHRXL performs "Logical Shift Right Without Affecting Flags". -// -// Mnemonic : SHRX -// Supported forms : (2 forms) -// -// * SHRXL r32, r32, r32 [BMI2] -// * SHRXL r32, m32, r32 [BMI2] -// -func (self *Program) SHRXL(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHRXL", 3, Operands { v0, v1, v2 }) - // SHRXL r32, r32, r32 - if isReg32(v0) && isReg32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7b ^ (hlcode(v[0]) << 3)) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // SHRXL r32, m32, r32 - if isReg32(v0) && isM32(v1) && isReg32(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x03, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf7) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHRXL") - } - return p -} - -// SHRXQ performs "Logical Shift Right Without Affecting Flags". -// -// Mnemonic : SHRX -// Supported forms : (2 forms) -// -// * SHRXQ r64, r64, r64 [BMI2] -// * SHRXQ r64, m64, r64 [BMI2] -// -func (self *Program) SHRXQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHRXQ", 3, Operands { v0, v1, v2 }) - // SHRXQ r64, r64, r64 - if isReg64(v0) && isReg64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xfb ^ (hlcode(v[0]) << 3)) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // SHRXQ r64, m64, r64 - if isReg64(v0) && isM64(v1) && isReg64(v2) { - self.require(ISA_BMI2) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x83, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0xf7) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SHRXQ") - } - return p -} - -// SHUFPD performs "Shuffle Packed Double-Precision Floating-Point Values". -// -// Mnemonic : SHUFPD -// Supported forms : (2 forms) -// -// * SHUFPD imm8, xmm, xmm [SSE2] -// * SHUFPD imm8, m128, xmm [SSE2] -// -func (self *Program) SHUFPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHUFPD", 3, Operands { v0, v1, v2 }) - // SHUFPD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHUFPD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc6) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for SHUFPD") - } - return p -} - -// SHUFPS performs "Shuffle Packed Single-Precision Floating-Point Values". -// -// Mnemonic : SHUFPS -// Supported forms : (2 forms) -// -// * SHUFPS imm8, xmm, xmm [SSE] -// * SHUFPS imm8, m128, xmm [SSE] -// -func (self *Program) SHUFPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("SHUFPS", 3, Operands { v0, v1, v2 }) - // SHUFPS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), v[1], false) - m.emit(0x0f) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SHUFPS imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[2]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc6) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for SHUFPS") - } - return p -} - -// SQRTPD performs "Compute Square Roots of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : SQRTPD -// Supported forms : (2 forms) -// -// * SQRTPD xmm, xmm [SSE2] -// * SQRTPD m128, xmm [SSE2] -// -func (self *Program) SQRTPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SQRTPD", 2, Operands { v0, v1 }) - // SQRTPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SQRTPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SQRTPD") - } - return p -} - -// SQRTPS performs "Compute Square Roots of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : SQRTPS -// Supported forms : (2 forms) -// -// * SQRTPS xmm, xmm [SSE] -// * SQRTPS m128, xmm [SSE] -// -func (self *Program) SQRTPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SQRTPS", 2, Operands { v0, v1 }) - // SQRTPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SQRTPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SQRTPS") - } - return p -} - -// SQRTSD performs "Compute Square Root of Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : SQRTSD -// Supported forms : (2 forms) -// -// * SQRTSD xmm, xmm [SSE2] -// * SQRTSD m64, xmm [SSE2] -// -func (self *Program) SQRTSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SQRTSD", 2, Operands { v0, v1 }) - // SQRTSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SQRTSD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SQRTSD") - } - return p -} - -// SQRTSS performs "Compute Square Root of Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : SQRTSS -// Supported forms : (2 forms) -// -// * SQRTSS xmm, xmm [SSE] -// * SQRTSS m32, xmm [SSE] -// -func (self *Program) SQRTSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SQRTSS", 2, Operands { v0, v1 }) - // SQRTSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SQRTSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SQRTSS") - } - return p -} - -// STC performs "Set Carry Flag". -// -// Mnemonic : STC -// Supported forms : (1 form) -// -// * STC -// -func (self *Program) STC() *Instruction { - p := self.alloc("STC", 0, Operands { }) - // STC - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf9) - }) - return p -} - -// STD performs "Set Direction Flag". -// -// Mnemonic : STD -// Supported forms : (1 form) -// -// * STD -// -func (self *Program) STD() *Instruction { - p := self.alloc("STD", 0, Operands { }) - // STD - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xfd) - }) - return p -} - -// STMXCSR performs "Store MXCSR Register State". -// -// Mnemonic : STMXCSR -// Supported forms : (1 form) -// -// * STMXCSR m32 [SSE] -// -func (self *Program) STMXCSR(v0 interface{}) *Instruction { - p := self.alloc("STMXCSR", 1, Operands { v0 }) - // STMXCSR m32 - if isM32(v0) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[0]), false) - m.emit(0x0f) - m.emit(0xae) - m.mrsd(3, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for STMXCSR") - } - return p -} - -// SUBB performs "Subtract". -// -// Mnemonic : SUB -// Supported forms : (6 forms) -// -// * SUBB imm8, al -// * SUBB imm8, r8 -// * SUBB r8, r8 -// * SUBB m8, r8 -// * SUBB imm8, m8 -// * SUBB r8, m8 -// -func (self *Program) SUBB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SUBB", 2, Operands { v0, v1 }) - // SUBB imm8, al - if isImm8(v0) && v1 == AL { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x2c) - m.imm1(toImmAny(v[0])) - }) - } - // SUBB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0x80) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SUBB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x28) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SUBB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // SUBB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x80) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SUBB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x28) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SUBB") - } - return p -} - -// SUBL performs "Subtract". -// -// Mnemonic : SUB -// Supported forms : (8 forms) -// -// * SUBL imm32, eax -// * SUBL imm8, r32 -// * SUBL imm32, r32 -// * SUBL r32, r32 -// * SUBL m32, r32 -// * SUBL imm8, m32 -// * SUBL imm32, m32 -// * SUBL r32, m32 -// -func (self *Program) SUBL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SUBL", 2, Operands { v0, v1 }) - // SUBL imm32, eax - if isImm32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x2d) - m.imm4(toImmAny(v[0])) - }) - } - // SUBL imm8, r32 - if isImm8Ext(v0, 4) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SUBL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xe8 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // SUBL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x2b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SUBL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x2b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // SUBL imm8, m32 - if isImm8Ext(v0, 4) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SUBL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(5, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // SUBL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SUBL") - } - return p -} - -// SUBPD performs "Subtract Packed Double-Precision Floating-Point Values". -// -// Mnemonic : SUBPD -// Supported forms : (2 forms) -// -// * SUBPD xmm, xmm [SSE2] -// * SUBPD m128, xmm [SSE2] -// -func (self *Program) SUBPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SUBPD", 2, Operands { v0, v1 }) - // SUBPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SUBPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SUBPD") - } - return p -} - -// SUBPS performs "Subtract Packed Single-Precision Floating-Point Values". -// -// Mnemonic : SUBPS -// Supported forms : (2 forms) -// -// * SUBPS xmm, xmm [SSE] -// * SUBPS m128, xmm [SSE] -// -func (self *Program) SUBPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SUBPS", 2, Operands { v0, v1 }) - // SUBPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SUBPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SUBPS") - } - return p -} - -// SUBQ performs "Subtract". -// -// Mnemonic : SUB -// Supported forms : (8 forms) -// -// * SUBQ imm32, rax -// * SUBQ imm8, r64 -// * SUBQ imm32, r64 -// * SUBQ r64, r64 -// * SUBQ m64, r64 -// * SUBQ imm8, m64 -// * SUBQ imm32, m64 -// * SUBQ r64, m64 -// -func (self *Program) SUBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SUBQ", 2, Operands { v0, v1 }) - // SUBQ imm32, rax - if isImm32(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x2d) - m.imm4(toImmAny(v[0])) - }) - } - // SUBQ imm8, r64 - if isImm8Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x83) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SUBQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x81) - m.emit(0xe8 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // SUBQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x2b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SUBQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x2b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // SUBQ imm8, m64 - if isImm8Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x83) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SUBQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x81) - m.mrsd(5, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // SUBQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SUBQ") - } - return p -} - -// SUBSD performs "Subtract Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : SUBSD -// Supported forms : (2 forms) -// -// * SUBSD xmm, xmm [SSE2] -// * SUBSD m64, xmm [SSE2] -// -func (self *Program) SUBSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SUBSD", 2, Operands { v0, v1 }) - // SUBSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SUBSD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf2) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SUBSD") - } - return p -} - -// SUBSS performs "Subtract Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : SUBSS -// Supported forms : (2 forms) -// -// * SUBSS xmm, xmm [SSE] -// * SUBSS m32, xmm [SSE] -// -func (self *Program) SUBSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SUBSS", 2, Operands { v0, v1 }) - // SUBSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SUBSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x5c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SUBSS") - } - return p -} - -// SUBW performs "Subtract". -// -// Mnemonic : SUB -// Supported forms : (8 forms) -// -// * SUBW imm16, ax -// * SUBW imm8, r16 -// * SUBW imm16, r16 -// * SUBW r16, r16 -// * SUBW m16, r16 -// * SUBW imm8, m16 -// * SUBW imm16, m16 -// * SUBW r16, m16 -// -func (self *Program) SUBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("SUBW", 2, Operands { v0, v1 }) - // SUBW imm16, ax - if isImm16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x2d) - m.imm2(toImmAny(v[0])) - }) - } - // SUBW imm8, r16 - if isImm8Ext(v0, 2) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xe8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // SUBW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xe8 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // SUBW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x2b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // SUBW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x2b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // SUBW imm8, m16 - if isImm8Ext(v0, 2) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(5, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // SUBW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(5, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // SUBW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for SUBW") - } - return p -} - -// SYSCALL performs "Fast System Call". -// -// Mnemonic : SYSCALL -// Supported forms : (1 form) -// -// * SYSCALL -// -func (self *Program) SYSCALL() *Instruction { - p := self.alloc("SYSCALL", 0, Operands { }) - // SYSCALL - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x05) - }) - return p -} - -// T1MSKC performs "Inverse Mask From Trailing Ones". -// -// Mnemonic : T1MSKC -// Supported forms : (4 forms) -// -// * T1MSKC r32, r32 [TBM] -// * T1MSKC m32, r32 [TBM] -// * T1MSKC r64, r64 [TBM] -// * T1MSKC m64, r64 [TBM] -// -func (self *Program) T1MSKC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("T1MSKC", 2, Operands { v0, v1 }) - // T1MSKC r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xf8 | lcode(v[0])) - }) - } - // T1MSKC m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(7, addr(v[0]), 1) - }) - } - // T1MSKC r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xf8 | lcode(v[0])) - }) - } - // T1MSKC m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(7, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for T1MSKC") - } - return p -} - -// TESTB performs "Logical Compare". -// -// Mnemonic : TEST -// Supported forms : (5 forms) -// -// * TESTB imm8, al -// * TESTB imm8, r8 -// * TESTB r8, r8 -// * TESTB imm8, m8 -// * TESTB r8, m8 -// -func (self *Program) TESTB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("TESTB", 2, Operands { v0, v1 }) - // TESTB imm8, al - if isImm8(v0) && v1 == AL { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xa8) - m.imm1(toImmAny(v[0])) - }) - } - // TESTB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // TESTB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x84) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // TESTB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xf6) - m.mrsd(0, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // TESTB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x84) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for TESTB") - } - return p -} - -// TESTL performs "Logical Compare". -// -// Mnemonic : TEST -// Supported forms : (5 forms) -// -// * TESTL imm32, eax -// * TESTL imm32, r32 -// * TESTL r32, r32 -// * TESTL imm32, m32 -// * TESTL r32, m32 -// -func (self *Program) TESTL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("TESTL", 2, Operands { v0, v1 }) - // TESTL imm32, eax - if isImm32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xa9) - m.imm4(toImmAny(v[0])) - }) - } - // TESTL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // TESTL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x85) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // TESTL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0xf7) - m.mrsd(0, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // TESTL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x85) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for TESTL") - } - return p -} - -// TESTQ performs "Logical Compare". -// -// Mnemonic : TEST -// Supported forms : (5 forms) -// -// * TESTQ imm32, rax -// * TESTQ imm32, r64 -// * TESTQ r64, r64 -// * TESTQ imm32, m64 -// * TESTQ r64, m64 -// -func (self *Program) TESTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("TESTQ", 2, Operands { v0, v1 }) - // TESTQ imm32, rax - if isImm32(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0xa9) - m.imm4(toImmAny(v[0])) - }) - } - // TESTQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // TESTQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x85) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // TESTQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0xf7) - m.mrsd(0, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // TESTQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x85) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for TESTQ") - } - return p -} - -// TESTW performs "Logical Compare". -// -// Mnemonic : TEST -// Supported forms : (5 forms) -// -// * TESTW imm16, ax -// * TESTW imm16, r16 -// * TESTW r16, r16 -// * TESTW imm16, m16 -// * TESTW r16, m16 -// -func (self *Program) TESTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("TESTW", 2, Operands { v0, v1 }) - // TESTW imm16, ax - if isImm16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0xa9) - m.imm2(toImmAny(v[0])) - }) - } - // TESTW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // TESTW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x85) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // TESTW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0xf7) - m.mrsd(0, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // TESTW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x85) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for TESTW") - } - return p -} - -// TZCNTL performs "Count the Number of Trailing Zero Bits". -// -// Mnemonic : TZCNT -// Supported forms : (2 forms) -// -// * TZCNTL r32, r32 [BMI] -// * TZCNTL m32, r32 [BMI] -// -func (self *Program) TZCNTL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("TZCNTL", 2, Operands { v0, v1 }) - // TZCNTL r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // TZCNTL m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for TZCNTL") - } - return p -} - -// TZCNTQ performs "Count the Number of Trailing Zero Bits". -// -// Mnemonic : TZCNT -// Supported forms : (2 forms) -// -// * TZCNTQ r64, r64 [BMI] -// * TZCNTQ m64, r64 [BMI] -// -func (self *Program) TZCNTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("TZCNTQ", 2, Operands { v0, v1 }) - // TZCNTQ r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x0f) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // TZCNTQ m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xf3) - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x0f) - m.emit(0xbc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for TZCNTQ") - } - return p -} - -// TZCNTW performs "Count the Number of Trailing Zero Bits". -// -// Mnemonic : TZCNT -// Supported forms : (2 forms) -// -// * TZCNTW r16, r16 [BMI] -// * TZCNTW m16, r16 [BMI] -// -func (self *Program) TZCNTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("TZCNTW", 2, Operands { v0, v1 }) - // TZCNTW r16, r16 - if isReg16(v0) && isReg16(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0xf3) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // TZCNTW m16, r16 - if isM16(v0) && isReg16(v1) { - self.require(ISA_BMI) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0xf3) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0xbc) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for TZCNTW") - } - return p -} - -// TZMSK performs "Mask From Trailing Zeros". -// -// Mnemonic : TZMSK -// Supported forms : (4 forms) -// -// * TZMSK r32, r32 [TBM] -// * TZMSK m32, r32 [TBM] -// * TZMSK r64, r64 [TBM] -// * TZMSK m64, r64 [TBM] -// -func (self *Program) TZMSK(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("TZMSK", 2, Operands { v0, v1 }) - // TZMSK r32, r32 - if isReg32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0x78 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xe0 | lcode(v[0])) - }) - } - // TZMSK m32, r32 - if isM32(v0) && isReg32(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(4, addr(v[0]), 1) - }) - } - // TZMSK r64, r64 - if isReg64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xe0 | lcode(v[0])) - }) - } - // TZMSK m64, r64 - if isM64(v0) && isReg64(v1) { - self.require(ISA_TBM) - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, 0, addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(4, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for TZMSK") - } - return p -} - -// UCOMISD performs "Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS". -// -// Mnemonic : UCOMISD -// Supported forms : (2 forms) -// -// * UCOMISD xmm, xmm [SSE2] -// * UCOMISD m64, xmm [SSE2] -// -func (self *Program) UCOMISD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("UCOMISD", 2, Operands { v0, v1 }) - // UCOMISD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // UCOMISD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for UCOMISD") - } - return p -} - -// UCOMISS performs "Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS". -// -// Mnemonic : UCOMISS -// Supported forms : (2 forms) -// -// * UCOMISS xmm, xmm [SSE] -// * UCOMISS m32, xmm [SSE] -// -func (self *Program) UCOMISS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("UCOMISS", 2, Operands { v0, v1 }) - // UCOMISS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x2e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // UCOMISS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x2e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for UCOMISS") - } - return p -} - -// UD2 performs "Undefined Instruction". -// -// Mnemonic : UD2 -// Supported forms : (1 form) -// -// * UD2 -// -func (self *Program) UD2() *Instruction { - p := self.alloc("UD2", 0, Operands { }) - // UD2 - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x0b) - }) - return p -} - -// UNPCKHPD performs "Unpack and Interleave High Packed Double-Precision Floating-Point Values". -// -// Mnemonic : UNPCKHPD -// Supported forms : (2 forms) -// -// * UNPCKHPD xmm, xmm [SSE2] -// * UNPCKHPD m128, xmm [SSE2] -// -func (self *Program) UNPCKHPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("UNPCKHPD", 2, Operands { v0, v1 }) - // UNPCKHPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x15) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // UNPCKHPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x15) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for UNPCKHPD") - } - return p -} - -// UNPCKHPS performs "Unpack and Interleave High Packed Single-Precision Floating-Point Values". -// -// Mnemonic : UNPCKHPS -// Supported forms : (2 forms) -// -// * UNPCKHPS xmm, xmm [SSE] -// * UNPCKHPS m128, xmm [SSE] -// -func (self *Program) UNPCKHPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("UNPCKHPS", 2, Operands { v0, v1 }) - // UNPCKHPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x15) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // UNPCKHPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x15) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for UNPCKHPS") - } - return p -} - -// UNPCKLPD performs "Unpack and Interleave Low Packed Double-Precision Floating-Point Values". -// -// Mnemonic : UNPCKLPD -// Supported forms : (2 forms) -// -// * UNPCKLPD xmm, xmm [SSE2] -// * UNPCKLPD m128, xmm [SSE2] -// -func (self *Program) UNPCKLPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("UNPCKLPD", 2, Operands { v0, v1 }) - // UNPCKLPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x14) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // UNPCKLPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x14) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for UNPCKLPD") - } - return p -} - -// UNPCKLPS performs "Unpack and Interleave Low Packed Single-Precision Floating-Point Values". -// -// Mnemonic : UNPCKLPS -// Supported forms : (2 forms) -// -// * UNPCKLPS xmm, xmm [SSE] -// * UNPCKLPS m128, xmm [SSE] -// -func (self *Program) UNPCKLPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("UNPCKLPS", 2, Operands { v0, v1 }) - // UNPCKLPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x14) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // UNPCKLPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x14) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for UNPCKLPS") - } - return p -} - -// VADDPD performs "Add Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VADDPD -// Supported forms : (11 forms) -// -// * VADDPD xmm, xmm, xmm [AVX] -// * VADDPD m128, xmm, xmm [AVX] -// * VADDPD ymm, ymm, ymm [AVX] -// * VADDPD m256, ymm, ymm [AVX] -// * VADDPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VADDPD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VADDPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VADDPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VADDPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VADDPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VADDPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VADDPD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VADDPD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VADDPD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VADDPD takes 3 or 4 operands") - } - // VADDPD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDPD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VADDPD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDPD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VADDPD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VADDPD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x58) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VADDPD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDPD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VADDPD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDPD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VADDPD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VADDPD") - } - return p -} - -// VADDPS performs "Add Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VADDPS -// Supported forms : (11 forms) -// -// * VADDPS xmm, xmm, xmm [AVX] -// * VADDPS m128, xmm, xmm [AVX] -// * VADDPS ymm, ymm, ymm [AVX] -// * VADDPS m256, ymm, ymm [AVX] -// * VADDPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VADDPS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VADDPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VADDPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VADDPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VADDPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VADDPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VADDPS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VADDPS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VADDPS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VADDPS takes 3 or 4 operands") - } - // VADDPS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDPS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VADDPS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDPS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VADDPS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VADDPS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x58) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VADDPS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDPS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VADDPS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDPS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VADDPS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VADDPS") - } - return p -} - -// VADDSD performs "Add Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VADDSD -// Supported forms : (5 forms) -// -// * VADDSD xmm, xmm, xmm [AVX] -// * VADDSD m64, xmm, xmm [AVX] -// * VADDSD m64, xmm, xmm{k}{z} [AVX512F] -// * VADDSD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VADDSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VADDSD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VADDSD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VADDSD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VADDSD takes 3 or 4 operands") - } - // VADDSD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDSD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VADDSD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VADDSD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x58) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VADDSD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VADDSD") - } - return p -} - -// VADDSS performs "Add Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VADDSS -// Supported forms : (5 forms) -// -// * VADDSS xmm, xmm, xmm [AVX] -// * VADDSS m32, xmm, xmm [AVX] -// * VADDSS m32, xmm, xmm{k}{z} [AVX512F] -// * VADDSS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VADDSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VADDSS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VADDSS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VADDSS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VADDSS takes 3 or 4 operands") - } - // VADDSS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDSS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VADDSS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x58) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VADDSS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x58) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VADDSS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x58) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VADDSS") - } - return p -} - -// VADDSUBPD performs "Packed Double-FP Add/Subtract". -// -// Mnemonic : VADDSUBPD -// Supported forms : (4 forms) -// -// * VADDSUBPD xmm, xmm, xmm [AVX] -// * VADDSUBPD m128, xmm, xmm [AVX] -// * VADDSUBPD ymm, ymm, ymm [AVX] -// * VADDSUBPD m256, ymm, ymm [AVX] -// -func (self *Program) VADDSUBPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VADDSUBPD", 3, Operands { v0, v1, v2 }) - // VADDSUBPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDSUBPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd0) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VADDSUBPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDSUBPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd0) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VADDSUBPD") - } - return p -} - -// VADDSUBPS performs "Packed Single-FP Add/Subtract". -// -// Mnemonic : VADDSUBPS -// Supported forms : (4 forms) -// -// * VADDSUBPS xmm, xmm, xmm [AVX] -// * VADDSUBPS m128, xmm, xmm [AVX] -// * VADDSUBPS ymm, ymm, ymm [AVX] -// * VADDSUBPS m256, ymm, ymm [AVX] -// -func (self *Program) VADDSUBPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VADDSUBPS", 3, Operands { v0, v1, v2 }) - // VADDSUBPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDSUBPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd0) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VADDSUBPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VADDSUBPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd0) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VADDSUBPS") - } - return p -} - -// VAESDEC performs "Perform One Round of an AES Decryption Flow". -// -// Mnemonic : VAESDEC -// Supported forms : (2 forms) -// -// * VAESDEC xmm, xmm, xmm [AES,AVX] -// * VAESDEC m128, xmm, xmm [AES,AVX] -// -func (self *Program) VAESDEC(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VAESDEC", 3, Operands { v0, v1, v2 }) - // VAESDEC xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xde) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VAESDEC m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xde) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VAESDEC") - } - return p -} - -// VAESDECLAST performs "Perform Last Round of an AES Decryption Flow". -// -// Mnemonic : VAESDECLAST -// Supported forms : (2 forms) -// -// * VAESDECLAST xmm, xmm, xmm [AES,AVX] -// * VAESDECLAST m128, xmm, xmm [AES,AVX] -// -func (self *Program) VAESDECLAST(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VAESDECLAST", 3, Operands { v0, v1, v2 }) - // VAESDECLAST xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VAESDECLAST m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VAESDECLAST") - } - return p -} - -// VAESENC performs "Perform One Round of an AES Encryption Flow". -// -// Mnemonic : VAESENC -// Supported forms : (2 forms) -// -// * VAESENC xmm, xmm, xmm [AES,AVX] -// * VAESENC m128, xmm, xmm [AES,AVX] -// -func (self *Program) VAESENC(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VAESENC", 3, Operands { v0, v1, v2 }) - // VAESENC xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xdc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VAESENC m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdc) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VAESENC") - } - return p -} - -// VAESENCLAST performs "Perform Last Round of an AES Encryption Flow". -// -// Mnemonic : VAESENCLAST -// Supported forms : (2 forms) -// -// * VAESENCLAST xmm, xmm, xmm [AES,AVX] -// * VAESENCLAST m128, xmm, xmm [AES,AVX] -// -func (self *Program) VAESENCLAST(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VAESENCLAST", 3, Operands { v0, v1, v2 }) - // VAESENCLAST xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xdd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VAESENCLAST m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdd) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VAESENCLAST") - } - return p -} - -// VAESIMC performs "Perform the AES InvMixColumn Transformation". -// -// Mnemonic : VAESIMC -// Supported forms : (2 forms) -// -// * VAESIMC xmm, xmm [AES,AVX] -// * VAESIMC m128, xmm [AES,AVX] -// -func (self *Program) VAESIMC(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VAESIMC", 2, Operands { v0, v1 }) - // VAESIMC xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VAESIMC m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0xdb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VAESIMC") - } - return p -} - -// VAESKEYGENASSIST performs "AES Round Key Generation Assist". -// -// Mnemonic : VAESKEYGENASSIST -// Supported forms : (2 forms) -// -// * VAESKEYGENASSIST imm8, xmm, xmm [AES,AVX] -// * VAESKEYGENASSIST imm8, m128, xmm [AES,AVX] -// -func (self *Program) VAESKEYGENASSIST(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VAESKEYGENASSIST", 3, Operands { v0, v1, v2 }) - // VAESKEYGENASSIST imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VAESKEYGENASSIST imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX | ISA_AES) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[2]), addr(v[1]), 0) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VAESKEYGENASSIST") - } - return p -} - -// VALIGND performs "Align Doubleword Vectors". -// -// Mnemonic : VALIGND -// Supported forms : (6 forms) -// -// * VALIGND imm8, m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VALIGND imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VALIGND imm8, m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VALIGND imm8, xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VALIGND imm8, m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VALIGND imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VALIGND(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VALIGND", 4, Operands { v0, v1, v2, v3 }) - // VALIGND imm8, m512/m32bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x03) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGND imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x03) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGND imm8, m128/m32bcst, xmm, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x03) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGND imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x03) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGND imm8, m256/m32bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x03) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGND imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x03) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VALIGND") - } - return p -} - -// VALIGNQ performs "Align Quadword Vectors". -// -// Mnemonic : VALIGNQ -// Supported forms : (6 forms) -// -// * VALIGNQ imm8, m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VALIGNQ imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VALIGNQ imm8, m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VALIGNQ imm8, xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VALIGNQ imm8, m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VALIGNQ imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VALIGNQ(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VALIGNQ", 4, Operands { v0, v1, v2, v3 }) - // VALIGNQ imm8, m512/m64bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x03) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGNQ imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x03) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGNQ imm8, m128/m64bcst, xmm, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x03) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGNQ imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x03) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGNQ imm8, m256/m64bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x03) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VALIGNQ imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x03) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VALIGNQ") - } - return p -} - -// VANDNPD performs "Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VANDNPD -// Supported forms : (10 forms) -// -// * VANDNPD xmm, xmm, xmm [AVX] -// * VANDNPD m128, xmm, xmm [AVX] -// * VANDNPD ymm, ymm, ymm [AVX] -// * VANDNPD m256, ymm, ymm [AVX] -// * VANDNPD m512/m64bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VANDNPD zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VANDNPD m128/m64bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VANDNPD xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VANDNPD m256/m64bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VANDNPD ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VANDNPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VANDNPD", 3, Operands { v0, v1, v2 }) - // VANDNPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDNPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VANDNPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDNPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VANDNPD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VANDNPD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDNPD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VANDNPD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDNPD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VANDNPD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VANDNPD") - } - return p -} - -// VANDNPS performs "Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VANDNPS -// Supported forms : (10 forms) -// -// * VANDNPS xmm, xmm, xmm [AVX] -// * VANDNPS m128, xmm, xmm [AVX] -// * VANDNPS ymm, ymm, ymm [AVX] -// * VANDNPS m256, ymm, ymm [AVX] -// * VANDNPS m512/m32bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VANDNPS zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VANDNPS m128/m32bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VANDNPS xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VANDNPS m256/m32bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VANDNPS ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VANDNPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VANDNPS", 3, Operands { v0, v1, v2 }) - // VANDNPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDNPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VANDNPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDNPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VANDNPS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VANDNPS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDNPS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VANDNPS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDNPS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x55) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VANDNPS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x55) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VANDNPS") - } - return p -} - -// VANDPD performs "Bitwise Logical AND of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VANDPD -// Supported forms : (10 forms) -// -// * VANDPD xmm, xmm, xmm [AVX] -// * VANDPD m128, xmm, xmm [AVX] -// * VANDPD ymm, ymm, ymm [AVX] -// * VANDPD m256, ymm, ymm [AVX] -// * VANDPD m512/m64bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VANDPD zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VANDPD m128/m64bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VANDPD xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VANDPD m256/m64bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VANDPD ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VANDPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VANDPD", 3, Operands { v0, v1, v2 }) - // VANDPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VANDPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VANDPD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VANDPD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDPD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VANDPD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDPD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VANDPD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VANDPD") - } - return p -} - -// VANDPS performs "Bitwise Logical AND of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VANDPS -// Supported forms : (10 forms) -// -// * VANDPS xmm, xmm, xmm [AVX] -// * VANDPS m128, xmm, xmm [AVX] -// * VANDPS ymm, ymm, ymm [AVX] -// * VANDPS m256, ymm, ymm [AVX] -// * VANDPS m512/m32bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VANDPS zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VANDPS m128/m32bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VANDPS xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VANDPS m256/m32bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VANDPS ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VANDPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VANDPS", 3, Operands { v0, v1, v2 }) - // VANDPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VANDPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VANDPS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VANDPS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDPS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VANDPS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VANDPS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x54) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VANDPS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x54) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VANDPS") - } - return p -} - -// VBLENDMPD performs "Blend Packed Double-Precision Floating-Point Vectors Using an OpMask Control". -// -// Mnemonic : VBLENDMPD -// Supported forms : (6 forms) -// -// * VBLENDMPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VBLENDMPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VBLENDMPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VBLENDMPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VBLENDMPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VBLENDMPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VBLENDMPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VBLENDMPD", 3, Operands { v0, v1, v2 }) - // VBLENDMPD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VBLENDMPD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VBLENDMPD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VBLENDMPD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VBLENDMPD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VBLENDMPD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VBLENDMPD") - } - return p -} - -// VBLENDMPS performs "Blend Packed Single-Precision Floating-Point Vectors Using an OpMask Control". -// -// Mnemonic : VBLENDMPS -// Supported forms : (6 forms) -// -// * VBLENDMPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VBLENDMPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VBLENDMPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VBLENDMPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VBLENDMPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VBLENDMPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VBLENDMPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VBLENDMPS", 3, Operands { v0, v1, v2 }) - // VBLENDMPS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VBLENDMPS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VBLENDMPS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VBLENDMPS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VBLENDMPS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VBLENDMPS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VBLENDMPS") - } - return p -} - -// VBLENDPD performs "Blend Packed Double Precision Floating-Point Values". -// -// Mnemonic : VBLENDPD -// Supported forms : (4 forms) -// -// * VBLENDPD imm8, xmm, xmm, xmm [AVX] -// * VBLENDPD imm8, m128, xmm, xmm [AVX] -// * VBLENDPD imm8, ymm, ymm, ymm [AVX] -// * VBLENDPD imm8, m256, ymm, ymm [AVX] -// -func (self *Program) VBLENDPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VBLENDPD", 4, Operands { v0, v1, v2, v3 }) - // VBLENDPD imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x0d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VBLENDPD imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0d) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VBLENDPD imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x0d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VBLENDPD imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0d) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VBLENDPD") - } - return p -} - -// VBLENDPS performs " Blend Packed Single Precision Floating-Point Values". -// -// Mnemonic : VBLENDPS -// Supported forms : (4 forms) -// -// * VBLENDPS imm8, xmm, xmm, xmm [AVX] -// * VBLENDPS imm8, m128, xmm, xmm [AVX] -// * VBLENDPS imm8, ymm, ymm, ymm [AVX] -// * VBLENDPS imm8, m256, ymm, ymm [AVX] -// -func (self *Program) VBLENDPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VBLENDPS", 4, Operands { v0, v1, v2, v3 }) - // VBLENDPS imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x0c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VBLENDPS imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VBLENDPS imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x0c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VBLENDPS imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VBLENDPS") - } - return p -} - -// VBLENDVPD performs " Variable Blend Packed Double Precision Floating-Point Values". -// -// Mnemonic : VBLENDVPD -// Supported forms : (4 forms) -// -// * VBLENDVPD xmm, xmm, xmm, xmm [AVX] -// * VBLENDVPD xmm, m128, xmm, xmm [AVX] -// * VBLENDVPD ymm, ymm, ymm, ymm [AVX] -// * VBLENDVPD ymm, m256, ymm, ymm [AVX] -// -func (self *Program) VBLENDVPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VBLENDVPD", 4, Operands { v0, v1, v2, v3 }) - // VBLENDVPD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VBLENDVPD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x4b) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VBLENDVPD ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x4b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VBLENDVPD ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x4b) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VBLENDVPD") - } - return p -} - -// VBLENDVPS performs " Variable Blend Packed Single Precision Floating-Point Values". -// -// Mnemonic : VBLENDVPS -// Supported forms : (4 forms) -// -// * VBLENDVPS xmm, xmm, xmm, xmm [AVX] -// * VBLENDVPS xmm, m128, xmm, xmm [AVX] -// * VBLENDVPS ymm, ymm, ymm, ymm [AVX] -// * VBLENDVPS ymm, m256, ymm, ymm [AVX] -// -func (self *Program) VBLENDVPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VBLENDVPS", 4, Operands { v0, v1, v2, v3 }) - // VBLENDVPS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VBLENDVPS xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x4a) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VBLENDVPS ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x4a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VBLENDVPS ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x4a) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VBLENDVPS") - } - return p -} - -// VBROADCASTF128 performs "Broadcast 128 Bit of Floating-Point Data". -// -// Mnemonic : VBROADCASTF128 -// Supported forms : (1 form) -// -// * VBROADCASTF128 m128, ymm [AVX] -// -func (self *Program) VBROADCASTF128(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTF128", 2, Operands { v0, v1 }) - // VBROADCASTF128 m128, ymm - if isM128(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x1a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTF128") - } - return p -} - -// VBROADCASTF32X2 performs "Broadcast Two Single-Precision Floating-Point Elements". -// -// Mnemonic : VBROADCASTF32X2 -// Supported forms : (4 forms) -// -// * VBROADCASTF32X2 xmm, zmm{k}{z} [AVX512DQ] -// * VBROADCASTF32X2 m64, zmm{k}{z} [AVX512DQ] -// * VBROADCASTF32X2 xmm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VBROADCASTF32X2 m64, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VBROADCASTF32X2(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTF32X2", 2, Operands { v0, v1 }) - // VBROADCASTF32X2 xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTF32X2 m64, zmm{k}{z} - if isM64(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VBROADCASTF32X2 xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTF32X2 m64, ymm{k}{z} - if isM64(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTF32X2") - } - return p -} - -// VBROADCASTF32X4 performs "Broadcast Four Single-Precision Floating-Point Elements". -// -// Mnemonic : VBROADCASTF32X4 -// Supported forms : (2 forms) -// -// * VBROADCASTF32X4 m128, zmm{k}{z} [AVX512F] -// * VBROADCASTF32X4 m128, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VBROADCASTF32X4(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTF32X4", 2, Operands { v0, v1 }) - // VBROADCASTF32X4 m128, zmm{k}{z} - if isM128(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VBROADCASTF32X4 m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTF32X4") - } - return p -} - -// VBROADCASTF32X8 performs "Broadcast Eight Single-Precision Floating-Point Elements". -// -// Mnemonic : VBROADCASTF32X8 -// Supported forms : (1 form) -// -// * VBROADCASTF32X8 m256, zmm{k}{z} [AVX512DQ] -// -func (self *Program) VBROADCASTF32X8(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTF32X8", 2, Operands { v0, v1 }) - // VBROADCASTF32X8 m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTF32X8") - } - return p -} - -// VBROADCASTF64X2 performs "Broadcast Two Double-Precision Floating-Point Elements". -// -// Mnemonic : VBROADCASTF64X2 -// Supported forms : (2 forms) -// -// * VBROADCASTF64X2 m128, zmm{k}{z} [AVX512DQ] -// * VBROADCASTF64X2 m128, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VBROADCASTF64X2(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTF64X2", 2, Operands { v0, v1 }) - // VBROADCASTF64X2 m128, zmm{k}{z} - if isM128(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VBROADCASTF64X2 m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTF64X2") - } - return p -} - -// VBROADCASTF64X4 performs "Broadcast Four Double-Precision Floating-Point Elements". -// -// Mnemonic : VBROADCASTF64X4 -// Supported forms : (1 form) -// -// * VBROADCASTF64X4 m256, zmm{k}{z} [AVX512F] -// -func (self *Program) VBROADCASTF64X4(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTF64X4", 2, Operands { v0, v1 }) - // VBROADCASTF64X4 m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTF64X4") - } - return p -} - -// VBROADCASTI128 performs "Broadcast 128 Bits of Integer Data". -// -// Mnemonic : VBROADCASTI128 -// Supported forms : (1 form) -// -// * VBROADCASTI128 m128, ymm [AVX2] -// -func (self *Program) VBROADCASTI128(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTI128", 2, Operands { v0, v1 }) - // VBROADCASTI128 m128, ymm - if isM128(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTI128") - } - return p -} - -// VBROADCASTI32X2 performs "Broadcast Two Doubleword Elements". -// -// Mnemonic : VBROADCASTI32X2 -// Supported forms : (6 forms) -// -// * VBROADCASTI32X2 xmm, zmm{k}{z} [AVX512DQ] -// * VBROADCASTI32X2 m64, zmm{k}{z} [AVX512DQ] -// * VBROADCASTI32X2 xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VBROADCASTI32X2 xmm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VBROADCASTI32X2 m64, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VBROADCASTI32X2 m64, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VBROADCASTI32X2(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTI32X2", 2, Operands { v0, v1 }) - // VBROADCASTI32X2 xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTI32X2 m64, zmm{k}{z} - if isM64(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VBROADCASTI32X2 xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTI32X2 xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTI32X2 m64, xmm{k}{z} - if isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VBROADCASTI32X2 m64, ymm{k}{z} - if isM64(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTI32X2") - } - return p -} - -// VBROADCASTI32X4 performs "Broadcast Four Doubleword Elements". -// -// Mnemonic : VBROADCASTI32X4 -// Supported forms : (2 forms) -// -// * VBROADCASTI32X4 m128, zmm{k}{z} [AVX512F] -// * VBROADCASTI32X4 m128, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VBROADCASTI32X4(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTI32X4", 2, Operands { v0, v1 }) - // VBROADCASTI32X4 m128, zmm{k}{z} - if isM128(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VBROADCASTI32X4 m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTI32X4") - } - return p -} - -// VBROADCASTI32X8 performs "Broadcast Eight Doubleword Elements". -// -// Mnemonic : VBROADCASTI32X8 -// Supported forms : (1 form) -// -// * VBROADCASTI32X8 m256, zmm{k}{z} [AVX512DQ] -// -func (self *Program) VBROADCASTI32X8(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTI32X8", 2, Operands { v0, v1 }) - // VBROADCASTI32X8 m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTI32X8") - } - return p -} - -// VBROADCASTI64X2 performs "Broadcast Two Quadword Elements". -// -// Mnemonic : VBROADCASTI64X2 -// Supported forms : (2 forms) -// -// * VBROADCASTI64X2 m128, zmm{k}{z} [AVX512DQ] -// * VBROADCASTI64X2 m128, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VBROADCASTI64X2(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTI64X2", 2, Operands { v0, v1 }) - // VBROADCASTI64X2 m128, zmm{k}{z} - if isM128(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VBROADCASTI64X2 m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTI64X2") - } - return p -} - -// VBROADCASTI64X4 performs "Broadcast Four Quadword Elements". -// -// Mnemonic : VBROADCASTI64X4 -// Supported forms : (1 form) -// -// * VBROADCASTI64X4 m256, zmm{k}{z} [AVX512F] -// -func (self *Program) VBROADCASTI64X4(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTI64X4", 2, Operands { v0, v1 }) - // VBROADCASTI64X4 m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTI64X4") - } - return p -} - -// VBROADCASTSD performs "Broadcast Double-Precision Floating-Point Element". -// -// Mnemonic : VBROADCASTSD -// Supported forms : (6 forms) -// -// * VBROADCASTSD m64, ymm [AVX] -// * VBROADCASTSD xmm, ymm [AVX2] -// * VBROADCASTSD xmm, zmm{k}{z} [AVX512F] -// * VBROADCASTSD m64, zmm{k}{z} [AVX512F] -// * VBROADCASTSD xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VBROADCASTSD m64, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VBROADCASTSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTSD", 2, Operands { v0, v1 }) - // VBROADCASTSD m64, ymm - if isM64(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VBROADCASTSD xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTSD xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTSD m64, zmm{k}{z} - if isM64(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VBROADCASTSD xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTSD m64, ymm{k}{z} - if isM64(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTSD") - } - return p -} - -// VBROADCASTSS performs "Broadcast Single-Precision Floating-Point Element". -// -// Mnemonic : VBROADCASTSS -// Supported forms : (8 forms) -// -// * VBROADCASTSS m32, xmm [AVX] -// * VBROADCASTSS m32, ymm [AVX] -// * VBROADCASTSS xmm, xmm [AVX2] -// * VBROADCASTSS xmm, ymm [AVX2] -// * VBROADCASTSS xmm, zmm{k}{z} [AVX512F] -// * VBROADCASTSS m32, zmm{k}{z} [AVX512F] -// * VBROADCASTSS xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VBROADCASTSS m32, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VBROADCASTSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VBROADCASTSS", 2, Operands { v0, v1 }) - // VBROADCASTSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x18) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VBROADCASTSS m32, ymm - if isM32(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x18) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VBROADCASTSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x18) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTSS xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x18) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTSS xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x18) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTSS m32, zmm{k}{z} - if isM32(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x18) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VBROADCASTSS xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x18) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VBROADCASTSS m32, ymm{k}{z} - if isM32(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x18) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VBROADCASTSS") - } - return p -} - -// VCMPPD performs "Compare Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VCMPPD -// Supported forms : (11 forms) -// -// * VCMPPD imm8, xmm, xmm, xmm [AVX] -// * VCMPPD imm8, m128, xmm, xmm [AVX] -// * VCMPPD imm8, ymm, ymm, ymm [AVX] -// * VCMPPD imm8, m256, ymm, ymm [AVX] -// * VCMPPD imm8, m512/m64bcst, zmm, k{k} [AVX512F] -// * VCMPPD imm8, {sae}, zmm, zmm, k{k} [AVX512F] -// * VCMPPD imm8, zmm, zmm, k{k} [AVX512F] -// * VCMPPD imm8, m128/m64bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VCMPPD imm8, xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VCMPPD imm8, m256/m64bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VCMPPD imm8, ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VCMPPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCMPPD", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VCMPPD", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VCMPPD takes 4 or 5 operands") - } - // VCMPPD imm8, xmm, xmm, xmm - if len(vv) == 0 && isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, m128, xmm, xmm - if len(vv) == 0 && isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, ymm, ymm, ymm - if len(vv) == 0 && isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, m256, ymm, ymm - if len(vv) == 0 && isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, m512/m64bcst, zmm, k{k} - if len(vv) == 0 && isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, {sae}, zmm, zmm, k{k} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMM(v3) && isKk(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0xfd ^ (hlcode(v[3]) << 3)) - m.emit((0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, zmm, zmm, k{k} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, m128/m64bcst, xmm, k{k} - if len(vv) == 0 && isImm8(v0) && isM128M64bcst(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, xmm, xmm, k{k} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, m256/m64bcst, ymm, k{k} - if len(vv) == 0 && isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPD imm8, ymm, ymm, k{k} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCMPPD") - } - return p -} - -// VCMPPS performs "Compare Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VCMPPS -// Supported forms : (11 forms) -// -// * VCMPPS imm8, xmm, xmm, xmm [AVX] -// * VCMPPS imm8, m128, xmm, xmm [AVX] -// * VCMPPS imm8, ymm, ymm, ymm [AVX] -// * VCMPPS imm8, m256, ymm, ymm [AVX] -// * VCMPPS imm8, m512/m32bcst, zmm, k{k} [AVX512F] -// * VCMPPS imm8, {sae}, zmm, zmm, k{k} [AVX512F] -// * VCMPPS imm8, zmm, zmm, k{k} [AVX512F] -// * VCMPPS imm8, m128/m32bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VCMPPS imm8, xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VCMPPS imm8, m256/m32bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VCMPPS imm8, ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VCMPPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCMPPS", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VCMPPS", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VCMPPS takes 4 or 5 operands") - } - // VCMPPS imm8, xmm, xmm, xmm - if len(vv) == 0 && isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, m128, xmm, xmm - if len(vv) == 0 && isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, ymm, ymm, ymm - if len(vv) == 0 && isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, m256, ymm, ymm - if len(vv) == 0 && isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, m512/m32bcst, zmm, k{k} - if len(vv) == 0 && isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, {sae}, zmm, zmm, k{k} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMM(v3) && isKk(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0x7c ^ (hlcode(v[3]) << 3)) - m.emit((0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, zmm, zmm, k{k} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, m128/m32bcst, xmm, k{k} - if len(vv) == 0 && isImm8(v0) && isM128M32bcst(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, xmm, xmm, k{k} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, m256/m32bcst, ymm, k{k} - if len(vv) == 0 && isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPPS imm8, ymm, ymm, k{k} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCMPPS") - } - return p -} - -// VCMPSD performs "Compare Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VCMPSD -// Supported forms : (5 forms) -// -// * VCMPSD imm8, xmm, xmm, xmm [AVX] -// * VCMPSD imm8, m64, xmm, xmm [AVX] -// * VCMPSD imm8, m64, xmm, k{k} [AVX512F] -// * VCMPSD imm8, {sae}, xmm, xmm, k{k} [AVX512F] -// * VCMPSD imm8, xmm, xmm, k{k} [AVX512F] -// -func (self *Program) VCMPSD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCMPSD", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VCMPSD", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VCMPSD takes 4 or 5 operands") - } - // VCMPSD imm8, xmm, xmm, xmm - if len(vv) == 0 && isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPSD imm8, m64, xmm, xmm - if len(vv) == 0 && isImm8(v0) && isM64(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPSD imm8, m64, xmm, k{k} - if len(vv) == 0 && isImm8(v0) && isM64(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 8) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPSD imm8, {sae}, xmm, xmm, k{k} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isKk(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0xff ^ (hlcode(v[3]) << 3)) - m.emit((0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPSD imm8, xmm, xmm, k{k} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCMPSD") - } - return p -} - -// VCMPSS performs "Compare Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VCMPSS -// Supported forms : (5 forms) -// -// * VCMPSS imm8, xmm, xmm, xmm [AVX] -// * VCMPSS imm8, m32, xmm, xmm [AVX] -// * VCMPSS imm8, m32, xmm, k{k} [AVX512F] -// * VCMPSS imm8, {sae}, xmm, xmm, k{k} [AVX512F] -// * VCMPSS imm8, xmm, xmm, k{k} [AVX512F] -// -func (self *Program) VCMPSS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCMPSS", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VCMPSS", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VCMPSS takes 4 or 5 operands") - } - // VCMPSS imm8, xmm, xmm, xmm - if len(vv) == 0 && isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPSS imm8, m32, xmm, xmm - if len(vv) == 0 && isImm8(v0) && isM32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPSS imm8, m32, xmm, k{k} - if len(vv) == 0 && isImm8(v0) && isM32(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0xc2) - m.mrsd(lcode(v[3]), addr(v[1]), 4) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPSS imm8, {sae}, xmm, xmm, k{k} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isKk(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0x7e ^ (hlcode(v[3]) << 3)) - m.emit((0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VCMPSS imm8, xmm, xmm, k{k} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCMPSS") - } - return p -} - -// VCOMISD performs "Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS". -// -// Mnemonic : VCOMISD -// Supported forms : (5 forms) -// -// * VCOMISD xmm, xmm [AVX] -// * VCOMISD m64, xmm [AVX] -// * VCOMISD m64, xmm [AVX512F] -// * VCOMISD {sae}, xmm, xmm [AVX512F] -// * VCOMISD xmm, xmm [AVX512F] -// -func (self *Program) VCOMISD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCOMISD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCOMISD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCOMISD takes 2 or 3 operands") - } - // VCOMISD xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x2f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCOMISD m64, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCOMISD m64, xmm - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2f) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCOMISD {sae}, xmm, xmm - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit(0x18) - m.emit(0x2f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCOMISD xmm, xmm - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit(0x48) - m.emit(0x2f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCOMISD") - } - return p -} - -// VCOMISS performs "Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS". -// -// Mnemonic : VCOMISS -// Supported forms : (5 forms) -// -// * VCOMISS xmm, xmm [AVX] -// * VCOMISS m32, xmm [AVX] -// * VCOMISS m32, xmm [AVX512F] -// * VCOMISS {sae}, xmm, xmm [AVX512F] -// * VCOMISS xmm, xmm [AVX512F] -// -func (self *Program) VCOMISS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCOMISS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCOMISS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCOMISS takes 2 or 3 operands") - } - // VCOMISS xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x2f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCOMISS m32, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCOMISS m32, xmm - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2f) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VCOMISS {sae}, xmm, xmm - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c) - m.emit(0x18) - m.emit(0x2f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCOMISS xmm, xmm - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit(0x48) - m.emit(0x2f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCOMISS") - } - return p -} - -// VCOMPRESSPD performs "Store Sparse Packed Double-Precision Floating-Point Values into Dense Memory/Register". -// -// Mnemonic : VCOMPRESSPD -// Supported forms : (6 forms) -// -// * VCOMPRESSPD zmm, zmm{k}{z} [AVX512F] -// * VCOMPRESSPD zmm, m512{k}{z} [AVX512F] -// * VCOMPRESSPD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCOMPRESSPD xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VCOMPRESSPD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VCOMPRESSPD ymm, m256{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCOMPRESSPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VCOMPRESSPD", 2, Operands { v0, v1 }) - // VCOMPRESSPD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x8a) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VCOMPRESSPD zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8a) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VCOMPRESSPD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x8a) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VCOMPRESSPD xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8a) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VCOMPRESSPD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x8a) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VCOMPRESSPD ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8a) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VCOMPRESSPD") - } - return p -} - -// VCOMPRESSPS performs "Store Sparse Packed Single-Precision Floating-Point Values into Dense Memory/Register". -// -// Mnemonic : VCOMPRESSPS -// Supported forms : (6 forms) -// -// * VCOMPRESSPS zmm, zmm{k}{z} [AVX512F] -// * VCOMPRESSPS zmm, m512{k}{z} [AVX512F] -// * VCOMPRESSPS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCOMPRESSPS xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VCOMPRESSPS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VCOMPRESSPS ymm, m256{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCOMPRESSPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VCOMPRESSPS", 2, Operands { v0, v1 }) - // VCOMPRESSPS zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x8a) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VCOMPRESSPS zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8a) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VCOMPRESSPS xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x8a) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VCOMPRESSPS xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8a) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VCOMPRESSPS ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x8a) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VCOMPRESSPS ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8a) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VCOMPRESSPS") - } - return p -} - -// VCVTDQ2PD performs "Convert Packed Dword Integers to Packed Double-Precision FP Values". -// -// Mnemonic : VCVTDQ2PD -// Supported forms : (10 forms) -// -// * VCVTDQ2PD xmm, xmm [AVX] -// * VCVTDQ2PD m64, xmm [AVX] -// * VCVTDQ2PD xmm, ymm [AVX] -// * VCVTDQ2PD m128, ymm [AVX] -// * VCVTDQ2PD m256/m32bcst, zmm{k}{z} [AVX512F] -// * VCVTDQ2PD ymm, zmm{k}{z} [AVX512F] -// * VCVTDQ2PD m64/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTDQ2PD m128/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VCVTDQ2PD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTDQ2PD xmm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTDQ2PD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VCVTDQ2PD", 2, Operands { v0, v1 }) - // VCVTDQ2PD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), v[0], 0) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTDQ2PD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), addr(v[0]), 0) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTDQ2PD xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), v[0], 0) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTDQ2PD m128, ymm - if isM128(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), addr(v[0]), 0) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTDQ2PD m256/m32bcst, zmm{k}{z} - if isM256M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTDQ2PD ymm, zmm{k}{z} - if isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTDQ2PD m64/m32bcst, xmm{k}{z} - if isM64M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTDQ2PD m128/m32bcst, ymm{k}{z} - if isM128M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTDQ2PD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTDQ2PD xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTDQ2PD") - } - return p -} - -// VCVTDQ2PS performs "Convert Packed Dword Integers to Packed Single-Precision FP Values". -// -// Mnemonic : VCVTDQ2PS -// Supported forms : (11 forms) -// -// * VCVTDQ2PS xmm, xmm [AVX] -// * VCVTDQ2PS m128, xmm [AVX] -// * VCVTDQ2PS ymm, ymm [AVX] -// * VCVTDQ2PS m256, ymm [AVX] -// * VCVTDQ2PS m512/m32bcst, zmm{k}{z} [AVX512F] -// * VCVTDQ2PS {er}, zmm, zmm{k}{z} [AVX512F] -// * VCVTDQ2PS zmm, zmm{k}{z} [AVX512F] -// * VCVTDQ2PS m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTDQ2PS m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VCVTDQ2PS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTDQ2PS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTDQ2PS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTDQ2PS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTDQ2PS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTDQ2PS takes 2 or 3 operands") - } - // VCVTDQ2PS xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTDQ2PS m128, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTDQ2PS ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), v[0], 0) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTDQ2PS m256, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTDQ2PS m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTDQ2PS {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTDQ2PS zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTDQ2PS m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTDQ2PS m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTDQ2PS xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTDQ2PS ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTDQ2PS") - } - return p -} - -// VCVTPD2DQ performs "Convert Packed Double-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : VCVTPD2DQ -// Supported forms : (11 forms) -// -// * VCVTPD2DQ xmm, xmm [AVX] -// * VCVTPD2DQ ymm, xmm [AVX] -// * VCVTPD2DQ m128, xmm [AVX] -// * VCVTPD2DQ m256, xmm [AVX] -// * VCVTPD2DQ m512/m64bcst, ymm{k}{z} [AVX512F] -// * VCVTPD2DQ {er}, zmm, ymm{k}{z} [AVX512F] -// * VCVTPD2DQ zmm, ymm{k}{z} [AVX512F] -// * VCVTPD2DQ m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPD2DQ m256/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPD2DQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPD2DQ ymm, xmm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTPD2DQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPD2DQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPD2DQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPD2DQ takes 2 or 3 operands") - } - // VCVTPD2DQ xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), v[0], 0) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2DQ ymm, xmm - if len(vv) == 0 && isYMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[1]), v[0], 0) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2DQ m128, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), addr(v[0]), 0) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPD2DQ m256, xmm - if len(vv) == 0 && isM256(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[1]), addr(v[0]), 0) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPD2DQ m512/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTPD2DQ {er}, zmm, ymm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isYMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPD2DQ zmm, ymm{k}{z} - if len(vv) == 0 && isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2DQ m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPD2DQ m256/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPD2DQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2DQ ymm, xmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPD2DQ") - } - return p -} - -// VCVTPD2PS performs "Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values". -// -// Mnemonic : VCVTPD2PS -// Supported forms : (11 forms) -// -// * VCVTPD2PS xmm, xmm [AVX] -// * VCVTPD2PS ymm, xmm [AVX] -// * VCVTPD2PS m128, xmm [AVX] -// * VCVTPD2PS m256, xmm [AVX] -// * VCVTPD2PS m512/m64bcst, ymm{k}{z} [AVX512F] -// * VCVTPD2PS {er}, zmm, ymm{k}{z} [AVX512F] -// * VCVTPD2PS zmm, ymm{k}{z} [AVX512F] -// * VCVTPD2PS m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPD2PS m256/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPD2PS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPD2PS ymm, xmm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTPD2PS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPD2PS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPD2PS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPD2PS takes 2 or 3 operands") - } - // VCVTPD2PS xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2PS ymm, xmm - if len(vv) == 0 && isYMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), v[0], 0) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2PS m128, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPD2PS m256, xmm - if len(vv) == 0 && isM256(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPD2PS m512/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTPD2PS {er}, zmm, ymm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isYMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPD2PS zmm, ymm{k}{z} - if len(vv) == 0 && isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2PS m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPD2PS m256/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPD2PS xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2PS ymm, xmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPD2PS") - } - return p -} - -// VCVTPD2QQ performs "Convert Packed Double-Precision Floating-Point Values to Packed Quadword Integers". -// -// Mnemonic : VCVTPD2QQ -// Supported forms : (7 forms) -// -// * VCVTPD2QQ m512/m64bcst, zmm{k}{z} [AVX512DQ] -// * VCVTPD2QQ {er}, zmm, zmm{k}{z} [AVX512DQ] -// * VCVTPD2QQ zmm, zmm{k}{z} [AVX512DQ] -// * VCVTPD2QQ m128/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPD2QQ m256/m64bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPD2QQ xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPD2QQ ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTPD2QQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPD2QQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPD2QQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPD2QQ takes 2 or 3 operands") - } - // VCVTPD2QQ m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7b) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTPD2QQ {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPD2QQ zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2QQ m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7b) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPD2QQ m256/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPD2QQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2QQ ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPD2QQ") - } - return p -} - -// VCVTPD2UDQ performs "Convert Packed Double-Precision Floating-Point Values to Packed Unsigned Doubleword Integers". -// -// Mnemonic : VCVTPD2UDQ -// Supported forms : (7 forms) -// -// * VCVTPD2UDQ m512/m64bcst, ymm{k}{z} [AVX512F] -// * VCVTPD2UDQ {er}, zmm, ymm{k}{z} [AVX512F] -// * VCVTPD2UDQ zmm, ymm{k}{z} [AVX512F] -// * VCVTPD2UDQ m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPD2UDQ m256/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPD2UDQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPD2UDQ ymm, xmm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTPD2UDQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPD2UDQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPD2UDQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPD2UDQ takes 2 or 3 operands") - } - // VCVTPD2UDQ m512/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x84, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTPD2UDQ {er}, zmm, ymm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isYMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x79) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPD2UDQ zmm, ymm{k}{z} - if len(vv) == 0 && isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2UDQ m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x84, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPD2UDQ m256/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x84, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPD2UDQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2UDQ ymm, xmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPD2UDQ") - } - return p -} - -// VCVTPD2UQQ performs "Convert Packed Double-Precision Floating-Point Values to Packed Unsigned Quadword Integers". -// -// Mnemonic : VCVTPD2UQQ -// Supported forms : (7 forms) -// -// * VCVTPD2UQQ m512/m64bcst, zmm{k}{z} [AVX512DQ] -// * VCVTPD2UQQ {er}, zmm, zmm{k}{z} [AVX512DQ] -// * VCVTPD2UQQ zmm, zmm{k}{z} [AVX512DQ] -// * VCVTPD2UQQ m128/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPD2UQQ m256/m64bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPD2UQQ xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPD2UQQ ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTPD2UQQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPD2UQQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPD2UQQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPD2UQQ takes 2 or 3 operands") - } - // VCVTPD2UQQ m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTPD2UQQ {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x79) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPD2UQQ zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2UQQ m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPD2UQQ m256/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPD2UQQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPD2UQQ ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPD2UQQ") - } - return p -} - -// VCVTPH2PS performs "Convert Half-Precision FP Values to Single-Precision FP Values". -// -// Mnemonic : VCVTPH2PS -// Supported forms : (11 forms) -// -// * VCVTPH2PS xmm, xmm [F16C] -// * VCVTPH2PS m64, xmm [F16C] -// * VCVTPH2PS xmm, ymm [F16C] -// * VCVTPH2PS m128, ymm [F16C] -// * VCVTPH2PS m256, zmm{k}{z} [AVX512F] -// * VCVTPH2PS {sae}, ymm, zmm{k}{z} [AVX512F] -// * VCVTPH2PS ymm, zmm{k}{z} [AVX512F] -// * VCVTPH2PS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPH2PS xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VCVTPH2PS m64, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPH2PS m128, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTPH2PS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPH2PS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPH2PS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPH2PS takes 2 or 3 operands") - } - // VCVTPH2PS xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_F16C) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x13) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPH2PS m64, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) { - self.require(ISA_F16C) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x13) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPH2PS xmm, ymm - if len(vv) == 0 && isXMM(v0) && isYMM(v1) { - self.require(ISA_F16C) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x13) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPH2PS m128, ymm - if len(vv) == 0 && isM128(v0) && isYMM(v1) { - self.require(ISA_F16C) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x13) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPH2PS m256, zmm{k}{z} - if len(vv) == 0 && isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x13) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPH2PS {sae}, ymm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXYMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x13) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPH2PS ymm, zmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x13) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPH2PS xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x13) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPH2PS xmm, ymm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x13) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPH2PS m64, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x13) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTPH2PS m128, ymm{k}{z} - if len(vv) == 0 && isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x13) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPH2PS") - } - return p -} - -// VCVTPS2DQ performs "Convert Packed Single-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : VCVTPS2DQ -// Supported forms : (11 forms) -// -// * VCVTPS2DQ xmm, xmm [AVX] -// * VCVTPS2DQ m128, xmm [AVX] -// * VCVTPS2DQ ymm, ymm [AVX] -// * VCVTPS2DQ m256, ymm [AVX] -// * VCVTPS2DQ m512/m32bcst, zmm{k}{z} [AVX512F] -// * VCVTPS2DQ {er}, zmm, zmm{k}{z} [AVX512F] -// * VCVTPS2DQ zmm, zmm{k}{z} [AVX512F] -// * VCVTPS2DQ m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2DQ m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2DQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2DQ ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTPS2DQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPS2DQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPS2DQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPS2DQ takes 2 or 3 operands") - } - // VCVTPS2DQ xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2DQ m128, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPS2DQ ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), v[0], 0) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2DQ m256, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPS2DQ m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTPS2DQ {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPS2DQ zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2DQ m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPS2DQ m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPS2DQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2DQ ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPS2DQ") - } - return p -} - -// VCVTPS2PD performs "Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values". -// -// Mnemonic : VCVTPS2PD -// Supported forms : (11 forms) -// -// * VCVTPS2PD xmm, xmm [AVX] -// * VCVTPS2PD m64, xmm [AVX] -// * VCVTPS2PD xmm, ymm [AVX] -// * VCVTPS2PD m128, ymm [AVX] -// * VCVTPS2PD m256/m32bcst, zmm{k}{z} [AVX512F] -// * VCVTPS2PD {sae}, ymm, zmm{k}{z} [AVX512F] -// * VCVTPS2PD ymm, zmm{k}{z} [AVX512F] -// * VCVTPS2PD m64/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2PD m128/m32bcst, ymm{k}{z} [AVX512VL] -// * VCVTPS2PD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2PD xmm, ymm{k}{z} [AVX512VL] -// -func (self *Program) VCVTPS2PD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPS2PD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPS2PD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPS2PD takes 2 or 3 operands") - } - // VCVTPS2PD xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2PD m64, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPS2PD xmm, ymm - if len(vv) == 0 && isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), v[0], 0) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2PD m128, ymm - if len(vv) == 0 && isM128(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTPS2PD m256/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPS2PD {sae}, ymm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXYMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPS2PD ymm, zmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2PD m64/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM64M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTPS2PD m128/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPS2PD xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2PD xmm, ymm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPS2PD") - } - return p -} - -// VCVTPS2PH performs "Convert Single-Precision FP value to Half-Precision FP value". -// -// Mnemonic : VCVTPS2PH -// Supported forms : (11 forms) -// -// * VCVTPS2PH imm8, xmm, xmm [F16C] -// * VCVTPS2PH imm8, ymm, xmm [F16C] -// * VCVTPS2PH imm8, xmm, m64 [F16C] -// * VCVTPS2PH imm8, ymm, m128 [F16C] -// * VCVTPS2PH imm8, zmm, m256{k}{z} [AVX512F] -// * VCVTPS2PH imm8, {sae}, zmm, ymm{k}{z} [AVX512F] -// * VCVTPS2PH imm8, zmm, ymm{k}{z} [AVX512F] -// * VCVTPS2PH imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2PH imm8, xmm, m64{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2PH imm8, ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2PH imm8, ymm, m128{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTPS2PH(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPS2PH", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VCVTPS2PH", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VCVTPS2PH takes 3 or 4 operands") - } - // VCVTPS2PH imm8, xmm, xmm - if len(vv) == 0 && isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_F16C) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[1]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x79) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, ymm, xmm - if len(vv) == 0 && isImm8(v0) && isYMM(v1) && isXMM(v2) { - self.require(ISA_F16C) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[1]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x7d) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, xmm, m64 - if len(vv) == 0 && isImm8(v0) && isXMM(v1) && isM64(v2) { - self.require(ISA_F16C) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[1]), addr(v[2]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, ymm, m128 - if len(vv) == 0 && isImm8(v0) && isYMM(v1) && isM128(v2) { - self.require(ISA_F16C) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[1]), addr(v[2]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, zmm, m256{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isM256kz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[2]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, {sae}, zmm, ymm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isYMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[3]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[3]) << 7) | kcode(v[3]) | 0x18) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[3])) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, zmm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, xmm, m64{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isM64kz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[2]), 8) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, ymm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VCVTPS2PH imm8, ymm, m128{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isM128kz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[2]), 16) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPS2PH") - } - return p -} - -// VCVTPS2QQ performs "Convert Packed Single Precision Floating-Point Values to Packed Singed Quadword Integer Values". -// -// Mnemonic : VCVTPS2QQ -// Supported forms : (7 forms) -// -// * VCVTPS2QQ m256/m32bcst, zmm{k}{z} [AVX512DQ] -// * VCVTPS2QQ {er}, ymm, zmm{k}{z} [AVX512DQ] -// * VCVTPS2QQ ymm, zmm{k}{z} [AVX512DQ] -// * VCVTPS2QQ m64/m32bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPS2QQ m128/m32bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPS2QQ xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPS2QQ xmm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTPS2QQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPS2QQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPS2QQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPS2QQ takes 2 or 3 operands") - } - // VCVTPS2QQ m256/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPS2QQ {er}, ymm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXYMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPS2QQ ymm, zmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2QQ m64/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM64M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7b) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTPS2QQ m128/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7b) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPS2QQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2QQ xmm, ymm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPS2QQ") - } - return p -} - -// VCVTPS2UDQ performs "Convert Packed Single-Precision Floating-Point Values to Packed Unsigned Doubleword Integer Values". -// -// Mnemonic : VCVTPS2UDQ -// Supported forms : (7 forms) -// -// * VCVTPS2UDQ m512/m32bcst, zmm{k}{z} [AVX512F] -// * VCVTPS2UDQ {er}, zmm, zmm{k}{z} [AVX512F] -// * VCVTPS2UDQ zmm, zmm{k}{z} [AVX512F] -// * VCVTPS2UDQ m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2UDQ m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2UDQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTPS2UDQ ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTPS2UDQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPS2UDQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPS2UDQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPS2UDQ takes 2 or 3 operands") - } - // VCVTPS2UDQ m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTPS2UDQ {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x79) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPS2UDQ zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2UDQ m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPS2UDQ m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPS2UDQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2UDQ ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPS2UDQ") - } - return p -} - -// VCVTPS2UQQ performs "Convert Packed Single Precision Floating-Point Values to Packed Unsigned Quadword Integer Values". -// -// Mnemonic : VCVTPS2UQQ -// Supported forms : (7 forms) -// -// * VCVTPS2UQQ m256/m32bcst, zmm{k}{z} [AVX512DQ] -// * VCVTPS2UQQ {er}, ymm, zmm{k}{z} [AVX512DQ] -// * VCVTPS2UQQ ymm, zmm{k}{z} [AVX512DQ] -// * VCVTPS2UQQ m64/m32bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPS2UQQ m128/m32bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPS2UQQ xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTPS2UQQ xmm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTPS2UQQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTPS2UQQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTPS2UQQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTPS2UQQ takes 2 or 3 operands") - } - // VCVTPS2UQQ m256/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTPS2UQQ {er}, ymm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXYMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x79) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTPS2UQQ ymm, zmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2UQQ m64/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM64M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTPS2UQQ m128/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTPS2UQQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTPS2UQQ xmm, ymm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTPS2UQQ") - } - return p -} - -// VCVTQQ2PD performs "Convert Packed Quadword Integers to Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VCVTQQ2PD -// Supported forms : (7 forms) -// -// * VCVTQQ2PD m512/m64bcst, zmm{k}{z} [AVX512DQ] -// * VCVTQQ2PD {er}, zmm, zmm{k}{z} [AVX512DQ] -// * VCVTQQ2PD zmm, zmm{k}{z} [AVX512DQ] -// * VCVTQQ2PD m128/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTQQ2PD m256/m64bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTQQ2PD xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTQQ2PD ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTQQ2PD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTQQ2PD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTQQ2PD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTQQ2PD takes 2 or 3 operands") - } - // VCVTQQ2PD m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTQQ2PD {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTQQ2PD zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTQQ2PD m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTQQ2PD m256/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTQQ2PD xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTQQ2PD ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTQQ2PD") - } - return p -} - -// VCVTQQ2PS performs "Convert Packed Quadword Integers to Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VCVTQQ2PS -// Supported forms : (7 forms) -// -// * VCVTQQ2PS m512/m64bcst, ymm{k}{z} [AVX512DQ] -// * VCVTQQ2PS {er}, zmm, ymm{k}{z} [AVX512DQ] -// * VCVTQQ2PS zmm, ymm{k}{z} [AVX512DQ] -// * VCVTQQ2PS m128/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTQQ2PS m256/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTQQ2PS xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTQQ2PS ymm, xmm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTQQ2PS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTQQ2PS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTQQ2PS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTQQ2PS takes 2 or 3 operands") - } - // VCVTQQ2PS m512/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x84, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTQQ2PS {er}, zmm, ymm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isYMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTQQ2PS zmm, ymm{k}{z} - if len(vv) == 0 && isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTQQ2PS m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x84, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTQQ2PS m256/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x84, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTQQ2PS xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTQQ2PS ymm, xmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTQQ2PS") - } - return p -} - -// VCVTSD2SI performs "Convert Scalar Double-Precision FP Value to Integer". -// -// Mnemonic : VCVTSD2SI -// Supported forms : (10 forms) -// -// * VCVTSD2SI xmm, r32 [AVX] -// * VCVTSD2SI m64, r32 [AVX] -// * VCVTSD2SI xmm, r64 [AVX] -// * VCVTSD2SI m64, r64 [AVX] -// * VCVTSD2SI m64, r32 [AVX512F] -// * VCVTSD2SI m64, r64 [AVX512F] -// * VCVTSD2SI {er}, xmm, r32 [AVX512F] -// * VCVTSD2SI {er}, xmm, r64 [AVX512F] -// * VCVTSD2SI xmm, r32 [AVX512F] -// * VCVTSD2SI xmm, r64 [AVX512F] -// -func (self *Program) VCVTSD2SI(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTSD2SI", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTSD2SI", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTSD2SI takes 2 or 3 operands") - } - // VCVTSD2SI xmm, r32 - if len(vv) == 0 && isXMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), v[0], 0) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTSD2SI m64, r32 - if len(vv) == 0 && isM64(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTSD2SI xmm, r64 - if len(vv) == 0 && isXMM(v0) && isReg64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfb) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTSD2SI m64, r64 - if len(vv) == 0 && isM64(v0) && isReg64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x83, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTSD2SI m64, r32 - if len(vv) == 0 && isM64(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTSD2SI m64, r64 - if len(vv) == 0 && isM64(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTSD2SI {er}, xmm, r32 - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isReg32(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f) - m.emit((vcode(v[0]) << 5) | 0x18) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTSD2SI {er}, xmm, r64 - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isReg64(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff) - m.emit((vcode(v[0]) << 5) | 0x18) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTSD2SI xmm, r32 - if len(vv) == 0 && isEVEXXMM(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit(0x48) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTSD2SI xmm, r64 - if len(vv) == 0 && isEVEXXMM(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit(0x48) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTSD2SI") - } - return p -} - -// VCVTSD2SS performs "Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value". -// -// Mnemonic : VCVTSD2SS -// Supported forms : (5 forms) -// -// * VCVTSD2SS xmm, xmm, xmm [AVX] -// * VCVTSD2SS m64, xmm, xmm [AVX] -// * VCVTSD2SS m64, xmm, xmm{k}{z} [AVX512F] -// * VCVTSD2SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VCVTSD2SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VCVTSD2SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTSD2SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VCVTSD2SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VCVTSD2SS takes 3 or 4 operands") - } - // VCVTSD2SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTSD2SS m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VCVTSD2SS m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VCVTSD2SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VCVTSD2SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTSD2SS") - } - return p -} - -// VCVTSD2USI performs "Convert Scalar Double-Precision Floating-Point Value to Unsigned Doubleword Integer". -// -// Mnemonic : VCVTSD2USI -// Supported forms : (6 forms) -// -// * VCVTSD2USI m64, r32 [AVX512F] -// * VCVTSD2USI m64, r64 [AVX512F] -// * VCVTSD2USI {er}, xmm, r32 [AVX512F] -// * VCVTSD2USI {er}, xmm, r64 [AVX512F] -// * VCVTSD2USI xmm, r32 [AVX512F] -// * VCVTSD2USI xmm, r64 [AVX512F] -// -func (self *Program) VCVTSD2USI(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTSD2USI", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTSD2USI", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTSD2USI takes 2 or 3 operands") - } - // VCVTSD2USI m64, r32 - if len(vv) == 0 && isM64(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTSD2USI m64, r64 - if len(vv) == 0 && isM64(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTSD2USI {er}, xmm, r32 - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isReg32(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f) - m.emit((vcode(v[0]) << 5) | 0x18) - m.emit(0x79) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTSD2USI {er}, xmm, r64 - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isReg64(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff) - m.emit((vcode(v[0]) << 5) | 0x18) - m.emit(0x79) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTSD2USI xmm, r32 - if len(vv) == 0 && isEVEXXMM(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit(0x48) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTSD2USI xmm, r64 - if len(vv) == 0 && isEVEXXMM(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit(0x48) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTSD2USI") - } - return p -} - -// VCVTSI2SD performs "Convert Dword Integer to Scalar Double-Precision FP Value". -// -// Mnemonic : VCVTSI2SD -// Supported forms : (9 forms) -// -// * VCVTSI2SD r32, xmm, xmm [AVX] -// * VCVTSI2SD r64, xmm, xmm [AVX] -// * VCVTSI2SD m32, xmm, xmm [AVX] -// * VCVTSI2SD m64, xmm, xmm [AVX] -// * VCVTSI2SD r32, xmm, xmm [AVX512F] -// * VCVTSI2SD m32, xmm, xmm [AVX512F] -// * VCVTSI2SD m64, xmm, xmm [AVX512F] -// * VCVTSI2SD {er}, r64, xmm, xmm [AVX512F] -// * VCVTSI2SD r64, xmm, xmm [AVX512F] -// -func (self *Program) VCVTSI2SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTSI2SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VCVTSI2SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VCVTSI2SD takes 3 or 4 operands") - } - // VCVTSI2SD r32, xmm, xmm - if len(vv) == 0 && isReg32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTSI2SD r64, xmm, xmm - if len(vv) == 0 && isReg64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfb ^ (hlcode(v[1]) << 3)) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTSI2SD m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VCVTSI2SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x83, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VCVTSI2SD r32, xmm, xmm - if len(vv) == 0 && isReg32(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x00) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTSI2SD m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x2a) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VCVTSI2SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x2a) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VCVTSI2SD {er}, r64, xmm, xmm - if len(vv) == 1 && isER(v0) && isReg64(v1) && isEVEXXMM(v2) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | 0x10) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VCVTSI2SD r64, xmm, xmm - if len(vv) == 0 && isReg64(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x40) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTSI2SD") - } - return p -} - -// VCVTSI2SS performs "Convert Dword Integer to Scalar Single-Precision FP Value". -// -// Mnemonic : VCVTSI2SS -// Supported forms : (10 forms) -// -// * VCVTSI2SS r32, xmm, xmm [AVX] -// * VCVTSI2SS r64, xmm, xmm [AVX] -// * VCVTSI2SS m32, xmm, xmm [AVX] -// * VCVTSI2SS m64, xmm, xmm [AVX] -// * VCVTSI2SS m32, xmm, xmm [AVX512F] -// * VCVTSI2SS m64, xmm, xmm [AVX512F] -// * VCVTSI2SS {er}, r32, xmm, xmm [AVX512F] -// * VCVTSI2SS {er}, r64, xmm, xmm [AVX512F] -// * VCVTSI2SS r32, xmm, xmm [AVX512F] -// * VCVTSI2SS r64, xmm, xmm [AVX512F] -// -func (self *Program) VCVTSI2SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTSI2SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VCVTSI2SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VCVTSI2SS takes 3 or 4 operands") - } - // VCVTSI2SS r32, xmm, xmm - if len(vv) == 0 && isReg32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTSI2SS r64, xmm, xmm - if len(vv) == 0 && isReg64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfa ^ (hlcode(v[1]) << 3)) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTSI2SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VCVTSI2SS m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x82, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VCVTSI2SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x2a) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VCVTSI2SS m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x2a) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VCVTSI2SS {er}, r32, xmm, xmm - if len(vv) == 1 && isER(v0) && isReg32(v1) && isEVEXXMM(v2) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | 0x10) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VCVTSI2SS {er}, r64, xmm, xmm - if len(vv) == 1 && isER(v0) && isReg64(v1) && isEVEXXMM(v2) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfe ^ (hlcode(v[2]) << 3)) - m.emit((vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | 0x10) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VCVTSI2SS r32, xmm, xmm - if len(vv) == 0 && isReg32(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x40) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTSI2SS r64, xmm, xmm - if len(vv) == 0 && isReg64(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x40) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTSI2SS") - } - return p -} - -// VCVTSS2SD performs "Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value". -// -// Mnemonic : VCVTSS2SD -// Supported forms : (5 forms) -// -// * VCVTSS2SD xmm, xmm, xmm [AVX] -// * VCVTSS2SD m32, xmm, xmm [AVX] -// * VCVTSS2SD m32, xmm, xmm{k}{z} [AVX512F] -// * VCVTSS2SD {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VCVTSS2SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VCVTSS2SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTSS2SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VCVTSS2SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VCVTSS2SD takes 3 or 4 operands") - } - // VCVTSS2SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTSS2SD m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VCVTSS2SD m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5a) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VCVTSS2SD {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VCVTSS2SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTSS2SD") - } - return p -} - -// VCVTSS2SI performs "Convert Scalar Single-Precision FP Value to Dword Integer". -// -// Mnemonic : VCVTSS2SI -// Supported forms : (10 forms) -// -// * VCVTSS2SI xmm, r32 [AVX] -// * VCVTSS2SI m32, r32 [AVX] -// * VCVTSS2SI xmm, r64 [AVX] -// * VCVTSS2SI m32, r64 [AVX] -// * VCVTSS2SI m32, r32 [AVX512F] -// * VCVTSS2SI m32, r64 [AVX512F] -// * VCVTSS2SI {er}, xmm, r32 [AVX512F] -// * VCVTSS2SI {er}, xmm, r64 [AVX512F] -// * VCVTSS2SI xmm, r32 [AVX512F] -// * VCVTSS2SI xmm, r64 [AVX512F] -// -func (self *Program) VCVTSS2SI(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTSS2SI", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTSS2SI", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTSS2SI takes 2 or 3 operands") - } - // VCVTSS2SI xmm, r32 - if len(vv) == 0 && isXMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), v[0], 0) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTSS2SI m32, r32 - if len(vv) == 0 && isM32(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTSS2SI xmm, r64 - if len(vv) == 0 && isXMM(v0) && isReg64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfa) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTSS2SI m32, r64 - if len(vv) == 0 && isM32(v0) && isReg64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x82, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTSS2SI m32, r32 - if len(vv) == 0 && isM32(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VCVTSS2SI m32, r64 - if len(vv) == 0 && isM32(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2d) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VCVTSS2SI {er}, xmm, r32 - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isReg32(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e) - m.emit((vcode(v[0]) << 5) | 0x18) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTSS2SI {er}, xmm, r64 - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isReg64(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe) - m.emit((vcode(v[0]) << 5) | 0x18) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTSS2SI xmm, r32 - if len(vv) == 0 && isEVEXXMM(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x48) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTSS2SI xmm, r64 - if len(vv) == 0 && isEVEXXMM(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x48) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTSS2SI") - } - return p -} - -// VCVTSS2USI performs "Convert Scalar Single-Precision Floating-Point Value to Unsigned Doubleword Integer". -// -// Mnemonic : VCVTSS2USI -// Supported forms : (6 forms) -// -// * VCVTSS2USI m32, r32 [AVX512F] -// * VCVTSS2USI m32, r64 [AVX512F] -// * VCVTSS2USI {er}, xmm, r32 [AVX512F] -// * VCVTSS2USI {er}, xmm, r64 [AVX512F] -// * VCVTSS2USI xmm, r32 [AVX512F] -// * VCVTSS2USI xmm, r64 [AVX512F] -// -func (self *Program) VCVTSS2USI(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTSS2USI", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTSS2USI", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTSS2USI takes 2 or 3 operands") - } - // VCVTSS2USI m32, r32 - if len(vv) == 0 && isM32(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VCVTSS2USI m32, r64 - if len(vv) == 0 && isM32(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VCVTSS2USI {er}, xmm, r32 - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isReg32(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e) - m.emit((vcode(v[0]) << 5) | 0x18) - m.emit(0x79) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTSS2USI {er}, xmm, r64 - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isReg64(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe) - m.emit((vcode(v[0]) << 5) | 0x18) - m.emit(0x79) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTSS2USI xmm, r32 - if len(vv) == 0 && isEVEXXMM(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x48) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTSS2USI xmm, r64 - if len(vv) == 0 && isEVEXXMM(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x48) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTSS2USI") - } - return p -} - -// VCVTTPD2DQ performs "Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : VCVTTPD2DQ -// Supported forms : (11 forms) -// -// * VCVTTPD2DQ xmm, xmm [AVX] -// * VCVTTPD2DQ ymm, xmm [AVX] -// * VCVTTPD2DQ m128, xmm [AVX] -// * VCVTTPD2DQ m256, xmm [AVX] -// * VCVTTPD2DQ m512/m64bcst, ymm{k}{z} [AVX512F] -// * VCVTTPD2DQ {sae}, zmm, ymm{k}{z} [AVX512F] -// * VCVTTPD2DQ zmm, ymm{k}{z} [AVX512F] -// * VCVTTPD2DQ m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPD2DQ m256/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPD2DQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPD2DQ ymm, xmm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTTPD2DQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTPD2DQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTPD2DQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTPD2DQ takes 2 or 3 operands") - } - // VCVTTPD2DQ xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2DQ ymm, xmm - if len(vv) == 0 && isYMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), v[0], 0) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2DQ m128, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTTPD2DQ m256, xmm - if len(vv) == 0 && isM256(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), addr(v[0]), 0) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTTPD2DQ m512/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTTPD2DQ {sae}, zmm, ymm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isYMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTPD2DQ zmm, ymm{k}{z} - if len(vv) == 0 && isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2DQ m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTTPD2DQ m256/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xe6) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTTPD2DQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2DQ ymm, xmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0xe6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTPD2DQ") - } - return p -} - -// VCVTTPD2QQ performs "Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Quadword Integers". -// -// Mnemonic : VCVTTPD2QQ -// Supported forms : (7 forms) -// -// * VCVTTPD2QQ m512/m64bcst, zmm{k}{z} [AVX512DQ] -// * VCVTTPD2QQ {sae}, zmm, zmm{k}{z} [AVX512DQ] -// * VCVTTPD2QQ zmm, zmm{k}{z} [AVX512DQ] -// * VCVTTPD2QQ m128/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPD2QQ m256/m64bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPD2QQ xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPD2QQ ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTTPD2QQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTPD2QQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTPD2QQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTPD2QQ takes 2 or 3 operands") - } - // VCVTTPD2QQ m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTTPD2QQ {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTPD2QQ zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2QQ m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTTPD2QQ m256/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTTPD2QQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2QQ ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTPD2QQ") - } - return p -} - -// VCVTTPD2UDQ performs "Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Unsigned Doubleword Integers". -// -// Mnemonic : VCVTTPD2UDQ -// Supported forms : (7 forms) -// -// * VCVTTPD2UDQ m512/m64bcst, ymm{k}{z} [AVX512F] -// * VCVTTPD2UDQ {sae}, zmm, ymm{k}{z} [AVX512F] -// * VCVTTPD2UDQ zmm, ymm{k}{z} [AVX512F] -// * VCVTTPD2UDQ m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPD2UDQ m256/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPD2UDQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPD2UDQ ymm, xmm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTTPD2UDQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTPD2UDQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTPD2UDQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTPD2UDQ takes 2 or 3 operands") - } - // VCVTTPD2UDQ m512/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x84, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTTPD2UDQ {sae}, zmm, ymm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isYMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x78) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTPD2UDQ zmm, ymm{k}{z} - if len(vv) == 0 && isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2UDQ m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x84, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTTPD2UDQ m256/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x84, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTTPD2UDQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2UDQ ymm, xmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfc) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTPD2UDQ") - } - return p -} - -// VCVTTPD2UQQ performs "Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Unsigned Quadword Integers". -// -// Mnemonic : VCVTTPD2UQQ -// Supported forms : (7 forms) -// -// * VCVTTPD2UQQ m512/m64bcst, zmm{k}{z} [AVX512DQ] -// * VCVTTPD2UQQ {sae}, zmm, zmm{k}{z} [AVX512DQ] -// * VCVTTPD2UQQ zmm, zmm{k}{z} [AVX512DQ] -// * VCVTTPD2UQQ m128/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPD2UQQ m256/m64bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPD2UQQ xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPD2UQQ ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTTPD2UQQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTPD2UQQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTPD2UQQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTPD2UQQ takes 2 or 3 operands") - } - // VCVTTPD2UQQ m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTTPD2UQQ {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x78) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTPD2UQQ zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2UQQ m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTTPD2UQQ m256/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTTPD2UQQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPD2UQQ ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTPD2UQQ") - } - return p -} - -// VCVTTPS2DQ performs "Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers". -// -// Mnemonic : VCVTTPS2DQ -// Supported forms : (11 forms) -// -// * VCVTTPS2DQ xmm, xmm [AVX] -// * VCVTTPS2DQ m128, xmm [AVX] -// * VCVTTPS2DQ ymm, ymm [AVX] -// * VCVTTPS2DQ m256, ymm [AVX] -// * VCVTTPS2DQ m512/m32bcst, zmm{k}{z} [AVX512F] -// * VCVTTPS2DQ {sae}, zmm, zmm{k}{z} [AVX512F] -// * VCVTTPS2DQ zmm, zmm{k}{z} [AVX512F] -// * VCVTTPS2DQ m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPS2DQ m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPS2DQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPS2DQ ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTTPS2DQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTPS2DQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTPS2DQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTPS2DQ takes 2 or 3 operands") - } - // VCVTTPS2DQ xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), v[0], 0) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2DQ m128, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTTPS2DQ ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), v[0], 0) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2DQ m256, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), addr(v[0]), 0) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTTPS2DQ m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTTPS2DQ {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTPS2DQ zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2DQ m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTTPS2DQ m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x5b) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTTPS2DQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2DQ ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x5b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTPS2DQ") - } - return p -} - -// VCVTTPS2QQ performs "Convert with Truncation Packed Single Precision Floating-Point Values to Packed Singed Quadword Integer Values". -// -// Mnemonic : VCVTTPS2QQ -// Supported forms : (7 forms) -// -// * VCVTTPS2QQ m256/m32bcst, zmm{k}{z} [AVX512DQ] -// * VCVTTPS2QQ {sae}, ymm, zmm{k}{z} [AVX512DQ] -// * VCVTTPS2QQ ymm, zmm{k}{z} [AVX512DQ] -// * VCVTTPS2QQ m64/m32bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPS2QQ m128/m32bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPS2QQ xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPS2QQ xmm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTTPS2QQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTPS2QQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTPS2QQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTPS2QQ takes 2 or 3 operands") - } - // VCVTTPS2QQ m256/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTTPS2QQ {sae}, ymm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXYMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTPS2QQ ymm, zmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2QQ m64/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM64M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTTPS2QQ m128/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTTPS2QQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2QQ xmm, ymm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTPS2QQ") - } - return p -} - -// VCVTTPS2UDQ performs "Convert with Truncation Packed Single-Precision Floating-Point Values to Packed Unsigned Doubleword Integer Values". -// -// Mnemonic : VCVTTPS2UDQ -// Supported forms : (7 forms) -// -// * VCVTTPS2UDQ m512/m32bcst, zmm{k}{z} [AVX512F] -// * VCVTTPS2UDQ {sae}, zmm, zmm{k}{z} [AVX512F] -// * VCVTTPS2UDQ zmm, zmm{k}{z} [AVX512F] -// * VCVTTPS2UDQ m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPS2UDQ m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPS2UDQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTTPS2UDQ ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTTPS2UDQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTPS2UDQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTPS2UDQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTPS2UDQ takes 2 or 3 operands") - } - // VCVTTPS2UDQ m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTTPS2UDQ {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x78) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTPS2UDQ zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2UDQ m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTTPS2UDQ m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTTPS2UDQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2UDQ ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTPS2UDQ") - } - return p -} - -// VCVTTPS2UQQ performs "Convert with Truncation Packed Single Precision Floating-Point Values to Packed Unsigned Quadword Integer Values". -// -// Mnemonic : VCVTTPS2UQQ -// Supported forms : (7 forms) -// -// * VCVTTPS2UQQ m256/m32bcst, zmm{k}{z} [AVX512DQ] -// * VCVTTPS2UQQ {sae}, ymm, zmm{k}{z} [AVX512DQ] -// * VCVTTPS2UQQ ymm, zmm{k}{z} [AVX512DQ] -// * VCVTTPS2UQQ m64/m32bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPS2UQQ m128/m32bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPS2UQQ xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTTPS2UQQ xmm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTTPS2UQQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTPS2UQQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTPS2UQQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTPS2UQQ takes 2 or 3 operands") - } - // VCVTTPS2UQQ m256/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTTPS2UQQ {sae}, ymm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXYMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x78) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTPS2UQQ ymm, zmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2UQQ m64/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM64M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTTPS2UQQ m128/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTTPS2UQQ xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTPS2UQQ xmm, ymm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTPS2UQQ") - } - return p -} - -// VCVTTSD2SI performs "Convert with Truncation Scalar Double-Precision FP Value to Signed Integer". -// -// Mnemonic : VCVTTSD2SI -// Supported forms : (10 forms) -// -// * VCVTTSD2SI xmm, r32 [AVX] -// * VCVTTSD2SI m64, r32 [AVX] -// * VCVTTSD2SI xmm, r64 [AVX] -// * VCVTTSD2SI m64, r64 [AVX] -// * VCVTTSD2SI m64, r32 [AVX512F] -// * VCVTTSD2SI m64, r64 [AVX512F] -// * VCVTTSD2SI {sae}, xmm, r32 [AVX512F] -// * VCVTTSD2SI {sae}, xmm, r64 [AVX512F] -// * VCVTTSD2SI xmm, r32 [AVX512F] -// * VCVTTSD2SI xmm, r64 [AVX512F] -// -func (self *Program) VCVTTSD2SI(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTSD2SI", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTSD2SI", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTSD2SI takes 2 or 3 operands") - } - // VCVTTSD2SI xmm, r32 - if len(vv) == 0 && isXMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), v[0], 0) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTSD2SI m64, r32 - if len(vv) == 0 && isM64(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTTSD2SI xmm, r64 - if len(vv) == 0 && isXMM(v0) && isReg64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfb) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTSD2SI m64, r64 - if len(vv) == 0 && isM64(v0) && isReg64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x83, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTTSD2SI m64, r32 - if len(vv) == 0 && isM64(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTTSD2SI m64, r64 - if len(vv) == 0 && isM64(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTTSD2SI {sae}, xmm, r32 - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isReg32(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f) - m.emit(0x18) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTSD2SI {sae}, xmm, r64 - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isReg64(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff) - m.emit(0x18) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTSD2SI xmm, r32 - if len(vv) == 0 && isEVEXXMM(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit(0x48) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTSD2SI xmm, r64 - if len(vv) == 0 && isEVEXXMM(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit(0x48) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTSD2SI") - } - return p -} - -// VCVTTSD2USI performs "Convert with Truncation Scalar Double-Precision Floating-Point Value to Unsigned Integer". -// -// Mnemonic : VCVTTSD2USI -// Supported forms : (6 forms) -// -// * VCVTTSD2USI m64, r32 [AVX512F] -// * VCVTTSD2USI m64, r64 [AVX512F] -// * VCVTTSD2USI {sae}, xmm, r32 [AVX512F] -// * VCVTTSD2USI {sae}, xmm, r64 [AVX512F] -// * VCVTTSD2USI xmm, r32 [AVX512F] -// * VCVTTSD2USI xmm, r64 [AVX512F] -// -func (self *Program) VCVTTSD2USI(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTSD2USI", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTSD2USI", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTSD2USI takes 2 or 3 operands") - } - // VCVTTSD2USI m64, r32 - if len(vv) == 0 && isM64(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTTSD2USI m64, r64 - if len(vv) == 0 && isM64(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTTSD2USI {sae}, xmm, r32 - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isReg32(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f) - m.emit(0x18) - m.emit(0x78) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTSD2USI {sae}, xmm, r64 - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isReg64(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff) - m.emit(0x18) - m.emit(0x78) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTSD2USI xmm, r32 - if len(vv) == 0 && isEVEXXMM(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit(0x48) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTSD2USI xmm, r64 - if len(vv) == 0 && isEVEXXMM(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit(0x48) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTSD2USI") - } - return p -} - -// VCVTTSS2SI performs "Convert with Truncation Scalar Single-Precision FP Value to Dword Integer". -// -// Mnemonic : VCVTTSS2SI -// Supported forms : (10 forms) -// -// * VCVTTSS2SI xmm, r32 [AVX] -// * VCVTTSS2SI m32, r32 [AVX] -// * VCVTTSS2SI xmm, r64 [AVX] -// * VCVTTSS2SI m32, r64 [AVX] -// * VCVTTSS2SI m32, r32 [AVX512F] -// * VCVTTSS2SI m32, r64 [AVX512F] -// * VCVTTSS2SI {sae}, xmm, r32 [AVX512F] -// * VCVTTSS2SI {sae}, xmm, r64 [AVX512F] -// * VCVTTSS2SI xmm, r32 [AVX512F] -// * VCVTTSS2SI xmm, r64 [AVX512F] -// -func (self *Program) VCVTTSS2SI(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTSS2SI", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTSS2SI", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTSS2SI takes 2 or 3 operands") - } - // VCVTTSS2SI xmm, r32 - if len(vv) == 0 && isXMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), v[0], 0) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTSS2SI m32, r32 - if len(vv) == 0 && isM32(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTTSS2SI xmm, r64 - if len(vv) == 0 && isXMM(v0) && isReg64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfa) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTSS2SI m32, r64 - if len(vv) == 0 && isM32(v0) && isReg64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x82, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VCVTTSS2SI m32, r32 - if len(vv) == 0 && isM32(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VCVTTSS2SI m32, r64 - if len(vv) == 0 && isM32(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2c) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VCVTTSS2SI {sae}, xmm, r32 - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isReg32(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e) - m.emit(0x18) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTSS2SI {sae}, xmm, r64 - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isReg64(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe) - m.emit(0x18) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTSS2SI xmm, r32 - if len(vv) == 0 && isEVEXXMM(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x48) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTSS2SI xmm, r64 - if len(vv) == 0 && isEVEXXMM(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x48) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTSS2SI") - } - return p -} - -// VCVTTSS2USI performs "Convert with Truncation Scalar Single-Precision Floating-Point Value to Unsigned Integer". -// -// Mnemonic : VCVTTSS2USI -// Supported forms : (6 forms) -// -// * VCVTTSS2USI m32, r32 [AVX512F] -// * VCVTTSS2USI m32, r64 [AVX512F] -// * VCVTTSS2USI {sae}, xmm, r32 [AVX512F] -// * VCVTTSS2USI {sae}, xmm, r64 [AVX512F] -// * VCVTTSS2USI xmm, r32 [AVX512F] -// * VCVTTSS2USI xmm, r64 [AVX512F] -// -func (self *Program) VCVTTSS2USI(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTTSS2USI", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTTSS2USI", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTTSS2USI takes 2 or 3 operands") - } - // VCVTTSS2USI m32, r32 - if len(vv) == 0 && isM32(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VCVTTSS2USI m32, r64 - if len(vv) == 0 && isM32(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VCVTTSS2USI {sae}, xmm, r32 - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isReg32(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e) - m.emit(0x18) - m.emit(0x78) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTSS2USI {sae}, xmm, r64 - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isReg64(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe) - m.emit(0x18) - m.emit(0x78) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTTSS2USI xmm, r32 - if len(vv) == 0 && isEVEXXMM(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x48) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTTSS2USI xmm, r64 - if len(vv) == 0 && isEVEXXMM(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x48) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTTSS2USI") - } - return p -} - -// VCVTUDQ2PD performs "Convert Packed Unsigned Doubleword Integers to Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VCVTUDQ2PD -// Supported forms : (6 forms) -// -// * VCVTUDQ2PD m256/m32bcst, zmm{k}{z} [AVX512F] -// * VCVTUDQ2PD ymm, zmm{k}{z} [AVX512F] -// * VCVTUDQ2PD m64/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTUDQ2PD m128/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VCVTUDQ2PD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTUDQ2PD xmm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTUDQ2PD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VCVTUDQ2PD", 2, Operands { v0, v1 }) - // VCVTUDQ2PD m256/m32bcst, zmm{k}{z} - if isM256M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTUDQ2PD ymm, zmm{k}{z} - if isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTUDQ2PD m64/m32bcst, xmm{k}{z} - if isM64M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VCVTUDQ2PD m128/m32bcst, ymm{k}{z} - if isM128M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTUDQ2PD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTUDQ2PD xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTUDQ2PD") - } - return p -} - -// VCVTUDQ2PS performs "Convert Packed Unsigned Doubleword Integers to Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VCVTUDQ2PS -// Supported forms : (7 forms) -// -// * VCVTUDQ2PS m512/m32bcst, zmm{k}{z} [AVX512F] -// * VCVTUDQ2PS {er}, zmm, zmm{k}{z} [AVX512F] -// * VCVTUDQ2PS zmm, zmm{k}{z} [AVX512F] -// * VCVTUDQ2PS m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTUDQ2PS m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VCVTUDQ2PS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VCVTUDQ2PS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VCVTUDQ2PS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTUDQ2PS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTUDQ2PS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTUDQ2PS takes 2 or 3 operands") - } - // VCVTUDQ2PS m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTUDQ2PS {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTUDQ2PS zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTUDQ2PS m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTUDQ2PS m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTUDQ2PS xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTUDQ2PS ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTUDQ2PS") - } - return p -} - -// VCVTUQQ2PD performs "Convert Packed Unsigned Quadword Integers to Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VCVTUQQ2PD -// Supported forms : (7 forms) -// -// * VCVTUQQ2PD m512/m64bcst, zmm{k}{z} [AVX512DQ] -// * VCVTUQQ2PD {er}, zmm, zmm{k}{z} [AVX512DQ] -// * VCVTUQQ2PD zmm, zmm{k}{z} [AVX512DQ] -// * VCVTUQQ2PD m128/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTUQQ2PD m256/m64bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTUQQ2PD xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTUQQ2PD ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTUQQ2PD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTUQQ2PD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTUQQ2PD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTUQQ2PD takes 2 or 3 operands") - } - // VCVTUQQ2PD m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTUQQ2PD {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTUQQ2PD zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTUQQ2PD m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTUQQ2PD m256/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTUQQ2PD xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTUQQ2PD ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTUQQ2PD") - } - return p -} - -// VCVTUQQ2PS performs "Convert Packed Unsigned Quadword Integers to Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VCVTUQQ2PS -// Supported forms : (7 forms) -// -// * VCVTUQQ2PS m512/m64bcst, ymm{k}{z} [AVX512DQ] -// * VCVTUQQ2PS {er}, zmm, ymm{k}{z} [AVX512DQ] -// * VCVTUQQ2PS zmm, ymm{k}{z} [AVX512DQ] -// * VCVTUQQ2PS m128/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTUQQ2PS m256/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTUQQ2PS xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VCVTUQQ2PS ymm, xmm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VCVTUQQ2PS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTUQQ2PS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VCVTUQQ2PS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VCVTUQQ2PS takes 2 or 3 operands") - } - // VCVTUQQ2PS m512/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VCVTUQQ2PS {er}, zmm, ymm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isYMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VCVTUQQ2PS zmm, ymm{k}{z} - if len(vv) == 0 && isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTUQQ2PS m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VCVTUQQ2PS m256/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x7a) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VCVTUQQ2PS xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VCVTUQQ2PS ymm, xmm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTUQQ2PS") - } - return p -} - -// VCVTUSI2SD performs "Convert Unsigned Integer to Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VCVTUSI2SD -// Supported forms : (5 forms) -// -// * VCVTUSI2SD r32, xmm, xmm [AVX512F] -// * VCVTUSI2SD m32, xmm, xmm [AVX512F] -// * VCVTUSI2SD m64, xmm, xmm [AVX512F] -// * VCVTUSI2SD {er}, r64, xmm, xmm [AVX512F] -// * VCVTUSI2SD r64, xmm, xmm [AVX512F] -// -func (self *Program) VCVTUSI2SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTUSI2SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VCVTUSI2SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VCVTUSI2SD takes 3 or 4 operands") - } - // VCVTUSI2SD r32, xmm, xmm - if len(vv) == 0 && isReg32(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x00) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTUSI2SD m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x7b) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VCVTUSI2SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x7b) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VCVTUSI2SD {er}, r64, xmm, xmm - if len(vv) == 1 && isER(v0) && isReg64(v1) && isEVEXXMM(v2) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | 0x10) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VCVTUSI2SD r64, xmm, xmm - if len(vv) == 0 && isReg64(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x40) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTUSI2SD") - } - return p -} - -// VCVTUSI2SS performs "Convert Unsigned Integer to Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VCVTUSI2SS -// Supported forms : (6 forms) -// -// * VCVTUSI2SS m32, xmm, xmm [AVX512F] -// * VCVTUSI2SS m64, xmm, xmm [AVX512F] -// * VCVTUSI2SS {er}, r32, xmm, xmm [AVX512F] -// * VCVTUSI2SS {er}, r64, xmm, xmm [AVX512F] -// * VCVTUSI2SS r32, xmm, xmm [AVX512F] -// * VCVTUSI2SS r64, xmm, xmm [AVX512F] -// -func (self *Program) VCVTUSI2SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VCVTUSI2SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VCVTUSI2SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VCVTUSI2SS takes 3 or 4 operands") - } - // VCVTUSI2SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x7b) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VCVTUSI2SS m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x7b) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VCVTUSI2SS {er}, r32, xmm, xmm - if len(vv) == 1 && isER(v0) && isReg32(v1) && isEVEXXMM(v2) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | 0x10) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VCVTUSI2SS {er}, r64, xmm, xmm - if len(vv) == 1 && isER(v0) && isReg64(v1) && isEVEXXMM(v2) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfe ^ (hlcode(v[2]) << 3)) - m.emit((vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | 0x10) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VCVTUSI2SS r32, xmm, xmm - if len(vv) == 0 && isReg32(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x40) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VCVTUSI2SS r64, xmm, xmm - if len(vv) == 0 && isReg64(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x40) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VCVTUSI2SS") - } - return p -} - -// VDBPSADBW performs "Double Block Packed Sum-Absolute-Differences on Unsigned Bytes". -// -// Mnemonic : VDBPSADBW -// Supported forms : (6 forms) -// -// * VDBPSADBW imm8, zmm, zmm, zmm{k}{z} [AVX512BW] -// * VDBPSADBW imm8, m512, zmm, zmm{k}{z} [AVX512BW] -// * VDBPSADBW imm8, xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VDBPSADBW imm8, m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VDBPSADBW imm8, ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VDBPSADBW imm8, m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VDBPSADBW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VDBPSADBW", 4, Operands { v0, v1, v2, v3 }) - // VDBPSADBW imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x42) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VDBPSADBW imm8, m512, zmm, zmm{k}{z} - if isImm8(v0) && isM512(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x42) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VDBPSADBW imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x42) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VDBPSADBW imm8, m128, xmm, xmm{k}{z} - if isImm8(v0) && isM128(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x42) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VDBPSADBW imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x42) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VDBPSADBW imm8, m256, ymm, ymm{k}{z} - if isImm8(v0) && isM256(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x42) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VDBPSADBW") - } - return p -} - -// VDIVPD performs "Divide Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VDIVPD -// Supported forms : (11 forms) -// -// * VDIVPD xmm, xmm, xmm [AVX] -// * VDIVPD m128, xmm, xmm [AVX] -// * VDIVPD ymm, ymm, ymm [AVX] -// * VDIVPD m256, ymm, ymm [AVX] -// * VDIVPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VDIVPD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VDIVPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VDIVPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VDIVPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VDIVPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VDIVPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VDIVPD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VDIVPD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VDIVPD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VDIVPD takes 3 or 4 operands") - } - // VDIVPD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVPD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VDIVPD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVPD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VDIVPD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VDIVPD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VDIVPD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVPD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VDIVPD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVPD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VDIVPD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VDIVPD") - } - return p -} - -// VDIVPS performs "Divide Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VDIVPS -// Supported forms : (11 forms) -// -// * VDIVPS xmm, xmm, xmm [AVX] -// * VDIVPS m128, xmm, xmm [AVX] -// * VDIVPS ymm, ymm, ymm [AVX] -// * VDIVPS m256, ymm, ymm [AVX] -// * VDIVPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VDIVPS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VDIVPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VDIVPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VDIVPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VDIVPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VDIVPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VDIVPS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VDIVPS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VDIVPS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VDIVPS takes 3 or 4 operands") - } - // VDIVPS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVPS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VDIVPS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVPS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VDIVPS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VDIVPS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VDIVPS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVPS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VDIVPS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVPS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VDIVPS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VDIVPS") - } - return p -} - -// VDIVSD performs "Divide Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VDIVSD -// Supported forms : (5 forms) -// -// * VDIVSD xmm, xmm, xmm [AVX] -// * VDIVSD m64, xmm, xmm [AVX] -// * VDIVSD m64, xmm, xmm{k}{z} [AVX512F] -// * VDIVSD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VDIVSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VDIVSD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VDIVSD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VDIVSD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VDIVSD takes 3 or 4 operands") - } - // VDIVSD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVSD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VDIVSD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VDIVSD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VDIVSD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VDIVSD") - } - return p -} - -// VDIVSS performs "Divide Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VDIVSS -// Supported forms : (5 forms) -// -// * VDIVSS xmm, xmm, xmm [AVX] -// * VDIVSS m32, xmm, xmm [AVX] -// * VDIVSS m32, xmm, xmm{k}{z} [AVX512F] -// * VDIVSS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VDIVSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VDIVSS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VDIVSS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VDIVSS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VDIVSS takes 3 or 4 operands") - } - // VDIVSS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VDIVSS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VDIVSS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5e) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VDIVSS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VDIVSS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VDIVSS") - } - return p -} - -// VDPPD performs "Dot Product of Packed Double Precision Floating-Point Values". -// -// Mnemonic : VDPPD -// Supported forms : (2 forms) -// -// * VDPPD imm8, xmm, xmm, xmm [AVX] -// * VDPPD imm8, m128, xmm, xmm [AVX] -// -func (self *Program) VDPPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VDPPD", 4, Operands { v0, v1, v2, v3 }) - // VDPPD imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x41) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VDPPD imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x41) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VDPPD") - } - return p -} - -// VDPPS performs "Dot Product of Packed Single Precision Floating-Point Values". -// -// Mnemonic : VDPPS -// Supported forms : (4 forms) -// -// * VDPPS imm8, xmm, xmm, xmm [AVX] -// * VDPPS imm8, m128, xmm, xmm [AVX] -// * VDPPS imm8, ymm, ymm, ymm [AVX] -// * VDPPS imm8, m256, ymm, ymm [AVX] -// -func (self *Program) VDPPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VDPPS", 4, Operands { v0, v1, v2, v3 }) - // VDPPS imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x40) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VDPPS imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x40) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VDPPS imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x40) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VDPPS imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x40) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VDPPS") - } - return p -} - -// VEXP2PD performs "Approximation to the Exponential 2^x of Packed Double-Precision Floating-Point Values with Less Than 2^-23 Relative Error". -// -// Mnemonic : VEXP2PD -// Supported forms : (3 forms) -// -// * VEXP2PD m512/m64bcst, zmm{k}{z} [AVX512ER] -// * VEXP2PD {sae}, zmm, zmm{k}{z} [AVX512ER] -// * VEXP2PD zmm, zmm{k}{z} [AVX512ER] -// -func (self *Program) VEXP2PD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VEXP2PD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VEXP2PD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VEXP2PD takes 2 or 3 operands") - } - // VEXP2PD m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xc8) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VEXP2PD {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0xc8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VEXP2PD zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xc8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXP2PD") - } - return p -} - -// VEXP2PS performs "Approximation to the Exponential 2^x of Packed Single-Precision Floating-Point Values with Less Than 2^-23 Relative Error". -// -// Mnemonic : VEXP2PS -// Supported forms : (3 forms) -// -// * VEXP2PS m512/m32bcst, zmm{k}{z} [AVX512ER] -// * VEXP2PS {sae}, zmm, zmm{k}{z} [AVX512ER] -// * VEXP2PS zmm, zmm{k}{z} [AVX512ER] -// -func (self *Program) VEXP2PS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VEXP2PS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VEXP2PS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VEXP2PS takes 2 or 3 operands") - } - // VEXP2PS m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xc8) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VEXP2PS {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0xc8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VEXP2PS zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xc8) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXP2PS") - } - return p -} - -// VEXPANDPD performs "Load Sparse Packed Double-Precision Floating-Point Values from Dense Memory". -// -// Mnemonic : VEXPANDPD -// Supported forms : (6 forms) -// -// * VEXPANDPD zmm, zmm{k}{z} [AVX512F] -// * VEXPANDPD m512, zmm{k}{z} [AVX512F] -// * VEXPANDPD xmm, xmm{k}{z} [AVX512VL] -// * VEXPANDPD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VEXPANDPD m128, xmm{k}{z} [AVX512VL] -// * VEXPANDPD m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VEXPANDPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VEXPANDPD", 2, Operands { v0, v1 }) - // VEXPANDPD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x88) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VEXPANDPD m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x88) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VEXPANDPD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x88) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VEXPANDPD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x88) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VEXPANDPD m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x88) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VEXPANDPD m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x88) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VEXPANDPD") - } - return p -} - -// VEXPANDPS performs "Load Sparse Packed Single-Precision Floating-Point Values from Dense Memory". -// -// Mnemonic : VEXPANDPS -// Supported forms : (6 forms) -// -// * VEXPANDPS zmm, zmm{k}{z} [AVX512F] -// * VEXPANDPS m512, zmm{k}{z} [AVX512F] -// * VEXPANDPS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VEXPANDPS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VEXPANDPS m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VEXPANDPS m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VEXPANDPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VEXPANDPS", 2, Operands { v0, v1 }) - // VEXPANDPS zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x88) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VEXPANDPS m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x88) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VEXPANDPS xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x88) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VEXPANDPS ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x88) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VEXPANDPS m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x88) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VEXPANDPS m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x88) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VEXPANDPS") - } - return p -} - -// VEXTRACTF128 performs "Extract Packed Floating-Point Values". -// -// Mnemonic : VEXTRACTF128 -// Supported forms : (2 forms) -// -// * VEXTRACTF128 imm8, ymm, xmm [AVX] -// * VEXTRACTF128 imm8, ymm, m128 [AVX] -// -func (self *Program) VEXTRACTF128(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTF128", 3, Operands { v0, v1, v2 }) - // VEXTRACTF128 imm8, ymm, xmm - if isImm8(v0) && isYMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[1]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x7d) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTF128 imm8, ymm, m128 - if isImm8(v0) && isYMM(v1) && isM128(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[1]), addr(v[2]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTF128") - } - return p -} - -// VEXTRACTF32X4 performs "Extract 128 Bits of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VEXTRACTF32X4 -// Supported forms : (4 forms) -// -// * VEXTRACTF32X4 imm8, zmm, xmm{k}{z} [AVX512F] -// * VEXTRACTF32X4 imm8, zmm, m128{k}{z} [AVX512F] -// * VEXTRACTF32X4 imm8, ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VEXTRACTF32X4 imm8, ymm, m128{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VEXTRACTF32X4(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTF32X4", 3, Operands { v0, v1, v2 }) - // VEXTRACTF32X4 imm8, zmm, xmm{k}{z} - if isImm8(v0) && isZMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTF32X4 imm8, zmm, m128{k}{z} - if isImm8(v0) && isZMM(v1) && isM128kz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[2]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTF32X4 imm8, ymm, xmm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTF32X4 imm8, ymm, m128{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isM128kz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[2]), 16) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTF32X4") - } - return p -} - -// VEXTRACTF32X8 performs "Extract 256 Bits of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VEXTRACTF32X8 -// Supported forms : (2 forms) -// -// * VEXTRACTF32X8 imm8, zmm, ymm{k}{z} [AVX512DQ] -// * VEXTRACTF32X8 imm8, zmm, m256{k}{z} [AVX512DQ] -// -func (self *Program) VEXTRACTF32X8(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTF32X8", 3, Operands { v0, v1, v2 }) - // VEXTRACTF32X8 imm8, zmm, ymm{k}{z} - if isImm8(v0) && isZMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x1b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTF32X8 imm8, zmm, m256{k}{z} - if isImm8(v0) && isZMM(v1) && isM256kz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x1b) - m.mrsd(lcode(v[1]), addr(v[2]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTF32X8") - } - return p -} - -// VEXTRACTF64X2 performs "Extract 128 Bits of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VEXTRACTF64X2 -// Supported forms : (4 forms) -// -// * VEXTRACTF64X2 imm8, zmm, xmm{k}{z} [AVX512DQ] -// * VEXTRACTF64X2 imm8, zmm, m128{k}{z} [AVX512DQ] -// * VEXTRACTF64X2 imm8, ymm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VEXTRACTF64X2 imm8, ymm, m128{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VEXTRACTF64X2(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTF64X2", 3, Operands { v0, v1, v2 }) - // VEXTRACTF64X2 imm8, zmm, xmm{k}{z} - if isImm8(v0) && isZMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTF64X2 imm8, zmm, m128{k}{z} - if isImm8(v0) && isZMM(v1) && isM128kz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[2]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTF64X2 imm8, ymm, xmm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x19) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTF64X2 imm8, ymm, m128{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isM128kz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x19) - m.mrsd(lcode(v[1]), addr(v[2]), 16) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTF64X2") - } - return p -} - -// VEXTRACTF64X4 performs "Extract 256 Bits of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VEXTRACTF64X4 -// Supported forms : (2 forms) -// -// * VEXTRACTF64X4 imm8, zmm, ymm{k}{z} [AVX512F] -// * VEXTRACTF64X4 imm8, zmm, m256{k}{z} [AVX512F] -// -func (self *Program) VEXTRACTF64X4(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTF64X4", 3, Operands { v0, v1, v2 }) - // VEXTRACTF64X4 imm8, zmm, ymm{k}{z} - if isImm8(v0) && isZMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x1b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTF64X4 imm8, zmm, m256{k}{z} - if isImm8(v0) && isZMM(v1) && isM256kz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x1b) - m.mrsd(lcode(v[1]), addr(v[2]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTF64X4") - } - return p -} - -// VEXTRACTI128 performs "Extract Packed Integer Values". -// -// Mnemonic : VEXTRACTI128 -// Supported forms : (2 forms) -// -// * VEXTRACTI128 imm8, ymm, xmm [AVX2] -// * VEXTRACTI128 imm8, ymm, m128 [AVX2] -// -func (self *Program) VEXTRACTI128(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTI128", 3, Operands { v0, v1, v2 }) - // VEXTRACTI128 imm8, ymm, xmm - if isImm8(v0) && isYMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[1]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x7d) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTI128 imm8, ymm, m128 - if isImm8(v0) && isYMM(v1) && isM128(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[1]), addr(v[2]), 0) - m.emit(0x39) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTI128") - } - return p -} - -// VEXTRACTI32X4 performs "Extract 128 Bits of Packed Doubleword Integer Values". -// -// Mnemonic : VEXTRACTI32X4 -// Supported forms : (4 forms) -// -// * VEXTRACTI32X4 imm8, zmm, xmm{k}{z} [AVX512F] -// * VEXTRACTI32X4 imm8, zmm, m128{k}{z} [AVX512F] -// * VEXTRACTI32X4 imm8, ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VEXTRACTI32X4 imm8, ymm, m128{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VEXTRACTI32X4(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTI32X4", 3, Operands { v0, v1, v2 }) - // VEXTRACTI32X4 imm8, zmm, xmm{k}{z} - if isImm8(v0) && isZMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTI32X4 imm8, zmm, m128{k}{z} - if isImm8(v0) && isZMM(v1) && isM128kz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x39) - m.mrsd(lcode(v[1]), addr(v[2]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTI32X4 imm8, ymm, xmm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTI32X4 imm8, ymm, m128{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isM128kz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x39) - m.mrsd(lcode(v[1]), addr(v[2]), 16) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTI32X4") - } - return p -} - -// VEXTRACTI32X8 performs "Extract 256 Bits of Packed Doubleword Integer Values". -// -// Mnemonic : VEXTRACTI32X8 -// Supported forms : (2 forms) -// -// * VEXTRACTI32X8 imm8, zmm, ymm{k}{z} [AVX512DQ] -// * VEXTRACTI32X8 imm8, zmm, m256{k}{z} [AVX512DQ] -// -func (self *Program) VEXTRACTI32X8(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTI32X8", 3, Operands { v0, v1, v2 }) - // VEXTRACTI32X8 imm8, zmm, ymm{k}{z} - if isImm8(v0) && isZMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTI32X8 imm8, zmm, m256{k}{z} - if isImm8(v0) && isZMM(v1) && isM256kz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3b) - m.mrsd(lcode(v[1]), addr(v[2]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTI32X8") - } - return p -} - -// VEXTRACTI64X2 performs "Extract 128 Bits of Packed Quadword Integer Values". -// -// Mnemonic : VEXTRACTI64X2 -// Supported forms : (4 forms) -// -// * VEXTRACTI64X2 imm8, zmm, xmm{k}{z} [AVX512DQ] -// * VEXTRACTI64X2 imm8, zmm, m128{k}{z} [AVX512DQ] -// * VEXTRACTI64X2 imm8, ymm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VEXTRACTI64X2 imm8, ymm, m128{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VEXTRACTI64X2(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTI64X2", 3, Operands { v0, v1, v2 }) - // VEXTRACTI64X2 imm8, zmm, xmm{k}{z} - if isImm8(v0) && isZMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTI64X2 imm8, zmm, m128{k}{z} - if isImm8(v0) && isZMM(v1) && isM128kz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x39) - m.mrsd(lcode(v[1]), addr(v[2]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTI64X2 imm8, ymm, xmm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTI64X2 imm8, ymm, m128{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isM128kz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x39) - m.mrsd(lcode(v[1]), addr(v[2]), 16) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTI64X2") - } - return p -} - -// VEXTRACTI64X4 performs "Extract 256 Bits of Packed Quadword Integer Values". -// -// Mnemonic : VEXTRACTI64X4 -// Supported forms : (2 forms) -// -// * VEXTRACTI64X4 imm8, zmm, ymm{k}{z} [AVX512F] -// * VEXTRACTI64X4 imm8, zmm, m256{k}{z} [AVX512F] -// -func (self *Program) VEXTRACTI64X4(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTI64X4", 3, Operands { v0, v1, v2 }) - // VEXTRACTI64X4 imm8, zmm, ymm{k}{z} - if isImm8(v0) && isZMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTI64X4 imm8, zmm, m256{k}{z} - if isImm8(v0) && isZMM(v1) && isM256kz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[1]), addr(v[2]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3b) - m.mrsd(lcode(v[1]), addr(v[2]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTI64X4") - } - return p -} - -// VEXTRACTPS performs "Extract Packed Single Precision Floating-Point Value". -// -// Mnemonic : VEXTRACTPS -// Supported forms : (4 forms) -// -// * VEXTRACTPS imm8, xmm, r32 [AVX] -// * VEXTRACTPS imm8, xmm, m32 [AVX] -// * VEXTRACTPS imm8, xmm, r32 [AVX512F] -// * VEXTRACTPS imm8, xmm, m32 [AVX512F] -// -func (self *Program) VEXTRACTPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VEXTRACTPS", 3, Operands { v0, v1, v2 }) - // VEXTRACTPS imm8, xmm, r32 - if isImm8(v0) && isXMM(v1) && isReg32(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[1]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x79) - m.emit(0x17) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTPS imm8, xmm, m32 - if isImm8(v0) && isXMM(v1) && isM32(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[1]), addr(v[2]), 0) - m.emit(0x17) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTPS imm8, xmm, r32 - if isImm8(v0) && isEVEXXMM(v1) && isReg32(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit(0x08) - m.emit(0x17) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VEXTRACTPS imm8, xmm, m32 - if isImm8(v0) && isEVEXXMM(v1) && isM32(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[1]), addr(v[2]), 0, 0, 0, 0) - m.emit(0x17) - m.mrsd(lcode(v[1]), addr(v[2]), 4) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VEXTRACTPS") - } - return p -} - -// VFIXUPIMMPD performs "Fix Up Special Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFIXUPIMMPD -// Supported forms : (7 forms) -// -// * VFIXUPIMMPD imm8, m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFIXUPIMMPD imm8, {sae}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFIXUPIMMPD imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFIXUPIMMPD imm8, m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFIXUPIMMPD imm8, xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFIXUPIMMPD imm8, m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFIXUPIMMPD imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFIXUPIMMPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFIXUPIMMPD", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VFIXUPIMMPD", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VFIXUPIMMPD takes 4 or 5 operands") - } - // VFIXUPIMMPD imm8, m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPD imm8, {sae}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMM(v3) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0xfd ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x54) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPD imm8, zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x54) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPD imm8, m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM128M64bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPD imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x54) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPD imm8, m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPD imm8, ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x54) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFIXUPIMMPD") - } - return p -} - -// VFIXUPIMMPS performs "Fix Up Special Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFIXUPIMMPS -// Supported forms : (7 forms) -// -// * VFIXUPIMMPS imm8, m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFIXUPIMMPS imm8, {sae}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFIXUPIMMPS imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFIXUPIMMPS imm8, m128/m32bcst, xmm, xmm{k}{z} [AVX512VL] -// * VFIXUPIMMPS imm8, xmm, xmm, xmm{k}{z} [AVX512VL] -// * VFIXUPIMMPS imm8, m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFIXUPIMMPS imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFIXUPIMMPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFIXUPIMMPS", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VFIXUPIMMPS", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VFIXUPIMMPS takes 4 or 5 operands") - } - // VFIXUPIMMPS imm8, m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPS imm8, {sae}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMM(v3) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0x7d ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x54) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPS imm8, zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x54) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPS imm8, m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM128M32bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPS imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x54) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPS imm8, m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x54) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMPS imm8, ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x54) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFIXUPIMMPS") - } - return p -} - -// VFIXUPIMMSD performs "Fix Up Special Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VFIXUPIMMSD -// Supported forms : (3 forms) -// -// * VFIXUPIMMSD imm8, m64, xmm, xmm{k}{z} [AVX512F] -// * VFIXUPIMMSD imm8, {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFIXUPIMMSD imm8, xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFIXUPIMMSD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFIXUPIMMSD", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VFIXUPIMMSD", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VFIXUPIMMSD takes 4 or 5 operands") - } - // VFIXUPIMMSD imm8, m64, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM64(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x55) - m.mrsd(lcode(v[3]), addr(v[1]), 8) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMSD imm8, {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0xfd ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x55) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMSD imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x55) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFIXUPIMMSD") - } - return p -} - -// VFIXUPIMMSS performs "Fix Up Special Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VFIXUPIMMSS -// Supported forms : (3 forms) -// -// * VFIXUPIMMSS imm8, m32, xmm, xmm{k}{z} [AVX512F] -// * VFIXUPIMMSS imm8, {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFIXUPIMMSS imm8, xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFIXUPIMMSS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFIXUPIMMSS", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VFIXUPIMMSS", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VFIXUPIMMSS takes 4 or 5 operands") - } - // VFIXUPIMMSS imm8, m32, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM32(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x55) - m.mrsd(lcode(v[3]), addr(v[1]), 4) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMSS imm8, {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0x7d ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x55) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VFIXUPIMMSS imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x55) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFIXUPIMMSS") - } - return p -} - -// VFMADD132PD performs "Fused Multiply-Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADD132PD -// Supported forms : (11 forms) -// -// * VFMADD132PD xmm, xmm, xmm [FMA3] -// * VFMADD132PD m128, xmm, xmm [FMA3] -// * VFMADD132PD ymm, ymm, ymm [FMA3] -// * VFMADD132PD m256, ymm, ymm [FMA3] -// * VFMADD132PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADD132PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD132PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD132PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD132PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD132PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADD132PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADD132PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD132PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD132PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD132PD takes 3 or 4 operands") - } - // VFMADD132PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD132PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD132PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADD132PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x98) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD132PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADD132PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADD132PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD132PD") - } - return p -} - -// VFMADD132PS performs "Fused Multiply-Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADD132PS -// Supported forms : (11 forms) -// -// * VFMADD132PS xmm, xmm, xmm [FMA3] -// * VFMADD132PS m128, xmm, xmm [FMA3] -// * VFMADD132PS ymm, ymm, ymm [FMA3] -// * VFMADD132PS m256, ymm, ymm [FMA3] -// * VFMADD132PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADD132PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD132PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD132PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD132PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD132PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADD132PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADD132PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD132PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD132PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD132PS takes 3 or 4 operands") - } - // VFMADD132PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD132PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD132PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADD132PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x98) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD132PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADD132PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADD132PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD132PS") - } - return p -} - -// VFMADD132SD performs "Fused Multiply-Add of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADD132SD -// Supported forms : (5 forms) -// -// * VFMADD132SD xmm, xmm, xmm [FMA3] -// * VFMADD132SD m64, xmm, xmm [FMA3] -// * VFMADD132SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFMADD132SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMADD132SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMADD132SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD132SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD132SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD132SD takes 3 or 4 operands") - } - // VFMADD132SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x99) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x99) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD132SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x99) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFMADD132SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x99) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD132SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x99) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD132SD") - } - return p -} - -// VFMADD132SS performs "Fused Multiply-Add of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADD132SS -// Supported forms : (5 forms) -// -// * VFMADD132SS xmm, xmm, xmm [FMA3] -// * VFMADD132SS m32, xmm, xmm [FMA3] -// * VFMADD132SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFMADD132SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMADD132SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMADD132SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD132SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD132SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD132SS takes 3 or 4 operands") - } - // VFMADD132SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x99) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD132SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x99) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD132SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x99) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFMADD132SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x99) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD132SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x99) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD132SS") - } - return p -} - -// VFMADD213PD performs "Fused Multiply-Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADD213PD -// Supported forms : (11 forms) -// -// * VFMADD213PD xmm, xmm, xmm [FMA3] -// * VFMADD213PD m128, xmm, xmm [FMA3] -// * VFMADD213PD ymm, ymm, ymm [FMA3] -// * VFMADD213PD m256, ymm, ymm [FMA3] -// * VFMADD213PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADD213PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD213PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD213PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD213PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD213PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADD213PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADD213PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD213PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD213PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD213PD takes 3 or 4 operands") - } - // VFMADD213PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD213PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD213PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADD213PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD213PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADD213PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADD213PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD213PD") - } - return p -} - -// VFMADD213PS performs "Fused Multiply-Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADD213PS -// Supported forms : (11 forms) -// -// * VFMADD213PS xmm, xmm, xmm [FMA3] -// * VFMADD213PS m128, xmm, xmm [FMA3] -// * VFMADD213PS ymm, ymm, ymm [FMA3] -// * VFMADD213PS m256, ymm, ymm [FMA3] -// * VFMADD213PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADD213PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD213PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD213PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD213PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD213PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADD213PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADD213PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD213PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD213PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD213PS takes 3 or 4 operands") - } - // VFMADD213PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD213PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD213PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADD213PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD213PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADD213PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa8) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADD213PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xa8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD213PS") - } - return p -} - -// VFMADD213SD performs "Fused Multiply-Add of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADD213SD -// Supported forms : (5 forms) -// -// * VFMADD213SD xmm, xmm, xmm [FMA3] -// * VFMADD213SD m64, xmm, xmm [FMA3] -// * VFMADD213SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFMADD213SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMADD213SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMADD213SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD213SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD213SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD213SD takes 3 or 4 operands") - } - // VFMADD213SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xa9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD213SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xa9) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFMADD213SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xa9) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD213SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xa9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD213SD") - } - return p -} - -// VFMADD213SS performs "Fused Multiply-Add of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADD213SS -// Supported forms : (5 forms) -// -// * VFMADD213SS xmm, xmm, xmm [FMA3] -// * VFMADD213SS m32, xmm, xmm [FMA3] -// * VFMADD213SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFMADD213SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMADD213SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMADD213SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD213SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD213SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD213SS takes 3 or 4 operands") - } - // VFMADD213SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xa9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD213SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD213SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xa9) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFMADD213SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xa9) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD213SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xa9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD213SS") - } - return p -} - -// VFMADD231PD performs "Fused Multiply-Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADD231PD -// Supported forms : (11 forms) -// -// * VFMADD231PD xmm, xmm, xmm [FMA3] -// * VFMADD231PD m128, xmm, xmm [FMA3] -// * VFMADD231PD ymm, ymm, ymm [FMA3] -// * VFMADD231PD m256, ymm, ymm [FMA3] -// * VFMADD231PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADD231PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD231PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD231PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD231PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD231PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADD231PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADD231PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD231PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD231PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD231PD takes 3 or 4 operands") - } - // VFMADD231PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD231PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD231PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADD231PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD231PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADD231PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADD231PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD231PD") - } - return p -} - -// VFMADD231PS performs "Fused Multiply-Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADD231PS -// Supported forms : (11 forms) -// -// * VFMADD231PS xmm, xmm, xmm [FMA3] -// * VFMADD231PS m128, xmm, xmm [FMA3] -// * VFMADD231PS ymm, ymm, ymm [FMA3] -// * VFMADD231PS m256, ymm, ymm [FMA3] -// * VFMADD231PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADD231PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD231PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADD231PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD231PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADD231PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADD231PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADD231PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD231PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD231PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD231PS takes 3 or 4 operands") - } - // VFMADD231PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD231PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD231PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADD231PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD231PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADD231PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb8) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADD231PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xb8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD231PS") - } - return p -} - -// VFMADD231SD performs "Fused Multiply-Add of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADD231SD -// Supported forms : (5 forms) -// -// * VFMADD231SD xmm, xmm, xmm [FMA3] -// * VFMADD231SD m64, xmm, xmm [FMA3] -// * VFMADD231SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFMADD231SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMADD231SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMADD231SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD231SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD231SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD231SD takes 3 or 4 operands") - } - // VFMADD231SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xb9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD231SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xb9) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFMADD231SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xb9) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD231SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD231SD") - } - return p -} - -// VFMADD231SS performs "Fused Multiply-Add of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADD231SS -// Supported forms : (5 forms) -// -// * VFMADD231SS xmm, xmm, xmm [FMA3] -// * VFMADD231SS m32, xmm, xmm [FMA3] -// * VFMADD231SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFMADD231SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMADD231SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMADD231SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADD231SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADD231SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADD231SS takes 3 or 4 operands") - } - // VFMADD231SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xb9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADD231SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADD231SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xb9) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFMADD231SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xb9) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADD231SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADD231SS") - } - return p -} - -// VFMADDPD performs "Fused Multiply-Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADDPD -// Supported forms : (6 forms) -// -// * VFMADDPD xmm, xmm, xmm, xmm [FMA4] -// * VFMADDPD m128, xmm, xmm, xmm [FMA4] -// * VFMADDPD xmm, m128, xmm, xmm [FMA4] -// * VFMADDPD ymm, ymm, ymm, ymm [FMA4] -// * VFMADDPD m256, ymm, ymm, ymm [FMA4] -// * VFMADDPD ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFMADDPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMADDPD", 4, Operands { v0, v1, v2, v3 }) - // VFMADDPD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x69) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x69) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDPD m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x69) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDPD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x69) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDPD ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x69) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x69) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDPD m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x69) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDPD ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x69) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDPD") - } - return p -} - -// VFMADDPS performs "Fused Multiply-Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADDPS -// Supported forms : (6 forms) -// -// * VFMADDPS xmm, xmm, xmm, xmm [FMA4] -// * VFMADDPS m128, xmm, xmm, xmm [FMA4] -// * VFMADDPS xmm, m128, xmm, xmm [FMA4] -// * VFMADDPS ymm, ymm, ymm, ymm [FMA4] -// * VFMADDPS m256, ymm, ymm, ymm [FMA4] -// * VFMADDPS ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFMADDPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMADDPS", 4, Operands { v0, v1, v2, v3 }) - // VFMADDPS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x68) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x68) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDPS m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x68) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDPS xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x68) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDPS ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x68) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x68) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDPS m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x68) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDPS ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x68) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDPS") - } - return p -} - -// VFMADDSD performs "Fused Multiply-Add of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSD -// Supported forms : (3 forms) -// -// * VFMADDSD xmm, xmm, xmm, xmm [FMA4] -// * VFMADDSD m64, xmm, xmm, xmm [FMA4] -// * VFMADDSD xmm, m64, xmm, xmm [FMA4] -// -func (self *Program) VFMADDSD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMADDSD", 4, Operands { v0, v1, v2, v3 }) - // VFMADDSD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDSD m64, xmm, xmm, xmm - if isM64(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x6b) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDSD xmm, m64, xmm, xmm - if isXMM(v0) && isM64(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x6b) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSD") - } - return p -} - -// VFMADDSS performs "Fused Multiply-Add of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSS -// Supported forms : (3 forms) -// -// * VFMADDSS xmm, xmm, xmm, xmm [FMA4] -// * VFMADDSS m32, xmm, xmm, xmm [FMA4] -// * VFMADDSS xmm, m32, xmm, xmm [FMA4] -// -func (self *Program) VFMADDSS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMADDSS", 4, Operands { v0, v1, v2, v3 }) - // VFMADDSS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x6a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x6a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDSS m32, xmm, xmm, xmm - if isM32(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x6a) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDSS xmm, m32, xmm, xmm - if isXMM(v0) && isM32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x6a) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSS") - } - return p -} - -// VFMADDSUB132PD performs "Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSUB132PD -// Supported forms : (11 forms) -// -// * VFMADDSUB132PD xmm, xmm, xmm [FMA3] -// * VFMADDSUB132PD m128, xmm, xmm [FMA3] -// * VFMADDSUB132PD ymm, ymm, ymm [FMA3] -// * VFMADDSUB132PD m256, ymm, ymm [FMA3] -// * VFMADDSUB132PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB132PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB132PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB132PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB132PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB132PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB132PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADDSUB132PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADDSUB132PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADDSUB132PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADDSUB132PD takes 3 or 4 operands") - } - // VFMADDSUB132PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB132PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB132PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB132PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB132PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADDSUB132PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x96) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADDSUB132PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB132PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADDSUB132PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB132PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADDSUB132PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSUB132PD") - } - return p -} - -// VFMADDSUB132PS performs "Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSUB132PS -// Supported forms : (11 forms) -// -// * VFMADDSUB132PS xmm, xmm, xmm [FMA3] -// * VFMADDSUB132PS m128, xmm, xmm [FMA3] -// * VFMADDSUB132PS ymm, ymm, ymm [FMA3] -// * VFMADDSUB132PS m256, ymm, ymm [FMA3] -// * VFMADDSUB132PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB132PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB132PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB132PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB132PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB132PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB132PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADDSUB132PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADDSUB132PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADDSUB132PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADDSUB132PS takes 3 or 4 operands") - } - // VFMADDSUB132PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB132PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB132PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB132PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB132PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADDSUB132PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x96) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADDSUB132PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB132PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADDSUB132PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB132PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADDSUB132PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSUB132PS") - } - return p -} - -// VFMADDSUB213PD performs "Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSUB213PD -// Supported forms : (11 forms) -// -// * VFMADDSUB213PD xmm, xmm, xmm [FMA3] -// * VFMADDSUB213PD m128, xmm, xmm [FMA3] -// * VFMADDSUB213PD ymm, ymm, ymm [FMA3] -// * VFMADDSUB213PD m256, ymm, ymm [FMA3] -// * VFMADDSUB213PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB213PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB213PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB213PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB213PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB213PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB213PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADDSUB213PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADDSUB213PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADDSUB213PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADDSUB213PD takes 3 or 4 operands") - } - // VFMADDSUB213PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB213PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB213PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB213PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB213PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADDSUB213PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADDSUB213PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB213PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADDSUB213PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB213PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADDSUB213PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSUB213PD") - } - return p -} - -// VFMADDSUB213PS performs "Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSUB213PS -// Supported forms : (11 forms) -// -// * VFMADDSUB213PS xmm, xmm, xmm [FMA3] -// * VFMADDSUB213PS m128, xmm, xmm [FMA3] -// * VFMADDSUB213PS ymm, ymm, ymm [FMA3] -// * VFMADDSUB213PS m256, ymm, ymm [FMA3] -// * VFMADDSUB213PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB213PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB213PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB213PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB213PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB213PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB213PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADDSUB213PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADDSUB213PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADDSUB213PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADDSUB213PS takes 3 or 4 operands") - } - // VFMADDSUB213PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB213PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB213PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB213PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB213PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADDSUB213PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADDSUB213PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB213PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADDSUB213PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB213PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa6) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADDSUB213PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSUB213PS") - } - return p -} - -// VFMADDSUB231PD performs "Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSUB231PD -// Supported forms : (11 forms) -// -// * VFMADDSUB231PD xmm, xmm, xmm [FMA3] -// * VFMADDSUB231PD m128, xmm, xmm [FMA3] -// * VFMADDSUB231PD ymm, ymm, ymm [FMA3] -// * VFMADDSUB231PD m256, ymm, ymm [FMA3] -// * VFMADDSUB231PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB231PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB231PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB231PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB231PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB231PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB231PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADDSUB231PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADDSUB231PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADDSUB231PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADDSUB231PD takes 3 or 4 operands") - } - // VFMADDSUB231PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB231PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB231PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB231PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB231PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADDSUB231PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADDSUB231PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB231PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADDSUB231PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB231PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADDSUB231PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSUB231PD") - } - return p -} - -// VFMADDSUB231PS performs "Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSUB231PS -// Supported forms : (11 forms) -// -// * VFMADDSUB231PS xmm, xmm, xmm [FMA3] -// * VFMADDSUB231PS m128, xmm, xmm [FMA3] -// * VFMADDSUB231PS ymm, ymm, ymm [FMA3] -// * VFMADDSUB231PS m256, ymm, ymm [FMA3] -// * VFMADDSUB231PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB231PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB231PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMADDSUB231PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB231PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB231PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMADDSUB231PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMADDSUB231PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMADDSUB231PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMADDSUB231PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMADDSUB231PS takes 3 or 4 operands") - } - // VFMADDSUB231PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB231PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB231PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB231PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMADDSUB231PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMADDSUB231PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMADDSUB231PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB231PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMADDSUB231PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMADDSUB231PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb6) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMADDSUB231PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSUB231PS") - } - return p -} - -// VFMADDSUBPD performs "Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSUBPD -// Supported forms : (6 forms) -// -// * VFMADDSUBPD xmm, xmm, xmm, xmm [FMA4] -// * VFMADDSUBPD m128, xmm, xmm, xmm [FMA4] -// * VFMADDSUBPD xmm, m128, xmm, xmm [FMA4] -// * VFMADDSUBPD ymm, ymm, ymm, ymm [FMA4] -// * VFMADDSUBPD m256, ymm, ymm, ymm [FMA4] -// * VFMADDSUBPD ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFMADDSUBPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMADDSUBPD", 4, Operands { v0, v1, v2, v3 }) - // VFMADDSUBPD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDSUBPD m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x5d) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDSUBPD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x5d) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDSUBPD ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDSUBPD m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x5d) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDSUBPD ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x5d) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSUBPD") - } - return p -} - -// VFMADDSUBPS performs "Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMADDSUBPS -// Supported forms : (6 forms) -// -// * VFMADDSUBPS xmm, xmm, xmm, xmm [FMA4] -// * VFMADDSUBPS m128, xmm, xmm, xmm [FMA4] -// * VFMADDSUBPS xmm, m128, xmm, xmm [FMA4] -// * VFMADDSUBPS ymm, ymm, ymm, ymm [FMA4] -// * VFMADDSUBPS m256, ymm, ymm, ymm [FMA4] -// * VFMADDSUBPS ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFMADDSUBPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMADDSUBPS", 4, Operands { v0, v1, v2, v3 }) - // VFMADDSUBPS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDSUBPS m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x5c) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDSUBPS xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x5c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDSUBPS ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMADDSUBPS m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x5c) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMADDSUBPS ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x5c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMADDSUBPS") - } - return p -} - -// VFMSUB132PD performs "Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB132PD -// Supported forms : (11 forms) -// -// * VFMSUB132PD xmm, xmm, xmm [FMA3] -// * VFMSUB132PD m128, xmm, xmm [FMA3] -// * VFMSUB132PD ymm, ymm, ymm [FMA3] -// * VFMSUB132PD m256, ymm, ymm [FMA3] -// * VFMSUB132PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB132PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB132PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB132PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB132PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB132PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB132PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUB132PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB132PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB132PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB132PD takes 3 or 4 operands") - } - // VFMSUB132PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB132PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB132PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUB132PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB132PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUB132PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUB132PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB132PD") - } - return p -} - -// VFMSUB132PS performs "Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB132PS -// Supported forms : (11 forms) -// -// * VFMSUB132PS xmm, xmm, xmm [FMA3] -// * VFMSUB132PS m128, xmm, xmm [FMA3] -// * VFMSUB132PS ymm, ymm, ymm [FMA3] -// * VFMSUB132PS m256, ymm, ymm [FMA3] -// * VFMSUB132PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB132PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB132PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB132PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB132PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB132PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB132PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUB132PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB132PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB132PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB132PS takes 3 or 4 operands") - } - // VFMSUB132PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB132PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB132PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUB132PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB132PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUB132PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUB132PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB132PS") - } - return p -} - -// VFMSUB132SD performs "Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB132SD -// Supported forms : (5 forms) -// -// * VFMSUB132SD xmm, xmm, xmm [FMA3] -// * VFMSUB132SD m64, xmm, xmm [FMA3] -// * VFMSUB132SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB132SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB132SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMSUB132SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB132SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB132SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB132SD takes 3 or 4 operands") - } - // VFMSUB132SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB132SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x9b) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFMSUB132SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB132SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB132SD") - } - return p -} - -// VFMSUB132SS performs "Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB132SS -// Supported forms : (5 forms) -// -// * VFMSUB132SS xmm, xmm, xmm [FMA3] -// * VFMSUB132SS m32, xmm, xmm [FMA3] -// * VFMSUB132SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB132SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB132SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMSUB132SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB132SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB132SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB132SS takes 3 or 4 operands") - } - // VFMSUB132SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB132SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB132SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x9b) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFMSUB132SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB132SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB132SS") - } - return p -} - -// VFMSUB213PD performs "Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB213PD -// Supported forms : (11 forms) -// -// * VFMSUB213PD xmm, xmm, xmm [FMA3] -// * VFMSUB213PD m128, xmm, xmm [FMA3] -// * VFMSUB213PD ymm, ymm, ymm [FMA3] -// * VFMSUB213PD m256, ymm, ymm [FMA3] -// * VFMSUB213PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB213PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB213PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB213PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB213PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB213PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB213PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUB213PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB213PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB213PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB213PD takes 3 or 4 operands") - } - // VFMSUB213PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB213PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB213PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUB213PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB213PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUB213PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUB213PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB213PD") - } - return p -} - -// VFMSUB213PS performs "Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB213PS -// Supported forms : (11 forms) -// -// * VFMSUB213PS xmm, xmm, xmm [FMA3] -// * VFMSUB213PS m128, xmm, xmm [FMA3] -// * VFMSUB213PS ymm, ymm, ymm [FMA3] -// * VFMSUB213PS m256, ymm, ymm [FMA3] -// * VFMSUB213PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB213PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB213PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB213PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB213PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB213PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB213PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUB213PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB213PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB213PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB213PS takes 3 or 4 operands") - } - // VFMSUB213PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB213PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB213PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUB213PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB213PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUB213PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xaa) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUB213PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xaa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB213PS") - } - return p -} - -// VFMSUB213SD performs "Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB213SD -// Supported forms : (5 forms) -// -// * VFMSUB213SD xmm, xmm, xmm [FMA3] -// * VFMSUB213SD m64, xmm, xmm [FMA3] -// * VFMSUB213SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB213SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB213SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMSUB213SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB213SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB213SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB213SD takes 3 or 4 operands") - } - // VFMSUB213SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xab) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xab) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB213SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xab) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFMSUB213SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xab) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB213SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xab) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB213SD") - } - return p -} - -// VFMSUB213SS performs "Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB213SS -// Supported forms : (5 forms) -// -// * VFMSUB213SS xmm, xmm, xmm [FMA3] -// * VFMSUB213SS m32, xmm, xmm [FMA3] -// * VFMSUB213SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB213SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB213SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMSUB213SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB213SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB213SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB213SS takes 3 or 4 operands") - } - // VFMSUB213SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xab) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB213SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xab) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB213SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xab) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFMSUB213SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xab) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB213SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xab) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB213SS") - } - return p -} - -// VFMSUB231PD performs "Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB231PD -// Supported forms : (11 forms) -// -// * VFMSUB231PD xmm, xmm, xmm [FMA3] -// * VFMSUB231PD m128, xmm, xmm [FMA3] -// * VFMSUB231PD ymm, ymm, ymm [FMA3] -// * VFMSUB231PD m256, ymm, ymm [FMA3] -// * VFMSUB231PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB231PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB231PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB231PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB231PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB231PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB231PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUB231PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB231PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB231PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB231PD takes 3 or 4 operands") - } - // VFMSUB231PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB231PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB231PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUB231PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xba) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB231PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUB231PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUB231PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB231PD") - } - return p -} - -// VFMSUB231PS performs "Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB231PS -// Supported forms : (11 forms) -// -// * VFMSUB231PS xmm, xmm, xmm [FMA3] -// * VFMSUB231PS m128, xmm, xmm [FMA3] -// * VFMSUB231PS ymm, ymm, ymm [FMA3] -// * VFMSUB231PS m256, ymm, ymm [FMA3] -// * VFMSUB231PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB231PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB231PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUB231PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB231PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB231PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUB231PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUB231PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB231PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB231PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB231PS takes 3 or 4 operands") - } - // VFMSUB231PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB231PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB231PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUB231PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xba) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB231PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUB231PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xba) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUB231PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xba) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB231PS") - } - return p -} - -// VFMSUB231SD performs "Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB231SD -// Supported forms : (5 forms) -// -// * VFMSUB231SD xmm, xmm, xmm [FMA3] -// * VFMSUB231SD m64, xmm, xmm [FMA3] -// * VFMSUB231SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB231SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB231SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMSUB231SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB231SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB231SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB231SD takes 3 or 4 operands") - } - // VFMSUB231SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xbb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbb) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB231SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xbb) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFMSUB231SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbb) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB231SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB231SD") - } - return p -} - -// VFMSUB231SS performs "Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUB231SS -// Supported forms : (5 forms) -// -// * VFMSUB231SS xmm, xmm, xmm [FMA3] -// * VFMSUB231SS m32, xmm, xmm [FMA3] -// * VFMSUB231SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB231SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFMSUB231SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFMSUB231SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUB231SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUB231SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUB231SS takes 3 or 4 operands") - } - // VFMSUB231SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xbb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUB231SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbb) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUB231SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xbb) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFMSUB231SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbb) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUB231SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUB231SS") - } - return p -} - -// VFMSUBADD132PD performs "Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBADD132PD -// Supported forms : (11 forms) -// -// * VFMSUBADD132PD xmm, xmm, xmm [FMA3] -// * VFMSUBADD132PD m128, xmm, xmm [FMA3] -// * VFMSUBADD132PD ymm, ymm, ymm [FMA3] -// * VFMSUBADD132PD m256, ymm, ymm [FMA3] -// * VFMSUBADD132PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD132PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD132PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD132PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD132PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD132PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD132PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUBADD132PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUBADD132PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUBADD132PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUBADD132PD takes 3 or 4 operands") - } - // VFMSUBADD132PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD132PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD132PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD132PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD132PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUBADD132PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x97) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUBADD132PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD132PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUBADD132PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD132PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUBADD132PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBADD132PD") - } - return p -} - -// VFMSUBADD132PS performs "Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBADD132PS -// Supported forms : (11 forms) -// -// * VFMSUBADD132PS xmm, xmm, xmm [FMA3] -// * VFMSUBADD132PS m128, xmm, xmm [FMA3] -// * VFMSUBADD132PS ymm, ymm, ymm [FMA3] -// * VFMSUBADD132PS m256, ymm, ymm [FMA3] -// * VFMSUBADD132PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD132PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD132PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD132PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD132PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD132PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD132PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUBADD132PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUBADD132PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUBADD132PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUBADD132PS takes 3 or 4 operands") - } - // VFMSUBADD132PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD132PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD132PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD132PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD132PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUBADD132PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x97) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUBADD132PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD132PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUBADD132PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD132PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUBADD132PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBADD132PS") - } - return p -} - -// VFMSUBADD213PD performs "Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBADD213PD -// Supported forms : (11 forms) -// -// * VFMSUBADD213PD xmm, xmm, xmm [FMA3] -// * VFMSUBADD213PD m128, xmm, xmm [FMA3] -// * VFMSUBADD213PD ymm, ymm, ymm [FMA3] -// * VFMSUBADD213PD m256, ymm, ymm [FMA3] -// * VFMSUBADD213PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD213PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD213PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD213PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD213PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD213PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD213PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUBADD213PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUBADD213PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUBADD213PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUBADD213PD takes 3 or 4 operands") - } - // VFMSUBADD213PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD213PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD213PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD213PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD213PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUBADD213PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUBADD213PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD213PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUBADD213PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD213PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUBADD213PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBADD213PD") - } - return p -} - -// VFMSUBADD213PS performs "Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBADD213PS -// Supported forms : (11 forms) -// -// * VFMSUBADD213PS xmm, xmm, xmm [FMA3] -// * VFMSUBADD213PS m128, xmm, xmm [FMA3] -// * VFMSUBADD213PS ymm, ymm, ymm [FMA3] -// * VFMSUBADD213PS m256, ymm, ymm [FMA3] -// * VFMSUBADD213PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD213PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD213PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD213PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD213PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD213PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD213PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUBADD213PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUBADD213PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUBADD213PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUBADD213PS takes 3 or 4 operands") - } - // VFMSUBADD213PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD213PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD213PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD213PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD213PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUBADD213PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUBADD213PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD213PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUBADD213PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD213PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xa7) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUBADD213PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xa7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBADD213PS") - } - return p -} - -// VFMSUBADD231PD performs "Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBADD231PD -// Supported forms : (11 forms) -// -// * VFMSUBADD231PD xmm, xmm, xmm [FMA3] -// * VFMSUBADD231PD m128, xmm, xmm [FMA3] -// * VFMSUBADD231PD ymm, ymm, ymm [FMA3] -// * VFMSUBADD231PD m256, ymm, ymm [FMA3] -// * VFMSUBADD231PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD231PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD231PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD231PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD231PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD231PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD231PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUBADD231PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUBADD231PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUBADD231PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUBADD231PD takes 3 or 4 operands") - } - // VFMSUBADD231PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD231PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD231PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD231PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD231PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUBADD231PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUBADD231PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD231PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUBADD231PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD231PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUBADD231PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBADD231PD") - } - return p -} - -// VFMSUBADD231PS performs "Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBADD231PS -// Supported forms : (11 forms) -// -// * VFMSUBADD231PS xmm, xmm, xmm [FMA3] -// * VFMSUBADD231PS m128, xmm, xmm [FMA3] -// * VFMSUBADD231PS ymm, ymm, ymm [FMA3] -// * VFMSUBADD231PS m256, ymm, ymm [FMA3] -// * VFMSUBADD231PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD231PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD231PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFMSUBADD231PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD231PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD231PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFMSUBADD231PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFMSUBADD231PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFMSUBADD231PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFMSUBADD231PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFMSUBADD231PS takes 3 or 4 operands") - } - // VFMSUBADD231PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD231PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD231PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD231PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFMSUBADD231PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFMSUBADD231PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFMSUBADD231PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD231PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFMSUBADD231PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFMSUBADD231PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb7) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFMSUBADD231PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xb7) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBADD231PS") - } - return p -} - -// VFMSUBADDPD performs "Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBADDPD -// Supported forms : (6 forms) -// -// * VFMSUBADDPD xmm, xmm, xmm, xmm [FMA4] -// * VFMSUBADDPD m128, xmm, xmm, xmm [FMA4] -// * VFMSUBADDPD xmm, m128, xmm, xmm [FMA4] -// * VFMSUBADDPD ymm, ymm, ymm, ymm [FMA4] -// * VFMSUBADDPD m256, ymm, ymm, ymm [FMA4] -// * VFMSUBADDPD ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFMSUBADDPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMSUBADDPD", 4, Operands { v0, v1, v2, v3 }) - // VFMSUBADDPD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBADDPD m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x5f) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBADDPD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x5f) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBADDPD ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBADDPD m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x5f) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBADDPD ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x5f) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBADDPD") - } - return p -} - -// VFMSUBADDPS performs "Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBADDPS -// Supported forms : (6 forms) -// -// * VFMSUBADDPS xmm, xmm, xmm, xmm [FMA4] -// * VFMSUBADDPS m128, xmm, xmm, xmm [FMA4] -// * VFMSUBADDPS xmm, m128, xmm, xmm [FMA4] -// * VFMSUBADDPS ymm, ymm, ymm, ymm [FMA4] -// * VFMSUBADDPS m256, ymm, ymm, ymm [FMA4] -// * VFMSUBADDPS ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFMSUBADDPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMSUBADDPS", 4, Operands { v0, v1, v2, v3 }) - // VFMSUBADDPS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBADDPS m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x5e) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBADDPS xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x5e) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBADDPS ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x5e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBADDPS m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x5e) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBADDPS ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x5e) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBADDPS") - } - return p -} - -// VFMSUBPD performs "Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBPD -// Supported forms : (6 forms) -// -// * VFMSUBPD xmm, xmm, xmm, xmm [FMA4] -// * VFMSUBPD m128, xmm, xmm, xmm [FMA4] -// * VFMSUBPD xmm, m128, xmm, xmm [FMA4] -// * VFMSUBPD ymm, ymm, ymm, ymm [FMA4] -// * VFMSUBPD m256, ymm, ymm, ymm [FMA4] -// * VFMSUBPD ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFMSUBPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMSUBPD", 4, Operands { v0, v1, v2, v3 }) - // VFMSUBPD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBPD m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x6d) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBPD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x6d) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBPD ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBPD m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x6d) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBPD ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x6d) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBPD") - } - return p -} - -// VFMSUBPS performs "Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBPS -// Supported forms : (6 forms) -// -// * VFMSUBPS xmm, xmm, xmm, xmm [FMA4] -// * VFMSUBPS m128, xmm, xmm, xmm [FMA4] -// * VFMSUBPS xmm, m128, xmm, xmm [FMA4] -// * VFMSUBPS ymm, ymm, ymm, ymm [FMA4] -// * VFMSUBPS m256, ymm, ymm, ymm [FMA4] -// * VFMSUBPS ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFMSUBPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMSUBPS", 4, Operands { v0, v1, v2, v3 }) - // VFMSUBPS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBPS m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x6c) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBPS xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x6c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBPS ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBPS m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x6c) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBPS ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x6c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBPS") - } - return p -} - -// VFMSUBSD performs "Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBSD -// Supported forms : (3 forms) -// -// * VFMSUBSD xmm, xmm, xmm, xmm [FMA4] -// * VFMSUBSD m64, xmm, xmm, xmm [FMA4] -// * VFMSUBSD xmm, m64, xmm, xmm [FMA4] -// -func (self *Program) VFMSUBSD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMSUBSD", 4, Operands { v0, v1, v2, v3 }) - // VFMSUBSD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBSD m64, xmm, xmm, xmm - if isM64(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x6f) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBSD xmm, m64, xmm, xmm - if isXMM(v0) && isM64(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x6f) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBSD") - } - return p -} - -// VFMSUBSS performs "Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFMSUBSS -// Supported forms : (3 forms) -// -// * VFMSUBSS xmm, xmm, xmm, xmm [FMA4] -// * VFMSUBSS m32, xmm, xmm, xmm [FMA4] -// * VFMSUBSS xmm, m32, xmm, xmm [FMA4] -// -func (self *Program) VFMSUBSS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFMSUBSS", 4, Operands { v0, v1, v2, v3 }) - // VFMSUBSS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFMSUBSS m32, xmm, xmm, xmm - if isM32(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x6e) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFMSUBSS xmm, m32, xmm, xmm - if isXMM(v0) && isM32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x6e) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFMSUBSS") - } - return p -} - -// VFNMADD132PD performs "Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD132PD -// Supported forms : (11 forms) -// -// * VFNMADD132PD xmm, xmm, xmm [FMA3] -// * VFNMADD132PD m128, xmm, xmm [FMA3] -// * VFNMADD132PD ymm, ymm, ymm [FMA3] -// * VFNMADD132PD m256, ymm, ymm [FMA3] -// * VFNMADD132PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD132PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD132PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD132PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD132PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD132PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD132PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMADD132PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD132PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD132PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD132PD takes 3 or 4 operands") - } - // VFNMADD132PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD132PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD132PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMADD132PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD132PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMADD132PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMADD132PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD132PD") - } - return p -} - -// VFNMADD132PS performs "Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD132PS -// Supported forms : (11 forms) -// -// * VFNMADD132PS xmm, xmm, xmm [FMA3] -// * VFNMADD132PS m128, xmm, xmm [FMA3] -// * VFNMADD132PS ymm, ymm, ymm [FMA3] -// * VFNMADD132PS m256, ymm, ymm [FMA3] -// * VFNMADD132PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD132PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD132PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD132PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD132PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD132PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD132PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMADD132PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD132PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD132PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD132PS takes 3 or 4 operands") - } - // VFNMADD132PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD132PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD132PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMADD132PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD132PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMADD132PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9c) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMADD132PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x9c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD132PS") - } - return p -} - -// VFNMADD132SD performs "Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD132SD -// Supported forms : (5 forms) -// -// * VFNMADD132SD xmm, xmm, xmm [FMA3] -// * VFNMADD132SD m64, xmm, xmm [FMA3] -// * VFNMADD132SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD132SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD132SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMADD132SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD132SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD132SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD132SD takes 3 or 4 operands") - } - // VFNMADD132SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x9d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD132SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x9d) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFNMADD132SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD132SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD132SD") - } - return p -} - -// VFNMADD132SS performs "Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD132SS -// Supported forms : (5 forms) -// -// * VFNMADD132SS xmm, xmm, xmm [FMA3] -// * VFNMADD132SS m32, xmm, xmm [FMA3] -// * VFNMADD132SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD132SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD132SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMADD132SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD132SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD132SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD132SS takes 3 or 4 operands") - } - // VFNMADD132SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x9d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD132SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD132SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x9d) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFNMADD132SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD132SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD132SS") - } - return p -} - -// VFNMADD213PD performs "Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD213PD -// Supported forms : (11 forms) -// -// * VFNMADD213PD xmm, xmm, xmm [FMA3] -// * VFNMADD213PD m128, xmm, xmm [FMA3] -// * VFNMADD213PD ymm, ymm, ymm [FMA3] -// * VFNMADD213PD m256, ymm, ymm [FMA3] -// * VFNMADD213PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD213PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD213PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD213PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD213PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD213PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD213PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMADD213PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD213PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD213PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD213PD takes 3 or 4 operands") - } - // VFNMADD213PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD213PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD213PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMADD213PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xac) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD213PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMADD213PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMADD213PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD213PD") - } - return p -} - -// VFNMADD213PS performs "Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD213PS -// Supported forms : (11 forms) -// -// * VFNMADD213PS xmm, xmm, xmm [FMA3] -// * VFNMADD213PS m128, xmm, xmm [FMA3] -// * VFNMADD213PS ymm, ymm, ymm [FMA3] -// * VFNMADD213PS m256, ymm, ymm [FMA3] -// * VFNMADD213PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD213PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD213PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD213PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD213PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD213PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD213PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMADD213PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD213PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD213PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD213PS takes 3 or 4 operands") - } - // VFNMADD213PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD213PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD213PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMADD213PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xac) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD213PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMADD213PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xac) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMADD213PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xac) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD213PS") - } - return p -} - -// VFNMADD213SD performs "Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD213SD -// Supported forms : (5 forms) -// -// * VFNMADD213SD xmm, xmm, xmm [FMA3] -// * VFNMADD213SD m64, xmm, xmm [FMA3] -// * VFNMADD213SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD213SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD213SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMADD213SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD213SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD213SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD213SD takes 3 or 4 operands") - } - // VFNMADD213SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xad) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xad) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD213SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xad) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFNMADD213SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xad) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD213SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xad) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD213SD") - } - return p -} - -// VFNMADD213SS performs "Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD213SS -// Supported forms : (5 forms) -// -// * VFNMADD213SS xmm, xmm, xmm [FMA3] -// * VFNMADD213SS m32, xmm, xmm [FMA3] -// * VFNMADD213SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD213SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD213SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMADD213SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD213SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD213SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD213SS takes 3 or 4 operands") - } - // VFNMADD213SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xad) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD213SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xad) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD213SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xad) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFNMADD213SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xad) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD213SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xad) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD213SS") - } - return p -} - -// VFNMADD231PD performs "Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD231PD -// Supported forms : (11 forms) -// -// * VFNMADD231PD xmm, xmm, xmm [FMA3] -// * VFNMADD231PD m128, xmm, xmm [FMA3] -// * VFNMADD231PD ymm, ymm, ymm [FMA3] -// * VFNMADD231PD m256, ymm, ymm [FMA3] -// * VFNMADD231PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD231PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD231PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD231PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD231PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD231PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD231PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMADD231PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD231PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD231PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD231PD takes 3 or 4 operands") - } - // VFNMADD231PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD231PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD231PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMADD231PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD231PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMADD231PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMADD231PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD231PD") - } - return p -} - -// VFNMADD231PS performs "Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD231PS -// Supported forms : (11 forms) -// -// * VFNMADD231PS xmm, xmm, xmm [FMA3] -// * VFNMADD231PS m128, xmm, xmm [FMA3] -// * VFNMADD231PS ymm, ymm, ymm [FMA3] -// * VFNMADD231PS m256, ymm, ymm [FMA3] -// * VFNMADD231PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD231PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD231PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMADD231PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD231PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD231PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMADD231PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMADD231PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD231PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD231PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD231PS takes 3 or 4 operands") - } - // VFNMADD231PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD231PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD231PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMADD231PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD231PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMADD231PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbc) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMADD231PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xbc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD231PS") - } - return p -} - -// VFNMADD231SD performs "Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD231SD -// Supported forms : (5 forms) -// -// * VFNMADD231SD xmm, xmm, xmm [FMA3] -// * VFNMADD231SD m64, xmm, xmm [FMA3] -// * VFNMADD231SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD231SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD231SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMADD231SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD231SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD231SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD231SD takes 3 or 4 operands") - } - // VFNMADD231SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbd) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD231SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xbd) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFNMADD231SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD231SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD231SD") - } - return p -} - -// VFNMADD231SS performs "Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMADD231SS -// Supported forms : (5 forms) -// -// * VFNMADD231SS xmm, xmm, xmm [FMA3] -// * VFNMADD231SS m32, xmm, xmm [FMA3] -// * VFNMADD231SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD231SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMADD231SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMADD231SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMADD231SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMADD231SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMADD231SS takes 3 or 4 operands") - } - // VFNMADD231SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMADD231SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbd) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMADD231SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xbd) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFNMADD231SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMADD231SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADD231SS") - } - return p -} - -// VFNMADDPD performs "Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMADDPD -// Supported forms : (6 forms) -// -// * VFNMADDPD xmm, xmm, xmm, xmm [FMA4] -// * VFNMADDPD m128, xmm, xmm, xmm [FMA4] -// * VFNMADDPD xmm, m128, xmm, xmm [FMA4] -// * VFNMADDPD ymm, ymm, ymm, ymm [FMA4] -// * VFNMADDPD m256, ymm, ymm, ymm [FMA4] -// * VFNMADDPD ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFNMADDPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFNMADDPD", 4, Operands { v0, v1, v2, v3 }) - // VFNMADDPD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x79) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x79) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMADDPD m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x79) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMADDPD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x79) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMADDPD ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x79) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x79) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMADDPD m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x79) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMADDPD ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x79) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADDPD") - } - return p -} - -// VFNMADDPS performs "Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMADDPS -// Supported forms : (6 forms) -// -// * VFNMADDPS xmm, xmm, xmm, xmm [FMA4] -// * VFNMADDPS m128, xmm, xmm, xmm [FMA4] -// * VFNMADDPS xmm, m128, xmm, xmm [FMA4] -// * VFNMADDPS ymm, ymm, ymm, ymm [FMA4] -// * VFNMADDPS m256, ymm, ymm, ymm [FMA4] -// * VFNMADDPS ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFNMADDPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFNMADDPS", 4, Operands { v0, v1, v2, v3 }) - // VFNMADDPS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x78) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x78) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMADDPS m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x78) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMADDPS xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x78) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMADDPS ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x78) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x78) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMADDPS m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x78) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMADDPS ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x78) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADDPS") - } - return p -} - -// VFNMADDSD performs "Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMADDSD -// Supported forms : (3 forms) -// -// * VFNMADDSD xmm, xmm, xmm, xmm [FMA4] -// * VFNMADDSD m64, xmm, xmm, xmm [FMA4] -// * VFNMADDSD xmm, m64, xmm, xmm [FMA4] -// -func (self *Program) VFNMADDSD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFNMADDSD", 4, Operands { v0, v1, v2, v3 }) - // VFNMADDSD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMADDSD m64, xmm, xmm, xmm - if isM64(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x7b) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMADDSD xmm, m64, xmm, xmm - if isXMM(v0) && isM64(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x7b) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADDSD") - } - return p -} - -// VFNMADDSS performs "Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMADDSS -// Supported forms : (3 forms) -// -// * VFNMADDSS xmm, xmm, xmm, xmm [FMA4] -// * VFNMADDSS m32, xmm, xmm, xmm [FMA4] -// * VFNMADDSS xmm, m32, xmm, xmm [FMA4] -// -func (self *Program) VFNMADDSS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFNMADDSS", 4, Operands { v0, v1, v2, v3 }) - // VFNMADDSS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMADDSS m32, xmm, xmm, xmm - if isM32(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x7a) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMADDSS xmm, m32, xmm, xmm - if isXMM(v0) && isM32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x7a) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMADDSS") - } - return p -} - -// VFNMSUB132PD performs "Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB132PD -// Supported forms : (11 forms) -// -// * VFNMSUB132PD xmm, xmm, xmm [FMA3] -// * VFNMSUB132PD m128, xmm, xmm [FMA3] -// * VFNMSUB132PD ymm, ymm, ymm [FMA3] -// * VFNMSUB132PD m256, ymm, ymm [FMA3] -// * VFNMSUB132PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB132PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB132PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB132PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB132PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB132PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB132PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMSUB132PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB132PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB132PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB132PD takes 3 or 4 operands") - } - // VFNMSUB132PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB132PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB132PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMSUB132PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB132PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMSUB132PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMSUB132PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB132PD") - } - return p -} - -// VFNMSUB132PS performs "Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB132PS -// Supported forms : (11 forms) -// -// * VFNMSUB132PS xmm, xmm, xmm [FMA3] -// * VFNMSUB132PS m128, xmm, xmm [FMA3] -// * VFNMSUB132PS ymm, ymm, ymm [FMA3] -// * VFNMSUB132PS m256, ymm, ymm [FMA3] -// * VFNMSUB132PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB132PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB132PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB132PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB132PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB132PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB132PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMSUB132PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB132PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB132PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB132PS takes 3 or 4 operands") - } - // VFNMSUB132PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB132PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB132PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMSUB132PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB132PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMSUB132PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x9e) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMSUB132PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB132PS") - } - return p -} - -// VFNMSUB132SD performs "Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB132SD -// Supported forms : (5 forms) -// -// * VFNMSUB132SD xmm, xmm, xmm [FMA3] -// * VFNMSUB132SD m64, xmm, xmm [FMA3] -// * VFNMSUB132SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB132SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB132SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMSUB132SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB132SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB132SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB132SD takes 3 or 4 operands") - } - // VFNMSUB132SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x9f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB132SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x9f) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFNMSUB132SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB132SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB132SD") - } - return p -} - -// VFNMSUB132SS performs "Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB132SS -// Supported forms : (5 forms) -// -// * VFNMSUB132SS xmm, xmm, xmm [FMA3] -// * VFNMSUB132SS m32, xmm, xmm [FMA3] -// * VFNMSUB132SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB132SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB132SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMSUB132SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB132SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB132SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB132SS takes 3 or 4 operands") - } - // VFNMSUB132SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x9f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB132SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB132SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x9f) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFNMSUB132SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x9f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB132SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x9f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB132SS") - } - return p -} - -// VFNMSUB213PD performs "Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB213PD -// Supported forms : (11 forms) -// -// * VFNMSUB213PD xmm, xmm, xmm [FMA3] -// * VFNMSUB213PD m128, xmm, xmm [FMA3] -// * VFNMSUB213PD ymm, ymm, ymm [FMA3] -// * VFNMSUB213PD m256, ymm, ymm [FMA3] -// * VFNMSUB213PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB213PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB213PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB213PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB213PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB213PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB213PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMSUB213PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB213PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB213PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB213PD takes 3 or 4 operands") - } - // VFNMSUB213PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB213PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB213PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMSUB213PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xae) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB213PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMSUB213PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMSUB213PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB213PD") - } - return p -} - -// VFNMSUB213PS performs "Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB213PS -// Supported forms : (11 forms) -// -// * VFNMSUB213PS xmm, xmm, xmm [FMA3] -// * VFNMSUB213PS m128, xmm, xmm [FMA3] -// * VFNMSUB213PS ymm, ymm, ymm [FMA3] -// * VFNMSUB213PS m256, ymm, ymm [FMA3] -// * VFNMSUB213PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB213PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB213PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB213PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB213PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB213PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB213PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMSUB213PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB213PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB213PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB213PS takes 3 or 4 operands") - } - // VFNMSUB213PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB213PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB213PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMSUB213PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xae) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB213PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMSUB213PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xae) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMSUB213PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xae) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB213PS") - } - return p -} - -// VFNMSUB213SD performs "Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB213SD -// Supported forms : (5 forms) -// -// * VFNMSUB213SD xmm, xmm, xmm [FMA3] -// * VFNMSUB213SD m64, xmm, xmm [FMA3] -// * VFNMSUB213SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB213SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB213SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMSUB213SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB213SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB213SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB213SD takes 3 or 4 operands") - } - // VFNMSUB213SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xaf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xaf) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB213SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xaf) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFNMSUB213SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xaf) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB213SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xaf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB213SD") - } - return p -} - -// VFNMSUB213SS performs "Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB213SS -// Supported forms : (5 forms) -// -// * VFNMSUB213SS xmm, xmm, xmm [FMA3] -// * VFNMSUB213SS m32, xmm, xmm [FMA3] -// * VFNMSUB213SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB213SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB213SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMSUB213SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB213SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB213SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB213SS takes 3 or 4 operands") - } - // VFNMSUB213SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xaf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB213SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xaf) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB213SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xaf) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFNMSUB213SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xaf) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB213SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xaf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB213SS") - } - return p -} - -// VFNMSUB231PD performs "Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB231PD -// Supported forms : (11 forms) -// -// * VFNMSUB231PD xmm, xmm, xmm [FMA3] -// * VFNMSUB231PD m128, xmm, xmm [FMA3] -// * VFNMSUB231PD ymm, ymm, ymm [FMA3] -// * VFNMSUB231PD m256, ymm, ymm [FMA3] -// * VFNMSUB231PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB231PD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB231PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB231PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB231PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB231PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB231PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMSUB231PD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB231PD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB231PD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB231PD takes 3 or 4 operands") - } - // VFNMSUB231PD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231PD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB231PD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231PD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB231PD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMSUB231PD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB231PD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231PD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMSUB231PD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231PD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMSUB231PD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB231PD") - } - return p -} - -// VFNMSUB231PS performs "Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB231PS -// Supported forms : (11 forms) -// -// * VFNMSUB231PS xmm, xmm, xmm [FMA3] -// * VFNMSUB231PS m128, xmm, xmm [FMA3] -// * VFNMSUB231PS ymm, ymm, ymm [FMA3] -// * VFNMSUB231PS m256, ymm, ymm [FMA3] -// * VFNMSUB231PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB231PS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB231PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VFNMSUB231PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB231PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB231PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VFNMSUB231PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VFNMSUB231PS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB231PS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB231PS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB231PS takes 3 or 4 operands") - } - // VFNMSUB231PS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231PS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB231PS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231PS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB231PS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VFNMSUB231PS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB231PS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231PS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VFNMSUB231PS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231PS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xbe) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VFNMSUB231PS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xbe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB231PS") - } - return p -} - -// VFNMSUB231SD performs "Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB231SD -// Supported forms : (5 forms) -// -// * VFNMSUB231SD xmm, xmm, xmm [FMA3] -// * VFNMSUB231SD m64, xmm, xmm [FMA3] -// * VFNMSUB231SD m64, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB231SD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB231SD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMSUB231SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB231SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB231SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB231SD takes 3 or 4 operands") - } - // VFNMSUB231SD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0xbf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231SD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbf) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB231SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xbf) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VFNMSUB231SD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbf) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB231SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB231SD") - } - return p -} - -// VFNMSUB231SS performs "Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUB231SS -// Supported forms : (5 forms) -// -// * VFNMSUB231SS xmm, xmm, xmm [FMA3] -// * VFNMSUB231SS m32, xmm, xmm [FMA3] -// * VFNMSUB231SS m32, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB231SS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VFNMSUB231SS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VFNMSUB231SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VFNMSUB231SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VFNMSUB231SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VFNMSUB231SS takes 3 or 4 operands") - } - // VFNMSUB231SS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0xbf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VFNMSUB231SS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_FMA3) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xbf) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VFNMSUB231SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xbf) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VFNMSUB231SS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xbf) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VFNMSUB231SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xbf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUB231SS") - } - return p -} - -// VFNMSUBPD performs "Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUBPD -// Supported forms : (6 forms) -// -// * VFNMSUBPD xmm, xmm, xmm, xmm [FMA4] -// * VFNMSUBPD m128, xmm, xmm, xmm [FMA4] -// * VFNMSUBPD xmm, m128, xmm, xmm [FMA4] -// * VFNMSUBPD ymm, ymm, ymm, ymm [FMA4] -// * VFNMSUBPD m256, ymm, ymm, ymm [FMA4] -// * VFNMSUBPD ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFNMSUBPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFNMSUBPD", 4, Operands { v0, v1, v2, v3 }) - // VFNMSUBPD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMSUBPD m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x7d) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMSUBPD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x7d) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMSUBPD ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMSUBPD m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x7d) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMSUBPD ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x7d) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUBPD") - } - return p -} - -// VFNMSUBPS performs "Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUBPS -// Supported forms : (6 forms) -// -// * VFNMSUBPS xmm, xmm, xmm, xmm [FMA4] -// * VFNMSUBPS m128, xmm, xmm, xmm [FMA4] -// * VFNMSUBPS xmm, m128, xmm, xmm [FMA4] -// * VFNMSUBPS ymm, ymm, ymm, ymm [FMA4] -// * VFNMSUBPS m256, ymm, ymm, ymm [FMA4] -// * VFNMSUBPS ymm, m256, ymm, ymm [FMA4] -// -func (self *Program) VFNMSUBPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFNMSUBPS", 4, Operands { v0, v1, v2, v3 }) - // VFNMSUBPS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMSUBPS m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x7c) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMSUBPS xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x7c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMSUBPS ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMSUBPS m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x7c) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMSUBPS ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x7c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUBPS") - } - return p -} - -// VFNMSUBSD performs "Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUBSD -// Supported forms : (3 forms) -// -// * VFNMSUBSD xmm, xmm, xmm, xmm [FMA4] -// * VFNMSUBSD m64, xmm, xmm, xmm [FMA4] -// * VFNMSUBSD xmm, m64, xmm, xmm [FMA4] -// -func (self *Program) VFNMSUBSD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFNMSUBSD", 4, Operands { v0, v1, v2, v3 }) - // VFNMSUBSD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMSUBSD m64, xmm, xmm, xmm - if isM64(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x7f) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMSUBSD xmm, m64, xmm, xmm - if isXMM(v0) && isM64(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x7f) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUBSD") - } - return p -} - -// VFNMSUBSS performs "Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VFNMSUBSS -// Supported forms : (3 forms) -// -// * VFNMSUBSS xmm, xmm, xmm, xmm [FMA4] -// * VFNMSUBSS m32, xmm, xmm, xmm [FMA4] -// * VFNMSUBSS xmm, m32, xmm, xmm [FMA4] -// -func (self *Program) VFNMSUBSS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VFNMSUBSS", 4, Operands { v0, v1, v2, v3 }) - // VFNMSUBSS xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VFNMSUBSS m32, xmm, xmm, xmm - if isM32(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0x7e) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VFNMSUBSS xmm, m32, xmm, xmm - if isXMM(v0) && isM32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_FMA4) - p.domain = DomainFMA - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x7e) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VFNMSUBSS") - } - return p -} - -// VFPCLASSPD performs "Test Class of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VFPCLASSPD -// Supported forms : (6 forms) -// -// * VFPCLASSPD imm8, m512/m64bcst, k{k} [AVX512DQ] -// * VFPCLASSPD imm8, zmm, k{k} [AVX512DQ] -// * VFPCLASSPD imm8, m128/m64bcst, k{k} [AVX512DQ,AVX512VL] -// * VFPCLASSPD imm8, m256/m64bcst, k{k} [AVX512DQ,AVX512VL] -// * VFPCLASSPD imm8, xmm, k{k} [AVX512DQ,AVX512VL] -// * VFPCLASSPD imm8, ymm, k{k} [AVX512DQ,AVX512VL] -// -func (self *Program) VFPCLASSPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VFPCLASSPD", 3, Operands { v0, v1, v2 }) - // VFPCLASSPD imm8, m512/m64bcst, k{k} - if isImm8(v0) && isM512M64bcst(v1) && isKk(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), 0, bcode(v[1])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPD imm8, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit(kcode(v[2]) | 0x48) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPD imm8, m128/m64bcst, k{k} - if isImm8(v0) && isM128M64bcst(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), 0, bcode(v[1])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPD imm8, m256/m64bcst, k{k} - if isImm8(v0) && isM256M64bcst(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), 0, bcode(v[1])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPD imm8, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit(kcode(v[2]) | 0x08) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPD imm8, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit(kcode(v[2]) | 0x28) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFPCLASSPD") - } - return p -} - -// VFPCLASSPS performs "Test Class of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VFPCLASSPS -// Supported forms : (6 forms) -// -// * VFPCLASSPS imm8, m512/m32bcst, k{k} [AVX512DQ] -// * VFPCLASSPS imm8, zmm, k{k} [AVX512DQ] -// * VFPCLASSPS imm8, m128/m32bcst, k{k} [AVX512DQ,AVX512VL] -// * VFPCLASSPS imm8, m256/m32bcst, k{k} [AVX512DQ,AVX512VL] -// * VFPCLASSPS imm8, xmm, k{k} [AVX512DQ,AVX512VL] -// * VFPCLASSPS imm8, ymm, k{k} [AVX512DQ,AVX512VL] -// -func (self *Program) VFPCLASSPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VFPCLASSPS", 3, Operands { v0, v1, v2 }) - // VFPCLASSPS imm8, m512/m32bcst, k{k} - if isImm8(v0) && isM512M32bcst(v1) && isKk(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), 0, bcode(v[1])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPS imm8, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit(kcode(v[2]) | 0x48) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPS imm8, m128/m32bcst, k{k} - if isImm8(v0) && isM128M32bcst(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), 0, bcode(v[1])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPS imm8, m256/m32bcst, k{k} - if isImm8(v0) && isM256M32bcst(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), 0, bcode(v[1])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPS imm8, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit(kcode(v[2]) | 0x08) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSPS imm8, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit(kcode(v[2]) | 0x28) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFPCLASSPS") - } - return p -} - -// VFPCLASSSD performs "Test Class of Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VFPCLASSSD -// Supported forms : (2 forms) -// -// * VFPCLASSSD imm8, xmm, k{k} [AVX512DQ] -// * VFPCLASSSD imm8, m64, k{k} [AVX512DQ] -// -func (self *Program) VFPCLASSSD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VFPCLASSSD", 3, Operands { v0, v1, v2 }) - // VFPCLASSSD imm8, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit(kcode(v[2]) | 0x08) - m.emit(0x67) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSSD imm8, m64, k{k} - if isImm8(v0) && isM64(v1) && isKk(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), 0, 0) - m.emit(0x67) - m.mrsd(lcode(v[2]), addr(v[1]), 8) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFPCLASSSD") - } - return p -} - -// VFPCLASSSS performs "Test Class of Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VFPCLASSSS -// Supported forms : (2 forms) -// -// * VFPCLASSSS imm8, xmm, k{k} [AVX512DQ] -// * VFPCLASSSS imm8, m32, k{k} [AVX512DQ] -// -func (self *Program) VFPCLASSSS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VFPCLASSSS", 3, Operands { v0, v1, v2 }) - // VFPCLASSSS imm8, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit(kcode(v[2]) | 0x08) - m.emit(0x67) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VFPCLASSSS imm8, m32, k{k} - if isImm8(v0) && isM32(v1) && isKk(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), 0, 0) - m.emit(0x67) - m.mrsd(lcode(v[2]), addr(v[1]), 4) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VFPCLASSSS") - } - return p -} - -// VFRCZPD performs "Extract Fraction Packed Double-Precision Floating-Point". -// -// Mnemonic : VFRCZPD -// Supported forms : (4 forms) -// -// * VFRCZPD xmm, xmm [XOP] -// * VFRCZPD m128, xmm [XOP] -// * VFRCZPD ymm, ymm [XOP] -// * VFRCZPD m256, ymm [XOP] -// -func (self *Program) VFRCZPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VFRCZPD", 2, Operands { v0, v1 }) - // VFRCZPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0x81) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VFRCZPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0x81) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VFRCZPD ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7c) - m.emit(0x81) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VFRCZPD m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x04, hcode(v[1]), addr(v[0]), 0) - m.emit(0x81) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VFRCZPD") - } - return p -} - -// VFRCZPS performs "Extract Fraction Packed Single-Precision Floating-Point". -// -// Mnemonic : VFRCZPS -// Supported forms : (4 forms) -// -// * VFRCZPS xmm, xmm [XOP] -// * VFRCZPS m128, xmm [XOP] -// * VFRCZPS ymm, ymm [XOP] -// * VFRCZPS m256, ymm [XOP] -// -func (self *Program) VFRCZPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VFRCZPS", 2, Operands { v0, v1 }) - // VFRCZPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0x80) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VFRCZPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0x80) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VFRCZPS ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7c) - m.emit(0x80) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VFRCZPS m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x04, hcode(v[1]), addr(v[0]), 0) - m.emit(0x80) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VFRCZPS") - } - return p -} - -// VFRCZSD performs "Extract Fraction Scalar Double-Precision Floating-Point". -// -// Mnemonic : VFRCZSD -// Supported forms : (2 forms) -// -// * VFRCZSD xmm, xmm [XOP] -// * VFRCZSD m64, xmm [XOP] -// -func (self *Program) VFRCZSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VFRCZSD", 2, Operands { v0, v1 }) - // VFRCZSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0x83) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VFRCZSD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0x83) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VFRCZSD") - } - return p -} - -// VFRCZSS performs "Extract Fraction Scalar Single-Precision Floating Point". -// -// Mnemonic : VFRCZSS -// Supported forms : (2 forms) -// -// * VFRCZSS xmm, xmm [XOP] -// * VFRCZSS m32, xmm [XOP] -// -func (self *Program) VFRCZSS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VFRCZSS", 2, Operands { v0, v1 }) - // VFRCZSS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0x82) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VFRCZSS m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0x82) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VFRCZSS") - } - return p -} - -// VGATHERDPD performs "Gather Packed Double-Precision Floating-Point Values Using Signed Doubleword Indices". -// -// Mnemonic : VGATHERDPD -// Supported forms : (5 forms) -// -// * VGATHERDPD xmm, vm32x, xmm [AVX2] -// * VGATHERDPD ymm, vm32x, ymm [AVX2] -// * VGATHERDPD vm32y, zmm{k} [AVX512F] -// * VGATHERDPD vm32x, xmm{k} [AVX512F,AVX512VL] -// * VGATHERDPD vm32x, ymm{k} [AVX512F,AVX512VL] -// -func (self *Program) VGATHERDPD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGATHERDPD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VGATHERDPD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VGATHERDPD takes 2 or 3 operands") - } - // VGATHERDPD xmm, vm32x, xmm - if len(vv) == 1 && isXMM(v0) && isVMX(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x92) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VGATHERDPD ymm, vm32x, ymm - if len(vv) == 1 && isYMM(v0) && isVMX(v1) && isYMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x92) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VGATHERDPD vm32y, zmm{k} - if len(vv) == 0 && isEVEXVMY(v0) && isZMMk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x92) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VGATHERDPD vm32x, xmm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x92) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VGATHERDPD vm32x, ymm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isYMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x92) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERDPD") - } - return p -} - -// VGATHERDPS performs "Gather Packed Single-Precision Floating-Point Values Using Signed Doubleword Indices". -// -// Mnemonic : VGATHERDPS -// Supported forms : (5 forms) -// -// * VGATHERDPS xmm, vm32x, xmm [AVX2] -// * VGATHERDPS ymm, vm32y, ymm [AVX2] -// * VGATHERDPS vm32z, zmm{k} [AVX512F] -// * VGATHERDPS vm32x, xmm{k} [AVX512F,AVX512VL] -// * VGATHERDPS vm32y, ymm{k} [AVX512F,AVX512VL] -// -func (self *Program) VGATHERDPS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGATHERDPS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VGATHERDPS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VGATHERDPS takes 2 or 3 operands") - } - // VGATHERDPS xmm, vm32x, xmm - if len(vv) == 1 && isXMM(v0) && isVMX(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x92) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VGATHERDPS ymm, vm32y, ymm - if len(vv) == 1 && isYMM(v0) && isVMY(v1) && isYMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x92) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VGATHERDPS vm32z, zmm{k} - if len(vv) == 0 && isVMZ(v0) && isZMMk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x92) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VGATHERDPS vm32x, xmm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x92) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VGATHERDPS vm32y, ymm{k} - if len(vv) == 0 && isEVEXVMY(v0) && isYMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x92) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERDPS") - } - return p -} - -// VGATHERPF0DPD performs "Sparse Prefetch Packed Double-Precision Floating-Point Data Values with Signed Doubleword Indices Using T0 Hint". -// -// Mnemonic : VGATHERPF0DPD -// Supported forms : (1 form) -// -// * VGATHERPF0DPD vm32y{k} [AVX512PF] -// -func (self *Program) VGATHERPF0DPD(v0 interface{}) *Instruction { - p := self.alloc("VGATHERPF0DPD", 1, Operands { v0 }) - // VGATHERPF0DPD vm32y{k} - if isVMYk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc6) - m.mrsd(1, addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERPF0DPD") - } - return p -} - -// VGATHERPF0DPS performs "Sparse Prefetch Packed Single-Precision Floating-Point Data Values with Signed Doubleword Indices Using T0 Hint". -// -// Mnemonic : VGATHERPF0DPS -// Supported forms : (1 form) -// -// * VGATHERPF0DPS vm32z{k} [AVX512PF] -// -func (self *Program) VGATHERPF0DPS(v0 interface{}) *Instruction { - p := self.alloc("VGATHERPF0DPS", 1, Operands { v0 }) - // VGATHERPF0DPS vm32z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc6) - m.mrsd(1, addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERPF0DPS") - } - return p -} - -// VGATHERPF0QPD performs "Sparse Prefetch Packed Double-Precision Floating-Point Data Values with Signed Quadword Indices Using T0 Hint". -// -// Mnemonic : VGATHERPF0QPD -// Supported forms : (1 form) -// -// * VGATHERPF0QPD vm64z{k} [AVX512PF] -// -func (self *Program) VGATHERPF0QPD(v0 interface{}) *Instruction { - p := self.alloc("VGATHERPF0QPD", 1, Operands { v0 }) - // VGATHERPF0QPD vm64z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc7) - m.mrsd(1, addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERPF0QPD") - } - return p -} - -// VGATHERPF0QPS performs "Sparse Prefetch Packed Single-Precision Floating-Point Data Values with Signed Quadword Indices Using T0 Hint". -// -// Mnemonic : VGATHERPF0QPS -// Supported forms : (1 form) -// -// * VGATHERPF0QPS vm64z{k} [AVX512PF] -// -func (self *Program) VGATHERPF0QPS(v0 interface{}) *Instruction { - p := self.alloc("VGATHERPF0QPS", 1, Operands { v0 }) - // VGATHERPF0QPS vm64z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc7) - m.mrsd(1, addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERPF0QPS") - } - return p -} - -// VGATHERPF1DPD performs "Sparse Prefetch Packed Double-Precision Floating-Point Data Values with Signed Doubleword Indices Using T1 Hint". -// -// Mnemonic : VGATHERPF1DPD -// Supported forms : (1 form) -// -// * VGATHERPF1DPD vm32y{k} [AVX512PF] -// -func (self *Program) VGATHERPF1DPD(v0 interface{}) *Instruction { - p := self.alloc("VGATHERPF1DPD", 1, Operands { v0 }) - // VGATHERPF1DPD vm32y{k} - if isVMYk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc6) - m.mrsd(2, addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERPF1DPD") - } - return p -} - -// VGATHERPF1DPS performs "Sparse Prefetch Packed Single-Precision Floating-Point Data Values with Signed Doubleword Indices Using T1 Hint". -// -// Mnemonic : VGATHERPF1DPS -// Supported forms : (1 form) -// -// * VGATHERPF1DPS vm32z{k} [AVX512PF] -// -func (self *Program) VGATHERPF1DPS(v0 interface{}) *Instruction { - p := self.alloc("VGATHERPF1DPS", 1, Operands { v0 }) - // VGATHERPF1DPS vm32z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc6) - m.mrsd(2, addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERPF1DPS") - } - return p -} - -// VGATHERPF1QPD performs "Sparse Prefetch Packed Double-Precision Floating-Point Data Values with Signed Quadword Indices Using T1 Hint". -// -// Mnemonic : VGATHERPF1QPD -// Supported forms : (1 form) -// -// * VGATHERPF1QPD vm64z{k} [AVX512PF] -// -func (self *Program) VGATHERPF1QPD(v0 interface{}) *Instruction { - p := self.alloc("VGATHERPF1QPD", 1, Operands { v0 }) - // VGATHERPF1QPD vm64z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc7) - m.mrsd(2, addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERPF1QPD") - } - return p -} - -// VGATHERPF1QPS performs "Sparse Prefetch Packed Single-Precision Floating-Point Data Values with Signed Quadword Indices Using T1 Hint". -// -// Mnemonic : VGATHERPF1QPS -// Supported forms : (1 form) -// -// * VGATHERPF1QPS vm64z{k} [AVX512PF] -// -func (self *Program) VGATHERPF1QPS(v0 interface{}) *Instruction { - p := self.alloc("VGATHERPF1QPS", 1, Operands { v0 }) - // VGATHERPF1QPS vm64z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc7) - m.mrsd(2, addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERPF1QPS") - } - return p -} - -// VGATHERQPD performs "Gather Packed Double-Precision Floating-Point Values Using Signed Quadword Indices". -// -// Mnemonic : VGATHERQPD -// Supported forms : (5 forms) -// -// * VGATHERQPD xmm, vm64x, xmm [AVX2] -// * VGATHERQPD ymm, vm64y, ymm [AVX2] -// * VGATHERQPD vm64z, zmm{k} [AVX512F] -// * VGATHERQPD vm64x, xmm{k} [AVX512F,AVX512VL] -// * VGATHERQPD vm64y, ymm{k} [AVX512F,AVX512VL] -// -func (self *Program) VGATHERQPD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGATHERQPD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VGATHERQPD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VGATHERQPD takes 2 or 3 operands") - } - // VGATHERQPD xmm, vm64x, xmm - if len(vv) == 1 && isXMM(v0) && isVMX(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x93) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VGATHERQPD ymm, vm64y, ymm - if len(vv) == 1 && isYMM(v0) && isVMY(v1) && isYMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x93) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VGATHERQPD vm64z, zmm{k} - if len(vv) == 0 && isVMZ(v0) && isZMMk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x93) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VGATHERQPD vm64x, xmm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x93) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VGATHERQPD vm64y, ymm{k} - if len(vv) == 0 && isEVEXVMY(v0) && isYMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x93) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERQPD") - } - return p -} - -// VGATHERQPS performs "Gather Packed Single-Precision Floating-Point Values Using Signed Quadword Indices". -// -// Mnemonic : VGATHERQPS -// Supported forms : (5 forms) -// -// * VGATHERQPS xmm, vm64x, xmm [AVX2] -// * VGATHERQPS xmm, vm64y, xmm [AVX2] -// * VGATHERQPS vm64z, ymm{k} [AVX512F] -// * VGATHERQPS vm64x, xmm{k} [AVX512F,AVX512VL] -// * VGATHERQPS vm64y, xmm{k} [AVX512F,AVX512VL] -// -func (self *Program) VGATHERQPS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGATHERQPS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VGATHERQPS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VGATHERQPS takes 2 or 3 operands") - } - // VGATHERQPS xmm, vm64x, xmm - if len(vv) == 1 && isXMM(v0) && isVMX(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x93) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VGATHERQPS xmm, vm64y, xmm - if len(vv) == 1 && isXMM(v0) && isVMY(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x93) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VGATHERQPS vm64z, ymm{k} - if len(vv) == 0 && isVMZ(v0) && isYMMk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x93) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VGATHERQPS vm64x, xmm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x93) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VGATHERQPS vm64y, xmm{k} - if len(vv) == 0 && isEVEXVMY(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x93) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VGATHERQPS") - } - return p -} - -// VGETEXPPD performs "Extract Exponents of Packed Double-Precision Floating-Point Values as Double-Precision Floating-Point Values". -// -// Mnemonic : VGETEXPPD -// Supported forms : (7 forms) -// -// * VGETEXPPD m512/m64bcst, zmm{k}{z} [AVX512F] -// * VGETEXPPD {sae}, zmm, zmm{k}{z} [AVX512F] -// * VGETEXPPD zmm, zmm{k}{z} [AVX512F] -// * VGETEXPPD m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VGETEXPPD m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VGETEXPPD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VGETEXPPD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VGETEXPPD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGETEXPPD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VGETEXPPD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VGETEXPPD takes 2 or 3 operands") - } - // VGETEXPPD m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VGETEXPPD {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x42) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VGETEXPPD zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VGETEXPPD m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VGETEXPPD m256/m64bcst, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VGETEXPPD xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VGETEXPPD ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VGETEXPPD") - } - return p -} - -// VGETEXPPS performs "Extract Exponents of Packed Single-Precision Floating-Point Values as Single-Precision Floating-Point Values". -// -// Mnemonic : VGETEXPPS -// Supported forms : (7 forms) -// -// * VGETEXPPS m512/m32bcst, zmm{k}{z} [AVX512F] -// * VGETEXPPS {sae}, zmm, zmm{k}{z} [AVX512F] -// * VGETEXPPS zmm, zmm{k}{z} [AVX512F] -// * VGETEXPPS m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VGETEXPPS m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VGETEXPPS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VGETEXPPS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VGETEXPPS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGETEXPPS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VGETEXPPS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VGETEXPPS takes 2 or 3 operands") - } - // VGETEXPPS m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VGETEXPPS {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0x42) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VGETEXPPS zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VGETEXPPS m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VGETEXPPS m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x42) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VGETEXPPS xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VGETEXPPS ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x42) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VGETEXPPS") - } - return p -} - -// VGETEXPSD performs "Extract Exponent of Scalar Double-Precision Floating-Point Value as Double-Precision Floating-Point Value". -// -// Mnemonic : VGETEXPSD -// Supported forms : (3 forms) -// -// * VGETEXPSD m64, xmm, xmm{k}{z} [AVX512F] -// * VGETEXPSD {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VGETEXPSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VGETEXPSD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGETEXPSD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VGETEXPSD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VGETEXPSD takes 3 or 4 operands") - } - // VGETEXPSD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x43) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VGETEXPSD {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x43) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VGETEXPSD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x43) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VGETEXPSD") - } - return p -} - -// VGETEXPSS performs "Extract Exponent of Scalar Single-Precision Floating-Point Value as Single-Precision Floating-Point Value". -// -// Mnemonic : VGETEXPSS -// Supported forms : (3 forms) -// -// * VGETEXPSS m32, xmm, xmm{k}{z} [AVX512F] -// * VGETEXPSS {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VGETEXPSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VGETEXPSS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGETEXPSS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VGETEXPSS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VGETEXPSS takes 3 or 4 operands") - } - // VGETEXPSS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x43) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VGETEXPSS {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x43) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VGETEXPSS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x43) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VGETEXPSS") - } - return p -} - -// VGETMANTPD performs "Extract Normalized Mantissas from Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VGETMANTPD -// Supported forms : (7 forms) -// -// * VGETMANTPD imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VGETMANTPD imm8, {sae}, zmm, zmm{k}{z} [AVX512F] -// * VGETMANTPD imm8, zmm, zmm{k}{z} [AVX512F] -// * VGETMANTPD imm8, m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VGETMANTPD imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VGETMANTPD imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VGETMANTPD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VGETMANTPD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGETMANTPD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VGETMANTPD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VGETMANTPD takes 3 or 4 operands") - } - // VGETMANTPD imm8, m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPD imm8, {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[3]) << 7) | kcode(v[3]) | 0x18) - m.emit(0x26) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPD imm8, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPD imm8, m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM128M64bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPD imm8, m256/m64bcst, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPD imm8, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPD imm8, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VGETMANTPD") - } - return p -} - -// VGETMANTPS performs "Extract Normalized Mantissas from Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VGETMANTPS -// Supported forms : (7 forms) -// -// * VGETMANTPS imm8, m512/m32bcst, zmm{k}{z} [AVX512F] -// * VGETMANTPS imm8, {sae}, zmm, zmm{k}{z} [AVX512F] -// * VGETMANTPS imm8, zmm, zmm{k}{z} [AVX512F] -// * VGETMANTPS imm8, m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VGETMANTPS imm8, m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VGETMANTPS imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VGETMANTPS imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VGETMANTPS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGETMANTPS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VGETMANTPS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VGETMANTPS takes 3 or 4 operands") - } - // VGETMANTPS imm8, m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPS imm8, {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[3]) << 7) | kcode(v[3]) | 0x18) - m.emit(0x26) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPS imm8, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPS imm8, m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPS imm8, m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPS imm8, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTPS imm8, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VGETMANTPS") - } - return p -} - -// VGETMANTSD performs "Extract Normalized Mantissa from Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VGETMANTSD -// Supported forms : (3 forms) -// -// * VGETMANTSD imm8, m64, xmm, xmm{k}{z} [AVX512F] -// * VGETMANTSD imm8, {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VGETMANTSD imm8, xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VGETMANTSD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGETMANTSD", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VGETMANTSD", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VGETMANTSD takes 4 or 5 operands") - } - // VGETMANTSD imm8, m64, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM64(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x27) - m.mrsd(lcode(v[3]), addr(v[1]), 8) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTSD imm8, {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0xfd ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x27) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTSD imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x27) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VGETMANTSD") - } - return p -} - -// VGETMANTSS performs "Extract Normalized Mantissa from Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VGETMANTSS -// Supported forms : (3 forms) -// -// * VGETMANTSS imm8, m32, xmm, xmm{k}{z} [AVX512F] -// * VGETMANTSS imm8, {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VGETMANTSS imm8, xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VGETMANTSS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VGETMANTSS", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VGETMANTSS", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VGETMANTSS takes 4 or 5 operands") - } - // VGETMANTSS imm8, m32, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM32(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x27) - m.mrsd(lcode(v[3]), addr(v[1]), 4) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTSS imm8, {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0x7d ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x27) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VGETMANTSS imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x27) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VGETMANTSS") - } - return p -} - -// VHADDPD performs "Packed Double-FP Horizontal Add". -// -// Mnemonic : VHADDPD -// Supported forms : (4 forms) -// -// * VHADDPD xmm, xmm, xmm [AVX] -// * VHADDPD m128, xmm, xmm [AVX] -// * VHADDPD ymm, ymm, ymm [AVX] -// * VHADDPD m256, ymm, ymm [AVX] -// -func (self *Program) VHADDPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VHADDPD", 3, Operands { v0, v1, v2 }) - // VHADDPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VHADDPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x7c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VHADDPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VHADDPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x7c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VHADDPD") - } - return p -} - -// VHADDPS performs "Packed Single-FP Horizontal Add". -// -// Mnemonic : VHADDPS -// Supported forms : (4 forms) -// -// * VHADDPS xmm, xmm, xmm [AVX] -// * VHADDPS m128, xmm, xmm [AVX] -// * VHADDPS ymm, ymm, ymm [AVX] -// * VHADDPS m256, ymm, ymm [AVX] -// -func (self *Program) VHADDPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VHADDPS", 3, Operands { v0, v1, v2 }) - // VHADDPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VHADDPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x7c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VHADDPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VHADDPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x7c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VHADDPS") - } - return p -} - -// VHSUBPD performs "Packed Double-FP Horizontal Subtract". -// -// Mnemonic : VHSUBPD -// Supported forms : (4 forms) -// -// * VHSUBPD xmm, xmm, xmm [AVX] -// * VHSUBPD m128, xmm, xmm [AVX] -// * VHSUBPD ymm, ymm, ymm [AVX] -// * VHSUBPD m256, ymm, ymm [AVX] -// -func (self *Program) VHSUBPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VHSUBPD", 3, Operands { v0, v1, v2 }) - // VHSUBPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VHSUBPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VHSUBPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VHSUBPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VHSUBPD") - } - return p -} - -// VHSUBPS performs "Packed Single-FP Horizontal Subtract". -// -// Mnemonic : VHSUBPS -// Supported forms : (4 forms) -// -// * VHSUBPS xmm, xmm, xmm [AVX] -// * VHSUBPS m128, xmm, xmm [AVX] -// * VHSUBPS ymm, ymm, ymm [AVX] -// * VHSUBPS m256, ymm, ymm [AVX] -// -func (self *Program) VHSUBPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VHSUBPS", 3, Operands { v0, v1, v2 }) - // VHSUBPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VHSUBPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VHSUBPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VHSUBPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VHSUBPS") - } - return p -} - -// VINSERTF128 performs "Insert Packed Floating-Point Values". -// -// Mnemonic : VINSERTF128 -// Supported forms : (2 forms) -// -// * VINSERTF128 imm8, xmm, ymm, ymm [AVX] -// * VINSERTF128 imm8, m128, ymm, ymm [AVX] -// -func (self *Program) VINSERTF128(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTF128", 4, Operands { v0, v1, v2, v3 }) - // VINSERTF128 imm8, xmm, ymm, ymm - if isImm8(v0) && isXMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x18) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTF128 imm8, m128, ymm, ymm - if isImm8(v0) && isM128(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x18) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTF128") - } - return p -} - -// VINSERTF32X4 performs "Insert 128 Bits of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VINSERTF32X4 -// Supported forms : (4 forms) -// -// * VINSERTF32X4 imm8, xmm, zmm, zmm{k}{z} [AVX512F] -// * VINSERTF32X4 imm8, m128, zmm, zmm{k}{z} [AVX512F] -// * VINSERTF32X4 imm8, xmm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VINSERTF32X4 imm8, m128, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VINSERTF32X4(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTF32X4", 4, Operands { v0, v1, v2, v3 }) - // VINSERTF32X4 imm8, xmm, zmm, zmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x18) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTF32X4 imm8, m128, zmm, zmm{k}{z} - if isImm8(v0) && isM128(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x18) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTF32X4 imm8, xmm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x18) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTF32X4 imm8, m128, ymm, ymm{k}{z} - if isImm8(v0) && isM128(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x18) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTF32X4") - } - return p -} - -// VINSERTF32X8 performs "Insert 256 Bits of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VINSERTF32X8 -// Supported forms : (2 forms) -// -// * VINSERTF32X8 imm8, ymm, zmm, zmm{k}{z} [AVX512DQ] -// * VINSERTF32X8 imm8, m256, zmm, zmm{k}{z} [AVX512DQ] -// -func (self *Program) VINSERTF32X8(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTF32X8", 4, Operands { v0, v1, v2, v3 }) - // VINSERTF32X8 imm8, ymm, zmm, zmm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x1a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTF32X8 imm8, m256, zmm, zmm{k}{z} - if isImm8(v0) && isM256(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x1a) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTF32X8") - } - return p -} - -// VINSERTF64X2 performs "Insert 128 Bits of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VINSERTF64X2 -// Supported forms : (4 forms) -// -// * VINSERTF64X2 imm8, xmm, zmm, zmm{k}{z} [AVX512DQ] -// * VINSERTF64X2 imm8, m128, zmm, zmm{k}{z} [AVX512DQ] -// * VINSERTF64X2 imm8, xmm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VINSERTF64X2 imm8, m128, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VINSERTF64X2(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTF64X2", 4, Operands { v0, v1, v2, v3 }) - // VINSERTF64X2 imm8, xmm, zmm, zmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x18) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTF64X2 imm8, m128, zmm, zmm{k}{z} - if isImm8(v0) && isM128(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x18) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTF64X2 imm8, xmm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x18) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTF64X2 imm8, m128, ymm, ymm{k}{z} - if isImm8(v0) && isM128(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x18) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTF64X2") - } - return p -} - -// VINSERTF64X4 performs "Insert 256 Bits of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VINSERTF64X4 -// Supported forms : (2 forms) -// -// * VINSERTF64X4 imm8, ymm, zmm, zmm{k}{z} [AVX512F] -// * VINSERTF64X4 imm8, m256, zmm, zmm{k}{z} [AVX512F] -// -func (self *Program) VINSERTF64X4(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTF64X4", 4, Operands { v0, v1, v2, v3 }) - // VINSERTF64X4 imm8, ymm, zmm, zmm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x1a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTF64X4 imm8, m256, zmm, zmm{k}{z} - if isImm8(v0) && isM256(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x1a) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTF64X4") - } - return p -} - -// VINSERTI128 performs "Insert Packed Integer Values". -// -// Mnemonic : VINSERTI128 -// Supported forms : (2 forms) -// -// * VINSERTI128 imm8, xmm, ymm, ymm [AVX2] -// * VINSERTI128 imm8, m128, ymm, ymm [AVX2] -// -func (self *Program) VINSERTI128(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTI128", 4, Operands { v0, v1, v2, v3 }) - // VINSERTI128 imm8, xmm, ymm, ymm - if isImm8(v0) && isXMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x38) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTI128 imm8, m128, ymm, ymm - if isImm8(v0) && isM128(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x38) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTI128") - } - return p -} - -// VINSERTI32X4 performs "Insert 128 Bits of Packed Doubleword Integer Values". -// -// Mnemonic : VINSERTI32X4 -// Supported forms : (4 forms) -// -// * VINSERTI32X4 imm8, xmm, zmm, zmm{k}{z} [AVX512F] -// * VINSERTI32X4 imm8, m128, zmm, zmm{k}{z} [AVX512F] -// * VINSERTI32X4 imm8, xmm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VINSERTI32X4 imm8, m128, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VINSERTI32X4(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTI32X4", 4, Operands { v0, v1, v2, v3 }) - // VINSERTI32X4 imm8, xmm, zmm, zmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x38) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTI32X4 imm8, m128, zmm, zmm{k}{z} - if isImm8(v0) && isM128(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x38) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTI32X4 imm8, xmm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x38) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTI32X4 imm8, m128, ymm, ymm{k}{z} - if isImm8(v0) && isM128(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x38) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTI32X4") - } - return p -} - -// VINSERTI32X8 performs "Insert 256 Bits of Packed Doubleword Integer Values". -// -// Mnemonic : VINSERTI32X8 -// Supported forms : (2 forms) -// -// * VINSERTI32X8 imm8, ymm, zmm, zmm{k}{z} [AVX512DQ] -// * VINSERTI32X8 imm8, m256, zmm, zmm{k}{z} [AVX512DQ] -// -func (self *Program) VINSERTI32X8(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTI32X8", 4, Operands { v0, v1, v2, v3 }) - // VINSERTI32X8 imm8, ymm, zmm, zmm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTI32X8 imm8, m256, zmm, zmm{k}{z} - if isImm8(v0) && isM256(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x3a) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTI32X8") - } - return p -} - -// VINSERTI64X2 performs "Insert 128 Bits of Packed Quadword Integer Values". -// -// Mnemonic : VINSERTI64X2 -// Supported forms : (4 forms) -// -// * VINSERTI64X2 imm8, xmm, zmm, zmm{k}{z} [AVX512DQ] -// * VINSERTI64X2 imm8, m128, zmm, zmm{k}{z} [AVX512DQ] -// * VINSERTI64X2 imm8, xmm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VINSERTI64X2 imm8, m128, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VINSERTI64X2(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTI64X2", 4, Operands { v0, v1, v2, v3 }) - // VINSERTI64X2 imm8, xmm, zmm, zmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x38) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTI64X2 imm8, m128, zmm, zmm{k}{z} - if isImm8(v0) && isM128(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x38) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTI64X2 imm8, xmm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x38) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTI64X2 imm8, m128, ymm, ymm{k}{z} - if isImm8(v0) && isM128(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x38) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTI64X2") - } - return p -} - -// VINSERTI64X4 performs "Insert 256 Bits of Packed Quadword Integer Values". -// -// Mnemonic : VINSERTI64X4 -// Supported forms : (2 forms) -// -// * VINSERTI64X4 imm8, ymm, zmm, zmm{k}{z} [AVX512F] -// * VINSERTI64X4 imm8, m256, zmm, zmm{k}{z} [AVX512F] -// -func (self *Program) VINSERTI64X4(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTI64X4", 4, Operands { v0, v1, v2, v3 }) - // VINSERTI64X4 imm8, ymm, zmm, zmm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTI64X4 imm8, m256, zmm, zmm{k}{z} - if isImm8(v0) && isM256(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x3a) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTI64X4") - } - return p -} - -// VINSERTPS performs "Insert Packed Single Precision Floating-Point Value". -// -// Mnemonic : VINSERTPS -// Supported forms : (4 forms) -// -// * VINSERTPS imm8, xmm, xmm, xmm [AVX] -// * VINSERTPS imm8, m32, xmm, xmm [AVX] -// * VINSERTPS imm8, xmm, xmm, xmm [AVX512F] -// * VINSERTPS imm8, m32, xmm, xmm [AVX512F] -// -func (self *Program) VINSERTPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VINSERTPS", 4, Operands { v0, v1, v2, v3 }) - // VINSERTPS imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x21) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTPS imm8, m32, xmm, xmm - if isImm8(v0) && isM32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x21) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTPS imm8, xmm, xmm, xmm - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x00) - m.emit(0x21) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VINSERTPS imm8, m32, xmm, xmm - if isImm8(v0) && isM32(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x21) - m.mrsd(lcode(v[3]), addr(v[1]), 4) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VINSERTPS") - } - return p -} - -// VLDDQU performs "Load Unaligned Integer 128 Bits". -// -// Mnemonic : VLDDQU -// Supported forms : (2 forms) -// -// * VLDDQU m128, xmm [AVX] -// * VLDDQU m256, ymm [AVX] -// -func (self *Program) VLDDQU(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VLDDQU", 2, Operands { v0, v1 }) - // VLDDQU m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), addr(v[0]), 0) - m.emit(0xf0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VLDDQU m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[1]), addr(v[0]), 0) - m.emit(0xf0) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VLDDQU") - } - return p -} - -// VLDMXCSR performs "Load MXCSR Register". -// -// Mnemonic : VLDMXCSR -// Supported forms : (1 form) -// -// * VLDMXCSR m32 [AVX] -// -func (self *Program) VLDMXCSR(v0 interface{}) *Instruction { - p := self.alloc("VLDMXCSR", 1, Operands { v0 }) - // VLDMXCSR m32 - if isM32(v0) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, addr(v[0]), 0) - m.emit(0xae) - m.mrsd(2, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VLDMXCSR") - } - return p -} - -// VMASKMOVDQU performs "Store Selected Bytes of Double Quadword". -// -// Mnemonic : VMASKMOVDQU -// Supported forms : (1 form) -// -// * VMASKMOVDQU xmm, xmm [AVX] -// -func (self *Program) VMASKMOVDQU(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMASKMOVDQU", 2, Operands { v0, v1 }) - // VMASKMOVDQU xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0xf7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMASKMOVDQU") - } - return p -} - -// VMASKMOVPD performs "Conditional Move Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VMASKMOVPD -// Supported forms : (4 forms) -// -// * VMASKMOVPD m128, xmm, xmm [AVX] -// * VMASKMOVPD m256, ymm, ymm [AVX] -// * VMASKMOVPD xmm, xmm, m128 [AVX] -// * VMASKMOVPD ymm, ymm, m256 [AVX] -// -func (self *Program) VMASKMOVPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VMASKMOVPD", 3, Operands { v0, v1, v2 }) - // VMASKMOVPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMASKMOVPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMASKMOVPD xmm, xmm, m128 - if isXMM(v0) && isXMM(v1) && isM128(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[0]), addr(v[2]), hlcode(v[1])) - m.emit(0x2f) - m.mrsd(lcode(v[0]), addr(v[2]), 1) - }) - } - // VMASKMOVPD ymm, ymm, m256 - if isYMM(v0) && isYMM(v1) && isM256(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[0]), addr(v[2]), hlcode(v[1])) - m.emit(0x2f) - m.mrsd(lcode(v[0]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VMASKMOVPD") - } - return p -} - -// VMASKMOVPS performs "Conditional Move Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VMASKMOVPS -// Supported forms : (4 forms) -// -// * VMASKMOVPS m128, xmm, xmm [AVX] -// * VMASKMOVPS m256, ymm, ymm [AVX] -// * VMASKMOVPS xmm, xmm, m128 [AVX] -// * VMASKMOVPS ymm, ymm, m256 [AVX] -// -func (self *Program) VMASKMOVPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VMASKMOVPS", 3, Operands { v0, v1, v2 }) - // VMASKMOVPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMASKMOVPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMASKMOVPS xmm, xmm, m128 - if isXMM(v0) && isXMM(v1) && isM128(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[0]), addr(v[2]), hlcode(v[1])) - m.emit(0x2e) - m.mrsd(lcode(v[0]), addr(v[2]), 1) - }) - } - // VMASKMOVPS ymm, ymm, m256 - if isYMM(v0) && isYMM(v1) && isM256(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[0]), addr(v[2]), hlcode(v[1])) - m.emit(0x2e) - m.mrsd(lcode(v[0]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VMASKMOVPS") - } - return p -} - -// VMAXPD performs "Return Maximum Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VMAXPD -// Supported forms : (11 forms) -// -// * VMAXPD xmm, xmm, xmm [AVX] -// * VMAXPD m128, xmm, xmm [AVX] -// * VMAXPD ymm, ymm, ymm [AVX] -// * VMAXPD m256, ymm, ymm [AVX] -// * VMAXPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VMAXPD {sae}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VMAXPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VMAXPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMAXPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMAXPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMAXPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMAXPD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMAXPD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMAXPD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMAXPD takes 3 or 4 operands") - } - // VMAXPD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXPD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMAXPD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXPD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMAXPD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VMAXPD {sae}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMAXPD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXPD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VMAXPD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXPD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VMAXPD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMAXPD") - } - return p -} - -// VMAXPS performs "Return Maximum Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VMAXPS -// Supported forms : (11 forms) -// -// * VMAXPS xmm, xmm, xmm [AVX] -// * VMAXPS m128, xmm, xmm [AVX] -// * VMAXPS ymm, ymm, ymm [AVX] -// * VMAXPS m256, ymm, ymm [AVX] -// * VMAXPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VMAXPS {sae}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VMAXPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VMAXPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMAXPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMAXPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMAXPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMAXPS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMAXPS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMAXPS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMAXPS takes 3 or 4 operands") - } - // VMAXPS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXPS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMAXPS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXPS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMAXPS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VMAXPS {sae}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMAXPS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXPS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VMAXPS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXPS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VMAXPS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMAXPS") - } - return p -} - -// VMAXSD performs "Return Maximum Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VMAXSD -// Supported forms : (5 forms) -// -// * VMAXSD xmm, xmm, xmm [AVX] -// * VMAXSD m64, xmm, xmm [AVX] -// * VMAXSD m64, xmm, xmm{k}{z} [AVX512F] -// * VMAXSD {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VMAXSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VMAXSD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMAXSD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMAXSD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMAXSD takes 3 or 4 operands") - } - // VMAXSD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXSD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMAXSD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VMAXSD {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMAXSD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMAXSD") - } - return p -} - -// VMAXSS performs "Return Maximum Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VMAXSS -// Supported forms : (5 forms) -// -// * VMAXSS xmm, xmm, xmm [AVX] -// * VMAXSS m32, xmm, xmm [AVX] -// * VMAXSS m32, xmm, xmm{k}{z} [AVX512F] -// * VMAXSS {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VMAXSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VMAXSS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMAXSS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMAXSS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMAXSS takes 3 or 4 operands") - } - // VMAXSS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMAXSS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMAXSS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5f) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VMAXSS {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMAXSS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMAXSS") - } - return p -} - -// VMINPD performs "Return Minimum Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VMINPD -// Supported forms : (11 forms) -// -// * VMINPD xmm, xmm, xmm [AVX] -// * VMINPD m128, xmm, xmm [AVX] -// * VMINPD ymm, ymm, ymm [AVX] -// * VMINPD m256, ymm, ymm [AVX] -// * VMINPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VMINPD {sae}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VMINPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VMINPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMINPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMINPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMINPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMINPD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMINPD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMINPD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMINPD takes 3 or 4 operands") - } - // VMINPD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINPD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMINPD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINPD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMINPD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VMINPD {sae}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMINPD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINPD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VMINPD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINPD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VMINPD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMINPD") - } - return p -} - -// VMINPS performs "Return Minimum Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VMINPS -// Supported forms : (11 forms) -// -// * VMINPS xmm, xmm, xmm [AVX] -// * VMINPS m128, xmm, xmm [AVX] -// * VMINPS ymm, ymm, ymm [AVX] -// * VMINPS m256, ymm, ymm [AVX] -// * VMINPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VMINPS {sae}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VMINPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VMINPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMINPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMINPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMINPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMINPS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMINPS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMINPS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMINPS takes 3 or 4 operands") - } - // VMINPS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINPS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMINPS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINPS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMINPS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VMINPS {sae}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMINPS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINPS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VMINPS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINPS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VMINPS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMINPS") - } - return p -} - -// VMINSD performs "Return Minimum Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VMINSD -// Supported forms : (5 forms) -// -// * VMINSD xmm, xmm, xmm [AVX] -// * VMINSD m64, xmm, xmm [AVX] -// * VMINSD m64, xmm, xmm{k}{z} [AVX512F] -// * VMINSD {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VMINSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VMINSD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMINSD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMINSD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMINSD takes 3 or 4 operands") - } - // VMINSD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINSD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMINSD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VMINSD {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMINSD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMINSD") - } - return p -} - -// VMINSS performs "Return Minimum Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VMINSS -// Supported forms : (5 forms) -// -// * VMINSS xmm, xmm, xmm [AVX] -// * VMINSS m32, xmm, xmm [AVX] -// * VMINSS m32, xmm, xmm{k}{z} [AVX512F] -// * VMINSS {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VMINSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VMINSS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMINSS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMINSS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMINSS takes 3 or 4 operands") - } - // VMINSS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMINSS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMINSS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5d) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VMINSS {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMINSS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMINSS") - } - return p -} - -// VMOVAPD performs "Move Aligned Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VMOVAPD -// Supported forms : (15 forms) -// -// * VMOVAPD xmm, xmm [AVX] -// * VMOVAPD m128, xmm [AVX] -// * VMOVAPD ymm, ymm [AVX] -// * VMOVAPD m256, ymm [AVX] -// * VMOVAPD xmm, m128 [AVX] -// * VMOVAPD ymm, m256 [AVX] -// * VMOVAPD zmm, m512{k}{z} [AVX512F] -// * VMOVAPD zmm, zmm{k}{z} [AVX512F] -// * VMOVAPD m512, zmm{k}{z} [AVX512F] -// * VMOVAPD xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VMOVAPD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVAPD ymm, m256{k}{z} [AVX512F,AVX512VL] -// * VMOVAPD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVAPD m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVAPD m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVAPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVAPD", 2, Operands { v0, v1 }) - // VMOVAPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), v[1], 0) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVAPD ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), v[0], 0) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[0]), v[1], 0) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPD m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), addr(v[0]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVAPD xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), addr(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVAPD ymm, m256 - if isYMM(v0) && isM256(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[0]), addr(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVAPD zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVAPD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPD m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVAPD xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVAPD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPD ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVAPD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPD m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVAPD m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVAPD") - } - return p -} - -// VMOVAPS performs "Move Aligned Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VMOVAPS -// Supported forms : (15 forms) -// -// * VMOVAPS xmm, xmm [AVX] -// * VMOVAPS m128, xmm [AVX] -// * VMOVAPS ymm, ymm [AVX] -// * VMOVAPS m256, ymm [AVX] -// * VMOVAPS xmm, m128 [AVX] -// * VMOVAPS ymm, m256 [AVX] -// * VMOVAPS zmm, m512{k}{z} [AVX512F] -// * VMOVAPS zmm, zmm{k}{z} [AVX512F] -// * VMOVAPS m512, zmm{k}{z} [AVX512F] -// * VMOVAPS xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VMOVAPS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVAPS ymm, m256{k}{z} [AVX512F,AVX512VL] -// * VMOVAPS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVAPS m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVAPS m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVAPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVAPS", 2, Operands { v0, v1 }) - // VMOVAPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[0]), v[1], 0) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), addr(v[0]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVAPS ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), v[0], 0) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[0]), v[1], 0) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPS m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), addr(v[0]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVAPS xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[0]), addr(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVAPS ymm, m256 - if isYMM(v0) && isM256(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[0]), addr(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVAPS zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVAPS zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPS m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVAPS xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVAPS xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPS ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x29) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVAPS ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x29) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVAPS m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVAPS m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x28) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVAPS") - } - return p -} - -// VMOVD performs "Move Doubleword". -// -// Mnemonic : VMOVD -// Supported forms : (8 forms) -// -// * VMOVD xmm, r32 [AVX] -// * VMOVD r32, xmm [AVX] -// * VMOVD m32, xmm [AVX] -// * VMOVD xmm, m32 [AVX] -// * VMOVD xmm, r32 [AVX512F] -// * VMOVD r32, xmm [AVX512F] -// * VMOVD m32, xmm [AVX512F] -// * VMOVD xmm, m32 [AVX512F] -// -func (self *Program) VMOVD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVD", 2, Operands { v0, v1 }) - // VMOVD xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), v[1], 0) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVD r32, xmm - if isReg32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVD m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0x6e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVD xmm, m32 - if isXMM(v0) && isM32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), addr(v[1]), 0) - m.emit(0x7e) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVD xmm, r32 - if isEVEXXMM(v0) && isReg32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit(0x08) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVD r32, xmm - if isReg32(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit(0x08) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVD m32, xmm - if isM32(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x6e) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VMOVD xmm, m32 - if isEVEXXMM(v0) && isM32(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x7e) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVD") - } - return p -} - -// VMOVDDUP performs "Move One Double-FP and Duplicate". -// -// Mnemonic : VMOVDDUP -// Supported forms : (10 forms) -// -// * VMOVDDUP xmm, xmm [AVX] -// * VMOVDDUP m64, xmm [AVX] -// * VMOVDDUP ymm, ymm [AVX] -// * VMOVDDUP m256, ymm [AVX] -// * VMOVDDUP zmm, zmm{k}{z} [AVX512F] -// * VMOVDDUP m512, zmm{k}{z} [AVX512F] -// * VMOVDDUP xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDDUP ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVDDUP m64, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDDUP m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVDDUP(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVDDUP", 2, Operands { v0, v1 }) - // VMOVDDUP xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), v[0], 0) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVDDUP m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), addr(v[0]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVDDUP ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[1]), v[0], 0) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVDDUP m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[1]), addr(v[0]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVDDUP zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVDDUP m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVDDUP xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVDDUP ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVDDUP m64, xmm{k}{z} - if isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VMOVDDUP m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVDDUP") - } - return p -} - -// VMOVDQA performs "Move Aligned Double Quadword". -// -// Mnemonic : VMOVDQA -// Supported forms : (6 forms) -// -// * VMOVDQA xmm, xmm [AVX] -// * VMOVDQA m128, xmm [AVX] -// * VMOVDQA ymm, ymm [AVX] -// * VMOVDQA m256, ymm [AVX] -// * VMOVDQA xmm, m128 [AVX] -// * VMOVDQA ymm, m256 [AVX] -// -func (self *Program) VMOVDQA(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVDQA", 2, Operands { v0, v1 }) - // VMOVDQA xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), v[1], 0) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQA m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVDQA ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), v[0], 0) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[0]), v[1], 0) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQA m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), addr(v[0]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVDQA xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), addr(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVDQA ymm, m256 - if isYMM(v0) && isM256(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[0]), addr(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVDQA") - } - return p -} - -// VMOVDQA32 performs "Move Aligned Doubleword Values". -// -// Mnemonic : VMOVDQA32 -// Supported forms : (9 forms) -// -// * VMOVDQA32 zmm, m512{k}{z} [AVX512F] -// * VMOVDQA32 zmm, zmm{k}{z} [AVX512F] -// * VMOVDQA32 m512, zmm{k}{z} [AVX512F] -// * VMOVDQA32 xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA32 xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA32 ymm, m256{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA32 ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA32 m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA32 m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVDQA32(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVDQA32", 2, Operands { v0, v1 }) - // VMOVDQA32 zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVDQA32 zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQA32 m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVDQA32 xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVDQA32 xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQA32 ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVDQA32 ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQA32 m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVDQA32 m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVDQA32") - } - return p -} - -// VMOVDQA64 performs "Move Aligned Quadword Values". -// -// Mnemonic : VMOVDQA64 -// Supported forms : (9 forms) -// -// * VMOVDQA64 zmm, m512{k}{z} [AVX512F] -// * VMOVDQA64 zmm, zmm{k}{z} [AVX512F] -// * VMOVDQA64 m512, zmm{k}{z} [AVX512F] -// * VMOVDQA64 xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA64 xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA64 ymm, m256{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA64 ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA64 m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQA64 m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVDQA64(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVDQA64", 2, Operands { v0, v1 }) - // VMOVDQA64 zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVDQA64 zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQA64 m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVDQA64 xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVDQA64 xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQA64 ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVDQA64 ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQA64 m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVDQA64 m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVDQA64") - } - return p -} - -// VMOVDQU performs "Move Unaligned Double Quadword". -// -// Mnemonic : VMOVDQU -// Supported forms : (6 forms) -// -// * VMOVDQU xmm, xmm [AVX] -// * VMOVDQU m128, xmm [AVX] -// * VMOVDQU ymm, ymm [AVX] -// * VMOVDQU m256, ymm [AVX] -// * VMOVDQU xmm, m128 [AVX] -// * VMOVDQU ymm, m256 [AVX] -// -func (self *Program) VMOVDQU(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVDQU", 2, Operands { v0, v1 }) - // VMOVDQU xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), v[0], 0) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[0]), v[1], 0) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), addr(v[0]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVDQU ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), v[0], 0) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[0]), v[1], 0) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), addr(v[0]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVDQU xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[0]), addr(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVDQU ymm, m256 - if isYMM(v0) && isM256(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[0]), addr(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVDQU") - } - return p -} - -// VMOVDQU16 performs "Move Unaligned Word Values". -// -// Mnemonic : VMOVDQU16 -// Supported forms : (9 forms) -// -// * VMOVDQU16 zmm, m512{k}{z} [AVX512BW] -// * VMOVDQU16 zmm, zmm{k}{z} [AVX512BW] -// * VMOVDQU16 m512, zmm{k}{z} [AVX512BW] -// * VMOVDQU16 xmm, m128{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU16 xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU16 ymm, m256{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU16 ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU16 m128, xmm{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU16 m256, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VMOVDQU16(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVDQU16", 2, Operands { v0, v1 }) - // VMOVDQU16 zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVDQU16 zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU16 m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVDQU16 xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVDQU16 xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU16 ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVDQU16 ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xff) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU16 m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVDQU16 m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVDQU16") - } - return p -} - -// VMOVDQU32 performs "Move Unaligned Doubleword Values". -// -// Mnemonic : VMOVDQU32 -// Supported forms : (9 forms) -// -// * VMOVDQU32 zmm, m512{k}{z} [AVX512F] -// * VMOVDQU32 zmm, zmm{k}{z} [AVX512F] -// * VMOVDQU32 m512, zmm{k}{z} [AVX512F] -// * VMOVDQU32 xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU32 xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU32 ymm, m256{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU32 ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU32 m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU32 m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVDQU32(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVDQU32", 2, Operands { v0, v1 }) - // VMOVDQU32 zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVDQU32 zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU32 m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVDQU32 xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVDQU32 xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU32 ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVDQU32 ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU32 m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVDQU32 m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVDQU32") - } - return p -} - -// VMOVDQU64 performs "Move Unaligned Quadword Values". -// -// Mnemonic : VMOVDQU64 -// Supported forms : (9 forms) -// -// * VMOVDQU64 zmm, m512{k}{z} [AVX512F] -// * VMOVDQU64 zmm, zmm{k}{z} [AVX512F] -// * VMOVDQU64 m512, zmm{k}{z} [AVX512F] -// * VMOVDQU64 xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU64 xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU64 ymm, m256{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU64 ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU64 m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVDQU64 m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVDQU64(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVDQU64", 2, Operands { v0, v1 }) - // VMOVDQU64 zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVDQU64 zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU64 m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVDQU64 xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVDQU64 xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU64 ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVDQU64 ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfe) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU64 m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVDQU64 m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVDQU64") - } - return p -} - -// VMOVDQU8 performs "Move Unaligned Byte Values". -// -// Mnemonic : VMOVDQU8 -// Supported forms : (9 forms) -// -// * VMOVDQU8 zmm, m512{k}{z} [AVX512BW] -// * VMOVDQU8 zmm, zmm{k}{z} [AVX512BW] -// * VMOVDQU8 m512, zmm{k}{z} [AVX512BW] -// * VMOVDQU8 xmm, m128{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU8 xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU8 ymm, m256{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU8 ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU8 m128, xmm{k}{z} [AVX512BW,AVX512VL] -// * VMOVDQU8 m256, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VMOVDQU8(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVDQU8", 2, Operands { v0, v1 }) - // VMOVDQU8 zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVDQU8 zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU8 m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVDQU8 xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVDQU8 xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU8 ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x7f) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVDQU8 ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x6f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVDQU8 m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVDQU8 m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x6f) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVDQU8") - } - return p -} - -// VMOVHLPS performs "Move Packed Single-Precision Floating-Point Values High to Low". -// -// Mnemonic : VMOVHLPS -// Supported forms : (2 forms) -// -// * VMOVHLPS xmm, xmm, xmm [AVX] -// * VMOVHLPS xmm, xmm, xmm [AVX512F] -// -func (self *Program) VMOVHLPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VMOVHLPS", 3, Operands { v0, v1, v2 }) - // VMOVHLPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x12) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMOVHLPS xmm, xmm, xmm - if isEVEXXMM(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x00) - m.emit(0x12) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVHLPS") - } - return p -} - -// VMOVHPD performs "Move High Packed Double-Precision Floating-Point Value". -// -// Mnemonic : VMOVHPD -// Supported forms : (4 forms) -// -// * VMOVHPD xmm, m64 [AVX] -// * VMOVHPD m64, xmm, xmm [AVX] -// * VMOVHPD xmm, m64 [AVX512F] -// * VMOVHPD m64, xmm, xmm [AVX512F] -// -func (self *Program) VMOVHPD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMOVHPD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VMOVHPD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VMOVHPD takes 2 or 3 operands") - } - // VMOVHPD xmm, m64 - if len(vv) == 0 && isXMM(v0) && isM64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), addr(v[1]), 0) - m.emit(0x17) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVHPD m64, xmm, xmm - if len(vv) == 1 && isM64(v0) && isXMM(v1) && isXMM(vv[0]) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x16) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMOVHPD xmm, m64 - if len(vv) == 0 && isEVEXXMM(v0) && isM64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x17) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VMOVHPD m64, xmm, xmm - if len(vv) == 1 && isM64(v0) && isEVEXXMM(v1) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x16) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVHPD") - } - return p -} - -// VMOVHPS performs "Move High Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VMOVHPS -// Supported forms : (4 forms) -// -// * VMOVHPS xmm, m64 [AVX] -// * VMOVHPS m64, xmm, xmm [AVX] -// * VMOVHPS xmm, m64 [AVX512F] -// * VMOVHPS m64, xmm, xmm [AVX512F] -// -func (self *Program) VMOVHPS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMOVHPS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VMOVHPS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VMOVHPS takes 2 or 3 operands") - } - // VMOVHPS xmm, m64 - if len(vv) == 0 && isXMM(v0) && isM64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[0]), addr(v[1]), 0) - m.emit(0x17) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVHPS m64, xmm, xmm - if len(vv) == 1 && isM64(v0) && isXMM(v1) && isXMM(vv[0]) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x16) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMOVHPS xmm, m64 - if len(vv) == 0 && isEVEXXMM(v0) && isM64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x17) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VMOVHPS m64, xmm, xmm - if len(vv) == 1 && isM64(v0) && isEVEXXMM(v1) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x16) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVHPS") - } - return p -} - -// VMOVLHPS performs "Move Packed Single-Precision Floating-Point Values Low to High". -// -// Mnemonic : VMOVLHPS -// Supported forms : (2 forms) -// -// * VMOVLHPS xmm, xmm, xmm [AVX] -// * VMOVLHPS xmm, xmm, xmm [AVX512F] -// -func (self *Program) VMOVLHPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VMOVLHPS", 3, Operands { v0, v1, v2 }) - // VMOVLHPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x16) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMOVLHPS xmm, xmm, xmm - if isEVEXXMM(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x00) - m.emit(0x16) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVLHPS") - } - return p -} - -// VMOVLPD performs "Move Low Packed Double-Precision Floating-Point Value". -// -// Mnemonic : VMOVLPD -// Supported forms : (4 forms) -// -// * VMOVLPD xmm, m64 [AVX] -// * VMOVLPD m64, xmm, xmm [AVX] -// * VMOVLPD xmm, m64 [AVX512F] -// * VMOVLPD m64, xmm, xmm [AVX512F] -// -func (self *Program) VMOVLPD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMOVLPD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VMOVLPD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VMOVLPD takes 2 or 3 operands") - } - // VMOVLPD xmm, m64 - if len(vv) == 0 && isXMM(v0) && isM64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), addr(v[1]), 0) - m.emit(0x13) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVLPD m64, xmm, xmm - if len(vv) == 1 && isM64(v0) && isXMM(v1) && isXMM(vv[0]) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x12) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMOVLPD xmm, m64 - if len(vv) == 0 && isEVEXXMM(v0) && isM64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x13) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VMOVLPD m64, xmm, xmm - if len(vv) == 1 && isM64(v0) && isEVEXXMM(v1) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x12) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVLPD") - } - return p -} - -// VMOVLPS performs "Move Low Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VMOVLPS -// Supported forms : (4 forms) -// -// * VMOVLPS xmm, m64 [AVX] -// * VMOVLPS m64, xmm, xmm [AVX] -// * VMOVLPS xmm, m64 [AVX512F] -// * VMOVLPS m64, xmm, xmm [AVX512F] -// -func (self *Program) VMOVLPS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMOVLPS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VMOVLPS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VMOVLPS takes 2 or 3 operands") - } - // VMOVLPS xmm, m64 - if len(vv) == 0 && isXMM(v0) && isM64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[0]), addr(v[1]), 0) - m.emit(0x13) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVLPS m64, xmm, xmm - if len(vv) == 1 && isM64(v0) && isXMM(v1) && isXMM(vv[0]) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x12) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMOVLPS xmm, m64 - if len(vv) == 0 && isEVEXXMM(v0) && isM64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x13) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VMOVLPS m64, xmm, xmm - if len(vv) == 1 && isM64(v0) && isEVEXXMM(v1) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0x12) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVLPS") - } - return p -} - -// VMOVMSKPD performs "Extract Packed Double-Precision Floating-Point Sign Mask". -// -// Mnemonic : VMOVMSKPD -// Supported forms : (2 forms) -// -// * VMOVMSKPD xmm, r32 [AVX] -// * VMOVMSKPD ymm, r32 [AVX] -// -func (self *Program) VMOVMSKPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVMSKPD", 2, Operands { v0, v1 }) - // VMOVMSKPD xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x50) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVMSKPD ymm, r32 - if isYMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), v[0], 0) - m.emit(0x50) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVMSKPD") - } - return p -} - -// VMOVMSKPS performs "Extract Packed Single-Precision Floating-Point Sign Mask". -// -// Mnemonic : VMOVMSKPS -// Supported forms : (2 forms) -// -// * VMOVMSKPS xmm, r32 [AVX] -// * VMOVMSKPS ymm, r32 [AVX] -// -func (self *Program) VMOVMSKPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVMSKPS", 2, Operands { v0, v1 }) - // VMOVMSKPS xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x50) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVMSKPS ymm, r32 - if isYMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), v[0], 0) - m.emit(0x50) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVMSKPS") - } - return p -} - -// VMOVNTDQ performs "Store Double Quadword Using Non-Temporal Hint". -// -// Mnemonic : VMOVNTDQ -// Supported forms : (5 forms) -// -// * VMOVNTDQ xmm, m128 [AVX] -// * VMOVNTDQ ymm, m256 [AVX] -// * VMOVNTDQ zmm, m512 [AVX512F] -// * VMOVNTDQ xmm, m128 [AVX512F,AVX512VL] -// * VMOVNTDQ ymm, m256 [AVX512F,AVX512VL] -// -func (self *Program) VMOVNTDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVNTDQ", 2, Operands { v0, v1 }) - // VMOVNTDQ xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), addr(v[1]), 0) - m.emit(0xe7) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVNTDQ ymm, m256 - if isYMM(v0) && isM256(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[0]), addr(v[1]), 0) - m.emit(0xe7) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVNTDQ zmm, m512 - if isZMM(v0) && isM512(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0xe7) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVNTDQ xmm, m128 - if isEVEXXMM(v0) && isM128(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0xe7) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVNTDQ ymm, m256 - if isEVEXYMM(v0) && isM256(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0xe7) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVNTDQ") - } - return p -} - -// VMOVNTDQA performs "Load Double Quadword Non-Temporal Aligned Hint". -// -// Mnemonic : VMOVNTDQA -// Supported forms : (5 forms) -// -// * VMOVNTDQA m128, xmm [AVX] -// * VMOVNTDQA m256, ymm [AVX2] -// * VMOVNTDQA m512, zmm [AVX512F] -// * VMOVNTDQA m128, xmm [AVX512F,AVX512VL] -// * VMOVNTDQA m256, ymm [AVX512F,AVX512VL] -// -func (self *Program) VMOVNTDQA(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVNTDQA", 2, Operands { v0, v1 }) - // VMOVNTDQA m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVNTDQA m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVNTDQA m512, zmm - if isM512(v0) && isZMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVNTDQA m128, xmm - if isM128(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVNTDQA m256, ymm - if isM256(v0) && isEVEXYMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2a) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVNTDQA") - } - return p -} - -// VMOVNTPD performs "Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint". -// -// Mnemonic : VMOVNTPD -// Supported forms : (5 forms) -// -// * VMOVNTPD xmm, m128 [AVX] -// * VMOVNTPD ymm, m256 [AVX] -// * VMOVNTPD zmm, m512 [AVX512F] -// * VMOVNTPD xmm, m128 [AVX512F,AVX512VL] -// * VMOVNTPD ymm, m256 [AVX512F,AVX512VL] -// -func (self *Program) VMOVNTPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVNTPD", 2, Operands { v0, v1 }) - // VMOVNTPD xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), addr(v[1]), 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVNTPD ymm, m256 - if isYMM(v0) && isM256(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[0]), addr(v[1]), 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVNTPD zmm, m512 - if isZMM(v0) && isM512(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVNTPD xmm, m128 - if isEVEXXMM(v0) && isM128(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVNTPD ymm, m256 - if isEVEXYMM(v0) && isM256(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVNTPD") - } - return p -} - -// VMOVNTPS performs "Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint". -// -// Mnemonic : VMOVNTPS -// Supported forms : (5 forms) -// -// * VMOVNTPS xmm, m128 [AVX] -// * VMOVNTPS ymm, m256 [AVX] -// * VMOVNTPS zmm, m512 [AVX512F] -// * VMOVNTPS xmm, m128 [AVX512F,AVX512VL] -// * VMOVNTPS ymm, m256 [AVX512F,AVX512VL] -// -func (self *Program) VMOVNTPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVNTPS", 2, Operands { v0, v1 }) - // VMOVNTPS xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[0]), addr(v[1]), 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVNTPS ymm, m256 - if isYMM(v0) && isM256(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[0]), addr(v[1]), 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVNTPS zmm, m512 - if isZMM(v0) && isM512(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVNTPS xmm, m128 - if isEVEXXMM(v0) && isM128(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVNTPS ymm, m256 - if isEVEXYMM(v0) && isM256(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x2b) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVNTPS") - } - return p -} - -// VMOVQ performs "Move Quadword". -// -// Mnemonic : VMOVQ -// Supported forms : (10 forms) -// -// * VMOVQ xmm, r64 [AVX] -// * VMOVQ r64, xmm [AVX] -// * VMOVQ xmm, xmm [AVX] -// * VMOVQ m64, xmm [AVX] -// * VMOVQ xmm, m64 [AVX] -// * VMOVQ xmm, r64 [AVX512F] -// * VMOVQ r64, xmm [AVX512F] -// * VMOVQ xmm, xmm [AVX512F] -// * VMOVQ m64, xmm [AVX512F] -// * VMOVQ xmm, m64 [AVX512F] -// -func (self *Program) VMOVQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVQ", 2, Operands { v0, v1 }) - // VMOVQ xmm, r64 - if isXMM(v0) && isReg64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[0]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xf9) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVQ r64, xmm - if isReg64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe1 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), v[0], 0) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), v[1], 0) - m.emit(0xd6) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVQ m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), addr(v[0]), 0) - m.emit(0x7e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x81, hcode(v[1]), addr(v[0]), 0) - m.emit(0x6e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVQ xmm, m64 - if isXMM(v0) && isM64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), addr(v[1]), 0) - m.emit(0xd6) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b1, 0x81, hcode(v[0]), addr(v[1]), 0) - m.emit(0x7e) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVQ xmm, r64 - if isEVEXXMM(v0) && isReg64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit(0x08) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVQ r64, xmm - if isReg64(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit(0x08) - m.emit(0x6e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVQ xmm, xmm - if isEVEXXMM(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x08) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit(0x08) - m.emit(0xd6) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVQ m64, xmm - if isM64(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x6e) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x86, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x7e) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VMOVQ xmm, m64 - if isEVEXXMM(v0) && isM64(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0x7e) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, 0, 0, 0) - m.emit(0xd6) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVQ") - } - return p -} - -// VMOVSD performs "Move Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VMOVSD -// Supported forms : (6 forms) -// -// * VMOVSD m64, xmm [AVX] -// * VMOVSD xmm, m64 [AVX] -// * VMOVSD xmm, xmm, xmm [AVX] -// * VMOVSD xmm, m64{k} [AVX512F] -// * VMOVSD m64, xmm{k}{z} [AVX512F] -// * VMOVSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VMOVSD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMOVSD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VMOVSD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VMOVSD takes 2 or 3 operands") - } - // VMOVSD m64, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[1]), addr(v[0]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVSD xmm, m64 - if len(vv) == 0 && isXMM(v0) && isM64(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[0]), addr(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVSD xmm, xmm, xmm - if len(vv) == 1 && isXMM(v0) && isXMM(v1) && isXMM(vv[0]) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[0]), v[2], hlcode(v[1])) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[2])) - }) - } - // VMOVSD xmm, m64{k} - if len(vv) == 0 && isEVEXXMM(v0) && isM64k(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VMOVSD m64, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VMOVSD xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[2])) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVSD") - } - return p -} - -// VMOVSHDUP performs "Move Packed Single-FP High and Duplicate". -// -// Mnemonic : VMOVSHDUP -// Supported forms : (10 forms) -// -// * VMOVSHDUP xmm, xmm [AVX] -// * VMOVSHDUP m128, xmm [AVX] -// * VMOVSHDUP ymm, ymm [AVX] -// * VMOVSHDUP m256, ymm [AVX] -// * VMOVSHDUP zmm, zmm{k}{z} [AVX512F] -// * VMOVSHDUP m512, zmm{k}{z} [AVX512F] -// * VMOVSHDUP xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVSHDUP ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVSHDUP m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVSHDUP m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVSHDUP(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVSHDUP", 2, Operands { v0, v1 }) - // VMOVSHDUP xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), v[0], 0) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSHDUP m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), addr(v[0]), 0) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVSHDUP ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), v[0], 0) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSHDUP m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), addr(v[0]), 0) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVSHDUP zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSHDUP m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVSHDUP xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSHDUP ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSHDUP m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVSHDUP m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVSHDUP") - } - return p -} - -// VMOVSLDUP performs "Move Packed Single-FP Low and Duplicate". -// -// Mnemonic : VMOVSLDUP -// Supported forms : (10 forms) -// -// * VMOVSLDUP xmm, xmm [AVX] -// * VMOVSLDUP m128, xmm [AVX] -// * VMOVSLDUP ymm, ymm [AVX] -// * VMOVSLDUP m256, ymm [AVX] -// * VMOVSLDUP zmm, zmm{k}{z} [AVX512F] -// * VMOVSLDUP m512, zmm{k}{z} [AVX512F] -// * VMOVSLDUP xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVSLDUP ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVSLDUP m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVSLDUP m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVSLDUP(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVSLDUP", 2, Operands { v0, v1 }) - // VMOVSLDUP xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), v[0], 0) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSLDUP m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), addr(v[0]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVSLDUP ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), v[0], 0) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSLDUP m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[1]), addr(v[0]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVSLDUP zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSLDUP m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVSLDUP xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSLDUP ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x12) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VMOVSLDUP m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVSLDUP m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x12) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVSLDUP") - } - return p -} - -// VMOVSS performs "Move Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VMOVSS -// Supported forms : (6 forms) -// -// * VMOVSS m32, xmm [AVX] -// * VMOVSS xmm, m32 [AVX] -// * VMOVSS xmm, xmm, xmm [AVX] -// * VMOVSS xmm, m32{k} [AVX512F] -// * VMOVSS m32, xmm{k}{z} [AVX512F] -// * VMOVSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VMOVSS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMOVSS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VMOVSS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VMOVSS takes 2 or 3 operands") - } - // VMOVSS m32, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[1]), addr(v[0]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVSS xmm, m32 - if len(vv) == 0 && isXMM(v0) && isM32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[0]), addr(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVSS xmm, xmm, xmm - if len(vv) == 1 && isXMM(v0) && isXMM(v1) && isXMM(vv[0]) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[0]), v[2], hlcode(v[1])) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[2])) - }) - } - // VMOVSS xmm, m32{k} - if len(vv) == 0 && isEVEXXMM(v0) && isM32k(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VMOVSS m32, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VMOVSS xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[2])) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVSS") - } - return p -} - -// VMOVUPD performs "Move Unaligned Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VMOVUPD -// Supported forms : (15 forms) -// -// * VMOVUPD xmm, xmm [AVX] -// * VMOVUPD m128, xmm [AVX] -// * VMOVUPD ymm, ymm [AVX] -// * VMOVUPD m256, ymm [AVX] -// * VMOVUPD xmm, m128 [AVX] -// * VMOVUPD ymm, m256 [AVX] -// * VMOVUPD zmm, m512{k}{z} [AVX512F] -// * VMOVUPD zmm, zmm{k}{z} [AVX512F] -// * VMOVUPD m512, zmm{k}{z} [AVX512F] -// * VMOVUPD xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VMOVUPD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVUPD ymm, m256{k}{z} [AVX512F,AVX512VL] -// * VMOVUPD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVUPD m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVUPD m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVUPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVUPD", 2, Operands { v0, v1 }) - // VMOVUPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), v[1], 0) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVUPD ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), v[0], 0) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[0]), v[1], 0) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPD m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), addr(v[0]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVUPD xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[0]), addr(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVUPD ymm, m256 - if isYMM(v0) && isM256(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[0]), addr(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVUPD zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVUPD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPD m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVUPD xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVUPD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPD ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVUPD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPD m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVUPD m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVUPD") - } - return p -} - -// VMOVUPS performs "Move Unaligned Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VMOVUPS -// Supported forms : (15 forms) -// -// * VMOVUPS xmm, xmm [AVX] -// * VMOVUPS m128, xmm [AVX] -// * VMOVUPS ymm, ymm [AVX] -// * VMOVUPS m256, ymm [AVX] -// * VMOVUPS xmm, m128 [AVX] -// * VMOVUPS ymm, m256 [AVX] -// * VMOVUPS zmm, m512{k}{z} [AVX512F] -// * VMOVUPS zmm, zmm{k}{z} [AVX512F] -// * VMOVUPS m512, zmm{k}{z} [AVX512F] -// * VMOVUPS xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VMOVUPS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVUPS ymm, m256{k}{z} [AVX512F,AVX512VL] -// * VMOVUPS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMOVUPS m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VMOVUPS m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMOVUPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VMOVUPS", 2, Operands { v0, v1 }) - // VMOVUPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[0]), v[1], 0) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), addr(v[0]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVUPS ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), v[0], 0) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[0]), v[1], 0) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPS m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), addr(v[0]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VMOVUPS xmm, m128 - if isXMM(v0) && isM128(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[0]), addr(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVUPS ymm, m256 - if isYMM(v0) && isM256(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[0]), addr(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - // VMOVUPS zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 64) - }) - } - // VMOVUPS zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPS m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VMOVUPS xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VMOVUPS xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPS ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VMOVUPS ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x10) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VMOVUPS m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VMOVUPS m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VMOVUPS") - } - return p -} - -// VMPSADBW performs "Compute Multiple Packed Sums of Absolute Difference". -// -// Mnemonic : VMPSADBW -// Supported forms : (4 forms) -// -// * VMPSADBW imm8, xmm, xmm, xmm [AVX] -// * VMPSADBW imm8, m128, xmm, xmm [AVX] -// * VMPSADBW imm8, ymm, ymm, ymm [AVX2] -// * VMPSADBW imm8, m256, ymm, ymm [AVX2] -// -func (self *Program) VMPSADBW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VMPSADBW", 4, Operands { v0, v1, v2, v3 }) - // VMPSADBW imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x42) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VMPSADBW imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x42) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VMPSADBW imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x42) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VMPSADBW imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x42) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMPSADBW") - } - return p -} - -// VMULPD performs "Multiply Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VMULPD -// Supported forms : (11 forms) -// -// * VMULPD xmm, xmm, xmm [AVX] -// * VMULPD m128, xmm, xmm [AVX] -// * VMULPD ymm, ymm, ymm [AVX] -// * VMULPD m256, ymm, ymm [AVX] -// * VMULPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VMULPD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VMULPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VMULPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMULPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMULPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMULPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMULPD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMULPD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMULPD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMULPD takes 3 or 4 operands") - } - // VMULPD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULPD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMULPD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULPD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMULPD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VMULPD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x59) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMULPD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULPD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VMULPD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULPD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VMULPD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMULPD") - } - return p -} - -// VMULPS performs "Multiply Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VMULPS -// Supported forms : (11 forms) -// -// * VMULPS xmm, xmm, xmm [AVX] -// * VMULPS m128, xmm, xmm [AVX] -// * VMULPS ymm, ymm, ymm [AVX] -// * VMULPS m256, ymm, ymm [AVX] -// * VMULPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VMULPS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VMULPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VMULPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMULPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VMULPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VMULPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VMULPS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMULPS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMULPS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMULPS takes 3 or 4 operands") - } - // VMULPS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULPS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMULPS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULPS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMULPS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VMULPS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x59) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMULPS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULPS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VMULPS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULPS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VMULPS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMULPS") - } - return p -} - -// VMULSD performs "Multiply Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VMULSD -// Supported forms : (5 forms) -// -// * VMULSD xmm, xmm, xmm [AVX] -// * VMULSD m64, xmm, xmm [AVX] -// * VMULSD m64, xmm, xmm{k}{z} [AVX512F] -// * VMULSD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VMULSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VMULSD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMULSD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMULSD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMULSD takes 3 or 4 operands") - } - // VMULSD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULSD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMULSD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VMULSD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x59) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMULSD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMULSD") - } - return p -} - -// VMULSS performs "Multiply Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VMULSS -// Supported forms : (5 forms) -// -// * VMULSS xmm, xmm, xmm [AVX] -// * VMULSS m32, xmm, xmm [AVX] -// * VMULSS m32, xmm, xmm{k}{z} [AVX512F] -// * VMULSS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VMULSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VMULSS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VMULSS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VMULSS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VMULSS takes 3 or 4 operands") - } - // VMULSS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VMULSS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VMULSS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x59) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VMULSS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x59) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VMULSS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x59) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VMULSS") - } - return p -} - -// VORPD performs "Bitwise Logical OR of Double-Precision Floating-Point Values". -// -// Mnemonic : VORPD -// Supported forms : (10 forms) -// -// * VORPD xmm, xmm, xmm [AVX] -// * VORPD m128, xmm, xmm [AVX] -// * VORPD ymm, ymm, ymm [AVX] -// * VORPD m256, ymm, ymm [AVX] -// * VORPD m512/m64bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VORPD zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VORPD m128/m64bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VORPD xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VORPD m256/m64bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VORPD ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VORPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VORPD", 3, Operands { v0, v1, v2 }) - // VORPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VORPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VORPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VORPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VORPD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VORPD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VORPD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VORPD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VORPD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VORPD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VORPD") - } - return p -} - -// VORPS performs "Bitwise Logical OR of Single-Precision Floating-Point Values". -// -// Mnemonic : VORPS -// Supported forms : (10 forms) -// -// * VORPS xmm, xmm, xmm [AVX] -// * VORPS m128, xmm, xmm [AVX] -// * VORPS ymm, ymm, ymm [AVX] -// * VORPS m256, ymm, ymm [AVX] -// * VORPS m512/m32bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VORPS zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VORPS m128/m32bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VORPS xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VORPS m256/m32bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VORPS ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VORPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VORPS", 3, Operands { v0, v1, v2 }) - // VORPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VORPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VORPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VORPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VORPS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VORPS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VORPS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VORPS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VORPS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VORPS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VORPS") - } - return p -} - -// VPABSB performs "Packed Absolute Value of Byte Integers". -// -// Mnemonic : VPABSB -// Supported forms : (10 forms) -// -// * VPABSB xmm, xmm [AVX] -// * VPABSB m128, xmm [AVX] -// * VPABSB ymm, ymm [AVX2] -// * VPABSB m256, ymm [AVX2] -// * VPABSB zmm, zmm{k}{z} [AVX512BW] -// * VPABSB m512, zmm{k}{z} [AVX512BW] -// * VPABSB xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPABSB ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPABSB m128, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPABSB m256, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPABSB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPABSB", 2, Operands { v0, v1 }) - // VPABSB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x1c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSB m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x1c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPABSB ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x1c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSB m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x1c) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPABSB zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x1c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSB m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1c) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPABSB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x1c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSB ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x1c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSB m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1c) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPABSB m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1c) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPABSB") - } - return p -} - -// VPABSD performs "Packed Absolute Value of Doubleword Integers". -// -// Mnemonic : VPABSD -// Supported forms : (10 forms) -// -// * VPABSD xmm, xmm [AVX] -// * VPABSD m128, xmm [AVX] -// * VPABSD ymm, ymm [AVX2] -// * VPABSD m256, ymm [AVX2] -// * VPABSD m512/m32bcst, zmm{k}{z} [AVX512F] -// * VPABSD zmm, zmm{k}{z} [AVX512F] -// * VPABSD m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPABSD m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPABSD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPABSD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPABSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPABSD", 2, Operands { v0, v1 }) - // VPABSD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x1e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPABSD ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSD m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x1e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPABSD m512/m32bcst, zmm{k}{z} - if isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x1e) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPABSD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSD m128/m32bcst, xmm{k}{z} - if isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x1e) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPABSD m256/m32bcst, ymm{k}{z} - if isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x1e) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPABSD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPABSD") - } - return p -} - -// VPABSQ performs "Packed Absolute Value of Quadword Integers". -// -// Mnemonic : VPABSQ -// Supported forms : (6 forms) -// -// * VPABSQ m512/m64bcst, zmm{k}{z} [AVX512F] -// * VPABSQ zmm, zmm{k}{z} [AVX512F] -// * VPABSQ m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPABSQ m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPABSQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPABSQ ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPABSQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPABSQ", 2, Operands { v0, v1 }) - // VPABSQ m512/m64bcst, zmm{k}{z} - if isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x1f) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPABSQ zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x1f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSQ m128/m64bcst, xmm{k}{z} - if isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x1f) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPABSQ m256/m64bcst, ymm{k}{z} - if isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x1f) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPABSQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x1f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSQ ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x1f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPABSQ") - } - return p -} - -// VPABSW performs "Packed Absolute Value of Word Integers". -// -// Mnemonic : VPABSW -// Supported forms : (10 forms) -// -// * VPABSW xmm, xmm [AVX] -// * VPABSW m128, xmm [AVX] -// * VPABSW ymm, ymm [AVX2] -// * VPABSW m256, ymm [AVX2] -// * VPABSW zmm, zmm{k}{z} [AVX512BW] -// * VPABSW m512, zmm{k}{z} [AVX512BW] -// * VPABSW xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPABSW ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPABSW m128, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPABSW m256, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPABSW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPABSW", 2, Operands { v0, v1 }) - // VPABSW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPABSW ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSW m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPABSW zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSW m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPABSW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSW ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x1d) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPABSW m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPABSW m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x1d) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPABSW") - } - return p -} - -// VPACKSSDW performs "Pack Doublewords into Words with Signed Saturation". -// -// Mnemonic : VPACKSSDW -// Supported forms : (10 forms) -// -// * VPACKSSDW xmm, xmm, xmm [AVX] -// * VPACKSSDW m128, xmm, xmm [AVX] -// * VPACKSSDW ymm, ymm, ymm [AVX2] -// * VPACKSSDW m256, ymm, ymm [AVX2] -// * VPACKSSDW m512/m32bcst, zmm, zmm{k}{z} [AVX512BW] -// * VPACKSSDW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPACKSSDW m128/m32bcst, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPACKSSDW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPACKSSDW m256/m32bcst, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPACKSSDW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPACKSSDW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPACKSSDW", 3, Operands { v0, v1, v2 }) - // VPACKSSDW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKSSDW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x6b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPACKSSDW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKSSDW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x6b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPACKSSDW m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6b) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPACKSSDW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKSSDW m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6b) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPACKSSDW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKSSDW m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6b) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPACKSSDW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x6b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPACKSSDW") - } - return p -} - -// VPACKSSWB performs "Pack Words into Bytes with Signed Saturation". -// -// Mnemonic : VPACKSSWB -// Supported forms : (10 forms) -// -// * VPACKSSWB xmm, xmm, xmm [AVX] -// * VPACKSSWB m128, xmm, xmm [AVX] -// * VPACKSSWB ymm, ymm, ymm [AVX2] -// * VPACKSSWB m256, ymm, ymm [AVX2] -// * VPACKSSWB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPACKSSWB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPACKSSWB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPACKSSWB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPACKSSWB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPACKSSWB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPACKSSWB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPACKSSWB", 3, Operands { v0, v1, v2 }) - // VPACKSSWB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x63) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKSSWB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x63) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPACKSSWB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x63) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKSSWB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x63) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPACKSSWB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x63) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKSSWB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x63) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPACKSSWB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x63) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKSSWB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x63) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPACKSSWB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x63) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKSSWB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x63) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPACKSSWB") - } - return p -} - -// VPACKUSDW performs "Pack Doublewords into Words with Unsigned Saturation". -// -// Mnemonic : VPACKUSDW -// Supported forms : (10 forms) -// -// * VPACKUSDW xmm, xmm, xmm [AVX] -// * VPACKUSDW m128, xmm, xmm [AVX] -// * VPACKUSDW ymm, ymm, ymm [AVX2] -// * VPACKUSDW m256, ymm, ymm [AVX2] -// * VPACKUSDW m512/m32bcst, zmm, zmm{k}{z} [AVX512BW] -// * VPACKUSDW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPACKUSDW m128/m32bcst, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPACKUSDW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPACKUSDW m256/m32bcst, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPACKUSDW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPACKUSDW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPACKUSDW", 3, Operands { v0, v1, v2 }) - // VPACKUSDW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x2b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKUSDW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPACKUSDW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x2b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKUSDW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x2b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPACKUSDW m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x2b) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPACKUSDW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x2b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKUSDW m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x2b) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPACKUSDW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x2b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKUSDW m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x2b) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPACKUSDW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x2b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPACKUSDW") - } - return p -} - -// VPACKUSWB performs "Pack Words into Bytes with Unsigned Saturation". -// -// Mnemonic : VPACKUSWB -// Supported forms : (10 forms) -// -// * VPACKUSWB xmm, xmm, xmm [AVX] -// * VPACKUSWB m128, xmm, xmm [AVX] -// * VPACKUSWB ymm, ymm, ymm [AVX2] -// * VPACKUSWB m256, ymm, ymm [AVX2] -// * VPACKUSWB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPACKUSWB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPACKUSWB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPACKUSWB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPACKUSWB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPACKUSWB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPACKUSWB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPACKUSWB", 3, Operands { v0, v1, v2 }) - // VPACKUSWB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x67) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKUSWB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x67) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPACKUSWB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x67) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKUSWB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x67) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPACKUSWB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x67) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKUSWB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x67) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPACKUSWB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x67) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKUSWB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x67) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPACKUSWB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x67) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPACKUSWB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x67) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPACKUSWB") - } - return p -} - -// VPADDB performs "Add Packed Byte Integers". -// -// Mnemonic : VPADDB -// Supported forms : (10 forms) -// -// * VPADDB xmm, xmm, xmm [AVX] -// * VPADDB m128, xmm, xmm [AVX] -// * VPADDB ymm, ymm, ymm [AVX2] -// * VPADDB m256, ymm, ymm [AVX2] -// * VPADDB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPADDB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPADDB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPADDB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPADDB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPADDB", 3, Operands { v0, v1, v2 }) - // VPADDB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfc) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfc) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xfc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xfc) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPADDB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xfc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xfc) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPADDB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xfc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xfc) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPADDB") - } - return p -} - -// VPADDD performs "Add Packed Doubleword Integers". -// -// Mnemonic : VPADDD -// Supported forms : (10 forms) -// -// * VPADDD xmm, xmm, xmm [AVX] -// * VPADDD m128, xmm, xmm [AVX] -// * VPADDD ymm, ymm, ymm [AVX2] -// * VPADDD m256, ymm, ymm [AVX2] -// * VPADDD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPADDD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPADDD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPADDD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPADDD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPADDD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPADDD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPADDD", 3, Operands { v0, v1, v2 }) - // VPADDD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfe) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfe) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xfe) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPADDD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xfe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xfe) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPADDD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xfe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xfe) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPADDD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xfe) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPADDD") - } - return p -} - -// VPADDQ performs "Add Packed Quadword Integers". -// -// Mnemonic : VPADDQ -// Supported forms : (10 forms) -// -// * VPADDQ xmm, xmm, xmm [AVX] -// * VPADDQ m128, xmm, xmm [AVX] -// * VPADDQ ymm, ymm, ymm [AVX2] -// * VPADDQ m256, ymm, ymm [AVX2] -// * VPADDQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPADDQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPADDQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPADDQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPADDQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPADDQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPADDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPADDQ", 3, Operands { v0, v1, v2 }) - // VPADDQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd4) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd4) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xd4) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPADDQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xd4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xd4) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPADDQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xd4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xd4) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPADDQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xd4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPADDQ") - } - return p -} - -// VPADDSB performs "Add Packed Signed Byte Integers with Signed Saturation". -// -// Mnemonic : VPADDSB -// Supported forms : (10 forms) -// -// * VPADDSB xmm, xmm, xmm [AVX] -// * VPADDSB m128, xmm, xmm [AVX] -// * VPADDSB ymm, ymm, ymm [AVX2] -// * VPADDSB m256, ymm, ymm [AVX2] -// * VPADDSB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPADDSB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPADDSB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDSB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDSB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPADDSB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPADDSB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPADDSB", 3, Operands { v0, v1, v2 }) - // VPADDSB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xec) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xec) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDSB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xec) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xec) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDSB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xec) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xec) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPADDSB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xec) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xec) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPADDSB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xec) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xec) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPADDSB") - } - return p -} - -// VPADDSW performs "Add Packed Signed Word Integers with Signed Saturation". -// -// Mnemonic : VPADDSW -// Supported forms : (10 forms) -// -// * VPADDSW xmm, xmm, xmm [AVX] -// * VPADDSW m128, xmm, xmm [AVX] -// * VPADDSW ymm, ymm, ymm [AVX2] -// * VPADDSW m256, ymm, ymm [AVX2] -// * VPADDSW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPADDSW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPADDSW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDSW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDSW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPADDSW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPADDSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPADDSW", 3, Operands { v0, v1, v2 }) - // VPADDSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xed) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xed) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xed) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xed) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDSW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xed) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xed) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPADDSW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xed) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xed) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPADDSW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xed) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDSW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xed) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPADDSW") - } - return p -} - -// VPADDUSB performs "Add Packed Unsigned Byte Integers with Unsigned Saturation". -// -// Mnemonic : VPADDUSB -// Supported forms : (10 forms) -// -// * VPADDUSB xmm, xmm, xmm [AVX] -// * VPADDUSB m128, xmm, xmm [AVX] -// * VPADDUSB ymm, ymm, ymm [AVX2] -// * VPADDUSB m256, ymm, ymm [AVX2] -// * VPADDUSB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPADDUSB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPADDUSB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDUSB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDUSB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPADDUSB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPADDUSB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPADDUSB", 3, Operands { v0, v1, v2 }) - // VPADDUSB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xdc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdc) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDUSB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xdc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdc) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDUSB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xdc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xdc) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPADDUSB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xdc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xdc) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPADDUSB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xdc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xdc) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPADDUSB") - } - return p -} - -// VPADDUSW performs "Add Packed Unsigned Word Integers with Unsigned Saturation". -// -// Mnemonic : VPADDUSW -// Supported forms : (10 forms) -// -// * VPADDUSW xmm, xmm, xmm [AVX] -// * VPADDUSW m128, xmm, xmm [AVX] -// * VPADDUSW ymm, ymm, ymm [AVX2] -// * VPADDUSW m256, ymm, ymm [AVX2] -// * VPADDUSW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPADDUSW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPADDUSW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDUSW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDUSW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPADDUSW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPADDUSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPADDUSW", 3, Operands { v0, v1, v2 }) - // VPADDUSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xdd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdd) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDUSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xdd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdd) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDUSW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xdd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xdd) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPADDUSW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xdd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xdd) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPADDUSW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xdd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDUSW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xdd) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPADDUSW") - } - return p -} - -// VPADDW performs "Add Packed Word Integers". -// -// Mnemonic : VPADDW -// Supported forms : (10 forms) -// -// * VPADDW xmm, xmm, xmm [AVX] -// * VPADDW m128, xmm, xmm [AVX] -// * VPADDW ymm, ymm, ymm [AVX2] -// * VPADDW m256, ymm, ymm [AVX2] -// * VPADDW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPADDW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPADDW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPADDW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPADDW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPADDW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPADDW", 3, Operands { v0, v1, v2 }) - // VPADDW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfd) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfd) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPADDW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xfd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xfd) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPADDW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xfd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xfd) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPADDW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xfd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPADDW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xfd) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPADDW") - } - return p -} - -// VPALIGNR performs "Packed Align Right". -// -// Mnemonic : VPALIGNR -// Supported forms : (10 forms) -// -// * VPALIGNR imm8, xmm, xmm, xmm [AVX] -// * VPALIGNR imm8, m128, xmm, xmm [AVX] -// * VPALIGNR imm8, ymm, ymm, ymm [AVX2] -// * VPALIGNR imm8, m256, ymm, ymm [AVX2] -// * VPALIGNR imm8, zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPALIGNR imm8, m512, zmm, zmm{k}{z} [AVX512BW] -// * VPALIGNR imm8, xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPALIGNR imm8, m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPALIGNR imm8, ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPALIGNR imm8, m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPALIGNR(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPALIGNR", 4, Operands { v0, v1, v2, v3 }) - // VPALIGNR imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPALIGNR imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0f) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPALIGNR imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPALIGNR imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0f) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPALIGNR imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPALIGNR imm8, m512, zmm, zmm{k}{z} - if isImm8(v0) && isM512(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x0f) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPALIGNR imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPALIGNR imm8, m128, xmm, xmm{k}{z} - if isImm8(v0) && isM128(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x0f) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPALIGNR imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPALIGNR imm8, m256, ymm, ymm{k}{z} - if isImm8(v0) && isM256(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x0f) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPALIGNR") - } - return p -} - -// VPAND performs "Packed Bitwise Logical AND". -// -// Mnemonic : VPAND -// Supported forms : (4 forms) -// -// * VPAND xmm, xmm, xmm [AVX] -// * VPAND m128, xmm, xmm [AVX] -// * VPAND ymm, ymm, ymm [AVX2] -// * VPAND m256, ymm, ymm [AVX2] -// -func (self *Program) VPAND(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPAND", 3, Operands { v0, v1, v2 }) - // VPAND xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAND m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdb) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPAND ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAND m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdb) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPAND") - } - return p -} - -// VPANDD performs "Bitwise Logical AND of Packed Doubleword Integers". -// -// Mnemonic : VPANDD -// Supported forms : (6 forms) -// -// * VPANDD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPANDD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPANDD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPANDD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPANDD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPANDD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPANDD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPANDD", 3, Operands { v0, v1, v2 }) - // VPANDD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdb) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPANDD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdb) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPANDD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdb) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPANDD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPANDD") - } - return p -} - -// VPANDN performs "Packed Bitwise Logical AND NOT". -// -// Mnemonic : VPANDN -// Supported forms : (4 forms) -// -// * VPANDN xmm, xmm, xmm [AVX] -// * VPANDN m128, xmm, xmm [AVX] -// * VPANDN ymm, ymm, ymm [AVX2] -// * VPANDN m256, ymm, ymm [AVX2] -// -func (self *Program) VPANDN(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPANDN", 3, Operands { v0, v1, v2 }) - // VPANDN xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDN m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPANDN ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDN m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPANDN") - } - return p -} - -// VPANDND performs "Bitwise Logical AND NOT of Packed Doubleword Integers". -// -// Mnemonic : VPANDND -// Supported forms : (6 forms) -// -// * VPANDND m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPANDND zmm, zmm, zmm{k}{z} [AVX512F] -// * VPANDND m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPANDND xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPANDND m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPANDND ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPANDND(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPANDND", 3, Operands { v0, v1, v2 }) - // VPANDND m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPANDND zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDND m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPANDND xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDND m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPANDND ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPANDND") - } - return p -} - -// VPANDNQ performs "Bitwise Logical AND NOT of Packed Quadword Integers". -// -// Mnemonic : VPANDNQ -// Supported forms : (6 forms) -// -// * VPANDNQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPANDNQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPANDNQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPANDNQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPANDNQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPANDNQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPANDNQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPANDNQ", 3, Operands { v0, v1, v2 }) - // VPANDNQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPANDNQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDNQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPANDNQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDNQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdf) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPANDNQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xdf) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPANDNQ") - } - return p -} - -// VPANDQ performs "Bitwise Logical AND of Packed Quadword Integers". -// -// Mnemonic : VPANDQ -// Supported forms : (6 forms) -// -// * VPANDQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPANDQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPANDQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPANDQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPANDQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPANDQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPANDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPANDQ", 3, Operands { v0, v1, v2 }) - // VPANDQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdb) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPANDQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdb) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPANDQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPANDQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xdb) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPANDQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPANDQ") - } - return p -} - -// VPAVGB performs "Average Packed Byte Integers". -// -// Mnemonic : VPAVGB -// Supported forms : (10 forms) -// -// * VPAVGB xmm, xmm, xmm [AVX] -// * VPAVGB m128, xmm, xmm [AVX] -// * VPAVGB ymm, ymm, ymm [AVX2] -// * VPAVGB m256, ymm, ymm [AVX2] -// * VPAVGB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPAVGB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPAVGB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPAVGB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPAVGB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPAVGB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPAVGB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPAVGB", 3, Operands { v0, v1, v2 }) - // VPAVGB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe0) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPAVGB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe0) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPAVGB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xe0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe0) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPAVGB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xe0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe0) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPAVGB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xe0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe0) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPAVGB") - } - return p -} - -// VPAVGW performs "Average Packed Word Integers". -// -// Mnemonic : VPAVGW -// Supported forms : (10 forms) -// -// * VPAVGW xmm, xmm, xmm [AVX] -// * VPAVGW m128, xmm, xmm [AVX] -// * VPAVGW ymm, ymm, ymm [AVX2] -// * VPAVGW m256, ymm, ymm [AVX2] -// * VPAVGW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPAVGW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPAVGW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPAVGW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPAVGW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPAVGW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPAVGW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPAVGW", 3, Operands { v0, v1, v2 }) - // VPAVGW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe3) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPAVGW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe3) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPAVGW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xe3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe3) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPAVGW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xe3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe3) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPAVGW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xe3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPAVGW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe3) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPAVGW") - } - return p -} - -// VPBLENDD performs "Blend Packed Doublewords". -// -// Mnemonic : VPBLENDD -// Supported forms : (4 forms) -// -// * VPBLENDD imm8, xmm, xmm, xmm [AVX2] -// * VPBLENDD imm8, m128, xmm, xmm [AVX2] -// * VPBLENDD imm8, ymm, ymm, ymm [AVX2] -// * VPBLENDD imm8, m256, ymm, ymm [AVX2] -// -func (self *Program) VPBLENDD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPBLENDD", 4, Operands { v0, v1, v2, v3 }) - // VPBLENDD imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x02) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPBLENDD imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x02) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPBLENDD imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x02) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPBLENDD imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x02) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPBLENDD") - } - return p -} - -// VPBLENDMB performs "Blend Byte Vectors Using an OpMask Control". -// -// Mnemonic : VPBLENDMB -// Supported forms : (6 forms) -// -// * VPBLENDMB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPBLENDMB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPBLENDMB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBLENDMB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBLENDMB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPBLENDMB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPBLENDMB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPBLENDMB", 3, Operands { v0, v1, v2 }) - // VPBLENDMB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPBLENDMB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPBLENDMB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPBLENDMB") - } - return p -} - -// VPBLENDMD performs "Blend Doubleword Vectors Using an OpMask Control". -// -// Mnemonic : VPBLENDMD -// Supported forms : (6 forms) -// -// * VPBLENDMD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPBLENDMD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPBLENDMD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBLENDMD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBLENDMD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPBLENDMD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPBLENDMD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPBLENDMD", 3, Operands { v0, v1, v2 }) - // VPBLENDMD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPBLENDMD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPBLENDMD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPBLENDMD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPBLENDMD") - } - return p -} - -// VPBLENDMQ performs "Blend Quadword Vectors Using an OpMask Control". -// -// Mnemonic : VPBLENDMQ -// Supported forms : (6 forms) -// -// * VPBLENDMQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPBLENDMQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPBLENDMQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBLENDMQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBLENDMQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPBLENDMQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPBLENDMQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPBLENDMQ", 3, Operands { v0, v1, v2 }) - // VPBLENDMQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPBLENDMQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPBLENDMQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPBLENDMQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPBLENDMQ") - } - return p -} - -// VPBLENDMW performs "Blend Word Vectors Using an OpMask Control". -// -// Mnemonic : VPBLENDMW -// Supported forms : (6 forms) -// -// * VPBLENDMW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPBLENDMW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPBLENDMW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBLENDMW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBLENDMW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPBLENDMW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPBLENDMW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPBLENDMW", 3, Operands { v0, v1, v2 }) - // VPBLENDMW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPBLENDMW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPBLENDMW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPBLENDMW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPBLENDMW") - } - return p -} - -// VPBLENDVB performs "Variable Blend Packed Bytes". -// -// Mnemonic : VPBLENDVB -// Supported forms : (4 forms) -// -// * VPBLENDVB xmm, xmm, xmm, xmm [AVX] -// * VPBLENDVB xmm, m128, xmm, xmm [AVX] -// * VPBLENDVB ymm, ymm, ymm, ymm [AVX2] -// * VPBLENDVB ymm, m256, ymm, ymm [AVX2] -// -func (self *Program) VPBLENDVB(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPBLENDVB", 4, Operands { v0, v1, v2, v3 }) - // VPBLENDVB xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPBLENDVB xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x4c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPBLENDVB ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPBLENDVB ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x4c) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPBLENDVB") - } - return p -} - -// VPBLENDW performs "Blend Packed Words". -// -// Mnemonic : VPBLENDW -// Supported forms : (4 forms) -// -// * VPBLENDW imm8, xmm, xmm, xmm [AVX] -// * VPBLENDW imm8, m128, xmm, xmm [AVX] -// * VPBLENDW imm8, ymm, ymm, ymm [AVX2] -// * VPBLENDW imm8, m256, ymm, ymm [AVX2] -// -func (self *Program) VPBLENDW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPBLENDW", 4, Operands { v0, v1, v2, v3 }) - // VPBLENDW imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x0e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPBLENDW imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0e) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPBLENDW imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x0e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPBLENDW imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0e) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPBLENDW") - } - return p -} - -// VPBROADCASTB performs "Broadcast Byte Integer". -// -// Mnemonic : VPBROADCASTB -// Supported forms : (13 forms) -// -// * VPBROADCASTB xmm, xmm [AVX2] -// * VPBROADCASTB m8, xmm [AVX2] -// * VPBROADCASTB xmm, ymm [AVX2] -// * VPBROADCASTB m8, ymm [AVX2] -// * VPBROADCASTB r32, zmm{k}{z} [AVX512BW] -// * VPBROADCASTB xmm, zmm{k}{z} [AVX512BW] -// * VPBROADCASTB m8, zmm{k}{z} [AVX512BW] -// * VPBROADCASTB r32, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTB r32, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTB xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTB xmm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTB m8, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTB m8, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPBROADCASTB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPBROADCASTB", 2, Operands { v0, v1 }) - // VPBROADCASTB xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTB m8, xmm - if isM8(v0) && isXMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTB xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTB m8, ymm - if isM8(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTB r32, zmm{k}{z} - if isReg32(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTB xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTB m8, zmm{k}{z} - if isM8(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTB r32, xmm{k}{z} - if isReg32(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTB r32, ymm{k}{z} - if isReg32(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTB xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x78) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTB m8, xmm{k}{z} - if isM8(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTB m8, ymm{k}{z} - if isM8(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x78) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPBROADCASTB") - } - return p -} - -// VPBROADCASTD performs "Broadcast Doubleword Integer". -// -// Mnemonic : VPBROADCASTD -// Supported forms : (13 forms) -// -// * VPBROADCASTD xmm, xmm [AVX2] -// * VPBROADCASTD m32, xmm [AVX2] -// * VPBROADCASTD xmm, ymm [AVX2] -// * VPBROADCASTD m32, ymm [AVX2] -// * VPBROADCASTD r32, zmm{k}{z} [AVX512F] -// * VPBROADCASTD xmm, zmm{k}{z} [AVX512F] -// * VPBROADCASTD m32, zmm{k}{z} [AVX512F] -// * VPBROADCASTD r32, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTD r32, ymm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTD xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTD m32, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTD m32, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPBROADCASTD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPBROADCASTD", 2, Operands { v0, v1 }) - // VPBROADCASTD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x58) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTD m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x58) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTD xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x58) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTD m32, ymm - if isM32(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x58) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTD r32, zmm{k}{z} - if isReg32(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTD xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x58) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTD m32, zmm{k}{z} - if isM32(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x58) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPBROADCASTD r32, xmm{k}{z} - if isReg32(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTD r32, ymm{k}{z} - if isReg32(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x58) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTD xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x58) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTD m32, xmm{k}{z} - if isM32(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x58) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPBROADCASTD m32, ymm{k}{z} - if isM32(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x58) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPBROADCASTD") - } - return p -} - -// VPBROADCASTMB2Q performs "Broadcast Low Byte of Mask Register to Packed Quadword Values". -// -// Mnemonic : VPBROADCASTMB2Q -// Supported forms : (3 forms) -// -// * VPBROADCASTMB2Q k, xmm [AVX512CD,AVX512VL] -// * VPBROADCASTMB2Q k, ymm [AVX512CD,AVX512VL] -// * VPBROADCASTMB2Q k, zmm [AVX512CD] -// -func (self *Program) VPBROADCASTMB2Q(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPBROADCASTMB2Q", 2, Operands { v0, v1 }) - // VPBROADCASTMB2Q k, xmm - if isK(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x08) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTMB2Q k, ymm - if isK(v0) && isEVEXYMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x28) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTMB2Q k, zmm - if isK(v0) && isZMM(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x48) - m.emit(0x2a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPBROADCASTMB2Q") - } - return p -} - -// VPBROADCASTMW2D performs "Broadcast Low Word of Mask Register to Packed Doubleword Values". -// -// Mnemonic : VPBROADCASTMW2D -// Supported forms : (3 forms) -// -// * VPBROADCASTMW2D k, xmm [AVX512CD,AVX512VL] -// * VPBROADCASTMW2D k, ymm [AVX512CD,AVX512VL] -// * VPBROADCASTMW2D k, zmm [AVX512CD] -// -func (self *Program) VPBROADCASTMW2D(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPBROADCASTMW2D", 2, Operands { v0, v1 }) - // VPBROADCASTMW2D k, xmm - if isK(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x08) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTMW2D k, ymm - if isK(v0) && isEVEXYMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x28) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTMW2D k, zmm - if isK(v0) && isZMM(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x48) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPBROADCASTMW2D") - } - return p -} - -// VPBROADCASTQ performs "Broadcast Quadword Integer". -// -// Mnemonic : VPBROADCASTQ -// Supported forms : (13 forms) -// -// * VPBROADCASTQ xmm, xmm [AVX2] -// * VPBROADCASTQ m64, xmm [AVX2] -// * VPBROADCASTQ xmm, ymm [AVX2] -// * VPBROADCASTQ m64, ymm [AVX2] -// * VPBROADCASTQ r64, zmm{k}{z} [AVX512F] -// * VPBROADCASTQ xmm, zmm{k}{z} [AVX512F] -// * VPBROADCASTQ m64, zmm{k}{z} [AVX512F] -// * VPBROADCASTQ r64, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTQ r64, ymm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTQ xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTQ m64, xmm{k}{z} [AVX512F,AVX512VL] -// * VPBROADCASTQ m64, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPBROADCASTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPBROADCASTQ", 2, Operands { v0, v1 }) - // VPBROADCASTQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTQ m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTQ xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTQ m64, ymm - if isM64(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTQ r64, zmm{k}{z} - if isReg64(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTQ xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTQ m64, zmm{k}{z} - if isM64(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPBROADCASTQ r64, xmm{k}{z} - if isReg64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTQ r64, ymm{k}{z} - if isReg64(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTQ xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x59) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTQ m64, xmm{k}{z} - if isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPBROADCASTQ m64, ymm{k}{z} - if isM64(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x59) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPBROADCASTQ") - } - return p -} - -// VPBROADCASTW performs "Broadcast Word Integer". -// -// Mnemonic : VPBROADCASTW -// Supported forms : (13 forms) -// -// * VPBROADCASTW xmm, xmm [AVX2] -// * VPBROADCASTW m16, xmm [AVX2] -// * VPBROADCASTW xmm, ymm [AVX2] -// * VPBROADCASTW m16, ymm [AVX2] -// * VPBROADCASTW r32, zmm{k}{z} [AVX512BW] -// * VPBROADCASTW xmm, zmm{k}{z} [AVX512BW] -// * VPBROADCASTW m16, zmm{k}{z} [AVX512BW] -// * VPBROADCASTW r32, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTW r32, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTW xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTW xmm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTW m16, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPBROADCASTW m16, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPBROADCASTW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPBROADCASTW", 2, Operands { v0, v1 }) - // VPBROADCASTW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTW m16, xmm - if isM16(v0) && isXMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTW xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTW m16, ymm - if isM16(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPBROADCASTW r32, zmm{k}{z} - if isReg32(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTW xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTW m16, zmm{k}{z} - if isM16(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 2) - }) - } - // VPBROADCASTW r32, xmm{k}{z} - if isReg32(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTW r32, ymm{k}{z} - if isReg32(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x7b) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTW xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x79) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPBROADCASTW m16, xmm{k}{z} - if isM16(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 2) - }) - } - // VPBROADCASTW m16, ymm{k}{z} - if isM16(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x79) - m.mrsd(lcode(v[1]), addr(v[0]), 2) - }) - } - if p.len == 0 { - panic("invalid operands for VPBROADCASTW") - } - return p -} - -// VPCLMULQDQ performs "Carry-Less Quadword Multiplication". -// -// Mnemonic : VPCLMULQDQ -// Supported forms : (2 forms) -// -// * VPCLMULQDQ imm8, xmm, xmm, xmm [AVX,PCLMULQDQ] -// * VPCLMULQDQ imm8, m128, xmm, xmm [AVX,PCLMULQDQ] -// -func (self *Program) VPCLMULQDQ(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCLMULQDQ", 4, Operands { v0, v1, v2, v3 }) - // VPCLMULQDQ imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX | ISA_PCLMULQDQ) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x44) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCLMULQDQ imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX | ISA_PCLMULQDQ) - p.domain = DomainCrypto - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x44) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCLMULQDQ") - } - return p -} - -// VPCMOV performs "Packed Conditional Move". -// -// Mnemonic : VPCMOV -// Supported forms : (6 forms) -// -// * VPCMOV xmm, xmm, xmm, xmm [XOP] -// * VPCMOV m128, xmm, xmm, xmm [XOP] -// * VPCMOV xmm, m128, xmm, xmm [XOP] -// * VPCMOV ymm, ymm, ymm, ymm [XOP] -// * VPCMOV m256, ymm, ymm, ymm [XOP] -// * VPCMOV ymm, m256, ymm, ymm [XOP] -// -func (self *Program) VPCMOV(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCMOV", 4, Operands { v0, v1, v2, v3 }) - // VPCMOV xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xa2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[2]) << 3)) - m.emit(0xa2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - } - // VPCMOV m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x80, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0xa2) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VPCMOV xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xa2) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPCMOV ymm, ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit(0xa2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfc ^ (hlcode(v[2]) << 3)) - m.emit(0xa2) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - } - // VPCMOV m256, ymm, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x84, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0xa2) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VPCMOV ymm, m256, ymm, ymm - if isYMM(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x04, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xa2) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMOV") - } - return p -} - -// VPCMPB performs "Compare Packed Signed Byte Values". -// -// Mnemonic : VPCMPB -// Supported forms : (6 forms) -// -// * VPCMPB imm8, zmm, zmm, k{k} [AVX512BW] -// * VPCMPB imm8, m512, zmm, k{k} [AVX512BW] -// * VPCMPB imm8, xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPB imm8, m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPB imm8, ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPCMPB imm8, m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPCMPB(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCMPB", 4, Operands { v0, v1, v2, v3 }) - // VPCMPB imm8, zmm, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPB imm8, m512, zmm, k{k} - if isImm8(v0) && isM512(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3f) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPB imm8, xmm, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPB imm8, m128, xmm, k{k} - if isImm8(v0) && isM128(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3f) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPB imm8, ymm, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPB imm8, m256, ymm, k{k} - if isImm8(v0) && isM256(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3f) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPB") - } - return p -} - -// VPCMPD performs "Compare Packed Signed Doubleword Values". -// -// Mnemonic : VPCMPD -// Supported forms : (6 forms) -// -// * VPCMPD imm8, m512/m32bcst, zmm, k{k} [AVX512F] -// * VPCMPD imm8, zmm, zmm, k{k} [AVX512F] -// * VPCMPD imm8, m128/m32bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPD imm8, xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPD imm8, m256/m32bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPCMPD imm8, ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPCMPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCMPD", 4, Operands { v0, v1, v2, v3 }) - // VPCMPD imm8, m512/m32bcst, zmm, k{k} - if isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1f) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPD imm8, zmm, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x1f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPD imm8, m128/m32bcst, xmm, k{k} - if isImm8(v0) && isM128M32bcst(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1f) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPD imm8, xmm, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x1f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPD imm8, m256/m32bcst, ymm, k{k} - if isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1f) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPD imm8, ymm, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x1f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPD") - } - return p -} - -// VPCMPEQB performs "Compare Packed Byte Data for Equality". -// -// Mnemonic : VPCMPEQB -// Supported forms : (10 forms) -// -// * VPCMPEQB xmm, xmm, xmm [AVX] -// * VPCMPEQB m128, xmm, xmm [AVX] -// * VPCMPEQB ymm, ymm, ymm [AVX2] -// * VPCMPEQB m256, ymm, ymm [AVX2] -// * VPCMPEQB zmm, zmm, k{k} [AVX512BW] -// * VPCMPEQB m512, zmm, k{k} [AVX512BW] -// * VPCMPEQB xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPEQB m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPEQB ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPCMPEQB m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPCMPEQB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPEQB", 3, Operands { v0, v1, v2 }) - // VPCMPEQB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x74) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x74) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPEQB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x74) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x74) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPEQB zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x74) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQB m512, zmm, k{k} - if isM512(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x74) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPCMPEQB xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x74) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQB m128, xmm, k{k} - if isM128(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x74) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPCMPEQB ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x74) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQB m256, ymm, k{k} - if isM256(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x74) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPEQB") - } - return p -} - -// VPCMPEQD performs "Compare Packed Doubleword Data for Equality". -// -// Mnemonic : VPCMPEQD -// Supported forms : (10 forms) -// -// * VPCMPEQD xmm, xmm, xmm [AVX] -// * VPCMPEQD m128, xmm, xmm [AVX] -// * VPCMPEQD ymm, ymm, ymm [AVX2] -// * VPCMPEQD m256, ymm, ymm [AVX2] -// * VPCMPEQD m512/m32bcst, zmm, k{k} [AVX512F] -// * VPCMPEQD zmm, zmm, k{k} [AVX512F] -// * VPCMPEQD m128/m32bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPEQD xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPEQD m256/m32bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPCMPEQD ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPCMPEQD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPEQD", 3, Operands { v0, v1, v2 }) - // VPCMPEQD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPEQD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPEQD m512/m32bcst, zmm, k{k} - if isM512M32bcst(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPCMPEQD zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQD m128/m32bcst, xmm, k{k} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPCMPEQD xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQD m256/m32bcst, ymm, k{k} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPCMPEQD ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPEQD") - } - return p -} - -// VPCMPEQQ performs "Compare Packed Quadword Data for Equality". -// -// Mnemonic : VPCMPEQQ -// Supported forms : (10 forms) -// -// * VPCMPEQQ xmm, xmm, xmm [AVX] -// * VPCMPEQQ m128, xmm, xmm [AVX] -// * VPCMPEQQ ymm, ymm, ymm [AVX2] -// * VPCMPEQQ m256, ymm, ymm [AVX2] -// * VPCMPEQQ m512/m64bcst, zmm, k{k} [AVX512F] -// * VPCMPEQQ zmm, zmm, k{k} [AVX512F] -// * VPCMPEQQ m128/m64bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPEQQ xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPEQQ m256/m64bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPCMPEQQ ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPCMPEQQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPEQQ", 3, Operands { v0, v1, v2 }) - // VPCMPEQQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x29) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x29) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPEQQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x29) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x29) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPEQQ m512/m64bcst, zmm, k{k} - if isM512M64bcst(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x29) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPCMPEQQ zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x29) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQQ m128/m64bcst, xmm, k{k} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x29) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPCMPEQQ xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x29) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQQ m256/m64bcst, ymm, k{k} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x29) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPCMPEQQ ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x29) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPEQQ") - } - return p -} - -// VPCMPEQW performs "Compare Packed Word Data for Equality". -// -// Mnemonic : VPCMPEQW -// Supported forms : (10 forms) -// -// * VPCMPEQW xmm, xmm, xmm [AVX] -// * VPCMPEQW m128, xmm, xmm [AVX] -// * VPCMPEQW ymm, ymm, ymm [AVX2] -// * VPCMPEQW m256, ymm, ymm [AVX2] -// * VPCMPEQW zmm, zmm, k{k} [AVX512BW] -// * VPCMPEQW m512, zmm, k{k} [AVX512BW] -// * VPCMPEQW xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPEQW m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPEQW ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPCMPEQW m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPCMPEQW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPEQW", 3, Operands { v0, v1, v2 }) - // VPCMPEQW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPEQW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPEQW zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQW m512, zmm, k{k} - if isM512(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPCMPEQW xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQW m128, xmm, k{k} - if isM128(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPCMPEQW ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPEQW m256, ymm, k{k} - if isM256(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPEQW") - } - return p -} - -// VPCMPESTRI performs "Packed Compare Explicit Length Strings, Return Index". -// -// Mnemonic : VPCMPESTRI -// Supported forms : (2 forms) -// -// * VPCMPESTRI imm8, xmm, xmm [AVX] -// * VPCMPESTRI imm8, m128, xmm [AVX] -// -func (self *Program) VPCMPESTRI(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPESTRI", 3, Operands { v0, v1, v2 }) - // VPCMPESTRI imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79) - m.emit(0x61) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPESTRI imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[2]), addr(v[1]), 0) - m.emit(0x61) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPESTRI") - } - return p -} - -// VPCMPESTRM performs "Packed Compare Explicit Length Strings, Return Mask". -// -// Mnemonic : VPCMPESTRM -// Supported forms : (2 forms) -// -// * VPCMPESTRM imm8, xmm, xmm [AVX] -// * VPCMPESTRM imm8, m128, xmm [AVX] -// -func (self *Program) VPCMPESTRM(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPESTRM", 3, Operands { v0, v1, v2 }) - // VPCMPESTRM imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79) - m.emit(0x60) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPESTRM imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[2]), addr(v[1]), 0) - m.emit(0x60) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPESTRM") - } - return p -} - -// VPCMPGTB performs "Compare Packed Signed Byte Integers for Greater Than". -// -// Mnemonic : VPCMPGTB -// Supported forms : (10 forms) -// -// * VPCMPGTB xmm, xmm, xmm [AVX] -// * VPCMPGTB m128, xmm, xmm [AVX] -// * VPCMPGTB ymm, ymm, ymm [AVX2] -// * VPCMPGTB m256, ymm, ymm [AVX2] -// * VPCMPGTB zmm, zmm, k{k} [AVX512BW] -// * VPCMPGTB m512, zmm, k{k} [AVX512BW] -// * VPCMPGTB xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPGTB m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPGTB ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPCMPGTB m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPCMPGTB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPGTB", 3, Operands { v0, v1, v2 }) - // VPCMPGTB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPGTB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPGTB zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTB m512, zmm, k{k} - if isM512(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPCMPGTB xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTB m128, xmm, k{k} - if isM128(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPCMPGTB ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x64) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTB m256, ymm, k{k} - if isM256(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x64) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPGTB") - } - return p -} - -// VPCMPGTD performs "Compare Packed Signed Doubleword Integers for Greater Than". -// -// Mnemonic : VPCMPGTD -// Supported forms : (10 forms) -// -// * VPCMPGTD xmm, xmm, xmm [AVX] -// * VPCMPGTD m128, xmm, xmm [AVX] -// * VPCMPGTD ymm, ymm, ymm [AVX2] -// * VPCMPGTD m256, ymm, ymm [AVX2] -// * VPCMPGTD m512/m32bcst, zmm, k{k} [AVX512F] -// * VPCMPGTD zmm, zmm, k{k} [AVX512F] -// * VPCMPGTD m128/m32bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPGTD xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPGTD m256/m32bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPCMPGTD ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPCMPGTD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPGTD", 3, Operands { v0, v1, v2 }) - // VPCMPGTD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPGTD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPGTD m512/m32bcst, zmm, k{k} - if isM512M32bcst(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPCMPGTD zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTD m128/m32bcst, xmm, k{k} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPCMPGTD xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTD m256/m32bcst, ymm, k{k} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x66) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPCMPGTD ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x66) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPGTD") - } - return p -} - -// VPCMPGTQ performs "Compare Packed Data for Greater Than". -// -// Mnemonic : VPCMPGTQ -// Supported forms : (10 forms) -// -// * VPCMPGTQ xmm, xmm, xmm [AVX] -// * VPCMPGTQ m128, xmm, xmm [AVX] -// * VPCMPGTQ ymm, ymm, ymm [AVX2] -// * VPCMPGTQ m256, ymm, ymm [AVX2] -// * VPCMPGTQ m512/m64bcst, zmm, k{k} [AVX512F] -// * VPCMPGTQ zmm, zmm, k{k} [AVX512F] -// * VPCMPGTQ m128/m64bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPGTQ xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPGTQ m256/m64bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPCMPGTQ ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPCMPGTQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPGTQ", 3, Operands { v0, v1, v2 }) - // VPCMPGTQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x37) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x37) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPGTQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x37) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x37) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPGTQ m512/m64bcst, zmm, k{k} - if isM512M64bcst(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x37) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPCMPGTQ zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x37) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTQ m128/m64bcst, xmm, k{k} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x37) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPCMPGTQ xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x37) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTQ m256/m64bcst, ymm, k{k} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x37) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPCMPGTQ ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x37) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPGTQ") - } - return p -} - -// VPCMPGTW performs "Compare Packed Signed Word Integers for Greater Than". -// -// Mnemonic : VPCMPGTW -// Supported forms : (10 forms) -// -// * VPCMPGTW xmm, xmm, xmm [AVX] -// * VPCMPGTW m128, xmm, xmm [AVX] -// * VPCMPGTW ymm, ymm, ymm [AVX2] -// * VPCMPGTW m256, ymm, ymm [AVX2] -// * VPCMPGTW zmm, zmm, k{k} [AVX512BW] -// * VPCMPGTW m512, zmm, k{k} [AVX512BW] -// * VPCMPGTW xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPGTW m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPGTW ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPCMPGTW m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPCMPGTW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPGTW", 3, Operands { v0, v1, v2 }) - // VPCMPGTW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPGTW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPCMPGTW zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTW m512, zmm, k{k} - if isM512(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPCMPGTW xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTW m128, xmm, k{k} - if isM128(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPCMPGTW ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x65) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPCMPGTW m256, ymm, k{k} - if isM256(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x65) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPGTW") - } - return p -} - -// VPCMPISTRI performs "Packed Compare Implicit Length Strings, Return Index". -// -// Mnemonic : VPCMPISTRI -// Supported forms : (2 forms) -// -// * VPCMPISTRI imm8, xmm, xmm [AVX] -// * VPCMPISTRI imm8, m128, xmm [AVX] -// -func (self *Program) VPCMPISTRI(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPISTRI", 3, Operands { v0, v1, v2 }) - // VPCMPISTRI imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79) - m.emit(0x63) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPISTRI imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[2]), addr(v[1]), 0) - m.emit(0x63) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPISTRI") - } - return p -} - -// VPCMPISTRM performs "Packed Compare Implicit Length Strings, Return Mask". -// -// Mnemonic : VPCMPISTRM -// Supported forms : (2 forms) -// -// * VPCMPISTRM imm8, xmm, xmm [AVX] -// * VPCMPISTRM imm8, m128, xmm [AVX] -// -func (self *Program) VPCMPISTRM(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPCMPISTRM", 3, Operands { v0, v1, v2 }) - // VPCMPISTRM imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79) - m.emit(0x62) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPISTRM imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[2]), addr(v[1]), 0) - m.emit(0x62) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPISTRM") - } - return p -} - -// VPCMPQ performs "Compare Packed Signed Quadword Values". -// -// Mnemonic : VPCMPQ -// Supported forms : (6 forms) -// -// * VPCMPQ imm8, m512/m64bcst, zmm, k{k} [AVX512F] -// * VPCMPQ imm8, zmm, zmm, k{k} [AVX512F] -// * VPCMPQ imm8, m128/m64bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPQ imm8, xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPQ imm8, m256/m64bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPCMPQ imm8, ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPCMPQ(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCMPQ", 4, Operands { v0, v1, v2, v3 }) - // VPCMPQ imm8, m512/m64bcst, zmm, k{k} - if isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1f) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPQ imm8, zmm, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x1f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPQ imm8, m128/m64bcst, xmm, k{k} - if isImm8(v0) && isM128M64bcst(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1f) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPQ imm8, xmm, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x1f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPQ imm8, m256/m64bcst, ymm, k{k} - if isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1f) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPQ imm8, ymm, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x1f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPQ") - } - return p -} - -// VPCMPUB performs "Compare Packed Unsigned Byte Values". -// -// Mnemonic : VPCMPUB -// Supported forms : (6 forms) -// -// * VPCMPUB imm8, zmm, zmm, k{k} [AVX512BW] -// * VPCMPUB imm8, m512, zmm, k{k} [AVX512BW] -// * VPCMPUB imm8, xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPUB imm8, m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPUB imm8, ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPCMPUB imm8, m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPCMPUB(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCMPUB", 4, Operands { v0, v1, v2, v3 }) - // VPCMPUB imm8, zmm, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUB imm8, m512, zmm, k{k} - if isImm8(v0) && isM512(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3e) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUB imm8, xmm, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUB imm8, m128, xmm, k{k} - if isImm8(v0) && isM128(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3e) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUB imm8, ymm, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUB imm8, m256, ymm, k{k} - if isImm8(v0) && isM256(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3e) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPUB") - } - return p -} - -// VPCMPUD performs "Compare Packed Unsigned Doubleword Values". -// -// Mnemonic : VPCMPUD -// Supported forms : (6 forms) -// -// * VPCMPUD imm8, m512/m32bcst, zmm, k{k} [AVX512F] -// * VPCMPUD imm8, zmm, zmm, k{k} [AVX512F] -// * VPCMPUD imm8, m128/m32bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPUD imm8, xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPUD imm8, m256/m32bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPCMPUD imm8, ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPCMPUD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCMPUD", 4, Operands { v0, v1, v2, v3 }) - // VPCMPUD imm8, m512/m32bcst, zmm, k{k} - if isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1e) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUD imm8, zmm, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUD imm8, m128/m32bcst, xmm, k{k} - if isImm8(v0) && isM128M32bcst(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1e) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUD imm8, xmm, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUD imm8, m256/m32bcst, ymm, k{k} - if isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1e) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUD imm8, ymm, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPUD") - } - return p -} - -// VPCMPUQ performs "Compare Packed Unsigned Quadword Values". -// -// Mnemonic : VPCMPUQ -// Supported forms : (6 forms) -// -// * VPCMPUQ imm8, m512/m64bcst, zmm, k{k} [AVX512F] -// * VPCMPUQ imm8, zmm, zmm, k{k} [AVX512F] -// * VPCMPUQ imm8, m128/m64bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPUQ imm8, xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPCMPUQ imm8, m256/m64bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPCMPUQ imm8, ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPCMPUQ(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCMPUQ", 4, Operands { v0, v1, v2, v3 }) - // VPCMPUQ imm8, m512/m64bcst, zmm, k{k} - if isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1e) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUQ imm8, zmm, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUQ imm8, m128/m64bcst, xmm, k{k} - if isImm8(v0) && isM128M64bcst(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1e) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUQ imm8, xmm, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUQ imm8, m256/m64bcst, ymm, k{k} - if isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, bcode(v[1])) - m.emit(0x1e) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUQ imm8, ymm, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x1e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPUQ") - } - return p -} - -// VPCMPUW performs "Compare Packed Unsigned Word Values". -// -// Mnemonic : VPCMPUW -// Supported forms : (6 forms) -// -// * VPCMPUW imm8, zmm, zmm, k{k} [AVX512BW] -// * VPCMPUW imm8, m512, zmm, k{k} [AVX512BW] -// * VPCMPUW imm8, xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPUW imm8, m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPUW imm8, ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPCMPUW imm8, m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPCMPUW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCMPUW", 4, Operands { v0, v1, v2, v3 }) - // VPCMPUW imm8, zmm, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUW imm8, m512, zmm, k{k} - if isImm8(v0) && isM512(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3e) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUW imm8, xmm, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUW imm8, m128, xmm, k{k} - if isImm8(v0) && isM128(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3e) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUW imm8, ymm, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPUW imm8, m256, ymm, k{k} - if isImm8(v0) && isM256(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3e) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPUW") - } - return p -} - -// VPCMPW performs "Compare Packed Signed Word Values". -// -// Mnemonic : VPCMPW -// Supported forms : (6 forms) -// -// * VPCMPW imm8, zmm, zmm, k{k} [AVX512BW] -// * VPCMPW imm8, m512, zmm, k{k} [AVX512BW] -// * VPCMPW imm8, xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPW imm8, m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPCMPW imm8, ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPCMPW imm8, m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPCMPW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCMPW", 4, Operands { v0, v1, v2, v3 }) - // VPCMPW imm8, zmm, zmm, k{k} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPW imm8, m512, zmm, k{k} - if isImm8(v0) && isM512(v1) && isZMM(v2) && isKk(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3f) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPW imm8, xmm, xmm, k{k} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPW imm8, m128, xmm, k{k} - if isImm8(v0) && isM128(v1) && isEVEXXMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3f) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPW imm8, ymm, ymm, k{k} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCMPW imm8, m256, ymm, k{k} - if isImm8(v0) && isM256(v1) && isEVEXYMM(v2) && isKk(v3) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), 0, 0) - m.emit(0x3f) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCMPW") - } - return p -} - -// VPCOMB performs "Compare Packed Signed Byte Integers". -// -// Mnemonic : VPCOMB -// Supported forms : (2 forms) -// -// * VPCOMB imm8, xmm, xmm, xmm [XOP] -// * VPCOMB imm8, m128, xmm, xmm [XOP] -// -func (self *Program) VPCOMB(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCOMB", 4, Operands { v0, v1, v2, v3 }) - // VPCOMB imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xcc) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCOMB imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xcc) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMB") - } - return p -} - -// VPCOMD performs "Compare Packed Signed Doubleword Integers". -// -// Mnemonic : VPCOMD -// Supported forms : (2 forms) -// -// * VPCOMD imm8, xmm, xmm, xmm [XOP] -// * VPCOMD imm8, m128, xmm, xmm [XOP] -// -func (self *Program) VPCOMD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCOMD", 4, Operands { v0, v1, v2, v3 }) - // VPCOMD imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xce) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCOMD imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xce) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMD") - } - return p -} - -// VPCOMPRESSD performs "Store Sparse Packed Doubleword Integer Values into Dense Memory/Register". -// -// Mnemonic : VPCOMPRESSD -// Supported forms : (6 forms) -// -// * VPCOMPRESSD zmm, zmm{k}{z} [AVX512F] -// * VPCOMPRESSD zmm, m512{k}{z} [AVX512F] -// * VPCOMPRESSD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPCOMPRESSD xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VPCOMPRESSD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPCOMPRESSD ymm, m256{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPCOMPRESSD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPCOMPRESSD", 2, Operands { v0, v1 }) - // VPCOMPRESSD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x8b) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPCOMPRESSD zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8b) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPCOMPRESSD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x8b) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPCOMPRESSD xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8b) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPCOMPRESSD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x8b) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPCOMPRESSD ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8b) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMPRESSD") - } - return p -} - -// VPCOMPRESSQ performs "Store Sparse Packed Quadword Integer Values into Dense Memory/Register". -// -// Mnemonic : VPCOMPRESSQ -// Supported forms : (6 forms) -// -// * VPCOMPRESSQ zmm, zmm{k}{z} [AVX512F] -// * VPCOMPRESSQ zmm, m512{k}{z} [AVX512F] -// * VPCOMPRESSQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPCOMPRESSQ xmm, m128{k}{z} [AVX512F,AVX512VL] -// * VPCOMPRESSQ ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPCOMPRESSQ ymm, m256{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPCOMPRESSQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPCOMPRESSQ", 2, Operands { v0, v1 }) - // VPCOMPRESSQ zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x8b) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPCOMPRESSQ zmm, m512{k}{z} - if isZMM(v0) && isM512kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8b) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPCOMPRESSQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x8b) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPCOMPRESSQ xmm, m128{k}{z} - if isEVEXXMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8b) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPCOMPRESSQ ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x8b) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPCOMPRESSQ ymm, m256{k}{z} - if isEVEXYMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x8b) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMPRESSQ") - } - return p -} - -// VPCOMQ performs "Compare Packed Signed Quadword Integers". -// -// Mnemonic : VPCOMQ -// Supported forms : (2 forms) -// -// * VPCOMQ imm8, xmm, xmm, xmm [XOP] -// * VPCOMQ imm8, m128, xmm, xmm [XOP] -// -func (self *Program) VPCOMQ(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCOMQ", 4, Operands { v0, v1, v2, v3 }) - // VPCOMQ imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xcf) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCOMQ imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xcf) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMQ") - } - return p -} - -// VPCOMUB performs "Compare Packed Unsigned Byte Integers". -// -// Mnemonic : VPCOMUB -// Supported forms : (2 forms) -// -// * VPCOMUB imm8, xmm, xmm, xmm [XOP] -// * VPCOMUB imm8, m128, xmm, xmm [XOP] -// -func (self *Program) VPCOMUB(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCOMUB", 4, Operands { v0, v1, v2, v3 }) - // VPCOMUB imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xec) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCOMUB imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xec) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMUB") - } - return p -} - -// VPCOMUD performs "Compare Packed Unsigned Doubleword Integers". -// -// Mnemonic : VPCOMUD -// Supported forms : (2 forms) -// -// * VPCOMUD imm8, xmm, xmm, xmm [XOP] -// * VPCOMUD imm8, m128, xmm, xmm [XOP] -// -func (self *Program) VPCOMUD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCOMUD", 4, Operands { v0, v1, v2, v3 }) - // VPCOMUD imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xee) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCOMUD imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xee) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMUD") - } - return p -} - -// VPCOMUQ performs "Compare Packed Unsigned Quadword Integers". -// -// Mnemonic : VPCOMUQ -// Supported forms : (2 forms) -// -// * VPCOMUQ imm8, xmm, xmm, xmm [XOP] -// * VPCOMUQ imm8, m128, xmm, xmm [XOP] -// -func (self *Program) VPCOMUQ(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCOMUQ", 4, Operands { v0, v1, v2, v3 }) - // VPCOMUQ imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xef) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCOMUQ imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xef) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMUQ") - } - return p -} - -// VPCOMUW performs "Compare Packed Unsigned Word Integers". -// -// Mnemonic : VPCOMUW -// Supported forms : (2 forms) -// -// * VPCOMUW imm8, xmm, xmm, xmm [XOP] -// * VPCOMUW imm8, m128, xmm, xmm [XOP] -// -func (self *Program) VPCOMUW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCOMUW", 4, Operands { v0, v1, v2, v3 }) - // VPCOMUW imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xed) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCOMUW imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xed) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMUW") - } - return p -} - -// VPCOMW performs "Compare Packed Signed Word Integers". -// -// Mnemonic : VPCOMW -// Supported forms : (2 forms) -// -// * VPCOMW imm8, xmm, xmm, xmm [XOP] -// * VPCOMW imm8, m128, xmm, xmm [XOP] -// -func (self *Program) VPCOMW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPCOMW", 4, Operands { v0, v1, v2, v3 }) - // VPCOMW imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xcd) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPCOMW imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xcd) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCOMW") - } - return p -} - -// VPCONFLICTD performs "Detect Conflicts Within a Vector of Packed Doubleword Values into Dense Memory/Register". -// -// Mnemonic : VPCONFLICTD -// Supported forms : (6 forms) -// -// * VPCONFLICTD m128/m32bcst, xmm{k}{z} [AVX512CD,AVX512VL] -// * VPCONFLICTD m256/m32bcst, ymm{k}{z} [AVX512CD,AVX512VL] -// * VPCONFLICTD m512/m32bcst, zmm{k}{z} [AVX512CD] -// * VPCONFLICTD xmm, xmm{k}{z} [AVX512CD,AVX512VL] -// * VPCONFLICTD ymm, ymm{k}{z} [AVX512CD,AVX512VL] -// * VPCONFLICTD zmm, zmm{k}{z} [AVX512CD] -// -func (self *Program) VPCONFLICTD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPCONFLICTD", 2, Operands { v0, v1 }) - // VPCONFLICTD m128/m32bcst, xmm{k}{z} - if isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xc4) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPCONFLICTD m256/m32bcst, ymm{k}{z} - if isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xc4) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPCONFLICTD m512/m32bcst, zmm{k}{z} - if isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xc4) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPCONFLICTD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPCONFLICTD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPCONFLICTD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCONFLICTD") - } - return p -} - -// VPCONFLICTQ performs "Detect Conflicts Within a Vector of Packed Quadword Values into Dense Memory/Register". -// -// Mnemonic : VPCONFLICTQ -// Supported forms : (6 forms) -// -// * VPCONFLICTQ m128/m64bcst, xmm{k}{z} [AVX512CD,AVX512VL] -// * VPCONFLICTQ m256/m64bcst, ymm{k}{z} [AVX512CD,AVX512VL] -// * VPCONFLICTQ m512/m64bcst, zmm{k}{z} [AVX512CD] -// * VPCONFLICTQ xmm, xmm{k}{z} [AVX512CD,AVX512VL] -// * VPCONFLICTQ ymm, ymm{k}{z} [AVX512CD,AVX512VL] -// * VPCONFLICTQ zmm, zmm{k}{z} [AVX512CD] -// -func (self *Program) VPCONFLICTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPCONFLICTQ", 2, Operands { v0, v1 }) - // VPCONFLICTQ m128/m64bcst, xmm{k}{z} - if isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xc4) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPCONFLICTQ m256/m64bcst, ymm{k}{z} - if isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xc4) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPCONFLICTQ m512/m64bcst, zmm{k}{z} - if isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xc4) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPCONFLICTQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPCONFLICTQ ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPCONFLICTQ zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPCONFLICTQ") - } - return p -} - -// VPERM2F128 performs "Permute Floating-Point Values". -// -// Mnemonic : VPERM2F128 -// Supported forms : (2 forms) -// -// * VPERM2F128 imm8, ymm, ymm, ymm [AVX] -// * VPERM2F128 imm8, m256, ymm, ymm [AVX] -// -func (self *Program) VPERM2F128(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPERM2F128", 4, Operands { v0, v1, v2, v3 }) - // VPERM2F128 imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x06) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERM2F128 imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x06) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERM2F128") - } - return p -} - -// VPERM2I128 performs "Permute 128-Bit Integer Values". -// -// Mnemonic : VPERM2I128 -// Supported forms : (2 forms) -// -// * VPERM2I128 imm8, ymm, ymm, ymm [AVX2] -// * VPERM2I128 imm8, m256, ymm, ymm [AVX2] -// -func (self *Program) VPERM2I128(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPERM2I128", 4, Operands { v0, v1, v2, v3 }) - // VPERM2I128 imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit(0x46) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERM2I128 imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x46) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERM2I128") - } - return p -} - -// VPERMB performs "Permute Byte Integers". -// -// Mnemonic : VPERMB -// Supported forms : (6 forms) -// -// * VPERMB xmm, xmm, xmm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMB m128, xmm, xmm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMB ymm, ymm, ymm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMB m256, ymm, ymm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMB zmm, zmm, zmm{k}{z} [AVX512VBMI] -// * VPERMB m512, zmm, zmm{k}{z} [AVX512VBMI] -// -func (self *Program) VPERMB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMB", 3, Operands { v0, v1, v2 }) - // VPERMB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x8d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x8d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x8d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x8d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x8d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x8d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMB") - } - return p -} - -// VPERMD performs "Permute Doubleword Integers". -// -// Mnemonic : VPERMD -// Supported forms : (6 forms) -// -// * VPERMD ymm, ymm, ymm [AVX2] -// * VPERMD m256, ymm, ymm [AVX2] -// * VPERMD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMD", 3, Operands { v0, v1, v2 }) - // VPERMD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x36) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x36) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPERMD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x36) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x36) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x36) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x36) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMD") - } - return p -} - -// VPERMI2B performs "Full Permute of Bytes From Two Tables Overwriting the Index". -// -// Mnemonic : VPERMI2B -// Supported forms : (6 forms) -// -// * VPERMI2B xmm, xmm, xmm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMI2B m128, xmm, xmm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMI2B ymm, ymm, ymm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMI2B m256, ymm, ymm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMI2B zmm, zmm, zmm{k}{z} [AVX512VBMI] -// * VPERMI2B m512, zmm, zmm{k}{z} [AVX512VBMI] -// -func (self *Program) VPERMI2B(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMI2B", 3, Operands { v0, v1, v2 }) - // VPERMI2B xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2B m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMI2B ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2B m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMI2B zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2B m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMI2B") - } - return p -} - -// VPERMI2D performs "Full Permute of Doublewords From Two Tables Overwriting the Index". -// -// Mnemonic : VPERMI2D -// Supported forms : (6 forms) -// -// * VPERMI2D m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMI2D zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMI2D m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2D xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2D m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2D ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMI2D(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMI2D", 3, Operands { v0, v1, v2 }) - // VPERMI2D m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMI2D zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2D m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMI2D xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2D m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMI2D ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMI2D") - } - return p -} - -// VPERMI2PD performs "Full Permute of Double-Precision Floating-Point Values From Two Tables Overwriting the Index". -// -// Mnemonic : VPERMI2PD -// Supported forms : (6 forms) -// -// * VPERMI2PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMI2PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMI2PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMI2PD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMI2PD", 3, Operands { v0, v1, v2 }) - // VPERMI2PD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x77) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMI2PD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x77) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2PD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x77) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMI2PD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x77) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2PD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x77) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMI2PD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x77) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMI2PD") - } - return p -} - -// VPERMI2PS performs "Full Permute of Single-Precision Floating-Point Values From Two Tables Overwriting the Index". -// -// Mnemonic : VPERMI2PS -// Supported forms : (6 forms) -// -// * VPERMI2PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMI2PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMI2PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMI2PS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMI2PS", 3, Operands { v0, v1, v2 }) - // VPERMI2PS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x77) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMI2PS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x77) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2PS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x77) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMI2PS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x77) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2PS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x77) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMI2PS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x77) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMI2PS") - } - return p -} - -// VPERMI2Q performs "Full Permute of Quadwords From Two Tables Overwriting the Index". -// -// Mnemonic : VPERMI2Q -// Supported forms : (6 forms) -// -// * VPERMI2Q m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMI2Q zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMI2Q m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2Q xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2Q m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMI2Q ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMI2Q(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMI2Q", 3, Operands { v0, v1, v2 }) - // VPERMI2Q m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMI2Q zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2Q m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMI2Q xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2Q m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x76) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMI2Q ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x76) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMI2Q") - } - return p -} - -// VPERMI2W performs "Full Permute of Words From Two Tables Overwriting the Index". -// -// Mnemonic : VPERMI2W -// Supported forms : (6 forms) -// -// * VPERMI2W zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPERMI2W m512, zmm, zmm{k}{z} [AVX512BW] -// * VPERMI2W xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPERMI2W m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPERMI2W ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPERMI2W m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPERMI2W(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMI2W", 3, Operands { v0, v1, v2 }) - // VPERMI2W zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2W m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMI2W xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2W m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMI2W ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x75) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMI2W m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x75) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMI2W") - } - return p -} - -// VPERMIL2PD performs "Permute Two-Source Double-Precision Floating-Point Vectors". -// -// Mnemonic : VPERMIL2PD -// Supported forms : (6 forms) -// -// * VPERMIL2PD imm4, xmm, xmm, xmm, xmm [XOP] -// * VPERMIL2PD imm4, m128, xmm, xmm, xmm [XOP] -// * VPERMIL2PD imm4, xmm, m128, xmm, xmm [XOP] -// * VPERMIL2PD imm4, ymm, ymm, ymm, ymm [XOP] -// * VPERMIL2PD imm4, m256, ymm, ymm, ymm [XOP] -// * VPERMIL2PD imm4, ymm, m256, ymm, ymm [XOP] -// -func (self *Program) VPERMIL2PD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, v4 interface{}) *Instruction { - p := self.alloc("VPERMIL2PD", 5, Operands { v0, v1, v2, v3, v4 }) - // VPERMIL2PD imm4, xmm, xmm, xmm, xmm - if isImm4(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) && isXMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x79 ^ (hlcode(v[3]) << 3)) - m.emit(0x49) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.emit((hlcode(v[1]) << 4) | imml(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xf9 ^ (hlcode(v[3]) << 3)) - m.emit(0x49) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[1])) - m.emit((hlcode(v[2]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PD imm4, m128, xmm, xmm, xmm - if isImm4(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) && isXMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[4]), addr(v[1]), hlcode(v[3])) - m.emit(0x49) - m.mrsd(lcode(v[4]), addr(v[1]), 1) - m.emit((hlcode(v[2]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PD imm4, xmm, m128, xmm, xmm - if isImm4(v0) && isXMM(v1) && isM128(v2) && isXMM(v3) && isXMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[4]), addr(v[2]), hlcode(v[3])) - m.emit(0x49) - m.mrsd(lcode(v[4]), addr(v[2]), 1) - m.emit((hlcode(v[1]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PD imm4, ymm, ymm, ymm, ymm - if isImm4(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) && isYMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x7d ^ (hlcode(v[3]) << 3)) - m.emit(0x49) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.emit((hlcode(v[1]) << 4) | imml(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[3]) << 3)) - m.emit(0x49) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[1])) - m.emit((hlcode(v[2]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PD imm4, m256, ymm, ymm, ymm - if isImm4(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) && isYMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[4]), addr(v[1]), hlcode(v[3])) - m.emit(0x49) - m.mrsd(lcode(v[4]), addr(v[1]), 1) - m.emit((hlcode(v[2]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PD imm4, ymm, m256, ymm, ymm - if isImm4(v0) && isYMM(v1) && isM256(v2) && isYMM(v3) && isYMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[4]), addr(v[2]), hlcode(v[3])) - m.emit(0x49) - m.mrsd(lcode(v[4]), addr(v[2]), 1) - m.emit((hlcode(v[1]) << 4) | imml(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMIL2PD") - } - return p -} - -// VPERMIL2PS performs "Permute Two-Source Single-Precision Floating-Point Vectors". -// -// Mnemonic : VPERMIL2PS -// Supported forms : (6 forms) -// -// * VPERMIL2PS imm4, xmm, xmm, xmm, xmm [XOP] -// * VPERMIL2PS imm4, m128, xmm, xmm, xmm [XOP] -// * VPERMIL2PS imm4, xmm, m128, xmm, xmm [XOP] -// * VPERMIL2PS imm4, ymm, ymm, ymm, ymm [XOP] -// * VPERMIL2PS imm4, m256, ymm, ymm, ymm [XOP] -// * VPERMIL2PS imm4, ymm, m256, ymm, ymm [XOP] -// -func (self *Program) VPERMIL2PS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, v4 interface{}) *Instruction { - p := self.alloc("VPERMIL2PS", 5, Operands { v0, v1, v2, v3, v4 }) - // VPERMIL2PS imm4, xmm, xmm, xmm, xmm - if isImm4(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) && isXMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x79 ^ (hlcode(v[3]) << 3)) - m.emit(0x48) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.emit((hlcode(v[1]) << 4) | imml(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xf9 ^ (hlcode(v[3]) << 3)) - m.emit(0x48) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[1])) - m.emit((hlcode(v[2]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PS imm4, m128, xmm, xmm, xmm - if isImm4(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) && isXMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[4]), addr(v[1]), hlcode(v[3])) - m.emit(0x48) - m.mrsd(lcode(v[4]), addr(v[1]), 1) - m.emit((hlcode(v[2]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PS imm4, xmm, m128, xmm, xmm - if isImm4(v0) && isXMM(v1) && isM128(v2) && isXMM(v3) && isXMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[4]), addr(v[2]), hlcode(v[3])) - m.emit(0x48) - m.mrsd(lcode(v[4]), addr(v[2]), 1) - m.emit((hlcode(v[1]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PS imm4, ymm, ymm, ymm, ymm - if isImm4(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) && isYMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x7d ^ (hlcode(v[3]) << 3)) - m.emit(0x48) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.emit((hlcode(v[1]) << 4) | imml(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[3]) << 3)) - m.emit(0x48) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[1])) - m.emit((hlcode(v[2]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PS imm4, m256, ymm, ymm, ymm - if isImm4(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) && isYMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[4]), addr(v[1]), hlcode(v[3])) - m.emit(0x48) - m.mrsd(lcode(v[4]), addr(v[1]), 1) - m.emit((hlcode(v[2]) << 4) | imml(v[0])) - }) - } - // VPERMIL2PS imm4, ymm, m256, ymm, ymm - if isImm4(v0) && isYMM(v1) && isM256(v2) && isYMM(v3) && isYMM(v4) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[4]), addr(v[2]), hlcode(v[3])) - m.emit(0x48) - m.mrsd(lcode(v[4]), addr(v[2]), 1) - m.emit((hlcode(v[1]) << 4) | imml(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMIL2PS") - } - return p -} - -// VPERMILPD performs "Permute Double-Precision Floating-Point Values". -// -// Mnemonic : VPERMILPD -// Supported forms : (20 forms) -// -// * VPERMILPD imm8, xmm, xmm [AVX] -// * VPERMILPD xmm, xmm, xmm [AVX] -// * VPERMILPD m128, xmm, xmm [AVX] -// * VPERMILPD imm8, m128, xmm [AVX] -// * VPERMILPD imm8, ymm, ymm [AVX] -// * VPERMILPD ymm, ymm, ymm [AVX] -// * VPERMILPD m256, ymm, ymm [AVX] -// * VPERMILPD imm8, m256, ymm [AVX] -// * VPERMILPD imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VPERMILPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMILPD imm8, zmm, zmm{k}{z} [AVX512F] -// * VPERMILPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMILPD imm8, m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPD imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPD imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMILPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMILPD", 3, Operands { v0, v1, v2 }) - // VPERMILPD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79) - m.emit(0x05) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x0d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMILPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x0d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPERMILPD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[2]), addr(v[1]), 0) - m.emit(0x05) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d) - m.emit(0x05) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x0d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMILPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x0d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPERMILPD imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[2]), addr(v[1]), 0) - m.emit(0x05) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD imm8, m512/m64bcst, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x05) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x0d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMILPD imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x05) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x0d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMILPD imm8, m128/m64bcst, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x05) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD imm8, m256/m64bcst, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x05) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x0d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMILPD imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x05) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x0d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMILPD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x0d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMILPD imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x05) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x0d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMILPD") - } - return p -} - -// VPERMILPS performs "Permute Single-Precision Floating-Point Values". -// -// Mnemonic : VPERMILPS -// Supported forms : (20 forms) -// -// * VPERMILPS imm8, xmm, xmm [AVX] -// * VPERMILPS xmm, xmm, xmm [AVX] -// * VPERMILPS m128, xmm, xmm [AVX] -// * VPERMILPS imm8, m128, xmm [AVX] -// * VPERMILPS imm8, ymm, ymm [AVX] -// * VPERMILPS ymm, ymm, ymm [AVX] -// * VPERMILPS m256, ymm, ymm [AVX] -// * VPERMILPS imm8, m256, ymm [AVX] -// * VPERMILPS imm8, m512/m32bcst, zmm{k}{z} [AVX512F] -// * VPERMILPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMILPS imm8, zmm, zmm{k}{z} [AVX512F] -// * VPERMILPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMILPS imm8, m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPS imm8, m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPS imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPS imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMILPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMILPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMILPS", 3, Operands { v0, v1, v2 }) - // VPERMILPS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x0c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMILPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x0c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPERMILPS imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[2]), addr(v[1]), 0) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x0c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMILPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x0c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPERMILPS imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[2]), addr(v[1]), 0) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS imm8, m512/m32bcst, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x0c) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMILPS imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x0c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMILPS imm8, m128/m32bcst, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS imm8, m256/m32bcst, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x0c) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMILPS imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x0c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMILPS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x0c) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMILPS imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMILPS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x0c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMILPS") - } - return p -} - -// VPERMPD performs "Permute Double-Precision Floating-Point Elements". -// -// Mnemonic : VPERMPD -// Supported forms : (10 forms) -// -// * VPERMPD imm8, ymm, ymm [AVX2] -// * VPERMPD imm8, m256, ymm [AVX2] -// * VPERMPD imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VPERMPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMPD imm8, zmm, zmm{k}{z} [AVX512F] -// * VPERMPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMPD imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMPD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMPD", 3, Operands { v0, v1, v2 }) - // VPERMPD imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xfd) - m.emit(0x01) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMPD imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[2]), addr(v[1]), 0) - m.emit(0x01) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMPD imm8, m512/m64bcst, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x01) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMPD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x16) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMPD imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x01) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMPD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x16) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMPD imm8, m256/m64bcst, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x01) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMPD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x16) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMPD imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x01) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMPD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x16) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMPD") - } - return p -} - -// VPERMPS performs "Permute Single-Precision Floating-Point Elements". -// -// Mnemonic : VPERMPS -// Supported forms : (6 forms) -// -// * VPERMPS ymm, ymm, ymm [AVX2] -// * VPERMPS m256, ymm, ymm [AVX2] -// * VPERMPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMPS", 3, Operands { v0, v1, v2 }) - // VPERMPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x16) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x16) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPERMPS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x16) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMPS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x16) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMPS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x16) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMPS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x16) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMPS") - } - return p -} - -// VPERMQ performs "Permute Quadword Integers". -// -// Mnemonic : VPERMQ -// Supported forms : (10 forms) -// -// * VPERMQ imm8, ymm, ymm [AVX2] -// * VPERMQ imm8, m256, ymm [AVX2] -// * VPERMQ imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VPERMQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMQ imm8, zmm, zmm{k}{z} [AVX512F] -// * VPERMQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMQ imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMQ imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMQ", 3, Operands { v0, v1, v2 }) - // VPERMQ imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xfd) - m.emit(0x00) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMQ imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x85, hcode(v[2]), addr(v[1]), 0) - m.emit(0x00) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMQ imm8, m512/m64bcst, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x00) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x36) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMQ imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x00) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x36) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMQ imm8, m256/m64bcst, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x00) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x36) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMQ imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x00) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPERMQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x36) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMQ") - } - return p -} - -// VPERMT2B performs "Full Permute of Bytes From Two Tables Overwriting a Table". -// -// Mnemonic : VPERMT2B -// Supported forms : (6 forms) -// -// * VPERMT2B xmm, xmm, xmm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMT2B m128, xmm, xmm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMT2B ymm, ymm, ymm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMT2B m256, ymm, ymm{k}{z} [AVX512VBMI,AVX512VL] -// * VPERMT2B zmm, zmm, zmm{k}{z} [AVX512VBMI] -// * VPERMT2B m512, zmm, zmm{k}{z} [AVX512VBMI] -// -func (self *Program) VPERMT2B(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMT2B", 3, Operands { v0, v1, v2 }) - // VPERMT2B xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2B m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMT2B ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2B m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMT2B zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2B m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMT2B") - } - return p -} - -// VPERMT2D performs "Full Permute of Doublewords From Two Tables Overwriting a Table". -// -// Mnemonic : VPERMT2D -// Supported forms : (6 forms) -// -// * VPERMT2D m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMT2D zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMT2D m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2D xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2D m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2D ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMT2D(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMT2D", 3, Operands { v0, v1, v2 }) - // VPERMT2D m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7e) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMT2D zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2D m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7e) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMT2D xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2D m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7e) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMT2D ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMT2D") - } - return p -} - -// VPERMT2PD performs "Full Permute of Double-Precision Floating-Point Values From Two Tables Overwriting a Table". -// -// Mnemonic : VPERMT2PD -// Supported forms : (6 forms) -// -// * VPERMT2PD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMT2PD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMT2PD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2PD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2PD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2PD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMT2PD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMT2PD", 3, Operands { v0, v1, v2 }) - // VPERMT2PD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7f) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMT2PD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2PD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7f) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMT2PD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2PD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7f) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMT2PD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMT2PD") - } - return p -} - -// VPERMT2PS performs "Full Permute of Single-Precision Floating-Point Values From Two Tables Overwriting a Table". -// -// Mnemonic : VPERMT2PS -// Supported forms : (6 forms) -// -// * VPERMT2PS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMT2PS zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMT2PS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2PS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2PS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2PS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMT2PS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMT2PS", 3, Operands { v0, v1, v2 }) - // VPERMT2PS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7f) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMT2PS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2PS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7f) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMT2PS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2PS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7f) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMT2PS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x7f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMT2PS") - } - return p -} - -// VPERMT2Q performs "Full Permute of Quadwords From Two Tables Overwriting a Table". -// -// Mnemonic : VPERMT2Q -// Supported forms : (6 forms) -// -// * VPERMT2Q m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPERMT2Q zmm, zmm, zmm{k}{z} [AVX512F] -// * VPERMT2Q m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2Q xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2Q m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPERMT2Q ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPERMT2Q(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMT2Q", 3, Operands { v0, v1, v2 }) - // VPERMT2Q m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7e) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMT2Q zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2Q m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7e) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMT2Q xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2Q m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x7e) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPERMT2Q ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x7e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMT2Q") - } - return p -} - -// VPERMT2W performs "Full Permute of Words From Two Tables Overwriting a Table". -// -// Mnemonic : VPERMT2W -// Supported forms : (6 forms) -// -// * VPERMT2W zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPERMT2W m512, zmm, zmm{k}{z} [AVX512BW] -// * VPERMT2W xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPERMT2W m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPERMT2W ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPERMT2W m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPERMT2W(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMT2W", 3, Operands { v0, v1, v2 }) - // VPERMT2W zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2W m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMT2W xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2W m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMT2W ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x7d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMT2W m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x7d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMT2W") - } - return p -} - -// VPERMW performs "Permute Word Integers". -// -// Mnemonic : VPERMW -// Supported forms : (6 forms) -// -// * VPERMW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPERMW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPERMW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPERMW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPERMW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPERMW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPERMW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPERMW", 3, Operands { v0, v1, v2 }) - // VPERMW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x8d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x8d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPERMW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x8d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x8d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPERMW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x8d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPERMW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x8d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPERMW") - } - return p -} - -// VPEXPANDD performs "Load Sparse Packed Doubleword Integer Values from Dense Memory/Register". -// -// Mnemonic : VPEXPANDD -// Supported forms : (6 forms) -// -// * VPEXPANDD zmm, zmm{k}{z} [AVX512F] -// * VPEXPANDD m512, zmm{k}{z} [AVX512F] -// * VPEXPANDD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPEXPANDD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPEXPANDD m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VPEXPANDD m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPEXPANDD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPEXPANDD", 2, Operands { v0, v1 }) - // VPEXPANDD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x89) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPEXPANDD m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x89) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPEXPANDD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x89) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPEXPANDD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x89) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPEXPANDD m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x89) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPEXPANDD m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x89) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPEXPANDD") - } - return p -} - -// VPEXPANDQ performs "Load Sparse Packed Quadword Integer Values from Dense Memory/Register". -// -// Mnemonic : VPEXPANDQ -// Supported forms : (6 forms) -// -// * VPEXPANDQ zmm, zmm{k}{z} [AVX512F] -// * VPEXPANDQ m512, zmm{k}{z} [AVX512F] -// * VPEXPANDQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPEXPANDQ ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPEXPANDQ m128, xmm{k}{z} [AVX512F,AVX512VL] -// * VPEXPANDQ m256, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPEXPANDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPEXPANDQ", 2, Operands { v0, v1 }) - // VPEXPANDQ zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x89) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPEXPANDQ m512, zmm{k}{z} - if isM512(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x89) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPEXPANDQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x89) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPEXPANDQ ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x89) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPEXPANDQ m128, xmm{k}{z} - if isM128(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x89) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPEXPANDQ m256, ymm{k}{z} - if isM256(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x89) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPEXPANDQ") - } - return p -} - -// VPEXTRB performs "Extract Byte". -// -// Mnemonic : VPEXTRB -// Supported forms : (4 forms) -// -// * VPEXTRB imm8, xmm, r32 [AVX] -// * VPEXTRB imm8, xmm, m8 [AVX] -// * VPEXTRB imm8, xmm, r32 [AVX512BW] -// * VPEXTRB imm8, xmm, m8 [AVX512BW] -// -func (self *Program) VPEXTRB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPEXTRB", 3, Operands { v0, v1, v2 }) - // VPEXTRB imm8, xmm, r32 - if isImm8(v0) && isXMM(v1) && isReg32(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[1]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x79) - m.emit(0x14) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRB imm8, xmm, m8 - if isImm8(v0) && isXMM(v1) && isM8(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[1]), addr(v[2]), 0) - m.emit(0x14) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRB imm8, xmm, r32 - if isImm8(v0) && isEVEXXMM(v1) && isReg32(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit(0x08) - m.emit(0x14) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRB imm8, xmm, m8 - if isImm8(v0) && isEVEXXMM(v1) && isM8(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[1]), addr(v[2]), 0, 0, 0, 0) - m.emit(0x14) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPEXTRB") - } - return p -} - -// VPEXTRD performs "Extract Doubleword". -// -// Mnemonic : VPEXTRD -// Supported forms : (4 forms) -// -// * VPEXTRD imm8, xmm, r32 [AVX] -// * VPEXTRD imm8, xmm, m32 [AVX] -// * VPEXTRD imm8, xmm, r32 [AVX512DQ] -// * VPEXTRD imm8, xmm, m32 [AVX512DQ] -// -func (self *Program) VPEXTRD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPEXTRD", 3, Operands { v0, v1, v2 }) - // VPEXTRD imm8, xmm, r32 - if isImm8(v0) && isXMM(v1) && isReg32(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[1]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x79) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRD imm8, xmm, m32 - if isImm8(v0) && isXMM(v1) && isM32(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[1]), addr(v[2]), 0) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRD imm8, xmm, r32 - if isImm8(v0) && isEVEXXMM(v1) && isReg32(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit(0x08) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRD imm8, xmm, m32 - if isImm8(v0) && isEVEXXMM(v1) && isM32(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[1]), addr(v[2]), 0, 0, 0, 0) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[2]), 4) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPEXTRD") - } - return p -} - -// VPEXTRQ performs "Extract Quadword". -// -// Mnemonic : VPEXTRQ -// Supported forms : (4 forms) -// -// * VPEXTRQ imm8, xmm, r64 [AVX] -// * VPEXTRQ imm8, xmm, m64 [AVX] -// * VPEXTRQ imm8, xmm, r64 [AVX512DQ] -// * VPEXTRQ imm8, xmm, m64 [AVX512DQ] -// -func (self *Program) VPEXTRQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPEXTRQ", 3, Operands { v0, v1, v2 }) - // VPEXTRQ imm8, xmm, r64 - if isImm8(v0) && isXMM(v1) && isReg64(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[1]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0xf9) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRQ imm8, xmm, m64 - if isImm8(v0) && isXMM(v1) && isM64(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[1]), addr(v[2]), 0) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRQ imm8, xmm, r64 - if isImm8(v0) && isEVEXXMM(v1) && isReg64(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit(0x08) - m.emit(0x16) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRQ imm8, xmm, m64 - if isImm8(v0) && isEVEXXMM(v1) && isM64(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[1]), addr(v[2]), 0, 0, 0, 0) - m.emit(0x16) - m.mrsd(lcode(v[1]), addr(v[2]), 8) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPEXTRQ") - } - return p -} - -// VPEXTRW performs "Extract Word". -// -// Mnemonic : VPEXTRW -// Supported forms : (4 forms) -// -// * VPEXTRW imm8, xmm, r32 [AVX] -// * VPEXTRW imm8, xmm, m16 [AVX] -// * VPEXTRW imm8, xmm, r32 [AVX512BW] -// * VPEXTRW imm8, xmm, m16 [AVX512BW] -// -func (self *Program) VPEXTRW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPEXTRW", 3, Operands { v0, v1, v2 }) - // VPEXTRW imm8, xmm, r32 - if isImm8(v0) && isXMM(v1) && isReg32(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[1], 0) - m.emit(0xc5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[1]) << 7) ^ (hcode(v[2]) << 5)) - m.emit(0x79) - m.emit(0x15) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRW imm8, xmm, m16 - if isImm8(v0) && isXMM(v1) && isM16(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[1]), addr(v[2]), 0) - m.emit(0x15) - m.mrsd(lcode(v[1]), addr(v[2]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRW imm8, xmm, r32 - if isImm8(v0) && isEVEXXMM(v1) && isReg32(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[1]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit(0x08) - m.emit(0x15) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit(0x08) - m.emit(0xc5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPEXTRW imm8, xmm, m16 - if isImm8(v0) && isEVEXXMM(v1) && isM16(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[1]), addr(v[2]), 0, 0, 0, 0) - m.emit(0x15) - m.mrsd(lcode(v[1]), addr(v[2]), 2) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPEXTRW") - } - return p -} - -// VPGATHERDD performs "Gather Packed Doubleword Values Using Signed Doubleword Indices". -// -// Mnemonic : VPGATHERDD -// Supported forms : (5 forms) -// -// * VPGATHERDD xmm, vm32x, xmm [AVX2] -// * VPGATHERDD ymm, vm32y, ymm [AVX2] -// * VPGATHERDD vm32z, zmm{k} [AVX512F] -// * VPGATHERDD vm32x, xmm{k} [AVX512F,AVX512VL] -// * VPGATHERDD vm32y, ymm{k} [AVX512F,AVX512VL] -// -func (self *Program) VPGATHERDD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VPGATHERDD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VPGATHERDD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VPGATHERDD takes 2 or 3 operands") - } - // VPGATHERDD xmm, vm32x, xmm - if len(vv) == 1 && isXMM(v0) && isVMX(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x90) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VPGATHERDD ymm, vm32y, ymm - if len(vv) == 1 && isYMM(v0) && isVMY(v1) && isYMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x90) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VPGATHERDD vm32z, zmm{k} - if len(vv) == 0 && isVMZ(v0) && isZMMk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPGATHERDD vm32x, xmm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPGATHERDD vm32y, ymm{k} - if len(vv) == 0 && isEVEXVMY(v0) && isYMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPGATHERDD") - } - return p -} - -// VPGATHERDQ performs "Gather Packed Quadword Values Using Signed Doubleword Indices". -// -// Mnemonic : VPGATHERDQ -// Supported forms : (5 forms) -// -// * VPGATHERDQ xmm, vm32x, xmm [AVX2] -// * VPGATHERDQ ymm, vm32x, ymm [AVX2] -// * VPGATHERDQ vm32y, zmm{k} [AVX512F] -// * VPGATHERDQ vm32x, xmm{k} [AVX512F,AVX512VL] -// * VPGATHERDQ vm32x, ymm{k} [AVX512F,AVX512VL] -// -func (self *Program) VPGATHERDQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VPGATHERDQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VPGATHERDQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VPGATHERDQ takes 2 or 3 operands") - } - // VPGATHERDQ xmm, vm32x, xmm - if len(vv) == 1 && isXMM(v0) && isVMX(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x90) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VPGATHERDQ ymm, vm32x, ymm - if len(vv) == 1 && isYMM(v0) && isVMX(v1) && isYMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x90) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VPGATHERDQ vm32y, zmm{k} - if len(vv) == 0 && isEVEXVMY(v0) && isZMMk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPGATHERDQ vm32x, xmm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPGATHERDQ vm32x, ymm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isYMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x90) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPGATHERDQ") - } - return p -} - -// VPGATHERQD performs "Gather Packed Doubleword Values Using Signed Quadword Indices". -// -// Mnemonic : VPGATHERQD -// Supported forms : (5 forms) -// -// * VPGATHERQD xmm, vm64x, xmm [AVX2] -// * VPGATHERQD xmm, vm64y, xmm [AVX2] -// * VPGATHERQD vm64z, ymm{k} [AVX512F] -// * VPGATHERQD vm64x, xmm{k} [AVX512F,AVX512VL] -// * VPGATHERQD vm64y, xmm{k} [AVX512F,AVX512VL] -// -func (self *Program) VPGATHERQD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VPGATHERQD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VPGATHERQD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VPGATHERQD takes 2 or 3 operands") - } - // VPGATHERQD xmm, vm64x, xmm - if len(vv) == 1 && isXMM(v0) && isVMX(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x91) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VPGATHERQD xmm, vm64y, xmm - if len(vv) == 1 && isXMM(v0) && isVMY(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x91) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VPGATHERQD vm64z, ymm{k} - if len(vv) == 0 && isVMZ(v0) && isYMMk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x91) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPGATHERQD vm64x, xmm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x91) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPGATHERQD vm64y, xmm{k} - if len(vv) == 0 && isEVEXVMY(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x91) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPGATHERQD") - } - return p -} - -// VPGATHERQQ performs "Gather Packed Quadword Values Using Signed Quadword Indices". -// -// Mnemonic : VPGATHERQQ -// Supported forms : (5 forms) -// -// * VPGATHERQQ xmm, vm64x, xmm [AVX2] -// * VPGATHERQQ ymm, vm64y, ymm [AVX2] -// * VPGATHERQQ vm64z, zmm{k} [AVX512F] -// * VPGATHERQQ vm64x, xmm{k} [AVX512F,AVX512VL] -// * VPGATHERQQ vm64y, ymm{k} [AVX512F,AVX512VL] -// -func (self *Program) VPGATHERQQ(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VPGATHERQQ", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VPGATHERQQ", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VPGATHERQQ takes 2 or 3 operands") - } - // VPGATHERQQ xmm, vm64x, xmm - if len(vv) == 1 && isXMM(v0) && isVMX(v1) && isXMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x91) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VPGATHERQQ ymm, vm64y, ymm - if len(vv) == 1 && isYMM(v0) && isVMY(v1) && isYMM(vv[0]) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x91) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - // VPGATHERQQ vm64z, zmm{k} - if len(vv) == 0 && isVMZ(v0) && isZMMk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x91) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPGATHERQQ vm64x, xmm{k} - if len(vv) == 0 && isEVEXVMX(v0) && isXMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x91) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPGATHERQQ vm64y, ymm{k} - if len(vv) == 0 && isEVEXVMY(v0) && isYMMk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), 0, 0) - m.emit(0x91) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPGATHERQQ") - } - return p -} - -// VPHADDBD performs "Packed Horizontal Add Signed Byte to Signed Doubleword". -// -// Mnemonic : VPHADDBD -// Supported forms : (2 forms) -// -// * VPHADDBD xmm, xmm [XOP] -// * VPHADDBD m128, xmm [XOP] -// -func (self *Program) VPHADDBD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDBD", 2, Operands { v0, v1 }) - // VPHADDBD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDBD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xc2) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDBD") - } - return p -} - -// VPHADDBQ performs "Packed Horizontal Add Signed Byte to Signed Quadword". -// -// Mnemonic : VPHADDBQ -// Supported forms : (2 forms) -// -// * VPHADDBQ xmm, xmm [XOP] -// * VPHADDBQ m128, xmm [XOP] -// -func (self *Program) VPHADDBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDBQ", 2, Operands { v0, v1 }) - // VPHADDBQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xc3) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDBQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xc3) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDBQ") - } - return p -} - -// VPHADDBW performs "Packed Horizontal Add Signed Byte to Signed Word". -// -// Mnemonic : VPHADDBW -// Supported forms : (2 forms) -// -// * VPHADDBW xmm, xmm [XOP] -// * VPHADDBW m128, xmm [XOP] -// -func (self *Program) VPHADDBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDBW", 2, Operands { v0, v1 }) - // VPHADDBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xc1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDBW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xc1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDBW") - } - return p -} - -// VPHADDD performs "Packed Horizontal Add Doubleword Integer". -// -// Mnemonic : VPHADDD -// Supported forms : (4 forms) -// -// * VPHADDD xmm, xmm, xmm [AVX] -// * VPHADDD m128, xmm, xmm [AVX] -// * VPHADDD ymm, ymm, ymm [AVX2] -// * VPHADDD m256, ymm, ymm [AVX2] -// -func (self *Program) VPHADDD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPHADDD", 3, Operands { v0, v1, v2 }) - // VPHADDD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x02) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHADDD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x02) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPHADDD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x02) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHADDD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x02) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDD") - } - return p -} - -// VPHADDDQ performs "Packed Horizontal Add Signed Doubleword to Signed Quadword". -// -// Mnemonic : VPHADDDQ -// Supported forms : (2 forms) -// -// * VPHADDDQ xmm, xmm [XOP] -// * VPHADDDQ m128, xmm [XOP] -// -func (self *Program) VPHADDDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDDQ", 2, Operands { v0, v1 }) - // VPHADDDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xcb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xcb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDDQ") - } - return p -} - -// VPHADDSW performs "Packed Horizontal Add Signed Word Integers with Signed Saturation". -// -// Mnemonic : VPHADDSW -// Supported forms : (4 forms) -// -// * VPHADDSW xmm, xmm, xmm [AVX] -// * VPHADDSW m128, xmm, xmm [AVX] -// * VPHADDSW ymm, ymm, ymm [AVX2] -// * VPHADDSW m256, ymm, ymm [AVX2] -// -func (self *Program) VPHADDSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPHADDSW", 3, Operands { v0, v1, v2 }) - // VPHADDSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x03) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHADDSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x03) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPHADDSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x03) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHADDSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x03) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDSW") - } - return p -} - -// VPHADDUBD performs "Packed Horizontal Add Unsigned Byte to Doubleword". -// -// Mnemonic : VPHADDUBD -// Supported forms : (2 forms) -// -// * VPHADDUBD xmm, xmm [XOP] -// * VPHADDUBD m128, xmm [XOP] -// -func (self *Program) VPHADDUBD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDUBD", 2, Operands { v0, v1 }) - // VPHADDUBD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xd2) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDUBD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xd2) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDUBD") - } - return p -} - -// VPHADDUBQ performs "Packed Horizontal Add Unsigned Byte to Quadword". -// -// Mnemonic : VPHADDUBQ -// Supported forms : (2 forms) -// -// * VPHADDUBQ xmm, xmm [XOP] -// * VPHADDUBQ m128, xmm [XOP] -// -func (self *Program) VPHADDUBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDUBQ", 2, Operands { v0, v1 }) - // VPHADDUBQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDUBQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xd3) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDUBQ") - } - return p -} - -// VPHADDUBW performs "Packed Horizontal Add Unsigned Byte to Word". -// -// Mnemonic : VPHADDUBW -// Supported forms : (2 forms) -// -// * VPHADDUBW xmm, xmm [XOP] -// * VPHADDUBW m128, xmm [XOP] -// -func (self *Program) VPHADDUBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDUBW", 2, Operands { v0, v1 }) - // VPHADDUBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDUBW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xd1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDUBW") - } - return p -} - -// VPHADDUDQ performs "Packed Horizontal Add Unsigned Doubleword to Quadword". -// -// Mnemonic : VPHADDUDQ -// Supported forms : (2 forms) -// -// * VPHADDUDQ xmm, xmm [XOP] -// * VPHADDUDQ m128, xmm [XOP] -// -func (self *Program) VPHADDUDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDUDQ", 2, Operands { v0, v1 }) - // VPHADDUDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xdb) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDUDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xdb) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDUDQ") - } - return p -} - -// VPHADDUWD performs "Packed Horizontal Add Unsigned Word to Doubleword". -// -// Mnemonic : VPHADDUWD -// Supported forms : (2 forms) -// -// * VPHADDUWD xmm, xmm [XOP] -// * VPHADDUWD m128, xmm [XOP] -// -func (self *Program) VPHADDUWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDUWD", 2, Operands { v0, v1 }) - // VPHADDUWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xd6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDUWD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xd6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDUWD") - } - return p -} - -// VPHADDUWQ performs "Packed Horizontal Add Unsigned Word to Quadword". -// -// Mnemonic : VPHADDUWQ -// Supported forms : (2 forms) -// -// * VPHADDUWQ xmm, xmm [XOP] -// * VPHADDUWQ m128, xmm [XOP] -// -func (self *Program) VPHADDUWQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDUWQ", 2, Operands { v0, v1 }) - // VPHADDUWQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xd7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDUWQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xd7) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDUWQ") - } - return p -} - -// VPHADDW performs "Packed Horizontal Add Word Integers". -// -// Mnemonic : VPHADDW -// Supported forms : (4 forms) -// -// * VPHADDW xmm, xmm, xmm [AVX] -// * VPHADDW m128, xmm, xmm [AVX] -// * VPHADDW ymm, ymm, ymm [AVX2] -// * VPHADDW m256, ymm, ymm [AVX2] -// -func (self *Program) VPHADDW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPHADDW", 3, Operands { v0, v1, v2 }) - // VPHADDW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHADDW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPHADDW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x01) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHADDW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x01) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDW") - } - return p -} - -// VPHADDWD performs "Packed Horizontal Add Signed Word to Signed Doubleword". -// -// Mnemonic : VPHADDWD -// Supported forms : (2 forms) -// -// * VPHADDWD xmm, xmm [XOP] -// * VPHADDWD m128, xmm [XOP] -// -func (self *Program) VPHADDWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDWD", 2, Operands { v0, v1 }) - // VPHADDWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDWD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xc6) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDWD") - } - return p -} - -// VPHADDWQ performs "Packed Horizontal Add Signed Word to Signed Quadword". -// -// Mnemonic : VPHADDWQ -// Supported forms : (2 forms) -// -// * VPHADDWQ xmm, xmm [XOP] -// * VPHADDWQ m128, xmm [XOP] -// -func (self *Program) VPHADDWQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHADDWQ", 2, Operands { v0, v1 }) - // VPHADDWQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xc7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHADDWQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xc7) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHADDWQ") - } - return p -} - -// VPHMINPOSUW performs "Packed Horizontal Minimum of Unsigned Word Integers". -// -// Mnemonic : VPHMINPOSUW -// Supported forms : (2 forms) -// -// * VPHMINPOSUW xmm, xmm [AVX] -// * VPHMINPOSUW m128, xmm [AVX] -// -func (self *Program) VPHMINPOSUW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHMINPOSUW", 2, Operands { v0, v1 }) - // VPHMINPOSUW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x41) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHMINPOSUW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x41) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHMINPOSUW") - } - return p -} - -// VPHSUBBW performs "Packed Horizontal Subtract Signed Byte to Signed Word". -// -// Mnemonic : VPHSUBBW -// Supported forms : (2 forms) -// -// * VPHSUBBW xmm, xmm [XOP] -// * VPHSUBBW m128, xmm [XOP] -// -func (self *Program) VPHSUBBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHSUBBW", 2, Operands { v0, v1 }) - // VPHSUBBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xe1) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHSUBBW m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xe1) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHSUBBW") - } - return p -} - -// VPHSUBD performs "Packed Horizontal Subtract Doubleword Integers". -// -// Mnemonic : VPHSUBD -// Supported forms : (4 forms) -// -// * VPHSUBD xmm, xmm, xmm [AVX] -// * VPHSUBD m128, xmm, xmm [AVX] -// * VPHSUBD ymm, ymm, ymm [AVX2] -// * VPHSUBD m256, ymm, ymm [AVX2] -// -func (self *Program) VPHSUBD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPHSUBD", 3, Operands { v0, v1, v2 }) - // VPHSUBD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x06) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHSUBD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x06) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPHSUBD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x06) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHSUBD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x06) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHSUBD") - } - return p -} - -// VPHSUBDQ performs "Packed Horizontal Subtract Signed Doubleword to Signed Quadword". -// -// Mnemonic : VPHSUBDQ -// Supported forms : (2 forms) -// -// * VPHSUBDQ xmm, xmm [XOP] -// * VPHSUBDQ m128, xmm [XOP] -// -func (self *Program) VPHSUBDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHSUBDQ", 2, Operands { v0, v1 }) - // VPHSUBDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xe3) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHSUBDQ m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xe3) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHSUBDQ") - } - return p -} - -// VPHSUBSW performs "Packed Horizontal Subtract Signed Word Integers with Signed Saturation". -// -// Mnemonic : VPHSUBSW -// Supported forms : (4 forms) -// -// * VPHSUBSW xmm, xmm, xmm [AVX] -// * VPHSUBSW m128, xmm, xmm [AVX] -// * VPHSUBSW ymm, ymm, ymm [AVX2] -// * VPHSUBSW m256, ymm, ymm [AVX2] -// -func (self *Program) VPHSUBSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPHSUBSW", 3, Operands { v0, v1, v2 }) - // VPHSUBSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x07) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHSUBSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x07) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPHSUBSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x07) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHSUBSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x07) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHSUBSW") - } - return p -} - -// VPHSUBW performs "Packed Horizontal Subtract Word Integers". -// -// Mnemonic : VPHSUBW -// Supported forms : (4 forms) -// -// * VPHSUBW xmm, xmm, xmm [AVX] -// * VPHSUBW m128, xmm, xmm [AVX] -// * VPHSUBW ymm, ymm, ymm [AVX2] -// * VPHSUBW m256, ymm, ymm [AVX2] -// -func (self *Program) VPHSUBW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPHSUBW", 3, Operands { v0, v1, v2 }) - // VPHSUBW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x05) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHSUBW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x05) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPHSUBW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x05) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPHSUBW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x05) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHSUBW") - } - return p -} - -// VPHSUBWD performs "Packed Horizontal Subtract Signed Word to Signed Doubleword". -// -// Mnemonic : VPHSUBWD -// Supported forms : (2 forms) -// -// * VPHSUBWD xmm, xmm [XOP] -// * VPHSUBWD m128, xmm [XOP] -// -func (self *Program) VPHSUBWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPHSUBWD", 2, Operands { v0, v1 }) - // VPHSUBWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x78) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPHSUBWD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[1]), addr(v[0]), 0) - m.emit(0xe2) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPHSUBWD") - } - return p -} - -// VPINSRB performs "Insert Byte". -// -// Mnemonic : VPINSRB -// Supported forms : (4 forms) -// -// * VPINSRB imm8, r32, xmm, xmm [AVX] -// * VPINSRB imm8, m8, xmm, xmm [AVX] -// * VPINSRB imm8, r32, xmm, xmm [AVX512BW] -// * VPINSRB imm8, m8, xmm, xmm [AVX512BW] -// -func (self *Program) VPINSRB(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPINSRB", 4, Operands { v0, v1, v2, v3 }) - // VPINSRB imm8, r32, xmm, xmm - if isImm8(v0) && isReg32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x20) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRB imm8, m8, xmm, xmm - if isImm8(v0) && isM8(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x20) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRB imm8, r32, xmm, xmm - if isImm8(v0) && isReg32(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x00) - m.emit(0x20) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRB imm8, m8, xmm, xmm - if isImm8(v0) && isM8(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x20) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPINSRB") - } - return p -} - -// VPINSRD performs "Insert Doubleword". -// -// Mnemonic : VPINSRD -// Supported forms : (4 forms) -// -// * VPINSRD imm8, r32, xmm, xmm [AVX] -// * VPINSRD imm8, m32, xmm, xmm [AVX] -// * VPINSRD imm8, r32, xmm, xmm [AVX512DQ] -// * VPINSRD imm8, m32, xmm, xmm [AVX512DQ] -// -func (self *Program) VPINSRD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPINSRD", 4, Operands { v0, v1, v2, v3 }) - // VPINSRD imm8, r32, xmm, xmm - if isImm8(v0) && isReg32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x22) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRD imm8, m32, xmm, xmm - if isImm8(v0) && isM32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x22) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRD imm8, r32, xmm, xmm - if isImm8(v0) && isReg32(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x00) - m.emit(0x22) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRD imm8, m32, xmm, xmm - if isImm8(v0) && isM32(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x22) - m.mrsd(lcode(v[3]), addr(v[1]), 4) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPINSRD") - } - return p -} - -// VPINSRQ performs "Insert Quadword". -// -// Mnemonic : VPINSRQ -// Supported forms : (4 forms) -// -// * VPINSRQ imm8, r64, xmm, xmm [AVX] -// * VPINSRQ imm8, m64, xmm, xmm [AVX] -// * VPINSRQ imm8, r64, xmm, xmm [AVX512DQ] -// * VPINSRQ imm8, m64, xmm, xmm [AVX512DQ] -// -func (self *Program) VPINSRQ(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPINSRQ", 4, Operands { v0, v1, v2, v3 }) - // VPINSRQ imm8, r64, xmm, xmm - if isImm8(v0) && isReg64(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0xf9 ^ (hlcode(v[2]) << 3)) - m.emit(0x22) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRQ imm8, m64, xmm, xmm - if isImm8(v0) && isM64(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x81, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x22) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRQ imm8, r64, xmm, xmm - if isImm8(v0) && isReg64(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x00) - m.emit(0x22) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRQ imm8, m64, xmm, xmm - if isImm8(v0) && isM64(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x22) - m.mrsd(lcode(v[3]), addr(v[1]), 8) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPINSRQ") - } - return p -} - -// VPINSRW performs "Insert Word". -// -// Mnemonic : VPINSRW -// Supported forms : (4 forms) -// -// * VPINSRW imm8, r32, xmm, xmm [AVX] -// * VPINSRW imm8, m16, xmm, xmm [AVX] -// * VPINSRW imm8, r32, xmm, xmm [AVX512BW] -// * VPINSRW imm8, m16, xmm, xmm [AVX512BW] -// -func (self *Program) VPINSRW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPINSRW", 4, Operands { v0, v1, v2, v3 }) - // VPINSRW imm8, r32, xmm, xmm - if isImm8(v0) && isReg32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRW imm8, m16, xmm, xmm - if isImm8(v0) && isM16(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc4) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRW imm8, r32, xmm, xmm - if isImm8(v0) && isReg32(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x00) - m.emit(0xc4) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPINSRW imm8, m16, xmm, xmm - if isImm8(v0) && isM16(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0xc4) - m.mrsd(lcode(v[3]), addr(v[1]), 2) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPINSRW") - } - return p -} - -// VPLZCNTD performs "Count the Number of Leading Zero Bits for Packed Doubleword Values". -// -// Mnemonic : VPLZCNTD -// Supported forms : (6 forms) -// -// * VPLZCNTD m128/m32bcst, xmm{k}{z} [AVX512CD,AVX512VL] -// * VPLZCNTD m256/m32bcst, ymm{k}{z} [AVX512CD,AVX512VL] -// * VPLZCNTD m512/m32bcst, zmm{k}{z} [AVX512CD] -// * VPLZCNTD xmm, xmm{k}{z} [AVX512CD,AVX512VL] -// * VPLZCNTD ymm, ymm{k}{z} [AVX512CD,AVX512VL] -// * VPLZCNTD zmm, zmm{k}{z} [AVX512CD] -// -func (self *Program) VPLZCNTD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPLZCNTD", 2, Operands { v0, v1 }) - // VPLZCNTD m128/m32bcst, xmm{k}{z} - if isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPLZCNTD m256/m32bcst, ymm{k}{z} - if isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPLZCNTD m512/m32bcst, zmm{k}{z} - if isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPLZCNTD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPLZCNTD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPLZCNTD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPLZCNTD") - } - return p -} - -// VPLZCNTQ performs "Count the Number of Leading Zero Bits for Packed Quadword Values". -// -// Mnemonic : VPLZCNTQ -// Supported forms : (6 forms) -// -// * VPLZCNTQ m128/m64bcst, xmm{k}{z} [AVX512CD,AVX512VL] -// * VPLZCNTQ m256/m64bcst, ymm{k}{z} [AVX512CD,AVX512VL] -// * VPLZCNTQ m512/m64bcst, zmm{k}{z} [AVX512CD] -// * VPLZCNTQ xmm, xmm{k}{z} [AVX512CD,AVX512VL] -// * VPLZCNTQ ymm, ymm{k}{z} [AVX512CD,AVX512VL] -// * VPLZCNTQ zmm, zmm{k}{z} [AVX512CD] -// -func (self *Program) VPLZCNTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPLZCNTQ", 2, Operands { v0, v1 }) - // VPLZCNTQ m128/m64bcst, xmm{k}{z} - if isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPLZCNTQ m256/m64bcst, ymm{k}{z} - if isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPLZCNTQ m512/m64bcst, zmm{k}{z} - if isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x44) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPLZCNTQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPLZCNTQ ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPLZCNTQ zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512CD) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x44) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPLZCNTQ") - } - return p -} - -// VPMACSDD performs "Packed Multiply Accumulate Signed Doubleword to Signed Doubleword". -// -// Mnemonic : VPMACSDD -// Supported forms : (2 forms) -// -// * VPMACSDD xmm, xmm, xmm, xmm [XOP] -// * VPMACSDD xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSDD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSDD", 4, Operands { v0, v1, v2, v3 }) - // VPMACSDD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x9e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSDD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x9e) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSDD") - } - return p -} - -// VPMACSDQH performs "Packed Multiply Accumulate Signed High Doubleword to Signed Quadword". -// -// Mnemonic : VPMACSDQH -// Supported forms : (2 forms) -// -// * VPMACSDQH xmm, xmm, xmm, xmm [XOP] -// * VPMACSDQH xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSDQH(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSDQH", 4, Operands { v0, v1, v2, v3 }) - // VPMACSDQH xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x9f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSDQH xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x9f) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSDQH") - } - return p -} - -// VPMACSDQL performs "Packed Multiply Accumulate Signed Low Doubleword to Signed Quadword". -// -// Mnemonic : VPMACSDQL -// Supported forms : (2 forms) -// -// * VPMACSDQL xmm, xmm, xmm, xmm [XOP] -// * VPMACSDQL xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSDQL(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSDQL", 4, Operands { v0, v1, v2, v3 }) - // VPMACSDQL xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x97) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSDQL xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x97) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSDQL") - } - return p -} - -// VPMACSSDD performs "Packed Multiply Accumulate with Saturation Signed Doubleword to Signed Doubleword". -// -// Mnemonic : VPMACSSDD -// Supported forms : (2 forms) -// -// * VPMACSSDD xmm, xmm, xmm, xmm [XOP] -// * VPMACSSDD xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSSDD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSSDD", 4, Operands { v0, v1, v2, v3 }) - // VPMACSSDD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x8e) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSSDD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x8e) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSSDD") - } - return p -} - -// VPMACSSDQH performs "Packed Multiply Accumulate with Saturation Signed High Doubleword to Signed Quadword". -// -// Mnemonic : VPMACSSDQH -// Supported forms : (2 forms) -// -// * VPMACSSDQH xmm, xmm, xmm, xmm [XOP] -// * VPMACSSDQH xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSSDQH(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSSDQH", 4, Operands { v0, v1, v2, v3 }) - // VPMACSSDQH xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x8f) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSSDQH xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x8f) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSSDQH") - } - return p -} - -// VPMACSSDQL performs "Packed Multiply Accumulate with Saturation Signed Low Doubleword to Signed Quadword". -// -// Mnemonic : VPMACSSDQL -// Supported forms : (2 forms) -// -// * VPMACSSDQL xmm, xmm, xmm, xmm [XOP] -// * VPMACSSDQL xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSSDQL(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSSDQL", 4, Operands { v0, v1, v2, v3 }) - // VPMACSSDQL xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x87) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSSDQL xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x87) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSSDQL") - } - return p -} - -// VPMACSSWD performs "Packed Multiply Accumulate with Saturation Signed Word to Signed Doubleword". -// -// Mnemonic : VPMACSSWD -// Supported forms : (2 forms) -// -// * VPMACSSWD xmm, xmm, xmm, xmm [XOP] -// * VPMACSSWD xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSSWD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSSWD", 4, Operands { v0, v1, v2, v3 }) - // VPMACSSWD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x86) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSSWD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x86) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSSWD") - } - return p -} - -// VPMACSSWW performs "Packed Multiply Accumulate with Saturation Signed Word to Signed Word". -// -// Mnemonic : VPMACSSWW -// Supported forms : (2 forms) -// -// * VPMACSSWW xmm, xmm, xmm, xmm [XOP] -// * VPMACSSWW xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSSWW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSSWW", 4, Operands { v0, v1, v2, v3 }) - // VPMACSSWW xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x85) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSSWW xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x85) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSSWW") - } - return p -} - -// VPMACSWD performs "Packed Multiply Accumulate Signed Word to Signed Doubleword". -// -// Mnemonic : VPMACSWD -// Supported forms : (2 forms) -// -// * VPMACSWD xmm, xmm, xmm, xmm [XOP] -// * VPMACSWD xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSWD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSWD", 4, Operands { v0, v1, v2, v3 }) - // VPMACSWD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x96) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSWD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x96) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSWD") - } - return p -} - -// VPMACSWW performs "Packed Multiply Accumulate Signed Word to Signed Word". -// -// Mnemonic : VPMACSWW -// Supported forms : (2 forms) -// -// * VPMACSWW xmm, xmm, xmm, xmm [XOP] -// * VPMACSWW xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMACSWW(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMACSWW", 4, Operands { v0, v1, v2, v3 }) - // VPMACSWW xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0x95) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMACSWW xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x95) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMACSWW") - } - return p -} - -// VPMADCSSWD performs "Packed Multiply Add Accumulate with Saturation Signed Word to Signed Doubleword". -// -// Mnemonic : VPMADCSSWD -// Supported forms : (2 forms) -// -// * VPMADCSSWD xmm, xmm, xmm, xmm [XOP] -// * VPMADCSSWD xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMADCSSWD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMADCSSWD", 4, Operands { v0, v1, v2, v3 }) - // VPMADCSSWD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xa6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMADCSSWD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xa6) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMADCSSWD") - } - return p -} - -// VPMADCSWD performs "Packed Multiply Add Accumulate Signed Word to Signed Doubleword". -// -// Mnemonic : VPMADCSWD -// Supported forms : (2 forms) -// -// * VPMADCSWD xmm, xmm, xmm, xmm [XOP] -// * VPMADCSWD xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPMADCSWD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPMADCSWD", 4, Operands { v0, v1, v2, v3 }) - // VPMADCSWD xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xb6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - } - // VPMADCSWD xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xb6) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMADCSWD") - } - return p -} - -// VPMADD52HUQ performs "Packed Multiply of Unsigned 52-bit Unsigned Integers and Add High 52-bit Products to Quadword Accumulators". -// -// Mnemonic : VPMADD52HUQ -// Supported forms : (6 forms) -// -// * VPMADD52HUQ m128/m64bcst, xmm, xmm{k}{z} [AVX512IFMA,AVX512VL] -// * VPMADD52HUQ xmm, xmm, xmm{k}{z} [AVX512IFMA,AVX512VL] -// * VPMADD52HUQ m256/m64bcst, ymm, ymm{k}{z} [AVX512IFMA,AVX512VL] -// * VPMADD52HUQ ymm, ymm, ymm{k}{z} [AVX512IFMA,AVX512VL] -// * VPMADD52HUQ m512/m64bcst, zmm, zmm{k}{z} [AVX512IFMA] -// * VPMADD52HUQ zmm, zmm, zmm{k}{z} [AVX512IFMA] -// -func (self *Program) VPMADD52HUQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMADD52HUQ", 3, Operands { v0, v1, v2 }) - // VPMADD52HUQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512IFMA | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb5) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMADD52HUQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512IFMA | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xb5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADD52HUQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512IFMA | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb5) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMADD52HUQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512IFMA | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xb5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADD52HUQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512IFMA) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb5) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMADD52HUQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512IFMA) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMADD52HUQ") - } - return p -} - -// VPMADD52LUQ performs "Packed Multiply of Unsigned 52-bit Integers and Add the Low 52-bit Products to Quadword Accumulators". -// -// Mnemonic : VPMADD52LUQ -// Supported forms : (6 forms) -// -// * VPMADD52LUQ m128/m64bcst, xmm, xmm{k}{z} [AVX512IFMA,AVX512VL] -// * VPMADD52LUQ xmm, xmm, xmm{k}{z} [AVX512IFMA,AVX512VL] -// * VPMADD52LUQ m256/m64bcst, ymm, ymm{k}{z} [AVX512IFMA,AVX512VL] -// * VPMADD52LUQ ymm, ymm, ymm{k}{z} [AVX512IFMA,AVX512VL] -// * VPMADD52LUQ m512/m64bcst, zmm, zmm{k}{z} [AVX512IFMA] -// * VPMADD52LUQ zmm, zmm, zmm{k}{z} [AVX512IFMA] -// -func (self *Program) VPMADD52LUQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMADD52LUQ", 3, Operands { v0, v1, v2 }) - // VPMADD52LUQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512IFMA | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb4) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMADD52LUQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512IFMA | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xb4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADD52LUQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512IFMA | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb4) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMADD52LUQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512IFMA | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xb4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADD52LUQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512IFMA) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xb4) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMADD52LUQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512IFMA) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xb4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMADD52LUQ") - } - return p -} - -// VPMADDUBSW performs "Multiply and Add Packed Signed and Unsigned Byte Integers". -// -// Mnemonic : VPMADDUBSW -// Supported forms : (10 forms) -// -// * VPMADDUBSW xmm, xmm, xmm [AVX] -// * VPMADDUBSW m128, xmm, xmm [AVX] -// * VPMADDUBSW ymm, ymm, ymm [AVX2] -// * VPMADDUBSW m256, ymm, ymm [AVX2] -// * VPMADDUBSW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMADDUBSW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMADDUBSW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMADDUBSW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMADDUBSW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMADDUBSW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMADDUBSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMADDUBSW", 3, Operands { v0, v1, v2 }) - // VPMADDUBSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDUBSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMADDUBSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDUBSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMADDUBSW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDUBSW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMADDUBSW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDUBSW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMADDUBSW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x04) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDUBSW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x04) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMADDUBSW") - } - return p -} - -// VPMADDWD performs "Multiply and Add Packed Signed Word Integers". -// -// Mnemonic : VPMADDWD -// Supported forms : (10 forms) -// -// * VPMADDWD xmm, xmm, xmm [AVX] -// * VPMADDWD m128, xmm, xmm [AVX] -// * VPMADDWD ymm, ymm, ymm [AVX2] -// * VPMADDWD m256, ymm, ymm [AVX2] -// * VPMADDWD zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMADDWD m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMADDWD xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMADDWD m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMADDWD ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMADDWD m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMADDWD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMADDWD", 3, Operands { v0, v1, v2 }) - // VPMADDWD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDWD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMADDWD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDWD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMADDWD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDWD m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMADDWD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDWD m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMADDWD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xf5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMADDWD m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf5) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMADDWD") - } - return p -} - -// VPMASKMOVD performs "Conditional Move Packed Doubleword Integers". -// -// Mnemonic : VPMASKMOVD -// Supported forms : (4 forms) -// -// * VPMASKMOVD m128, xmm, xmm [AVX2] -// * VPMASKMOVD m256, ymm, ymm [AVX2] -// * VPMASKMOVD xmm, xmm, m128 [AVX2] -// * VPMASKMOVD ymm, ymm, m256 [AVX2] -// -func (self *Program) VPMASKMOVD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMASKMOVD", 3, Operands { v0, v1, v2 }) - // VPMASKMOVD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x8c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMASKMOVD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x8c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMASKMOVD xmm, xmm, m128 - if isXMM(v0) && isXMM(v1) && isM128(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[0]), addr(v[2]), hlcode(v[1])) - m.emit(0x8e) - m.mrsd(lcode(v[0]), addr(v[2]), 1) - }) - } - // VPMASKMOVD ymm, ymm, m256 - if isYMM(v0) && isYMM(v1) && isM256(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[0]), addr(v[2]), hlcode(v[1])) - m.emit(0x8e) - m.mrsd(lcode(v[0]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPMASKMOVD") - } - return p -} - -// VPMASKMOVQ performs "Conditional Move Packed Quadword Integers". -// -// Mnemonic : VPMASKMOVQ -// Supported forms : (4 forms) -// -// * VPMASKMOVQ m128, xmm, xmm [AVX2] -// * VPMASKMOVQ m256, ymm, ymm [AVX2] -// * VPMASKMOVQ xmm, xmm, m128 [AVX2] -// * VPMASKMOVQ ymm, ymm, m256 [AVX2] -// -func (self *Program) VPMASKMOVQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMASKMOVQ", 3, Operands { v0, v1, v2 }) - // VPMASKMOVQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x8c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMASKMOVQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x8c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMASKMOVQ xmm, xmm, m128 - if isXMM(v0) && isXMM(v1) && isM128(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[0]), addr(v[2]), hlcode(v[1])) - m.emit(0x8e) - m.mrsd(lcode(v[0]), addr(v[2]), 1) - }) - } - // VPMASKMOVQ ymm, ymm, m256 - if isYMM(v0) && isYMM(v1) && isM256(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[0]), addr(v[2]), hlcode(v[1])) - m.emit(0x8e) - m.mrsd(lcode(v[0]), addr(v[2]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPMASKMOVQ") - } - return p -} - -// VPMAXSB performs "Maximum of Packed Signed Byte Integers". -// -// Mnemonic : VPMAXSB -// Supported forms : (10 forms) -// -// * VPMAXSB xmm, xmm, xmm [AVX] -// * VPMAXSB m128, xmm, xmm [AVX] -// * VPMAXSB ymm, ymm, ymm [AVX2] -// * VPMAXSB m256, ymm, ymm [AVX2] -// * VPMAXSB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMAXSB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMAXSB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXSB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXSB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXSB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMAXSB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMAXSB", 3, Operands { v0, v1, v2 }) - // VPMAXSB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x3c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXSB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x3c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXSB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x3c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3c) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMAXSB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x3c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3c) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMAXSB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x3c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3c) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMAXSB") - } - return p -} - -// VPMAXSD performs "Maximum of Packed Signed Doubleword Integers". -// -// Mnemonic : VPMAXSD -// Supported forms : (10 forms) -// -// * VPMAXSD xmm, xmm, xmm [AVX] -// * VPMAXSD m128, xmm, xmm [AVX] -// * VPMAXSD ymm, ymm, ymm [AVX2] -// * VPMAXSD m256, ymm, ymm [AVX2] -// * VPMAXSD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMAXSD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMAXSD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMAXSD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMAXSD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMAXSD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMAXSD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMAXSD", 3, Operands { v0, v1, v2 }) - // VPMAXSD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x3d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXSD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x3d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXSD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMAXSD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x3d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMAXSD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x3d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMAXSD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x3d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMAXSD") - } - return p -} - -// VPMAXSQ performs "Maximum of Packed Signed Quadword Integers". -// -// Mnemonic : VPMAXSQ -// Supported forms : (6 forms) -// -// * VPMAXSQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMAXSQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMAXSQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMAXSQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMAXSQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMAXSQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMAXSQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMAXSQ", 3, Operands { v0, v1, v2 }) - // VPMAXSQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMAXSQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x3d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMAXSQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x3d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMAXSQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x3d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMAXSQ") - } - return p -} - -// VPMAXSW performs "Maximum of Packed Signed Word Integers". -// -// Mnemonic : VPMAXSW -// Supported forms : (10 forms) -// -// * VPMAXSW xmm, xmm, xmm [AVX] -// * VPMAXSW m128, xmm, xmm [AVX] -// * VPMAXSW ymm, ymm, ymm [AVX2] -// * VPMAXSW m256, ymm, ymm [AVX2] -// * VPMAXSW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMAXSW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMAXSW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXSW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXSW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXSW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMAXSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMAXSW", 3, Operands { v0, v1, v2 }) - // VPMAXSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xee) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xee) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xee) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xee) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXSW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xee) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xee) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMAXSW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xee) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xee) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMAXSW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xee) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXSW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xee) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMAXSW") - } - return p -} - -// VPMAXUB performs "Maximum of Packed Unsigned Byte Integers". -// -// Mnemonic : VPMAXUB -// Supported forms : (10 forms) -// -// * VPMAXUB xmm, xmm, xmm [AVX] -// * VPMAXUB m128, xmm, xmm [AVX] -// * VPMAXUB ymm, ymm, ymm [AVX2] -// * VPMAXUB m256, ymm, ymm [AVX2] -// * VPMAXUB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMAXUB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMAXUB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXUB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXUB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXUB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMAXUB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMAXUB", 3, Operands { v0, v1, v2 }) - // VPMAXUB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xde) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xde) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXUB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xde) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xde) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXUB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xde) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xde) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMAXUB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xde) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xde) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMAXUB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xde) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xde) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMAXUB") - } - return p -} - -// VPMAXUD performs "Maximum of Packed Unsigned Doubleword Integers". -// -// Mnemonic : VPMAXUD -// Supported forms : (10 forms) -// -// * VPMAXUD xmm, xmm, xmm [AVX] -// * VPMAXUD m128, xmm, xmm [AVX] -// * VPMAXUD ymm, ymm, ymm [AVX2] -// * VPMAXUD m256, ymm, ymm [AVX2] -// * VPMAXUD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMAXUD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMAXUD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMAXUD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMAXUD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMAXUD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMAXUD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMAXUD", 3, Operands { v0, v1, v2 }) - // VPMAXUD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXUD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3f) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXUD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3f) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMAXUD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3f) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMAXUD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3f) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMAXUD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMAXUD") - } - return p -} - -// VPMAXUQ performs "Maximum of Packed Unsigned Quadword Integers". -// -// Mnemonic : VPMAXUQ -// Supported forms : (6 forms) -// -// * VPMAXUQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMAXUQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMAXUQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMAXUQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMAXUQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMAXUQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMAXUQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMAXUQ", 3, Operands { v0, v1, v2 }) - // VPMAXUQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3f) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMAXUQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3f) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMAXUQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3f) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMAXUQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x3f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMAXUQ") - } - return p -} - -// VPMAXUW performs "Maximum of Packed Unsigned Word Integers". -// -// Mnemonic : VPMAXUW -// Supported forms : (10 forms) -// -// * VPMAXUW xmm, xmm, xmm [AVX] -// * VPMAXUW m128, xmm, xmm [AVX] -// * VPMAXUW ymm, ymm, ymm [AVX2] -// * VPMAXUW m256, ymm, ymm [AVX2] -// * VPMAXUW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMAXUW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMAXUW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXUW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXUW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMAXUW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMAXUW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMAXUW", 3, Operands { v0, v1, v2 }) - // VPMAXUW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXUW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3e) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMAXUW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3e) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMAXUW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3e) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMAXUW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x3e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMAXUW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3e) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMAXUW") - } - return p -} - -// VPMINSB performs "Minimum of Packed Signed Byte Integers". -// -// Mnemonic : VPMINSB -// Supported forms : (10 forms) -// -// * VPMINSB xmm, xmm, xmm [AVX] -// * VPMINSB m128, xmm, xmm [AVX] -// * VPMINSB ymm, ymm, ymm [AVX2] -// * VPMINSB m256, ymm, ymm [AVX2] -// * VPMINSB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMINSB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMINSB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMINSB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMINSB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMINSB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMINSB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMINSB", 3, Operands { v0, v1, v2 }) - // VPMINSB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x38) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x38) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINSB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x38) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x38) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINSB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x38) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x38) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMINSB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x38) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x38) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMINSB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x38) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x38) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMINSB") - } - return p -} - -// VPMINSD performs "Minimum of Packed Signed Doubleword Integers". -// -// Mnemonic : VPMINSD -// Supported forms : (10 forms) -// -// * VPMINSD xmm, xmm, xmm [AVX] -// * VPMINSD m128, xmm, xmm [AVX] -// * VPMINSD ymm, ymm, ymm [AVX2] -// * VPMINSD m256, ymm, ymm [AVX2] -// * VPMINSD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMINSD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMINSD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMINSD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMINSD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMINSD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMINSD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMINSD", 3, Operands { v0, v1, v2 }) - // VPMINSD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x39) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x39) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINSD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x39) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x39) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINSD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x39) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMINSD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x39) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x39) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMINSD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x39) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x39) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMINSD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x39) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMINSD") - } - return p -} - -// VPMINSQ performs "Minimum of Packed Signed Quadword Integers". -// -// Mnemonic : VPMINSQ -// Supported forms : (6 forms) -// -// * VPMINSQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMINSQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMINSQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMINSQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMINSQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMINSQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMINSQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMINSQ", 3, Operands { v0, v1, v2 }) - // VPMINSQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x39) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMINSQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x39) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x39) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMINSQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x39) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x39) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMINSQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x39) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMINSQ") - } - return p -} - -// VPMINSW performs "Minimum of Packed Signed Word Integers". -// -// Mnemonic : VPMINSW -// Supported forms : (10 forms) -// -// * VPMINSW xmm, xmm, xmm [AVX] -// * VPMINSW m128, xmm, xmm [AVX] -// * VPMINSW ymm, ymm, ymm [AVX2] -// * VPMINSW m256, ymm, ymm [AVX2] -// * VPMINSW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMINSW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMINSW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMINSW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMINSW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMINSW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMINSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMINSW", 3, Operands { v0, v1, v2 }) - // VPMINSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xea) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xea) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xea) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xea) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINSW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xea) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xea) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMINSW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xea) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xea) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMINSW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xea) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINSW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xea) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMINSW") - } - return p -} - -// VPMINUB performs "Minimum of Packed Unsigned Byte Integers". -// -// Mnemonic : VPMINUB -// Supported forms : (10 forms) -// -// * VPMINUB xmm, xmm, xmm [AVX] -// * VPMINUB m128, xmm, xmm [AVX] -// * VPMINUB ymm, ymm, ymm [AVX2] -// * VPMINUB m256, ymm, ymm [AVX2] -// * VPMINUB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMINUB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMINUB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMINUB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMINUB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMINUB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMINUB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMINUB", 3, Operands { v0, v1, v2 }) - // VPMINUB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xda) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xda) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINUB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xda) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xda) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINUB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xda) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xda) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMINUB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xda) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xda) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMINUB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xda) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xda) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMINUB") - } - return p -} - -// VPMINUD performs "Minimum of Packed Unsigned Doubleword Integers". -// -// Mnemonic : VPMINUD -// Supported forms : (10 forms) -// -// * VPMINUD xmm, xmm, xmm [AVX] -// * VPMINUD m128, xmm, xmm [AVX] -// * VPMINUD ymm, ymm, ymm [AVX2] -// * VPMINUD m256, ymm, ymm [AVX2] -// * VPMINUD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMINUD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMINUD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMINUD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMINUD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMINUD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMINUD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMINUD", 3, Operands { v0, v1, v2 }) - // VPMINUD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINUD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINUD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3b) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMINUD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3b) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMINUD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3b) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMINUD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMINUD") - } - return p -} - -// VPMINUQ performs "Minimum of Packed Unsigned Quadword Integers". -// -// Mnemonic : VPMINUQ -// Supported forms : (6 forms) -// -// * VPMINUQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMINUQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMINUQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMINUQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMINUQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMINUQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMINUQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMINUQ", 3, Operands { v0, v1, v2 }) - // VPMINUQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3b) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMINUQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3b) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMINUQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x3b) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMINUQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x3b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMINUQ") - } - return p -} - -// VPMINUW performs "Minimum of Packed Unsigned Word Integers". -// -// Mnemonic : VPMINUW -// Supported forms : (10 forms) -// -// * VPMINUW xmm, xmm, xmm [AVX] -// * VPMINUW m128, xmm, xmm [AVX] -// * VPMINUW ymm, ymm, ymm [AVX2] -// * VPMINUW m256, ymm, ymm [AVX2] -// * VPMINUW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMINUW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMINUW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMINUW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMINUW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMINUW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMINUW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMINUW", 3, Operands { v0, v1, v2 }) - // VPMINUW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINUW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x3a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMINUW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3a) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMINUW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3a) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMINUW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x3a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMINUW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x3a) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMINUW") - } - return p -} - -// VPMOVB2M performs "Move Signs of Packed Byte Integers to Mask Register". -// -// Mnemonic : VPMOVB2M -// Supported forms : (3 forms) -// -// * VPMOVB2M zmm, k [AVX512BW] -// * VPMOVB2M xmm, k [AVX512BW,AVX512VL] -// * VPMOVB2M ymm, k [AVX512BW,AVX512VL] -// -func (self *Program) VPMOVB2M(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVB2M", 2, Operands { v0, v1 }) - // VPMOVB2M zmm, k - if isZMM(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x48) - m.emit(0x29) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVB2M xmm, k - if isEVEXXMM(v0) && isK(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x08) - m.emit(0x29) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVB2M ymm, k - if isEVEXYMM(v0) && isK(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x28) - m.emit(0x29) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVB2M") - } - return p -} - -// VPMOVD2M performs "Move Signs of Packed Doubleword Integers to Mask Register". -// -// Mnemonic : VPMOVD2M -// Supported forms : (3 forms) -// -// * VPMOVD2M zmm, k [AVX512DQ] -// * VPMOVD2M xmm, k [AVX512DQ,AVX512VL] -// * VPMOVD2M ymm, k [AVX512DQ,AVX512VL] -// -func (self *Program) VPMOVD2M(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVD2M", 2, Operands { v0, v1 }) - // VPMOVD2M zmm, k - if isZMM(v0) && isK(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x48) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVD2M xmm, k - if isEVEXXMM(v0) && isK(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x08) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVD2M ymm, k - if isEVEXYMM(v0) && isK(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x28) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVD2M") - } - return p -} - -// VPMOVDB performs "Down Convert Packed Doubleword Values to Byte Values with Truncation". -// -// Mnemonic : VPMOVDB -// Supported forms : (6 forms) -// -// * VPMOVDB zmm, xmm{k}{z} [AVX512F] -// * VPMOVDB zmm, m128{k}{z} [AVX512F] -// * VPMOVDB xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVDB xmm, m32{k}{z} [AVX512F,AVX512VL] -// * VPMOVDB ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVDB ymm, m64{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVDB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVDB", 2, Operands { v0, v1 }) - // VPMOVDB zmm, xmm{k}{z} - if isZMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x31) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVDB zmm, m128{k}{z} - if isZMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x31) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VPMOVDB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x31) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVDB xmm, m32{k}{z} - if isEVEXXMM(v0) && isM32kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x31) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPMOVDB ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x31) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVDB ymm, m64{k}{z} - if isEVEXYMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x31) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVDB") - } - return p -} - -// VPMOVDW performs "Down Convert Packed Doubleword Values to Word Values with Truncation". -// -// Mnemonic : VPMOVDW -// Supported forms : (6 forms) -// -// * VPMOVDW zmm, ymm{k}{z} [AVX512F] -// * VPMOVDW zmm, m256{k}{z} [AVX512F] -// * VPMOVDW xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVDW xmm, m64{k}{z} [AVX512F,AVX512VL] -// * VPMOVDW ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVDW ymm, m128{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVDW", 2, Operands { v0, v1 }) - // VPMOVDW zmm, ymm{k}{z} - if isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x33) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVDW zmm, m256{k}{z} - if isZMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x33) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VPMOVDW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x33) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVDW xmm, m64{k}{z} - if isEVEXXMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x33) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVDW ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x33) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVDW ymm, m128{k}{z} - if isEVEXYMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x33) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVDW") - } - return p -} - -// VPMOVM2B performs "Expand Bits of Mask Register to Packed Byte Integers". -// -// Mnemonic : VPMOVM2B -// Supported forms : (3 forms) -// -// * VPMOVM2B k, zmm [AVX512BW] -// * VPMOVM2B k, xmm [AVX512BW,AVX512VL] -// * VPMOVM2B k, ymm [AVX512BW,AVX512VL] -// -func (self *Program) VPMOVM2B(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVM2B", 2, Operands { v0, v1 }) - // VPMOVM2B k, zmm - if isK(v0) && isZMM(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x48) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVM2B k, xmm - if isK(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x08) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVM2B k, ymm - if isK(v0) && isEVEXYMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x28) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVM2B") - } - return p -} - -// VPMOVM2D performs "Expand Bits of Mask Register to Packed Doubleword Integers". -// -// Mnemonic : VPMOVM2D -// Supported forms : (3 forms) -// -// * VPMOVM2D k, zmm [AVX512DQ] -// * VPMOVM2D k, xmm [AVX512DQ,AVX512VL] -// * VPMOVM2D k, ymm [AVX512DQ,AVX512VL] -// -func (self *Program) VPMOVM2D(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVM2D", 2, Operands { v0, v1 }) - // VPMOVM2D k, zmm - if isK(v0) && isZMM(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x48) - m.emit(0x38) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVM2D k, xmm - if isK(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x08) - m.emit(0x38) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVM2D k, ymm - if isK(v0) && isEVEXYMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7e) - m.emit(0x28) - m.emit(0x38) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVM2D") - } - return p -} - -// VPMOVM2Q performs "Expand Bits of Mask Register to Packed Quadword Integers". -// -// Mnemonic : VPMOVM2Q -// Supported forms : (3 forms) -// -// * VPMOVM2Q k, zmm [AVX512DQ] -// * VPMOVM2Q k, xmm [AVX512DQ,AVX512VL] -// * VPMOVM2Q k, ymm [AVX512DQ,AVX512VL] -// -func (self *Program) VPMOVM2Q(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVM2Q", 2, Operands { v0, v1 }) - // VPMOVM2Q k, zmm - if isK(v0) && isZMM(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x48) - m.emit(0x38) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVM2Q k, xmm - if isK(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x08) - m.emit(0x38) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVM2Q k, ymm - if isK(v0) && isEVEXYMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x28) - m.emit(0x38) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVM2Q") - } - return p -} - -// VPMOVM2W performs "Expand Bits of Mask Register to Packed Word Integers". -// -// Mnemonic : VPMOVM2W -// Supported forms : (3 forms) -// -// * VPMOVM2W k, zmm [AVX512BW] -// * VPMOVM2W k, xmm [AVX512BW,AVX512VL] -// * VPMOVM2W k, ymm [AVX512BW,AVX512VL] -// -func (self *Program) VPMOVM2W(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVM2W", 2, Operands { v0, v1 }) - // VPMOVM2W k, zmm - if isK(v0) && isZMM(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x48) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVM2W k, xmm - if isK(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x08) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVM2W k, ymm - if isK(v0) && isEVEXYMM(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x28) - m.emit(0x28) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVM2W") - } - return p -} - -// VPMOVMSKB performs "Move Byte Mask". -// -// Mnemonic : VPMOVMSKB -// Supported forms : (2 forms) -// -// * VPMOVMSKB xmm, r32 [AVX] -// * VPMOVMSKB ymm, r32 [AVX2] -// -func (self *Program) VPMOVMSKB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVMSKB", 2, Operands { v0, v1 }) - // VPMOVMSKB xmm, r32 - if isXMM(v0) && isReg32(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0xd7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVMSKB ymm, r32 - if isYMM(v0) && isReg32(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), v[0], 0) - m.emit(0xd7) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVMSKB") - } - return p -} - -// VPMOVQ2M performs "Move Signs of Packed Quadword Integers to Mask Register". -// -// Mnemonic : VPMOVQ2M -// Supported forms : (3 forms) -// -// * VPMOVQ2M zmm, k [AVX512DQ] -// * VPMOVQ2M xmm, k [AVX512DQ,AVX512VL] -// * VPMOVQ2M ymm, k [AVX512DQ,AVX512VL] -// -func (self *Program) VPMOVQ2M(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVQ2M", 2, Operands { v0, v1 }) - // VPMOVQ2M zmm, k - if isZMM(v0) && isK(v1) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x48) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVQ2M xmm, k - if isEVEXXMM(v0) && isK(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x08) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVQ2M ymm, k - if isEVEXYMM(v0) && isK(v1) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x28) - m.emit(0x39) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVQ2M") - } - return p -} - -// VPMOVQB performs "Down Convert Packed Quadword Values to Byte Values with Truncation". -// -// Mnemonic : VPMOVQB -// Supported forms : (6 forms) -// -// * VPMOVQB zmm, xmm{k}{z} [AVX512F] -// * VPMOVQB zmm, m64{k}{z} [AVX512F] -// * VPMOVQB xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVQB xmm, m16{k}{z} [AVX512F,AVX512VL] -// * VPMOVQB ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVQB ymm, m32{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVQB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVQB", 2, Operands { v0, v1 }) - // VPMOVQB zmm, xmm{k}{z} - if isZMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x32) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVQB zmm, m64{k}{z} - if isZMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x32) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVQB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x32) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVQB xmm, m16{k}{z} - if isEVEXXMM(v0) && isM16kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x32) - m.mrsd(lcode(v[0]), addr(v[1]), 2) - }) - } - // VPMOVQB ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x32) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVQB ymm, m32{k}{z} - if isEVEXYMM(v0) && isM32kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x32) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVQB") - } - return p -} - -// VPMOVQD performs "Down Convert Packed Quadword Values to Doubleword Values with Truncation". -// -// Mnemonic : VPMOVQD -// Supported forms : (6 forms) -// -// * VPMOVQD zmm, ymm{k}{z} [AVX512F] -// * VPMOVQD zmm, m256{k}{z} [AVX512F] -// * VPMOVQD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVQD xmm, m64{k}{z} [AVX512F,AVX512VL] -// * VPMOVQD ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVQD ymm, m128{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVQD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVQD", 2, Operands { v0, v1 }) - // VPMOVQD zmm, ymm{k}{z} - if isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x35) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVQD zmm, m256{k}{z} - if isZMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x35) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VPMOVQD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x35) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVQD xmm, m64{k}{z} - if isEVEXXMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x35) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVQD ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x35) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVQD ymm, m128{k}{z} - if isEVEXYMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x35) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVQD") - } - return p -} - -// VPMOVQW performs "Down Convert Packed Quadword Values to Word Values with Truncation". -// -// Mnemonic : VPMOVQW -// Supported forms : (6 forms) -// -// * VPMOVQW zmm, xmm{k}{z} [AVX512F] -// * VPMOVQW zmm, m128{k}{z} [AVX512F] -// * VPMOVQW xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVQW xmm, m32{k}{z} [AVX512F,AVX512VL] -// * VPMOVQW ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVQW ymm, m64{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVQW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVQW", 2, Operands { v0, v1 }) - // VPMOVQW zmm, xmm{k}{z} - if isZMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x34) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVQW zmm, m128{k}{z} - if isZMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x34) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VPMOVQW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x34) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVQW xmm, m32{k}{z} - if isEVEXXMM(v0) && isM32kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x34) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPMOVQW ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x34) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVQW ymm, m64{k}{z} - if isEVEXYMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x34) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVQW") - } - return p -} - -// VPMOVSDB performs "Down Convert Packed Doubleword Values to Byte Values with Signed Saturation". -// -// Mnemonic : VPMOVSDB -// Supported forms : (6 forms) -// -// * VPMOVSDB zmm, xmm{k}{z} [AVX512F] -// * VPMOVSDB zmm, m128{k}{z} [AVX512F] -// * VPMOVSDB xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSDB xmm, m32{k}{z} [AVX512F,AVX512VL] -// * VPMOVSDB ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSDB ymm, m64{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSDB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSDB", 2, Operands { v0, v1 }) - // VPMOVSDB zmm, xmm{k}{z} - if isZMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x21) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSDB zmm, m128{k}{z} - if isZMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x21) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VPMOVSDB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x21) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSDB xmm, m32{k}{z} - if isEVEXXMM(v0) && isM32kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x21) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPMOVSDB ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x21) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSDB ymm, m64{k}{z} - if isEVEXYMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x21) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSDB") - } - return p -} - -// VPMOVSDW performs "Down Convert Packed Doubleword Values to Word Values with Signed Saturation". -// -// Mnemonic : VPMOVSDW -// Supported forms : (6 forms) -// -// * VPMOVSDW zmm, ymm{k}{z} [AVX512F] -// * VPMOVSDW zmm, m256{k}{z} [AVX512F] -// * VPMOVSDW xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSDW xmm, m64{k}{z} [AVX512F,AVX512VL] -// * VPMOVSDW ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSDW ymm, m128{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSDW", 2, Operands { v0, v1 }) - // VPMOVSDW zmm, ymm{k}{z} - if isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x23) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSDW zmm, m256{k}{z} - if isZMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x23) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VPMOVSDW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x23) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSDW xmm, m64{k}{z} - if isEVEXXMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x23) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVSDW ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x23) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSDW ymm, m128{k}{z} - if isEVEXYMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x23) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSDW") - } - return p -} - -// VPMOVSQB performs "Down Convert Packed Quadword Values to Byte Values with Signed Saturation". -// -// Mnemonic : VPMOVSQB -// Supported forms : (6 forms) -// -// * VPMOVSQB zmm, xmm{k}{z} [AVX512F] -// * VPMOVSQB zmm, m64{k}{z} [AVX512F] -// * VPMOVSQB xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSQB xmm, m16{k}{z} [AVX512F,AVX512VL] -// * VPMOVSQB ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSQB ymm, m32{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSQB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSQB", 2, Operands { v0, v1 }) - // VPMOVSQB zmm, xmm{k}{z} - if isZMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x22) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSQB zmm, m64{k}{z} - if isZMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x22) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVSQB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x22) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSQB xmm, m16{k}{z} - if isEVEXXMM(v0) && isM16kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x22) - m.mrsd(lcode(v[0]), addr(v[1]), 2) - }) - } - // VPMOVSQB ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x22) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSQB ymm, m32{k}{z} - if isEVEXYMM(v0) && isM32kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x22) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSQB") - } - return p -} - -// VPMOVSQD performs "Down Convert Packed Quadword Values to Doubleword Values with Signed Saturation". -// -// Mnemonic : VPMOVSQD -// Supported forms : (6 forms) -// -// * VPMOVSQD zmm, ymm{k}{z} [AVX512F] -// * VPMOVSQD zmm, m256{k}{z} [AVX512F] -// * VPMOVSQD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSQD xmm, m64{k}{z} [AVX512F,AVX512VL] -// * VPMOVSQD ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSQD ymm, m128{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSQD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSQD", 2, Operands { v0, v1 }) - // VPMOVSQD zmm, ymm{k}{z} - if isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x25) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSQD zmm, m256{k}{z} - if isZMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x25) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VPMOVSQD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x25) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSQD xmm, m64{k}{z} - if isEVEXXMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x25) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVSQD ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x25) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSQD ymm, m128{k}{z} - if isEVEXYMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x25) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSQD") - } - return p -} - -// VPMOVSQW performs "Down Convert Packed Quadword Values to Word Values with Signed Saturation". -// -// Mnemonic : VPMOVSQW -// Supported forms : (6 forms) -// -// * VPMOVSQW zmm, xmm{k}{z} [AVX512F] -// * VPMOVSQW zmm, m128{k}{z} [AVX512F] -// * VPMOVSQW xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSQW xmm, m32{k}{z} [AVX512F,AVX512VL] -// * VPMOVSQW ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSQW ymm, m64{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSQW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSQW", 2, Operands { v0, v1 }) - // VPMOVSQW zmm, xmm{k}{z} - if isZMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x24) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSQW zmm, m128{k}{z} - if isZMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x24) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VPMOVSQW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x24) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSQW xmm, m32{k}{z} - if isEVEXXMM(v0) && isM32kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x24) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPMOVSQW ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x24) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSQW ymm, m64{k}{z} - if isEVEXYMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x24) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSQW") - } - return p -} - -// VPMOVSWB performs "Down Convert Packed Word Values to Byte Values with Signed Saturation". -// -// Mnemonic : VPMOVSWB -// Supported forms : (6 forms) -// -// * VPMOVSWB zmm, ymm{k}{z} [AVX512BW] -// * VPMOVSWB zmm, m256{k}{z} [AVX512BW] -// * VPMOVSWB xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVSWB xmm, m64{k}{z} [AVX512BW,AVX512VL] -// * VPMOVSWB ymm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVSWB ymm, m128{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMOVSWB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSWB", 2, Operands { v0, v1 }) - // VPMOVSWB zmm, ymm{k}{z} - if isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x20) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSWB zmm, m256{k}{z} - if isZMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x20) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VPMOVSWB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x20) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSWB xmm, m64{k}{z} - if isEVEXXMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x20) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVSWB ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x20) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVSWB ymm, m128{k}{z} - if isEVEXYMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x20) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSWB") - } - return p -} - -// VPMOVSXBD performs "Move Packed Byte Integers to Doubleword Integers with Sign Extension". -// -// Mnemonic : VPMOVSXBD -// Supported forms : (10 forms) -// -// * VPMOVSXBD xmm, xmm [AVX] -// * VPMOVSXBD m32, xmm [AVX] -// * VPMOVSXBD xmm, ymm [AVX2] -// * VPMOVSXBD m64, ymm [AVX2] -// * VPMOVSXBD xmm, zmm{k}{z} [AVX512F] -// * VPMOVSXBD m128, zmm{k}{z} [AVX512F] -// * VPMOVSXBD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXBD xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXBD m32, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXBD m64, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSXBD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSXBD", 2, Operands { v0, v1 }) - // VPMOVSXBD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x21) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBD m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x21) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXBD xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x21) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBD m64, ymm - if isM64(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x21) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXBD xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x21) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBD m128, zmm{k}{z} - if isM128(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x21) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPMOVSXBD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x21) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBD xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x21) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBD m32, xmm{k}{z} - if isM32(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x21) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPMOVSXBD m64, ymm{k}{z} - if isM64(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x21) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSXBD") - } - return p -} - -// VPMOVSXBQ performs "Move Packed Byte Integers to Quadword Integers with Sign Extension". -// -// Mnemonic : VPMOVSXBQ -// Supported forms : (10 forms) -// -// * VPMOVSXBQ xmm, xmm [AVX] -// * VPMOVSXBQ m16, xmm [AVX] -// * VPMOVSXBQ xmm, ymm [AVX2] -// * VPMOVSXBQ m32, ymm [AVX2] -// * VPMOVSXBQ xmm, zmm{k}{z} [AVX512F] -// * VPMOVSXBQ m64, zmm{k}{z} [AVX512F] -// * VPMOVSXBQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXBQ xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXBQ m16, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXBQ m32, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSXBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSXBQ", 2, Operands { v0, v1 }) - // VPMOVSXBQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x22) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBQ m16, xmm - if isM16(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x22) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXBQ xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x22) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBQ m32, ymm - if isM32(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x22) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXBQ xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x22) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBQ m64, zmm{k}{z} - if isM64(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x22) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPMOVSXBQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x22) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBQ xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x22) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBQ m16, xmm{k}{z} - if isM16(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x22) - m.mrsd(lcode(v[1]), addr(v[0]), 2) - }) - } - // VPMOVSXBQ m32, ymm{k}{z} - if isM32(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x22) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSXBQ") - } - return p -} - -// VPMOVSXBW performs "Move Packed Byte Integers to Word Integers with Sign Extension". -// -// Mnemonic : VPMOVSXBW -// Supported forms : (10 forms) -// -// * VPMOVSXBW xmm, xmm [AVX] -// * VPMOVSXBW m64, xmm [AVX] -// * VPMOVSXBW xmm, ymm [AVX2] -// * VPMOVSXBW m128, ymm [AVX2] -// * VPMOVSXBW ymm, zmm{k}{z} [AVX512BW] -// * VPMOVSXBW m256, zmm{k}{z} [AVX512BW] -// * VPMOVSXBW xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVSXBW xmm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVSXBW m64, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVSXBW m128, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMOVSXBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSXBW", 2, Operands { v0, v1 }) - // VPMOVSXBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x20) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBW m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x20) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXBW xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x20) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBW m128, ymm - if isM128(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x20) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXBW ymm, zmm{k}{z} - if isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x20) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBW m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x20) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPMOVSXBW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x20) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBW xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x20) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXBW m64, xmm{k}{z} - if isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x20) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPMOVSXBW m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x20) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSXBW") - } - return p -} - -// VPMOVSXDQ performs "Move Packed Doubleword Integers to Quadword Integers with Sign Extension". -// -// Mnemonic : VPMOVSXDQ -// Supported forms : (10 forms) -// -// * VPMOVSXDQ xmm, xmm [AVX] -// * VPMOVSXDQ m64, xmm [AVX] -// * VPMOVSXDQ xmm, ymm [AVX2] -// * VPMOVSXDQ m128, ymm [AVX2] -// * VPMOVSXDQ ymm, zmm{k}{z} [AVX512F] -// * VPMOVSXDQ m256, zmm{k}{z} [AVX512F] -// * VPMOVSXDQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXDQ xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXDQ m64, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXDQ m128, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSXDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSXDQ", 2, Operands { v0, v1 }) - // VPMOVSXDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x25) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXDQ m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x25) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXDQ xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x25) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXDQ m128, ymm - if isM128(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x25) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXDQ ymm, zmm{k}{z} - if isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x25) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXDQ m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x25) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPMOVSXDQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x25) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXDQ xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x25) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXDQ m64, xmm{k}{z} - if isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x25) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPMOVSXDQ m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x25) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSXDQ") - } - return p -} - -// VPMOVSXWD performs "Move Packed Word Integers to Doubleword Integers with Sign Extension". -// -// Mnemonic : VPMOVSXWD -// Supported forms : (10 forms) -// -// * VPMOVSXWD xmm, xmm [AVX] -// * VPMOVSXWD m64, xmm [AVX] -// * VPMOVSXWD xmm, ymm [AVX2] -// * VPMOVSXWD m128, ymm [AVX2] -// * VPMOVSXWD ymm, zmm{k}{z} [AVX512F] -// * VPMOVSXWD m256, zmm{k}{z} [AVX512F] -// * VPMOVSXWD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXWD xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXWD m64, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXWD m128, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSXWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSXWD", 2, Operands { v0, v1 }) - // VPMOVSXWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x23) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x23) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXWD xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x23) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWD m128, ymm - if isM128(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x23) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXWD ymm, zmm{k}{z} - if isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x23) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWD m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x23) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPMOVSXWD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x23) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWD xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x23) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWD m64, xmm{k}{z} - if isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x23) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPMOVSXWD m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x23) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSXWD") - } - return p -} - -// VPMOVSXWQ performs "Move Packed Word Integers to Quadword Integers with Sign Extension". -// -// Mnemonic : VPMOVSXWQ -// Supported forms : (10 forms) -// -// * VPMOVSXWQ xmm, xmm [AVX] -// * VPMOVSXWQ m32, xmm [AVX] -// * VPMOVSXWQ xmm, ymm [AVX2] -// * VPMOVSXWQ m64, ymm [AVX2] -// * VPMOVSXWQ xmm, zmm{k}{z} [AVX512F] -// * VPMOVSXWQ m128, zmm{k}{z} [AVX512F] -// * VPMOVSXWQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXWQ xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXWQ m32, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVSXWQ m64, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVSXWQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVSXWQ", 2, Operands { v0, v1 }) - // VPMOVSXWQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x24) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWQ m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x24) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXWQ xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x24) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWQ m64, ymm - if isM64(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x24) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVSXWQ xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x24) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWQ m128, zmm{k}{z} - if isM128(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x24) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPMOVSXWQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x24) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWQ xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x24) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVSXWQ m32, xmm{k}{z} - if isM32(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x24) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPMOVSXWQ m64, ymm{k}{z} - if isM64(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x24) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVSXWQ") - } - return p -} - -// VPMOVUSDB performs "Down Convert Packed Doubleword Values to Byte Values with Unsigned Saturation". -// -// Mnemonic : VPMOVUSDB -// Supported forms : (6 forms) -// -// * VPMOVUSDB zmm, xmm{k}{z} [AVX512F] -// * VPMOVUSDB zmm, m128{k}{z} [AVX512F] -// * VPMOVUSDB xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSDB xmm, m32{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSDB ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSDB ymm, m64{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVUSDB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVUSDB", 2, Operands { v0, v1 }) - // VPMOVUSDB zmm, xmm{k}{z} - if isZMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSDB zmm, m128{k}{z} - if isZMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VPMOVUSDB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSDB xmm, m32{k}{z} - if isEVEXXMM(v0) && isM32kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPMOVUSDB ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x11) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSDB ymm, m64{k}{z} - if isEVEXYMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x11) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVUSDB") - } - return p -} - -// VPMOVUSDW performs "Down Convert Packed Doubleword Values to Word Values with Unsigned Saturation". -// -// Mnemonic : VPMOVUSDW -// Supported forms : (6 forms) -// -// * VPMOVUSDW zmm, ymm{k}{z} [AVX512F] -// * VPMOVUSDW zmm, m256{k}{z} [AVX512F] -// * VPMOVUSDW xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSDW xmm, m64{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSDW ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSDW ymm, m128{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVUSDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVUSDW", 2, Operands { v0, v1 }) - // VPMOVUSDW zmm, ymm{k}{z} - if isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x13) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSDW zmm, m256{k}{z} - if isZMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x13) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VPMOVUSDW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x13) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSDW xmm, m64{k}{z} - if isEVEXXMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x13) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVUSDW ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x13) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSDW ymm, m128{k}{z} - if isEVEXYMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x13) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVUSDW") - } - return p -} - -// VPMOVUSQB performs "Down Convert Packed Quadword Values to Byte Values with Unsigned Saturation". -// -// Mnemonic : VPMOVUSQB -// Supported forms : (6 forms) -// -// * VPMOVUSQB zmm, xmm{k}{z} [AVX512F] -// * VPMOVUSQB zmm, m64{k}{z} [AVX512F] -// * VPMOVUSQB xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSQB xmm, m16{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSQB ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSQB ymm, m32{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVUSQB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVUSQB", 2, Operands { v0, v1 }) - // VPMOVUSQB zmm, xmm{k}{z} - if isZMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x12) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSQB zmm, m64{k}{z} - if isZMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x12) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVUSQB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x12) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSQB xmm, m16{k}{z} - if isEVEXXMM(v0) && isM16kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x12) - m.mrsd(lcode(v[0]), addr(v[1]), 2) - }) - } - // VPMOVUSQB ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x12) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSQB ymm, m32{k}{z} - if isEVEXYMM(v0) && isM32kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x12) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVUSQB") - } - return p -} - -// VPMOVUSQD performs "Down Convert Packed Quadword Values to Doubleword Values with Unsigned Saturation". -// -// Mnemonic : VPMOVUSQD -// Supported forms : (6 forms) -// -// * VPMOVUSQD zmm, ymm{k}{z} [AVX512F] -// * VPMOVUSQD zmm, m256{k}{z} [AVX512F] -// * VPMOVUSQD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSQD xmm, m64{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSQD ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSQD ymm, m128{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVUSQD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVUSQD", 2, Operands { v0, v1 }) - // VPMOVUSQD zmm, ymm{k}{z} - if isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x15) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSQD zmm, m256{k}{z} - if isZMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x15) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VPMOVUSQD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x15) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSQD xmm, m64{k}{z} - if isEVEXXMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x15) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVUSQD ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x15) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSQD ymm, m128{k}{z} - if isEVEXYMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x15) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVUSQD") - } - return p -} - -// VPMOVUSQW performs "Down Convert Packed Quadword Values to Word Values with Unsigned Saturation". -// -// Mnemonic : VPMOVUSQW -// Supported forms : (6 forms) -// -// * VPMOVUSQW zmm, xmm{k}{z} [AVX512F] -// * VPMOVUSQW zmm, m128{k}{z} [AVX512F] -// * VPMOVUSQW xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSQW xmm, m32{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSQW ymm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVUSQW ymm, m64{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVUSQW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVUSQW", 2, Operands { v0, v1 }) - // VPMOVUSQW zmm, xmm{k}{z} - if isZMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x14) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSQW zmm, m128{k}{z} - if isZMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x14) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - // VPMOVUSQW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x14) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSQW xmm, m32{k}{z} - if isEVEXXMM(v0) && isM32kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x14) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPMOVUSQW ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x14) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSQW ymm, m64{k}{z} - if isEVEXYMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x14) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVUSQW") - } - return p -} - -// VPMOVUSWB performs "Down Convert Packed Word Values to Byte Values with Unsigned Saturation". -// -// Mnemonic : VPMOVUSWB -// Supported forms : (6 forms) -// -// * VPMOVUSWB zmm, ymm{k}{z} [AVX512BW] -// * VPMOVUSWB zmm, m256{k}{z} [AVX512BW] -// * VPMOVUSWB xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVUSWB xmm, m64{k}{z} [AVX512BW,AVX512VL] -// * VPMOVUSWB ymm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVUSWB ymm, m128{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMOVUSWB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVUSWB", 2, Operands { v0, v1 }) - // VPMOVUSWB zmm, ymm{k}{z} - if isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x10) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSWB zmm, m256{k}{z} - if isZMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VPMOVUSWB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x10) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSWB xmm, m64{k}{z} - if isEVEXXMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVUSWB ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x10) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVUSWB ymm, m128{k}{z} - if isEVEXYMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x10) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVUSWB") - } - return p -} - -// VPMOVW2M performs "Move Signs of Packed Word Integers to Mask Register". -// -// Mnemonic : VPMOVW2M -// Supported forms : (3 forms) -// -// * VPMOVW2M zmm, k [AVX512BW] -// * VPMOVW2M xmm, k [AVX512BW,AVX512VL] -// * VPMOVW2M ymm, k [AVX512BW,AVX512VL] -// -func (self *Program) VPMOVW2M(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVW2M", 2, Operands { v0, v1 }) - // VPMOVW2M zmm, k - if isZMM(v0) && isK(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x48) - m.emit(0x29) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVW2M xmm, k - if isEVEXXMM(v0) && isK(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x08) - m.emit(0x29) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVW2M ymm, k - if isEVEXYMM(v0) && isK(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfe) - m.emit(0x28) - m.emit(0x29) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVW2M") - } - return p -} - -// VPMOVWB performs "Down Convert Packed Word Values to Byte Values with Truncation". -// -// Mnemonic : VPMOVWB -// Supported forms : (6 forms) -// -// * VPMOVWB zmm, ymm{k}{z} [AVX512BW] -// * VPMOVWB zmm, m256{k}{z} [AVX512BW] -// * VPMOVWB xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVWB xmm, m64{k}{z} [AVX512BW,AVX512VL] -// * VPMOVWB ymm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVWB ymm, m128{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMOVWB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVWB", 2, Operands { v0, v1 }) - // VPMOVWB zmm, ymm{k}{z} - if isZMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x30) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVWB zmm, m256{k}{z} - if isZMM(v0) && isM256kz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x30) - m.mrsd(lcode(v[0]), addr(v[1]), 32) - }) - } - // VPMOVWB xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x30) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVWB xmm, m64{k}{z} - if isEVEXXMM(v0) && isM64kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x30) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPMOVWB ymm, xmm{k}{z} - if isEVEXYMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[0]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[0]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x30) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // VPMOVWB ymm, m128{k}{z} - if isEVEXYMM(v0) && isM128kz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x30) - m.mrsd(lcode(v[0]), addr(v[1]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVWB") - } - return p -} - -// VPMOVZXBD performs "Move Packed Byte Integers to Doubleword Integers with Zero Extension". -// -// Mnemonic : VPMOVZXBD -// Supported forms : (10 forms) -// -// * VPMOVZXBD xmm, xmm [AVX] -// * VPMOVZXBD m32, xmm [AVX] -// * VPMOVZXBD xmm, ymm [AVX2] -// * VPMOVZXBD m64, ymm [AVX2] -// * VPMOVZXBD xmm, zmm{k}{z} [AVX512F] -// * VPMOVZXBD m128, zmm{k}{z} [AVX512F] -// * VPMOVZXBD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXBD xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXBD m32, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXBD m64, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVZXBD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVZXBD", 2, Operands { v0, v1 }) - // VPMOVZXBD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x31) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBD m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x31) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXBD xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x31) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBD m64, ymm - if isM64(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x31) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXBD xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x31) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBD m128, zmm{k}{z} - if isM128(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x31) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPMOVZXBD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x31) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBD xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x31) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBD m32, xmm{k}{z} - if isM32(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x31) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPMOVZXBD m64, ymm{k}{z} - if isM64(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x31) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVZXBD") - } - return p -} - -// VPMOVZXBQ performs "Move Packed Byte Integers to Quadword Integers with Zero Extension". -// -// Mnemonic : VPMOVZXBQ -// Supported forms : (10 forms) -// -// * VPMOVZXBQ xmm, xmm [AVX] -// * VPMOVZXBQ m16, xmm [AVX] -// * VPMOVZXBQ xmm, ymm [AVX2] -// * VPMOVZXBQ m32, ymm [AVX2] -// * VPMOVZXBQ xmm, zmm{k}{z} [AVX512F] -// * VPMOVZXBQ m64, zmm{k}{z} [AVX512F] -// * VPMOVZXBQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXBQ xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXBQ m16, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXBQ m32, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVZXBQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVZXBQ", 2, Operands { v0, v1 }) - // VPMOVZXBQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x32) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBQ m16, xmm - if isM16(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x32) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXBQ xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x32) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBQ m32, ymm - if isM32(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x32) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXBQ xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x32) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBQ m64, zmm{k}{z} - if isM64(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x32) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPMOVZXBQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x32) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBQ xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x32) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBQ m16, xmm{k}{z} - if isM16(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x32) - m.mrsd(lcode(v[1]), addr(v[0]), 2) - }) - } - // VPMOVZXBQ m32, ymm{k}{z} - if isM32(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x32) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVZXBQ") - } - return p -} - -// VPMOVZXBW performs "Move Packed Byte Integers to Word Integers with Zero Extension". -// -// Mnemonic : VPMOVZXBW -// Supported forms : (10 forms) -// -// * VPMOVZXBW xmm, xmm [AVX] -// * VPMOVZXBW m64, xmm [AVX] -// * VPMOVZXBW xmm, ymm [AVX2] -// * VPMOVZXBW m128, ymm [AVX2] -// * VPMOVZXBW ymm, zmm{k}{z} [AVX512BW] -// * VPMOVZXBW m256, zmm{k}{z} [AVX512BW] -// * VPMOVZXBW xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVZXBW xmm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVZXBW m64, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMOVZXBW m128, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMOVZXBW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVZXBW", 2, Operands { v0, v1 }) - // VPMOVZXBW xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x30) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBW m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x30) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXBW xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x30) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBW m128, ymm - if isM128(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x30) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXBW ymm, zmm{k}{z} - if isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x30) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBW m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x30) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPMOVZXBW xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x30) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBW xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x30) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXBW m64, xmm{k}{z} - if isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x30) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPMOVZXBW m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x30) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVZXBW") - } - return p -} - -// VPMOVZXDQ performs "Move Packed Doubleword Integers to Quadword Integers with Zero Extension". -// -// Mnemonic : VPMOVZXDQ -// Supported forms : (10 forms) -// -// * VPMOVZXDQ xmm, xmm [AVX] -// * VPMOVZXDQ m64, xmm [AVX] -// * VPMOVZXDQ xmm, ymm [AVX2] -// * VPMOVZXDQ m128, ymm [AVX2] -// * VPMOVZXDQ ymm, zmm{k}{z} [AVX512F] -// * VPMOVZXDQ m256, zmm{k}{z} [AVX512F] -// * VPMOVZXDQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXDQ xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXDQ m64, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXDQ m128, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVZXDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVZXDQ", 2, Operands { v0, v1 }) - // VPMOVZXDQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x35) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXDQ m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x35) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXDQ xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x35) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXDQ m128, ymm - if isM128(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x35) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXDQ ymm, zmm{k}{z} - if isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x35) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXDQ m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x35) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPMOVZXDQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x35) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXDQ xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x35) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXDQ m64, xmm{k}{z} - if isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x35) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPMOVZXDQ m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x35) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVZXDQ") - } - return p -} - -// VPMOVZXWD performs "Move Packed Word Integers to Doubleword Integers with Zero Extension". -// -// Mnemonic : VPMOVZXWD -// Supported forms : (10 forms) -// -// * VPMOVZXWD xmm, xmm [AVX] -// * VPMOVZXWD m64, xmm [AVX] -// * VPMOVZXWD xmm, ymm [AVX2] -// * VPMOVZXWD m128, ymm [AVX2] -// * VPMOVZXWD ymm, zmm{k}{z} [AVX512F] -// * VPMOVZXWD m256, zmm{k}{z} [AVX512F] -// * VPMOVZXWD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXWD xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXWD m64, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXWD m128, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVZXWD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVZXWD", 2, Operands { v0, v1 }) - // VPMOVZXWD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x33) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWD m64, xmm - if isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x33) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXWD xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x33) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWD m128, ymm - if isM128(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x33) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXWD ymm, zmm{k}{z} - if isEVEXYMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x33) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWD m256, zmm{k}{z} - if isM256(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x33) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VPMOVZXWD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x33) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWD xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x33) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWD m64, xmm{k}{z} - if isM64(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x33) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VPMOVZXWD m128, ymm{k}{z} - if isM128(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x33) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVZXWD") - } - return p -} - -// VPMOVZXWQ performs "Move Packed Word Integers to Quadword Integers with Zero Extension". -// -// Mnemonic : VPMOVZXWQ -// Supported forms : (10 forms) -// -// * VPMOVZXWQ xmm, xmm [AVX] -// * VPMOVZXWQ m32, xmm [AVX] -// * VPMOVZXWQ xmm, ymm [AVX2] -// * VPMOVZXWQ m64, ymm [AVX2] -// * VPMOVZXWQ xmm, zmm{k}{z} [AVX512F] -// * VPMOVZXWQ m128, zmm{k}{z} [AVX512F] -// * VPMOVZXWQ xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXWQ xmm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXWQ m32, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMOVZXWQ m64, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMOVZXWQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPMOVZXWQ", 2, Operands { v0, v1 }) - // VPMOVZXWQ xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x34) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWQ m32, xmm - if isM32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x34) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXWQ xmm, ymm - if isXMM(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x34) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWQ m64, ymm - if isM64(v0) && isYMM(v1) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x34) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPMOVZXWQ xmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x34) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWQ m128, zmm{k}{z} - if isM128(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x34) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VPMOVZXWQ xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x34) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWQ xmm, ymm{k}{z} - if isEVEXXMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x34) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPMOVZXWQ m32, xmm{k}{z} - if isM32(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x34) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VPMOVZXWQ m64, ymm{k}{z} - if isM64(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), 0) - m.emit(0x34) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPMOVZXWQ") - } - return p -} - -// VPMULDQ performs "Multiply Packed Signed Doubleword Integers and Store Quadword Result". -// -// Mnemonic : VPMULDQ -// Supported forms : (10 forms) -// -// * VPMULDQ xmm, xmm, xmm [AVX] -// * VPMULDQ m128, xmm, xmm [AVX] -// * VPMULDQ ymm, ymm, ymm [AVX2] -// * VPMULDQ m256, ymm, ymm [AVX2] -// * VPMULDQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMULDQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMULDQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMULDQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMULDQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMULDQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMULDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMULDQ", 3, Operands { v0, v1, v2 }) - // VPMULDQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x28) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULDQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x28) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULDQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x28) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULDQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x28) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULDQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x28) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMULDQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x28) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULDQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x28) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMULDQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x28) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULDQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x28) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMULDQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x28) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMULDQ") - } - return p -} - -// VPMULHRSW performs "Packed Multiply Signed Word Integers and Store High Result with Round and Scale". -// -// Mnemonic : VPMULHRSW -// Supported forms : (10 forms) -// -// * VPMULHRSW xmm, xmm, xmm [AVX] -// * VPMULHRSW m128, xmm, xmm [AVX] -// * VPMULHRSW ymm, ymm, ymm [AVX2] -// * VPMULHRSW m256, ymm, ymm [AVX2] -// * VPMULHRSW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMULHRSW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMULHRSW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMULHRSW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMULHRSW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMULHRSW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMULHRSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMULHRSW", 3, Operands { v0, v1, v2 }) - // VPMULHRSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHRSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x0b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULHRSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHRSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x0b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULHRSW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHRSW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x0b) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMULHRSW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHRSW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x0b) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMULHRSW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHRSW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x0b) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMULHRSW") - } - return p -} - -// VPMULHUW performs "Multiply Packed Unsigned Word Integers and Store High Result". -// -// Mnemonic : VPMULHUW -// Supported forms : (10 forms) -// -// * VPMULHUW xmm, xmm, xmm [AVX] -// * VPMULHUW m128, xmm, xmm [AVX] -// * VPMULHUW ymm, ymm, ymm [AVX2] -// * VPMULHUW m256, ymm, ymm [AVX2] -// * VPMULHUW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMULHUW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMULHUW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMULHUW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMULHUW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMULHUW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMULHUW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMULHUW", 3, Operands { v0, v1, v2 }) - // VPMULHUW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHUW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe4) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULHUW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHUW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe4) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULHUW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xe4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHUW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe4) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMULHUW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xe4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHUW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe4) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMULHUW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xe4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHUW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe4) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMULHUW") - } - return p -} - -// VPMULHW performs "Multiply Packed Signed Word Integers and Store High Result". -// -// Mnemonic : VPMULHW -// Supported forms : (10 forms) -// -// * VPMULHW xmm, xmm, xmm [AVX] -// * VPMULHW m128, xmm, xmm [AVX] -// * VPMULHW ymm, ymm, ymm [AVX2] -// * VPMULHW m256, ymm, ymm [AVX2] -// * VPMULHW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMULHW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMULHW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMULHW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMULHW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMULHW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMULHW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMULHW", 3, Operands { v0, v1, v2 }) - // VPMULHW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULHW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULHW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xe5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe5) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMULHW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xe5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe5) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMULHW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xe5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULHW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe5) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMULHW") - } - return p -} - -// VPMULLD performs "Multiply Packed Signed Doubleword Integers and Store Low Result". -// -// Mnemonic : VPMULLD -// Supported forms : (10 forms) -// -// * VPMULLD xmm, xmm, xmm [AVX] -// * VPMULLD m128, xmm, xmm [AVX] -// * VPMULLD ymm, ymm, ymm [AVX2] -// * VPMULLD m256, ymm, ymm [AVX2] -// * VPMULLD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMULLD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMULLD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMULLD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMULLD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMULLD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMULLD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMULLD", 3, Operands { v0, v1, v2 }) - // VPMULLD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x40) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x40) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULLD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x40) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x40) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULLD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x40) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMULLD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x40) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x40) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMULLD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x40) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x40) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMULLD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x40) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMULLD") - } - return p -} - -// VPMULLQ performs "Multiply Packed Signed Quadword Integers and Store Low Result". -// -// Mnemonic : VPMULLQ -// Supported forms : (6 forms) -// -// * VPMULLQ m512/m64bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VPMULLQ zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VPMULLQ m128/m64bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VPMULLQ xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VPMULLQ m256/m64bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VPMULLQ ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VPMULLQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMULLQ", 3, Operands { v0, v1, v2 }) - // VPMULLQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x40) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMULLQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x40) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x40) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMULLQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x40) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x40) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMULLQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x40) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMULLQ") - } - return p -} - -// VPMULLW performs "Multiply Packed Signed Word Integers and Store Low Result". -// -// Mnemonic : VPMULLW -// Supported forms : (10 forms) -// -// * VPMULLW xmm, xmm, xmm [AVX] -// * VPMULLW m128, xmm, xmm [AVX] -// * VPMULLW ymm, ymm, ymm [AVX2] -// * VPMULLW m256, ymm, ymm [AVX2] -// * VPMULLW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPMULLW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPMULLW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMULLW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPMULLW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPMULLW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPMULLW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMULLW", 3, Operands { v0, v1, v2 }) - // VPMULLW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULLW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd5) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULLW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xd5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd5) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMULLW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xd5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd5) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMULLW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xd5) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULLW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd5) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPMULLW") - } - return p -} - -// VPMULTISHIFTQB performs "Select Packed Unaligned Bytes from Quadword Sources". -// -// Mnemonic : VPMULTISHIFTQB -// Supported forms : (6 forms) -// -// * VPMULTISHIFTQB m128/m64bcst, xmm, xmm{k}{z} [AVX512VBMI,AVX512VL] -// * VPMULTISHIFTQB xmm, xmm, xmm{k}{z} [AVX512VBMI,AVX512VL] -// * VPMULTISHIFTQB m256/m64bcst, ymm, ymm{k}{z} [AVX512VBMI,AVX512VL] -// * VPMULTISHIFTQB ymm, ymm, ymm{k}{z} [AVX512VBMI,AVX512VL] -// * VPMULTISHIFTQB m512/m64bcst, zmm, zmm{k}{z} [AVX512VBMI] -// * VPMULTISHIFTQB zmm, zmm, zmm{k}{z} [AVX512VBMI] -// -func (self *Program) VPMULTISHIFTQB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMULTISHIFTQB", 3, Operands { v0, v1, v2 }) - // VPMULTISHIFTQB m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VBMI | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x83) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMULTISHIFTQB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VBMI | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x83) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULTISHIFTQB m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VBMI | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x83) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMULTISHIFTQB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VBMI | ISA_AVX512VL) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x83) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULTISHIFTQB m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x83) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMULTISHIFTQB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512VBMI) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x83) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMULTISHIFTQB") - } - return p -} - -// VPMULUDQ performs "Multiply Packed Unsigned Doubleword Integers". -// -// Mnemonic : VPMULUDQ -// Supported forms : (10 forms) -// -// * VPMULUDQ xmm, xmm, xmm [AVX] -// * VPMULUDQ m128, xmm, xmm [AVX] -// * VPMULUDQ ymm, ymm, ymm [AVX2] -// * VPMULUDQ m256, ymm, ymm [AVX2] -// * VPMULUDQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPMULUDQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPMULUDQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMULUDQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPMULUDQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPMULUDQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPMULUDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPMULUDQ", 3, Operands { v0, v1, v2 }) - // VPMULUDQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULUDQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf4) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULUDQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULUDQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf4) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPMULUDQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xf4) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPMULUDQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xf4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULUDQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xf4) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPMULUDQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xf4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPMULUDQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xf4) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPMULUDQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xf4) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPMULUDQ") - } - return p -} - -// VPOPCNTD performs "Packed Population Count for Doubleword Integers". -// -// Mnemonic : VPOPCNTD -// Supported forms : (2 forms) -// -// * VPOPCNTD m512/m32bcst, zmm{k}{z} [AVX512VPOPCNTDQ] -// * VPOPCNTD zmm, zmm{k}{z} [AVX512VPOPCNTDQ] -// -func (self *Program) VPOPCNTD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPOPCNTD", 2, Operands { v0, v1 }) - // VPOPCNTD m512/m32bcst, zmm{k}{z} - if isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512VPOPCNTDQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x55) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPOPCNTD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512VPOPCNTDQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x55) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPOPCNTD") - } - return p -} - -// VPOPCNTQ performs "Packed Population Count for Quadword Integers". -// -// Mnemonic : VPOPCNTQ -// Supported forms : (2 forms) -// -// * VPOPCNTQ m512/m64bcst, zmm{k}{z} [AVX512VPOPCNTDQ] -// * VPOPCNTQ zmm, zmm{k}{z} [AVX512VPOPCNTDQ] -// -func (self *Program) VPOPCNTQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPOPCNTQ", 2, Operands { v0, v1 }) - // VPOPCNTQ m512/m64bcst, zmm{k}{z} - if isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512VPOPCNTDQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x55) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VPOPCNTQ zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512VPOPCNTDQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x55) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPOPCNTQ") - } - return p -} - -// VPOR performs "Packed Bitwise Logical OR". -// -// Mnemonic : VPOR -// Supported forms : (4 forms) -// -// * VPOR xmm, xmm, xmm [AVX] -// * VPOR m128, xmm, xmm [AVX] -// * VPOR ymm, ymm, ymm [AVX2] -// * VPOR m256, ymm, ymm [AVX2] -// -func (self *Program) VPOR(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPOR", 3, Operands { v0, v1, v2 }) - // VPOR xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPOR m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xeb) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPOR ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPOR m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xeb) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPOR") - } - return p -} - -// VPORD performs "Bitwise Logical OR of Packed Doubleword Integers". -// -// Mnemonic : VPORD -// Supported forms : (6 forms) -// -// * VPORD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPORD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPORD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPORD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPORD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPORD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPORD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPORD", 3, Operands { v0, v1, v2 }) - // VPORD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xeb) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPORD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPORD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xeb) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPORD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPORD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xeb) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPORD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPORD") - } - return p -} - -// VPORQ performs "Bitwise Logical OR of Packed Quadword Integers". -// -// Mnemonic : VPORQ -// Supported forms : (6 forms) -// -// * VPORQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPORQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPORQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPORQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPORQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPORQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPORQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPORQ", 3, Operands { v0, v1, v2 }) - // VPORQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xeb) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPORQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPORQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xeb) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPORQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPORQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xeb) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPORQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xeb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPORQ") - } - return p -} - -// VPPERM performs "Packed Permute Bytes". -// -// Mnemonic : VPPERM -// Supported forms : (3 forms) -// -// * VPPERM xmm, xmm, xmm, xmm [XOP] -// * VPPERM m128, xmm, xmm, xmm [XOP] -// * VPPERM xmm, m128, xmm, xmm [XOP] -// -func (self *Program) VPPERM(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPPERM", 4, Operands { v0, v1, v2, v3 }) - // VPPERM xmm, xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[2]) << 3)) - m.emit(0xa3) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.emit(hlcode(v[0]) << 4) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[3]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[2]) << 3)) - m.emit(0xa3) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[0])) - m.emit(hlcode(v[1]) << 4) - }) - } - // VPPERM m128, xmm, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x80, hcode(v[3]), addr(v[0]), hlcode(v[2])) - m.emit(0xa3) - m.mrsd(lcode(v[3]), addr(v[0]), 1) - m.emit(hlcode(v[1]) << 4) - }) - } - // VPPERM xmm, m128, xmm, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xa3) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.emit(hlcode(v[0]) << 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPPERM") - } - return p -} - -// VPROLD performs "Rotate Packed Doubleword Left". -// -// Mnemonic : VPROLD -// Supported forms : (6 forms) -// -// * VPROLD imm8, m512/m32bcst, zmm{k}{z} [AVX512F] -// * VPROLD imm8, zmm, zmm{k}{z} [AVX512F] -// * VPROLD imm8, m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPROLD imm8, m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPROLD imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPROLD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPROLD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPROLD", 3, Operands { v0, v1, v2 }) - // VPROLD imm8, m512/m32bcst, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(1, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLD imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x72) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLD imm8, m128/m32bcst, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(1, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLD imm8, m256/m32bcst, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(1, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLD imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x72) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLD imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x72) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPROLD") - } - return p -} - -// VPROLQ performs "Rotate Packed Quadword Left". -// -// Mnemonic : VPROLQ -// Supported forms : (6 forms) -// -// * VPROLQ imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VPROLQ imm8, zmm, zmm{k}{z} [AVX512F] -// * VPROLQ imm8, m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPROLQ imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPROLQ imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPROLQ imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPROLQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPROLQ", 3, Operands { v0, v1, v2 }) - // VPROLQ imm8, m512/m64bcst, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(1, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLQ imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x72) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLQ imm8, m128/m64bcst, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(1, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLQ imm8, m256/m64bcst, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(1, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLQ imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x72) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPROLQ imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x72) - m.emit(0xc8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPROLQ") - } - return p -} - -// VPROLVD performs "Variable Rotate Packed Doubleword Left". -// -// Mnemonic : VPROLVD -// Supported forms : (6 forms) -// -// * VPROLVD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPROLVD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPROLVD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPROLVD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPROLVD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPROLVD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPROLVD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPROLVD", 3, Operands { v0, v1, v2 }) - // VPROLVD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPROLVD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPROLVD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPROLVD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPROLVD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPROLVD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPROLVD") - } - return p -} - -// VPROLVQ performs "Variable Rotate Packed Quadword Left". -// -// Mnemonic : VPROLVQ -// Supported forms : (6 forms) -// -// * VPROLVQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPROLVQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPROLVQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPROLVQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPROLVQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPROLVQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPROLVQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPROLVQ", 3, Operands { v0, v1, v2 }) - // VPROLVQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPROLVQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPROLVQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPROLVQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPROLVQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPROLVQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPROLVQ") - } - return p -} - -// VPRORD performs "Rotate Packed Doubleword Right". -// -// Mnemonic : VPRORD -// Supported forms : (6 forms) -// -// * VPRORD imm8, m512/m32bcst, zmm{k}{z} [AVX512F] -// * VPRORD imm8, zmm, zmm{k}{z} [AVX512F] -// * VPRORD imm8, m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPRORD imm8, m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPRORD imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPRORD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPRORD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPRORD", 3, Operands { v0, v1, v2 }) - // VPRORD imm8, m512/m32bcst, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(0, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORD imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x72) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORD imm8, m128/m32bcst, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(0, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORD imm8, m256/m32bcst, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(0, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORD imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x72) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORD imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x72) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPRORD") - } - return p -} - -// VPRORQ performs "Rotate Packed Quadword Right". -// -// Mnemonic : VPRORQ -// Supported forms : (6 forms) -// -// * VPRORQ imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VPRORQ imm8, zmm, zmm{k}{z} [AVX512F] -// * VPRORQ imm8, m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPRORQ imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPRORQ imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPRORQ imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPRORQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPRORQ", 3, Operands { v0, v1, v2 }) - // VPRORQ imm8, m512/m64bcst, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(0, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORQ imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x72) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORQ imm8, m128/m64bcst, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(0, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORQ imm8, m256/m64bcst, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(0, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORQ imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x72) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPRORQ imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x72) - m.emit(0xc0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPRORQ") - } - return p -} - -// VPRORVD performs "Variable Rotate Packed Doubleword Right". -// -// Mnemonic : VPRORVD -// Supported forms : (6 forms) -// -// * VPRORVD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPRORVD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPRORVD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPRORVD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPRORVD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPRORVD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPRORVD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPRORVD", 3, Operands { v0, v1, v2 }) - // VPRORVD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPRORVD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPRORVD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPRORVD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPRORVD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPRORVD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPRORVD") - } - return p -} - -// VPRORVQ performs "Variable Rotate Packed Quadword Right". -// -// Mnemonic : VPRORVQ -// Supported forms : (6 forms) -// -// * VPRORVQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPRORVQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPRORVQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPRORVQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPRORVQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPRORVQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPRORVQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPRORVQ", 3, Operands { v0, v1, v2 }) - // VPRORVQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPRORVQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPRORVQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPRORVQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPRORVQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPRORVQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPRORVQ") - } - return p -} - -// VPROTB performs "Packed Rotate Bytes". -// -// Mnemonic : VPROTB -// Supported forms : (5 forms) -// -// * VPROTB imm8, xmm, xmm [XOP] -// * VPROTB xmm, xmm, xmm [XOP] -// * VPROTB m128, xmm, xmm [XOP] -// * VPROTB imm8, m128, xmm [XOP] -// * VPROTB xmm, m128, xmm [XOP] -// -func (self *Program) VPROTB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPROTB", 3, Operands { v0, v1, v2 }) - // VPROTB imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78) - m.emit(0xc0) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPROTB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x90) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x90) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPROTB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x90) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPROTB imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[2]), addr(v[1]), 0) - m.emit(0xc0) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPROTB xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x90) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPROTB") - } - return p -} - -// VPROTD performs "Packed Rotate Doublewords". -// -// Mnemonic : VPROTD -// Supported forms : (5 forms) -// -// * VPROTD imm8, xmm, xmm [XOP] -// * VPROTD xmm, xmm, xmm [XOP] -// * VPROTD m128, xmm, xmm [XOP] -// * VPROTD imm8, m128, xmm [XOP] -// * VPROTD xmm, m128, xmm [XOP] -// -func (self *Program) VPROTD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPROTD", 3, Operands { v0, v1, v2 }) - // VPROTD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78) - m.emit(0xc2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPROTD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x92) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x92) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPROTD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x92) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPROTD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[2]), addr(v[1]), 0) - m.emit(0xc2) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPROTD xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x92) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPROTD") - } - return p -} - -// VPROTQ performs "Packed Rotate Quadwords". -// -// Mnemonic : VPROTQ -// Supported forms : (5 forms) -// -// * VPROTQ imm8, xmm, xmm [XOP] -// * VPROTQ xmm, xmm, xmm [XOP] -// * VPROTQ m128, xmm, xmm [XOP] -// * VPROTQ imm8, m128, xmm [XOP] -// * VPROTQ xmm, m128, xmm [XOP] -// -func (self *Program) VPROTQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPROTQ", 3, Operands { v0, v1, v2 }) - // VPROTQ imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78) - m.emit(0xc3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPROTQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x93) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x93) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPROTQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x93) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPROTQ imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[2]), addr(v[1]), 0) - m.emit(0xc3) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPROTQ xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x93) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPROTQ") - } - return p -} - -// VPROTW performs "Packed Rotate Words". -// -// Mnemonic : VPROTW -// Supported forms : (5 forms) -// -// * VPROTW imm8, xmm, xmm [XOP] -// * VPROTW xmm, xmm, xmm [XOP] -// * VPROTW m128, xmm, xmm [XOP] -// * VPROTW imm8, m128, xmm [XOP] -// * VPROTW xmm, m128, xmm [XOP] -// -func (self *Program) VPROTW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPROTW", 3, Operands { v0, v1, v2 }) - // VPROTW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe8 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78) - m.emit(0xc1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPROTW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x91) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x91) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPROTW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x91) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPROTW imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1000, 0x00, hcode(v[2]), addr(v[1]), 0) - m.emit(0xc1) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPROTW xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x91) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPROTW") - } - return p -} - -// VPSADBW performs "Compute Sum of Absolute Differences". -// -// Mnemonic : VPSADBW -// Supported forms : (10 forms) -// -// * VPSADBW xmm, xmm, xmm [AVX] -// * VPSADBW m128, xmm, xmm [AVX] -// * VPSADBW ymm, ymm, ymm [AVX2] -// * VPSADBW m256, ymm, ymm [AVX2] -// * VPSADBW zmm, zmm, zmm [AVX512BW] -// * VPSADBW m512, zmm, zmm [AVX512BW] -// * VPSADBW xmm, xmm, xmm [AVX512BW,AVX512VL] -// * VPSADBW m128, xmm, xmm [AVX512BW,AVX512VL] -// * VPSADBW ymm, ymm, ymm [AVX512BW,AVX512VL] -// * VPSADBW m256, ymm, ymm [AVX512BW,AVX512VL] -// -func (self *Program) VPSADBW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSADBW", 3, Operands { v0, v1, v2 }) - // VPSADBW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSADBW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSADBW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSADBW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf6) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSADBW zmm, zmm, zmm - if isZMM(v0) && isZMM(v1) && isZMM(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x40) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSADBW m512, zmm, zmm - if isM512(v0) && isZMM(v1) && isZMM(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0xf6) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSADBW xmm, xmm, xmm - if isEVEXXMM(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x00) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSADBW m128, xmm, xmm - if isM128(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0xf6) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSADBW ymm, ymm, ymm - if isEVEXYMM(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | 0x20) - m.emit(0xf6) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSADBW m256, ymm, ymm - if isM256(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), 0, 0, 0) - m.emit(0xf6) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSADBW") - } - return p -} - -// VPSCATTERDD performs "Scatter Packed Doubleword Values with Signed Doubleword Indices". -// -// Mnemonic : VPSCATTERDD -// Supported forms : (3 forms) -// -// * VPSCATTERDD zmm, vm32z{k} [AVX512F] -// * VPSCATTERDD xmm, vm32x{k} [AVX512F,AVX512VL] -// * VPSCATTERDD ymm, vm32y{k} [AVX512F,AVX512VL] -// -func (self *Program) VPSCATTERDD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPSCATTERDD", 2, Operands { v0, v1 }) - // VPSCATTERDD zmm, vm32z{k} - if isZMM(v0) && isVMZk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa0) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPSCATTERDD xmm, vm32x{k} - if isEVEXXMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa0) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPSCATTERDD ymm, vm32y{k} - if isEVEXYMM(v0) && isVMYk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa0) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPSCATTERDD") - } - return p -} - -// VPSCATTERDQ performs "Scatter Packed Quadword Values with Signed Doubleword Indices". -// -// Mnemonic : VPSCATTERDQ -// Supported forms : (3 forms) -// -// * VPSCATTERDQ zmm, vm32y{k} [AVX512F] -// * VPSCATTERDQ xmm, vm32x{k} [AVX512F,AVX512VL] -// * VPSCATTERDQ ymm, vm32x{k} [AVX512F,AVX512VL] -// -func (self *Program) VPSCATTERDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPSCATTERDQ", 2, Operands { v0, v1 }) - // VPSCATTERDQ zmm, vm32y{k} - if isZMM(v0) && isVMYk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa0) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPSCATTERDQ xmm, vm32x{k} - if isEVEXXMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa0) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPSCATTERDQ ymm, vm32x{k} - if isEVEXYMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa0) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPSCATTERDQ") - } - return p -} - -// VPSCATTERQD performs "Scatter Packed Doubleword Values with Signed Quadword Indices". -// -// Mnemonic : VPSCATTERQD -// Supported forms : (3 forms) -// -// * VPSCATTERQD ymm, vm64z{k} [AVX512F] -// * VPSCATTERQD xmm, vm64x{k} [AVX512F,AVX512VL] -// * VPSCATTERQD xmm, vm64y{k} [AVX512F,AVX512VL] -// -func (self *Program) VPSCATTERQD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPSCATTERQD", 2, Operands { v0, v1 }) - // VPSCATTERQD ymm, vm64z{k} - if isEVEXYMM(v0) && isVMZk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa1) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPSCATTERQD xmm, vm64x{k} - if isEVEXXMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa1) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VPSCATTERQD xmm, vm64y{k} - if isEVEXXMM(v0) && isVMYk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa1) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VPSCATTERQD") - } - return p -} - -// VPSCATTERQQ performs "Scatter Packed Quadword Values with Signed Quadword Indices". -// -// Mnemonic : VPSCATTERQQ -// Supported forms : (3 forms) -// -// * VPSCATTERQQ zmm, vm64z{k} [AVX512F] -// * VPSCATTERQQ xmm, vm64x{k} [AVX512F,AVX512VL] -// * VPSCATTERQQ ymm, vm64y{k} [AVX512F,AVX512VL] -// -func (self *Program) VPSCATTERQQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPSCATTERQQ", 2, Operands { v0, v1 }) - // VPSCATTERQQ zmm, vm64z{k} - if isZMM(v0) && isVMZk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa1) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPSCATTERQQ xmm, vm64x{k} - if isEVEXXMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa1) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VPSCATTERQQ ymm, vm64y{k} - if isEVEXYMM(v0) && isVMYk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa1) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VPSCATTERQQ") - } - return p -} - -// VPSHAB performs "Packed Shift Arithmetic Bytes". -// -// Mnemonic : VPSHAB -// Supported forms : (3 forms) -// -// * VPSHAB xmm, xmm, xmm [XOP] -// * VPSHAB m128, xmm, xmm [XOP] -// * VPSHAB xmm, m128, xmm [XOP] -// -func (self *Program) VPSHAB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHAB", 3, Operands { v0, v1, v2 }) - // VPSHAB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x98) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHAB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHAB xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x98) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHAB") - } - return p -} - -// VPSHAD performs "Packed Shift Arithmetic Doublewords". -// -// Mnemonic : VPSHAD -// Supported forms : (3 forms) -// -// * VPSHAD xmm, xmm, xmm [XOP] -// * VPSHAD m128, xmm, xmm [XOP] -// * VPSHAD xmm, m128, xmm [XOP] -// -func (self *Program) VPSHAD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHAD", 3, Operands { v0, v1, v2 }) - // VPSHAD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x9a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHAD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHAD xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x9a) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHAD") - } - return p -} - -// VPSHAQ performs "Packed Shift Arithmetic Quadwords". -// -// Mnemonic : VPSHAQ -// Supported forms : (3 forms) -// -// * VPSHAQ xmm, xmm, xmm [XOP] -// * VPSHAQ m128, xmm, xmm [XOP] -// * VPSHAQ xmm, m128, xmm [XOP] -// -func (self *Program) VPSHAQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHAQ", 3, Operands { v0, v1, v2 }) - // VPSHAQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x9b) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHAQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x9b) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHAQ xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x9b) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHAQ") - } - return p -} - -// VPSHAW performs "Packed Shift Arithmetic Words". -// -// Mnemonic : VPSHAW -// Supported forms : (3 forms) -// -// * VPSHAW xmm, xmm, xmm [XOP] -// * VPSHAW m128, xmm, xmm [XOP] -// * VPSHAW xmm, m128, xmm [XOP] -// -func (self *Program) VPSHAW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHAW", 3, Operands { v0, v1, v2 }) - // VPSHAW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x99) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x99) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHAW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x99) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHAW xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x99) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHAW") - } - return p -} - -// VPSHLB performs "Packed Shift Logical Bytes". -// -// Mnemonic : VPSHLB -// Supported forms : (3 forms) -// -// * VPSHLB xmm, xmm, xmm [XOP] -// * VPSHLB m128, xmm, xmm [XOP] -// * VPSHLB xmm, m128, xmm [XOP] -// -func (self *Program) VPSHLB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHLB", 3, Operands { v0, v1, v2 }) - // VPSHLB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x94) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x94) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHLB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x94) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHLB xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x94) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHLB") - } - return p -} - -// VPSHLD performs "Packed Shift Logical Doublewords". -// -// Mnemonic : VPSHLD -// Supported forms : (3 forms) -// -// * VPSHLD xmm, xmm, xmm [XOP] -// * VPSHLD m128, xmm, xmm [XOP] -// * VPSHLD xmm, m128, xmm [XOP] -// -func (self *Program) VPSHLD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHLD", 3, Operands { v0, v1, v2 }) - // VPSHLD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x96) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHLD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHLD xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x96) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHLD") - } - return p -} - -// VPSHLQ performs "Packed Shift Logical Quadwords". -// -// Mnemonic : VPSHLQ -// Supported forms : (3 forms) -// -// * VPSHLQ xmm, xmm, xmm [XOP] -// * VPSHLQ m128, xmm, xmm [XOP] -// * VPSHLQ xmm, m128, xmm [XOP] -// -func (self *Program) VPSHLQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHLQ", 3, Operands { v0, v1, v2 }) - // VPSHLQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x97) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHLQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHLQ xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x97) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHLQ") - } - return p -} - -// VPSHLW performs "Packed Shift Logical Words". -// -// Mnemonic : VPSHLW -// Supported forms : (3 forms) -// -// * VPSHLW xmm, xmm, xmm [XOP] -// * VPSHLW m128, xmm, xmm [XOP] -// * VPSHLW xmm, m128, xmm [XOP] -// -func (self *Program) VPSHLW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHLW", 3, Operands { v0, v1, v2 }) - // VPSHLW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x78 ^ (hlcode(v[0]) << 3)) - m.emit(0x95) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x8f) - m.emit(0xe9 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf8 ^ (hlcode(v[1]) << 3)) - m.emit(0x95) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHLW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x80, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x95) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHLW xmm, m128, xmm - if isXMM(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_XOP) - p.domain = DomainAMDSpecific - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0x8f, 0b1001, 0x00, hcode(v[2]), addr(v[1]), hlcode(v[0])) - m.emit(0x95) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHLW") - } - return p -} - -// VPSHUFB performs "Packed Shuffle Bytes". -// -// Mnemonic : VPSHUFB -// Supported forms : (10 forms) -// -// * VPSHUFB xmm, xmm, xmm [AVX] -// * VPSHUFB m128, xmm, xmm [AVX] -// * VPSHUFB ymm, ymm, ymm [AVX2] -// * VPSHUFB m256, ymm, ymm [AVX2] -// * VPSHUFB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSHUFB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSHUFB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSHUFB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSHUFB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSHUFB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSHUFB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHUFB", 3, Operands { v0, v1, v2 }) - // VPSHUFB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x00) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHUFB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x00) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHUFB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x00) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHUFB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x00) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSHUFB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x00) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHUFB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x00) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSHUFB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x00) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHUFB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x00) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSHUFB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x00) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSHUFB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x00) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHUFB") - } - return p -} - -// VPSHUFD performs "Shuffle Packed Doublewords". -// -// Mnemonic : VPSHUFD -// Supported forms : (10 forms) -// -// * VPSHUFD imm8, xmm, xmm [AVX] -// * VPSHUFD imm8, m128, xmm [AVX] -// * VPSHUFD imm8, ymm, ymm [AVX2] -// * VPSHUFD imm8, m256, ymm [AVX2] -// * VPSHUFD imm8, m512/m32bcst, zmm{k}{z} [AVX512F] -// * VPSHUFD imm8, zmm, zmm{k}{z} [AVX512F] -// * VPSHUFD imm8, m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSHUFD imm8, m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSHUFD imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSHUFD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSHUFD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHUFD", 3, Operands { v0, v1, v2 }) - // VPSHUFD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[1], 0) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[1]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFD imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[1], 0) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFD imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[1]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFD imm8, m512/m32bcst, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFD imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFD imm8, m128/m32bcst, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFD imm8, m256/m32bcst, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFD imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFD imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHUFD") - } - return p -} - -// VPSHUFHW performs "Shuffle Packed High Words". -// -// Mnemonic : VPSHUFHW -// Supported forms : (10 forms) -// -// * VPSHUFHW imm8, xmm, xmm [AVX] -// * VPSHUFHW imm8, m128, xmm [AVX] -// * VPSHUFHW imm8, ymm, ymm [AVX2] -// * VPSHUFHW imm8, m256, ymm [AVX2] -// * VPSHUFHW imm8, zmm, zmm{k}{z} [AVX512BW] -// * VPSHUFHW imm8, m512, zmm{k}{z} [AVX512BW] -// * VPSHUFHW imm8, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSHUFHW imm8, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSHUFHW imm8, m128, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSHUFHW imm8, m256, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSHUFHW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHUFHW", 3, Operands { v0, v1, v2 }) - // VPSHUFHW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[1], 0) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFHW imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[1]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFHW imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[2]), v[1], 0) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFHW imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(6, hcode(v[2]), addr(v[1]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFHW imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFHW imm8, m512, zmm{k}{z} - if isImm8(v0) && isM512(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFHW imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFHW imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFHW imm8, m128, xmm{k}{z} - if isImm8(v0) && isM128(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFHW imm8, m256, ymm{k}{z} - if isImm8(v0) && isM256(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHUFHW") - } - return p -} - -// VPSHUFLW performs "Shuffle Packed Low Words". -// -// Mnemonic : VPSHUFLW -// Supported forms : (10 forms) -// -// * VPSHUFLW imm8, xmm, xmm [AVX] -// * VPSHUFLW imm8, m128, xmm [AVX] -// * VPSHUFLW imm8, ymm, ymm [AVX2] -// * VPSHUFLW imm8, m256, ymm [AVX2] -// * VPSHUFLW imm8, zmm, zmm{k}{z} [AVX512BW] -// * VPSHUFLW imm8, m512, zmm{k}{z} [AVX512BW] -// * VPSHUFLW imm8, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSHUFLW imm8, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSHUFLW imm8, m128, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSHUFLW imm8, m256, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSHUFLW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSHUFLW", 3, Operands { v0, v1, v2 }) - // VPSHUFLW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[1], 0) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFLW imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[1]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFLW imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[2]), v[1], 0) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFLW imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(7, hcode(v[2]), addr(v[1]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFLW imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFLW imm8, m512, zmm{k}{z} - if isImm8(v0) && isM512(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFLW imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFLW imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7f) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x70) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFLW imm8, m128, xmm{k}{z} - if isImm8(v0) && isM128(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSHUFLW imm8, m256, ymm{k}{z} - if isImm8(v0) && isM256(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x07, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), 0) - m.emit(0x70) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSHUFLW") - } - return p -} - -// VPSIGNB performs "Packed Sign of Byte Integers". -// -// Mnemonic : VPSIGNB -// Supported forms : (4 forms) -// -// * VPSIGNB xmm, xmm, xmm [AVX] -// * VPSIGNB m128, xmm, xmm [AVX] -// * VPSIGNB ymm, ymm, ymm [AVX2] -// * VPSIGNB m256, ymm, ymm [AVX2] -// -func (self *Program) VPSIGNB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSIGNB", 3, Operands { v0, v1, v2 }) - // VPSIGNB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x08) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSIGNB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x08) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSIGNB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x08) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSIGNB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x08) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSIGNB") - } - return p -} - -// VPSIGND performs "Packed Sign of Doubleword Integers". -// -// Mnemonic : VPSIGND -// Supported forms : (4 forms) -// -// * VPSIGND xmm, xmm, xmm [AVX] -// * VPSIGND m128, xmm, xmm [AVX] -// * VPSIGND ymm, ymm, ymm [AVX2] -// * VPSIGND m256, ymm, ymm [AVX2] -// -func (self *Program) VPSIGND(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSIGND", 3, Operands { v0, v1, v2 }) - // VPSIGND xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x0a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSIGND m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x0a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSIGND ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x0a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSIGND m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x0a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSIGND") - } - return p -} - -// VPSIGNW performs "Packed Sign of Word Integers". -// -// Mnemonic : VPSIGNW -// Supported forms : (4 forms) -// -// * VPSIGNW xmm, xmm, xmm [AVX] -// * VPSIGNW m128, xmm, xmm [AVX] -// * VPSIGNW ymm, ymm, ymm [AVX2] -// * VPSIGNW m256, ymm, ymm [AVX2] -// -func (self *Program) VPSIGNW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSIGNW", 3, Operands { v0, v1, v2 }) - // VPSIGNW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x09) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSIGNW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x09) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSIGNW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x09) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSIGNW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x09) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPSIGNW") - } - return p -} - -// VPSLLD performs "Shift Packed Doubleword Data Left Logical". -// -// Mnemonic : VPSLLD -// Supported forms : (18 forms) -// -// * VPSLLD imm8, xmm, xmm [AVX] -// * VPSLLD xmm, xmm, xmm [AVX] -// * VPSLLD m128, xmm, xmm [AVX] -// * VPSLLD imm8, ymm, ymm [AVX2] -// * VPSLLD xmm, ymm, ymm [AVX2] -// * VPSLLD m128, ymm, ymm [AVX2] -// * VPSLLD imm8, m512/m32bcst, zmm{k}{z} [AVX512F] -// * VPSLLD imm8, zmm, zmm{k}{z} [AVX512F] -// * VPSLLD xmm, zmm, zmm{k}{z} [AVX512F] -// * VPSLLD m128, zmm, zmm{k}{z} [AVX512F] -// * VPSLLD imm8, m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLD imm8, m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSLLD imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLD m128, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSLLD xmm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSLLD m128, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSLLD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSLLD", 3, Operands { v0, v1, v2 }) - // VPSLLD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x72) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf2) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLD imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x72) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLD xmm, ymm, ymm - if isXMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLD m128, ymm, ymm - if isM128(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf2) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLD imm8, m512/m32bcst, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(6, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLD imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x72) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLD xmm, zmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xf2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLD m128, zmm, zmm{k}{z} - if isM128(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLD imm8, m128/m32bcst, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(6, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLD imm8, m256/m32bcst, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(6, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLD imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x72) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xf2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLD m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLD imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x72) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLD xmm, ymm, ymm{k}{z} - if isEVEXXMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xf2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLD m128, ymm, ymm{k}{z} - if isM128(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPSLLD") - } - return p -} - -// VPSLLDQ performs "Shift Packed Double Quadword Left Logical". -// -// Mnemonic : VPSLLDQ -// Supported forms : (8 forms) -// -// * VPSLLDQ imm8, xmm, xmm [AVX] -// * VPSLLDQ imm8, ymm, ymm [AVX2] -// * VPSLLDQ imm8, zmm, zmm [AVX512BW] -// * VPSLLDQ imm8, m512, zmm [AVX512BW] -// * VPSLLDQ imm8, xmm, xmm [AVX512BW,AVX512VL] -// * VPSLLDQ imm8, m128, xmm [AVX512BW,AVX512VL] -// * VPSLLDQ imm8, ymm, ymm [AVX512BW,AVX512VL] -// * VPSLLDQ imm8, m256, ymm [AVX512BW,AVX512VL] -// -func (self *Program) VPSLLDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSLLDQ", 3, Operands { v0, v1, v2 }) - // VPSLLDQ imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x73) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLDQ imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x73) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLDQ imm8, zmm, zmm - if isImm8(v0) && isZMM(v1) && isZMM(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x40) - m.emit(0x73) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLDQ imm8, m512, zmm - if isImm8(v0) && isM512(v1) && isZMM(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x73) - m.mrsd(7, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLDQ imm8, xmm, xmm - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x00) - m.emit(0x73) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLDQ imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x73) - m.mrsd(7, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLDQ imm8, ymm, ymm - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x20) - m.emit(0x73) - m.emit(0xf8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLDQ imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isEVEXYMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x73) - m.mrsd(7, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSLLDQ") - } - return p -} - -// VPSLLQ performs "Shift Packed Quadword Data Left Logical". -// -// Mnemonic : VPSLLQ -// Supported forms : (18 forms) -// -// * VPSLLQ imm8, xmm, xmm [AVX] -// * VPSLLQ xmm, xmm, xmm [AVX] -// * VPSLLQ m128, xmm, xmm [AVX] -// * VPSLLQ imm8, ymm, ymm [AVX2] -// * VPSLLQ xmm, ymm, ymm [AVX2] -// * VPSLLQ m128, ymm, ymm [AVX2] -// * VPSLLQ imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VPSLLQ imm8, zmm, zmm{k}{z} [AVX512F] -// * VPSLLQ xmm, zmm, zmm{k}{z} [AVX512F] -// * VPSLLQ m128, zmm, zmm{k}{z} [AVX512F] -// * VPSLLQ imm8, m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLQ imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSLLQ imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLQ m128, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLQ imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSLLQ xmm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSLLQ m128, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSLLQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSLLQ", 3, Operands { v0, v1, v2 }) - // VPSLLQ imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x73) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf3) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLQ imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x73) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLQ xmm, ymm, ymm - if isXMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLQ m128, ymm, ymm - if isM128(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf3) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLQ imm8, m512/m64bcst, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x73) - m.mrsd(6, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLQ imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x73) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLQ xmm, zmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xf3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLQ m128, zmm, zmm{k}{z} - if isM128(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf3) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLQ imm8, m128/m64bcst, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x73) - m.mrsd(6, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLQ imm8, m256/m64bcst, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x73) - m.mrsd(6, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLQ imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x73) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xf3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLQ m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf3) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLQ imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x73) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLQ xmm, ymm, ymm{k}{z} - if isEVEXXMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xf3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLQ m128, ymm, ymm{k}{z} - if isM128(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf3) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPSLLQ") - } - return p -} - -// VPSLLVD performs "Variable Shift Packed Doubleword Data Left Logical". -// -// Mnemonic : VPSLLVD -// Supported forms : (10 forms) -// -// * VPSLLVD xmm, xmm, xmm [AVX2] -// * VPSLLVD m128, xmm, xmm [AVX2] -// * VPSLLVD ymm, ymm, ymm [AVX2] -// * VPSLLVD m256, ymm, ymm [AVX2] -// * VPSLLVD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPSLLVD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPSLLVD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLVD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLVD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSLLVD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSLLVD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSLLVD", 3, Operands { v0, v1, v2 }) - // VPSLLVD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLVD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLVD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSLLVD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLVD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPSLLVD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSLLVD") - } - return p -} - -// VPSLLVQ performs "Variable Shift Packed Quadword Data Left Logical". -// -// Mnemonic : VPSLLVQ -// Supported forms : (10 forms) -// -// * VPSLLVQ xmm, xmm, xmm [AVX2] -// * VPSLLVQ m128, xmm, xmm [AVX2] -// * VPSLLVQ ymm, ymm, ymm [AVX2] -// * VPSLLVQ m256, ymm, ymm [AVX2] -// * VPSLLVQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPSLLVQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPSLLVQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLVQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSLLVQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSLLVQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSLLVQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSLLVQ", 3, Operands { v0, v1, v2 }) - // VPSLLVQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLVQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLVQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSLLVQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLVQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x47) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPSLLVQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x47) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSLLVQ") - } - return p -} - -// VPSLLVW performs "Variable Shift Packed Word Data Left Logical". -// -// Mnemonic : VPSLLVW -// Supported forms : (6 forms) -// -// * VPSLLVW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSLLVW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSLLVW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLVW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLVW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLVW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSLLVW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSLLVW", 3, Operands { v0, v1, v2 }) - // VPSLLVW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x12) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x12) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSLLVW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x12) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x12) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLVW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x12) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLVW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x12) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSLLVW") - } - return p -} - -// VPSLLW performs "Shift Packed Word Data Left Logical". -// -// Mnemonic : VPSLLW -// Supported forms : (18 forms) -// -// * VPSLLW imm8, xmm, xmm [AVX] -// * VPSLLW xmm, xmm, xmm [AVX] -// * VPSLLW m128, xmm, xmm [AVX] -// * VPSLLW imm8, ymm, ymm [AVX2] -// * VPSLLW xmm, ymm, ymm [AVX2] -// * VPSLLW m128, ymm, ymm [AVX2] -// * VPSLLW imm8, zmm, zmm{k}{z} [AVX512BW] -// * VPSLLW xmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSLLW m128, zmm, zmm{k}{z} [AVX512BW] -// * VPSLLW imm8, m512, zmm{k}{z} [AVX512BW] -// * VPSLLW imm8, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLW imm8, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLW xmm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLW m128, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLW imm8, m128, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSLLW imm8, m256, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSLLW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSLLW", 3, Operands { v0, v1, v2 }) - // VPSLLW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x71) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf1) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLW imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x71) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLW xmm, ymm, ymm - if isXMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLW m128, ymm, ymm - if isM128(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf1) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSLLW imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x71) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLW xmm, zmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLW m128, zmm, zmm{k}{z} - if isM128(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf1) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLW imm8, m512, zmm{k}{z} - if isImm8(v0) && isM512(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x71) - m.mrsd(6, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLW imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x71) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf1) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLW imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x71) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLW xmm, ymm, ymm{k}{z} - if isEVEXXMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xf1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSLLW m128, ymm, ymm{k}{z} - if isM128(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf1) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSLLW imm8, m128, xmm{k}{z} - if isImm8(v0) && isM128(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x71) - m.mrsd(6, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSLLW imm8, m256, ymm{k}{z} - if isImm8(v0) && isM256(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x71) - m.mrsd(6, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSLLW") - } - return p -} - -// VPSRAD performs "Shift Packed Doubleword Data Right Arithmetic". -// -// Mnemonic : VPSRAD -// Supported forms : (18 forms) -// -// * VPSRAD imm8, xmm, xmm [AVX] -// * VPSRAD xmm, xmm, xmm [AVX] -// * VPSRAD m128, xmm, xmm [AVX] -// * VPSRAD imm8, ymm, ymm [AVX2] -// * VPSRAD xmm, ymm, ymm [AVX2] -// * VPSRAD m128, ymm, ymm [AVX2] -// * VPSRAD imm8, m512/m32bcst, zmm{k}{z} [AVX512F] -// * VPSRAD imm8, zmm, zmm{k}{z} [AVX512F] -// * VPSRAD xmm, zmm, zmm{k}{z} [AVX512F] -// * VPSRAD m128, zmm, zmm{k}{z} [AVX512F] -// * VPSRAD imm8, m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAD imm8, m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRAD imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAD m128, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRAD xmm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRAD m128, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSRAD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRAD", 3, Operands { v0, v1, v2 }) - // VPSRAD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe2) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRAD imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAD xmm, ymm, ymm - if isXMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAD m128, ymm, ymm - if isM128(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe2) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRAD imm8, m512/m32bcst, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(4, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAD imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAD xmm, zmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAD m128, zmm, zmm{k}{z} - if isM128(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAD imm8, m128/m32bcst, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(4, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAD imm8, m256/m32bcst, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(4, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAD imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAD m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAD imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAD xmm, ymm, ymm{k}{z} - if isEVEXXMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAD m128, ymm, ymm{k}{z} - if isM128(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRAD") - } - return p -} - -// VPSRAQ performs "Shift Packed Quadword Data Right Arithmetic". -// -// Mnemonic : VPSRAQ -// Supported forms : (12 forms) -// -// * VPSRAQ imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VPSRAQ imm8, zmm, zmm{k}{z} [AVX512F] -// * VPSRAQ xmm, zmm, zmm{k}{z} [AVX512F] -// * VPSRAQ m128, zmm, zmm{k}{z} [AVX512F] -// * VPSRAQ imm8, m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAQ imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRAQ imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAQ m128, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAQ imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRAQ xmm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRAQ m128, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSRAQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRAQ", 3, Operands { v0, v1, v2 }) - // VPSRAQ imm8, m512/m64bcst, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(4, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAQ imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAQ xmm, zmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAQ m128, zmm, zmm{k}{z} - if isM128(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAQ imm8, m128/m64bcst, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(4, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAQ imm8, m256/m64bcst, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(4, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAQ imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAQ m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAQ imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x72) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAQ xmm, ymm, ymm{k}{z} - if isEVEXXMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xe2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAQ m128, ymm, ymm{k}{z} - if isM128(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRAQ") - } - return p -} - -// VPSRAVD performs "Variable Shift Packed Doubleword Data Right Arithmetic". -// -// Mnemonic : VPSRAVD -// Supported forms : (10 forms) -// -// * VPSRAVD xmm, xmm, xmm [AVX2] -// * VPSRAVD m128, xmm, xmm [AVX2] -// * VPSRAVD ymm, ymm, ymm [AVX2] -// * VPSRAVD m256, ymm, ymm [AVX2] -// * VPSRAVD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPSRAVD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPSRAVD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAVD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAVD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRAVD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSRAVD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRAVD", 3, Operands { v0, v1, v2 }) - // VPSRAVD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAVD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x46) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRAVD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAVD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x46) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRAVD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x46) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSRAVD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAVD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x46) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAVD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAVD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x46) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPSRAVD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRAVD") - } - return p -} - -// VPSRAVQ performs "Variable Shift Packed Quadword Data Right Arithmetic". -// -// Mnemonic : VPSRAVQ -// Supported forms : (6 forms) -// -// * VPSRAVQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPSRAVQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPSRAVQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAVQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRAVQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRAVQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSRAVQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRAVQ", 3, Operands { v0, v1, v2 }) - // VPSRAVQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x46) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSRAVQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAVQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x46) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAVQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAVQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x46) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPSRAVQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x46) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRAVQ") - } - return p -} - -// VPSRAVW performs "Variable Shift Packed Word Data Right Arithmetic". -// -// Mnemonic : VPSRAVW -// Supported forms : (6 forms) -// -// * VPSRAVW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSRAVW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSRAVW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAVW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAVW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAVW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSRAVW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRAVW", 3, Operands { v0, v1, v2 }) - // VPSRAVW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x11) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAVW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x11) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSRAVW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x11) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAVW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x11) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAVW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x11) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAVW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x11) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRAVW") - } - return p -} - -// VPSRAW performs "Shift Packed Word Data Right Arithmetic". -// -// Mnemonic : VPSRAW -// Supported forms : (18 forms) -// -// * VPSRAW imm8, xmm, xmm [AVX] -// * VPSRAW xmm, xmm, xmm [AVX] -// * VPSRAW m128, xmm, xmm [AVX] -// * VPSRAW imm8, ymm, ymm [AVX2] -// * VPSRAW xmm, ymm, ymm [AVX2] -// * VPSRAW m128, ymm, ymm [AVX2] -// * VPSRAW imm8, zmm, zmm{k}{z} [AVX512BW] -// * VPSRAW xmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSRAW m128, zmm, zmm{k}{z} [AVX512BW] -// * VPSRAW imm8, m512, zmm{k}{z} [AVX512BW] -// * VPSRAW imm8, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAW imm8, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAW xmm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAW m128, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAW imm8, m128, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRAW imm8, m256, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSRAW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRAW", 3, Operands { v0, v1, v2 }) - // VPSRAW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x71) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe1) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRAW imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x71) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAW xmm, ymm, ymm - if isXMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAW m128, ymm, ymm - if isM128(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe1) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRAW imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x71) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAW xmm, zmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xe1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAW m128, zmm, zmm{k}{z} - if isM128(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe1) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAW imm8, m512, zmm{k}{z} - if isImm8(v0) && isM512(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x71) - m.mrsd(4, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAW imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x71) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xe1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe1) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAW imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x71) - m.emit(0xe0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAW xmm, ymm, ymm{k}{z} - if isEVEXXMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xe1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRAW m128, ymm, ymm{k}{z} - if isM128(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe1) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRAW imm8, m128, xmm{k}{z} - if isImm8(v0) && isM128(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x71) - m.mrsd(4, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRAW imm8, m256, ymm{k}{z} - if isImm8(v0) && isM256(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x71) - m.mrsd(4, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRAW") - } - return p -} - -// VPSRLD performs "Shift Packed Doubleword Data Right Logical". -// -// Mnemonic : VPSRLD -// Supported forms : (18 forms) -// -// * VPSRLD imm8, xmm, xmm [AVX] -// * VPSRLD xmm, xmm, xmm [AVX] -// * VPSRLD m128, xmm, xmm [AVX] -// * VPSRLD imm8, ymm, ymm [AVX2] -// * VPSRLD xmm, ymm, ymm [AVX2] -// * VPSRLD m128, ymm, ymm [AVX2] -// * VPSRLD imm8, m512/m32bcst, zmm{k}{z} [AVX512F] -// * VPSRLD imm8, zmm, zmm{k}{z} [AVX512F] -// * VPSRLD xmm, zmm, zmm{k}{z} [AVX512F] -// * VPSRLD m128, zmm, zmm{k}{z} [AVX512F] -// * VPSRLD imm8, m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLD imm8, m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRLD imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLD m128, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRLD xmm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRLD m128, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSRLD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRLD", 3, Operands { v0, v1, v2 }) - // VPSRLD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x72) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd2) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLD imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x72) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLD xmm, ymm, ymm - if isXMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLD m128, ymm, ymm - if isM128(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd2) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLD imm8, m512/m32bcst, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(2, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLD imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x72) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLD xmm, zmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xd2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLD m128, zmm, zmm{k}{z} - if isM128(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLD imm8, m128/m32bcst, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(2, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLD imm8, m256/m32bcst, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x72) - m.mrsd(2, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLD imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x72) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xd2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLD m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLD imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x72) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLD xmm, ymm, ymm{k}{z} - if isEVEXXMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xd2) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLD m128, ymm, ymm{k}{z} - if isM128(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd2) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRLD") - } - return p -} - -// VPSRLDQ performs "Shift Packed Double Quadword Right Logical". -// -// Mnemonic : VPSRLDQ -// Supported forms : (8 forms) -// -// * VPSRLDQ imm8, xmm, xmm [AVX] -// * VPSRLDQ imm8, ymm, ymm [AVX2] -// * VPSRLDQ imm8, zmm, zmm [AVX512BW] -// * VPSRLDQ imm8, m512, zmm [AVX512BW] -// * VPSRLDQ imm8, xmm, xmm [AVX512BW,AVX512VL] -// * VPSRLDQ imm8, m128, xmm [AVX512BW,AVX512VL] -// * VPSRLDQ imm8, ymm, ymm [AVX512BW,AVX512VL] -// * VPSRLDQ imm8, m256, ymm [AVX512BW,AVX512VL] -// -func (self *Program) VPSRLDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRLDQ", 3, Operands { v0, v1, v2 }) - // VPSRLDQ imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x73) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLDQ imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x73) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLDQ imm8, zmm, zmm - if isImm8(v0) && isZMM(v1) && isZMM(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x40) - m.emit(0x73) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLDQ imm8, m512, zmm - if isImm8(v0) && isM512(v1) && isZMM(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x73) - m.mrsd(3, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLDQ imm8, xmm, xmm - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x00) - m.emit(0x73) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLDQ imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isEVEXXMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x73) - m.mrsd(3, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLDQ imm8, ymm, ymm - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((0x08 ^ (ecode(v[2]) << 3)) | 0x20) - m.emit(0x73) - m.emit(0xd8 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLDQ imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isEVEXYMM(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), 0, 0, 0) - m.emit(0x73) - m.mrsd(3, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRLDQ") - } - return p -} - -// VPSRLQ performs "Shift Packed Quadword Data Right Logical". -// -// Mnemonic : VPSRLQ -// Supported forms : (18 forms) -// -// * VPSRLQ imm8, xmm, xmm [AVX] -// * VPSRLQ xmm, xmm, xmm [AVX] -// * VPSRLQ m128, xmm, xmm [AVX] -// * VPSRLQ imm8, ymm, ymm [AVX2] -// * VPSRLQ xmm, ymm, ymm [AVX2] -// * VPSRLQ m128, ymm, ymm [AVX2] -// * VPSRLQ imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VPSRLQ imm8, zmm, zmm{k}{z} [AVX512F] -// * VPSRLQ xmm, zmm, zmm{k}{z} [AVX512F] -// * VPSRLQ m128, zmm, zmm{k}{z} [AVX512F] -// * VPSRLQ imm8, m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLQ imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRLQ imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLQ m128, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLQ imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRLQ xmm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRLQ m128, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSRLQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRLQ", 3, Operands { v0, v1, v2 }) - // VPSRLQ imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x73) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd3) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLQ imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x73) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLQ xmm, ymm, ymm - if isXMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLQ m128, ymm, ymm - if isM128(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd3) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLQ imm8, m512/m64bcst, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x73) - m.mrsd(2, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLQ imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x73) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLQ xmm, zmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLQ m128, zmm, zmm{k}{z} - if isM128(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd3) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLQ imm8, m128/m64bcst, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x73) - m.mrsd(2, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLQ imm8, m256/m64bcst, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x73) - m.mrsd(2, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLQ imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x73) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLQ m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd3) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLQ imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x73) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLQ xmm, ymm, ymm{k}{z} - if isEVEXXMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xd3) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLQ m128, ymm, ymm{k}{z} - if isM128(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd3) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRLQ") - } - return p -} - -// VPSRLVD performs "Variable Shift Packed Doubleword Data Right Logical". -// -// Mnemonic : VPSRLVD -// Supported forms : (10 forms) -// -// * VPSRLVD xmm, xmm, xmm [AVX2] -// * VPSRLVD m128, xmm, xmm [AVX2] -// * VPSRLVD ymm, ymm, ymm [AVX2] -// * VPSRLVD m256, ymm, ymm [AVX2] -// * VPSRLVD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPSRLVD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPSRLVD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLVD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLVD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRLVD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSRLVD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRLVD", 3, Operands { v0, v1, v2 }) - // VPSRLVD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79 ^ (hlcode(v[1]) << 3)) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLVD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLVD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSRLVD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLVD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPSRLVD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRLVD") - } - return p -} - -// VPSRLVQ performs "Variable Shift Packed Quadword Data Right Logical". -// -// Mnemonic : VPSRLVQ -// Supported forms : (10 forms) -// -// * VPSRLVQ xmm, xmm, xmm [AVX2] -// * VPSRLVQ m128, xmm, xmm [AVX2] -// * VPSRLVQ ymm, ymm, ymm [AVX2] -// * VPSRLVQ m256, ymm, ymm [AVX2] -// * VPSRLVQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPSRLVQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPSRLVQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLVQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSRLVQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSRLVQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSRLVQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRLVQ", 3, Operands { v0, v1, v2 }) - // VPSRLVQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xf9 ^ (hlcode(v[1]) << 3)) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x81, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLVQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[2]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x85, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLVQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSRLVQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLVQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x45) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPSRLVQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x45) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRLVQ") - } - return p -} - -// VPSRLVW performs "Variable Shift Packed Word Data Right Logical". -// -// Mnemonic : VPSRLVW -// Supported forms : (6 forms) -// -// * VPSRLVW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSRLVW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSRLVW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLVW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLVW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLVW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSRLVW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRLVW", 3, Operands { v0, v1, v2 }) - // VPSRLVW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x10) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSRLVW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x10) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLVW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x10) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLVW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x10) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRLVW") - } - return p -} - -// VPSRLW performs "Shift Packed Word Data Right Logical". -// -// Mnemonic : VPSRLW -// Supported forms : (18 forms) -// -// * VPSRLW imm8, xmm, xmm [AVX] -// * VPSRLW xmm, xmm, xmm [AVX] -// * VPSRLW m128, xmm, xmm [AVX] -// * VPSRLW imm8, ymm, ymm [AVX2] -// * VPSRLW xmm, ymm, ymm [AVX2] -// * VPSRLW m128, ymm, ymm [AVX2] -// * VPSRLW imm8, zmm, zmm{k}{z} [AVX512BW] -// * VPSRLW xmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSRLW m128, zmm, zmm{k}{z} [AVX512BW] -// * VPSRLW imm8, m512, zmm{k}{z} [AVX512BW] -// * VPSRLW imm8, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLW imm8, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLW xmm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLW m128, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLW imm8, m128, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSRLW imm8, m256, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSRLW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSRLW", 3, Operands { v0, v1, v2 }) - // VPSRLW imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, 0, v[1], hlcode(v[2])) - m.emit(0x71) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd1) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLW imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, 0, v[1], hlcode(v[2])) - m.emit(0x71) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLW xmm, ymm, ymm - if isXMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLW m128, ymm, ymm - if isM128(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd1) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSRLW imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x71) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLW xmm, zmm, zmm{k}{z} - if isEVEXXMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLW m128, zmm, zmm{k}{z} - if isM128(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd1) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLW imm8, m512, zmm{k}{z} - if isImm8(v0) && isM512(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x71) - m.mrsd(2, addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLW imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x71) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd1) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLW imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ (ehcode(v[1]) << 5)) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x71) - m.emit(0xd0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLW xmm, ymm, ymm{k}{z} - if isEVEXXMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xd1) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSRLW m128, ymm, ymm{k}{z} - if isM128(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd1) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSRLW imm8, m128, xmm{k}{z} - if isImm8(v0) && isM128(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x71) - m.mrsd(2, addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPSRLW imm8, m256, ymm{k}{z} - if isImm8(v0) && isM256(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, 0, addr(v[1]), vcode(v[2]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x71) - m.mrsd(2, addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSRLW") - } - return p -} - -// VPSUBB performs "Subtract Packed Byte Integers". -// -// Mnemonic : VPSUBB -// Supported forms : (10 forms) -// -// * VPSUBB xmm, xmm, xmm [AVX] -// * VPSUBB m128, xmm, xmm [AVX] -// * VPSUBB ymm, ymm, ymm [AVX2] -// * VPSUBB m256, ymm, ymm [AVX2] -// * VPSUBB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSUBB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSUBB", 3, Operands { v0, v1, v2 }) - // VPSUBB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xf8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf8) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSUBB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xf8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf8) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSUBB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xf8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf8) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSUBB") - } - return p -} - -// VPSUBD performs "Subtract Packed Doubleword Integers". -// -// Mnemonic : VPSUBD -// Supported forms : (10 forms) -// -// * VPSUBD xmm, xmm, xmm [AVX] -// * VPSUBD m128, xmm, xmm [AVX] -// * VPSUBD ymm, ymm, ymm [AVX2] -// * VPSUBD m256, ymm, ymm [AVX2] -// * VPSUBD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPSUBD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPSUBD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSUBD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSUBD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSUBD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSUBD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSUBD", 3, Operands { v0, v1, v2 }) - // VPSUBD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfa) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfa) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xfa) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSUBD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xfa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xfa) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSUBD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xfa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xfa) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPSUBD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xfa) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSUBD") - } - return p -} - -// VPSUBQ performs "Subtract Packed Quadword Integers". -// -// Mnemonic : VPSUBQ -// Supported forms : (10 forms) -// -// * VPSUBQ xmm, xmm, xmm [AVX] -// * VPSUBQ m128, xmm, xmm [AVX] -// * VPSUBQ ymm, ymm, ymm [AVX2] -// * VPSUBQ m256, ymm, ymm [AVX2] -// * VPSUBQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPSUBQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPSUBQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSUBQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPSUBQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPSUBQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPSUBQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSUBQ", 3, Operands { v0, v1, v2 }) - // VPSUBQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfb) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xfb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xfb) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xfb) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSUBQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xfb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xfb) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSUBQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xfb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xfb) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPSUBQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xfb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPSUBQ") - } - return p -} - -// VPSUBSB performs "Subtract Packed Signed Byte Integers with Signed Saturation". -// -// Mnemonic : VPSUBSB -// Supported forms : (10 forms) -// -// * VPSUBSB xmm, xmm, xmm [AVX] -// * VPSUBSB m128, xmm, xmm [AVX] -// * VPSUBSB ymm, ymm, ymm [AVX2] -// * VPSUBSB m256, ymm, ymm [AVX2] -// * VPSUBSB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBSB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBSB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBSB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBSB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBSB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSUBSB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSUBSB", 3, Operands { v0, v1, v2 }) - // VPSUBSB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBSB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBSB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xe8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe8) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSUBSB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xe8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe8) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSUBSB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xe8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe8) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSUBSB") - } - return p -} - -// VPSUBSW performs "Subtract Packed Signed Word Integers with Signed Saturation". -// -// Mnemonic : VPSUBSW -// Supported forms : (10 forms) -// -// * VPSUBSW xmm, xmm, xmm [AVX] -// * VPSUBSW m128, xmm, xmm [AVX] -// * VPSUBSW ymm, ymm, ymm [AVX2] -// * VPSUBSW m256, ymm, ymm [AVX2] -// * VPSUBSW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBSW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBSW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBSW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBSW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBSW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSUBSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSUBSW", 3, Operands { v0, v1, v2 }) - // VPSUBSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xe9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xe9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBSW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xe9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe9) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSUBSW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xe9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe9) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSUBSW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xe9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBSW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xe9) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSUBSW") - } - return p -} - -// VPSUBUSB performs "Subtract Packed Unsigned Byte Integers with Unsigned Saturation". -// -// Mnemonic : VPSUBUSB -// Supported forms : (10 forms) -// -// * VPSUBUSB xmm, xmm, xmm [AVX] -// * VPSUBUSB m128, xmm, xmm [AVX] -// * VPSUBUSB ymm, ymm, ymm [AVX2] -// * VPSUBUSB m256, ymm, ymm [AVX2] -// * VPSUBUSB zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBUSB m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBUSB xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBUSB m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBUSB ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBUSB m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSUBUSB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSUBUSB", 3, Operands { v0, v1, v2 }) - // VPSUBUSB xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSB m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBUSB ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSB m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd8) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBUSB zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xd8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSB m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd8) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSUBUSB xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xd8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSB m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd8) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSUBUSB ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xd8) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSB m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd8) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSUBUSB") - } - return p -} - -// VPSUBUSW performs "Subtract Packed Unsigned Word Integers with Unsigned Saturation". -// -// Mnemonic : VPSUBUSW -// Supported forms : (10 forms) -// -// * VPSUBUSW xmm, xmm, xmm [AVX] -// * VPSUBUSW m128, xmm, xmm [AVX] -// * VPSUBUSW ymm, ymm, ymm [AVX2] -// * VPSUBUSW m256, ymm, ymm [AVX2] -// * VPSUBUSW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBUSW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBUSW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBUSW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBUSW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBUSW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSUBUSW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSUBUSW", 3, Operands { v0, v1, v2 }) - // VPSUBUSW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBUSW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xd9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xd9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBUSW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xd9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd9) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSUBUSW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xd9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd9) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSUBUSW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xd9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBUSW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xd9) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSUBUSW") - } - return p -} - -// VPSUBW performs "Subtract Packed Word Integers". -// -// Mnemonic : VPSUBW -// Supported forms : (10 forms) -// -// * VPSUBW xmm, xmm, xmm [AVX] -// * VPSUBW m128, xmm, xmm [AVX] -// * VPSUBW ymm, ymm, ymm [AVX2] -// * VPSUBW m256, ymm, ymm [AVX2] -// * VPSUBW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPSUBW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPSUBW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPSUBW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPSUBW", 3, Operands { v0, v1, v2 }) - // VPSUBW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xf9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xf9) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPSUBW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xf9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf9) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPSUBW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xf9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf9) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPSUBW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xf9) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPSUBW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xf9) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPSUBW") - } - return p -} - -// VPTERNLOGD performs "Bitwise Ternary Logical Operation on Doubleword Values". -// -// Mnemonic : VPTERNLOGD -// Supported forms : (6 forms) -// -// * VPTERNLOGD imm8, m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPTERNLOGD imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VPTERNLOGD imm8, m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPTERNLOGD imm8, xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPTERNLOGD imm8, m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPTERNLOGD imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPTERNLOGD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPTERNLOGD", 4, Operands { v0, v1, v2, v3 }) - // VPTERNLOGD imm8, m512/m32bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x25) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGD imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x25) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGD imm8, m128/m32bcst, xmm, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x25) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGD imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x25) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGD imm8, m256/m32bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x25) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGD imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x25) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPTERNLOGD") - } - return p -} - -// VPTERNLOGQ performs "Bitwise Ternary Logical Operation on Quadword Values". -// -// Mnemonic : VPTERNLOGQ -// Supported forms : (6 forms) -// -// * VPTERNLOGQ imm8, m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPTERNLOGQ imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VPTERNLOGQ imm8, m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPTERNLOGQ imm8, xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPTERNLOGQ imm8, m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPTERNLOGQ imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPTERNLOGQ(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VPTERNLOGQ", 4, Operands { v0, v1, v2, v3 }) - // VPTERNLOGQ imm8, m512/m64bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x25) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGQ imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x25) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGQ imm8, m128/m64bcst, xmm, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x25) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGQ imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x25) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGQ imm8, m256/m64bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x25) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VPTERNLOGQ imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x25) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPTERNLOGQ") - } - return p -} - -// VPTEST performs "Packed Logical Compare". -// -// Mnemonic : VPTEST -// Supported forms : (4 forms) -// -// * VPTEST xmm, xmm [AVX] -// * VPTEST m128, xmm [AVX] -// * VPTEST ymm, ymm [AVX] -// * VPTEST m256, ymm [AVX] -// -func (self *Program) VPTEST(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VPTEST", 2, Operands { v0, v1 }) - // VPTEST xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x17) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPTEST m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x17) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VPTEST ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x17) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VPTEST m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x17) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPTEST") - } - return p -} - -// VPTESTMB performs "Logical AND of Packed Byte Integer Values and Set Mask". -// -// Mnemonic : VPTESTMB -// Supported forms : (6 forms) -// -// * VPTESTMB zmm, zmm, k{k} [AVX512BW] -// * VPTESTMB m512, zmm, k{k} [AVX512BW] -// * VPTESTMB xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPTESTMB m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPTESTMB ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPTESTMB m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPTESTMB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPTESTMB", 3, Operands { v0, v1, v2 }) - // VPTESTMB zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMB m512, zmm, k{k} - if isM512(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPTESTMB xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMB m128, xmm, k{k} - if isM128(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPTESTMB ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMB m256, ymm, k{k} - if isM256(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPTESTMB") - } - return p -} - -// VPTESTMD performs "Logical AND of Packed Doubleword Integer Values and Set Mask". -// -// Mnemonic : VPTESTMD -// Supported forms : (6 forms) -// -// * VPTESTMD m512/m32bcst, zmm, k{k} [AVX512F] -// * VPTESTMD zmm, zmm, k{k} [AVX512F] -// * VPTESTMD m128/m32bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPTESTMD xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPTESTMD m256/m32bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPTESTMD ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPTESTMD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPTESTMD", 3, Operands { v0, v1, v2 }) - // VPTESTMD m512/m32bcst, zmm, k{k} - if isM512M32bcst(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPTESTMD zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMD m128/m32bcst, xmm, k{k} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPTESTMD xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMD m256/m32bcst, ymm, k{k} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPTESTMD ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPTESTMD") - } - return p -} - -// VPTESTMQ performs "Logical AND of Packed Quadword Integer Values and Set Mask". -// -// Mnemonic : VPTESTMQ -// Supported forms : (6 forms) -// -// * VPTESTMQ m512/m64bcst, zmm, k{k} [AVX512F] -// * VPTESTMQ zmm, zmm, k{k} [AVX512F] -// * VPTESTMQ m128/m64bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPTESTMQ xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPTESTMQ m256/m64bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPTESTMQ ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPTESTMQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPTESTMQ", 3, Operands { v0, v1, v2 }) - // VPTESTMQ m512/m64bcst, zmm, k{k} - if isM512M64bcst(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPTESTMQ zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMQ m128/m64bcst, xmm, k{k} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPTESTMQ xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMQ m256/m64bcst, ymm, k{k} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPTESTMQ ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPTESTMQ") - } - return p -} - -// VPTESTMW performs "Logical AND of Packed Word Integer Values and Set Mask". -// -// Mnemonic : VPTESTMW -// Supported forms : (6 forms) -// -// * VPTESTMW zmm, zmm, k{k} [AVX512BW] -// * VPTESTMW m512, zmm, k{k} [AVX512BW] -// * VPTESTMW xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPTESTMW m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPTESTMW ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPTESTMW m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPTESTMW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPTESTMW", 3, Operands { v0, v1, v2 }) - // VPTESTMW zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMW m512, zmm, k{k} - if isM512(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPTESTMW xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMW m128, xmm, k{k} - if isM128(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPTESTMW ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTMW m256, ymm, k{k} - if isM256(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPTESTMW") - } - return p -} - -// VPTESTNMB performs "Logical NAND of Packed Byte Integer Values and Set Mask". -// -// Mnemonic : VPTESTNMB -// Supported forms : (6 forms) -// -// * VPTESTNMB zmm, zmm, k{k} [AVX512BW,AVX512F] -// * VPTESTNMB m512, zmm, k{k} [AVX512BW,AVX512F] -// * VPTESTNMB xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPTESTNMB m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPTESTNMB ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPTESTNMB m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPTESTNMB(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPTESTNMB", 3, Operands { v0, v1, v2 }) - // VPTESTNMB zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMB m512, zmm, k{k} - if isM512(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPTESTNMB xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMB m128, xmm, k{k} - if isM128(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPTESTNMB ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMB m256, ymm, k{k} - if isM256(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPTESTNMB") - } - return p -} - -// VPTESTNMD performs "Logical NAND of Packed Doubleword Integer Values and Set Mask". -// -// Mnemonic : VPTESTNMD -// Supported forms : (6 forms) -// -// * VPTESTNMD m512/m32bcst, zmm, k{k} [AVX512F] -// * VPTESTNMD zmm, zmm, k{k} [AVX512F] -// * VPTESTNMD m128/m32bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPTESTNMD xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPTESTNMD m256/m32bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPTESTNMD ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPTESTNMD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPTESTNMD", 3, Operands { v0, v1, v2 }) - // VPTESTNMD m512/m32bcst, zmm, k{k} - if isM512M32bcst(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPTESTNMD zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMD m128/m32bcst, xmm, k{k} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPTESTNMD xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMD m256/m32bcst, ymm, k{k} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x06, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPTESTNMD ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPTESTNMD") - } - return p -} - -// VPTESTNMQ performs "Logical NAND of Packed Quadword Integer Values and Set Mask". -// -// Mnemonic : VPTESTNMQ -// Supported forms : (6 forms) -// -// * VPTESTNMQ m512/m64bcst, zmm, k{k} [AVX512F] -// * VPTESTNMQ zmm, zmm, k{k} [AVX512F] -// * VPTESTNMQ m128/m64bcst, xmm, k{k} [AVX512F,AVX512VL] -// * VPTESTNMQ xmm, xmm, k{k} [AVX512F,AVX512VL] -// * VPTESTNMQ m256/m64bcst, ymm, k{k} [AVX512F,AVX512VL] -// * VPTESTNMQ ymm, ymm, k{k} [AVX512F,AVX512VL] -// -func (self *Program) VPTESTNMQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPTESTNMQ", 3, Operands { v0, v1, v2 }) - // VPTESTNMQ m512/m64bcst, zmm, k{k} - if isM512M64bcst(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x86, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPTESTNMQ zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMQ m128/m64bcst, xmm, k{k} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x86, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPTESTNMQ xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMQ m256/m64bcst, ymm, k{k} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x86, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, bcode(v[0])) - m.emit(0x27) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPTESTNMQ ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x27) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPTESTNMQ") - } - return p -} - -// VPTESTNMW performs "Logical NAND of Packed Word Integer Values and Set Mask". -// -// Mnemonic : VPTESTNMW -// Supported forms : (6 forms) -// -// * VPTESTNMW zmm, zmm, k{k} [AVX512BW,AVX512F] -// * VPTESTNMW m512, zmm, k{k} [AVX512BW,AVX512F] -// * VPTESTNMW xmm, xmm, k{k} [AVX512BW,AVX512VL] -// * VPTESTNMW m128, xmm, k{k} [AVX512BW,AVX512VL] -// * VPTESTNMW ymm, ymm, k{k} [AVX512BW,AVX512VL] -// * VPTESTNMW m256, ymm, k{k} [AVX512BW,AVX512VL] -// -func (self *Program) VPTESTNMW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPTESTNMW", 3, Operands { v0, v1, v2 }) - // VPTESTNMW zmm, zmm, k{k} - if isZMM(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMW m512, zmm, k{k} - if isM512(v0) && isZMM(v1) && isKk(v2) { - self.require(ISA_AVX512F | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x86, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPTESTNMW xmm, xmm, k{k} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMW m128, xmm, k{k} - if isM128(v0) && isEVEXXMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x86, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPTESTNMW ymm, ymm, k{k} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfe ^ (hlcode(v[1]) << 3)) - m.emit((0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x26) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPTESTNMW m256, ymm, k{k} - if isM256(v0) && isEVEXYMM(v1) && isKk(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x86, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), 0, 0) - m.emit(0x26) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPTESTNMW") - } - return p -} - -// VPUNPCKHBW performs "Unpack and Interleave High-Order Bytes into Words". -// -// Mnemonic : VPUNPCKHBW -// Supported forms : (10 forms) -// -// * VPUNPCKHBW xmm, xmm, xmm [AVX] -// * VPUNPCKHBW m128, xmm, xmm [AVX] -// * VPUNPCKHBW ymm, ymm, ymm [AVX2] -// * VPUNPCKHBW m256, ymm, ymm [AVX2] -// * VPUNPCKHBW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPUNPCKHBW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPUNPCKHBW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKHBW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKHBW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKHBW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPUNPCKHBW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPUNPCKHBW", 3, Operands { v0, v1, v2 }) - // VPUNPCKHBW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x68) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHBW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x68) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKHBW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x68) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHBW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x68) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKHBW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x68) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHBW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x68) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPUNPCKHBW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x68) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHBW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x68) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPUNPCKHBW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x68) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHBW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x68) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPUNPCKHBW") - } - return p -} - -// VPUNPCKHDQ performs "Unpack and Interleave High-Order Doublewords into Quadwords". -// -// Mnemonic : VPUNPCKHDQ -// Supported forms : (10 forms) -// -// * VPUNPCKHDQ xmm, xmm, xmm [AVX] -// * VPUNPCKHDQ m128, xmm, xmm [AVX] -// * VPUNPCKHDQ ymm, ymm, ymm [AVX2] -// * VPUNPCKHDQ m256, ymm, ymm [AVX2] -// * VPUNPCKHDQ m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPUNPCKHDQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPUNPCKHDQ m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKHDQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKHDQ m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKHDQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPUNPCKHDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPUNPCKHDQ", 3, Operands { v0, v1, v2 }) - // VPUNPCKHDQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x6a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHDQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x6a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKHDQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x6a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHDQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x6a) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKHDQ m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6a) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPUNPCKHDQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x6a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHDQ m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6a) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPUNPCKHDQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x6a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHDQ m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6a) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPUNPCKHDQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x6a) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPUNPCKHDQ") - } - return p -} - -// VPUNPCKHQDQ performs "Unpack and Interleave High-Order Quadwords into Double Quadwords". -// -// Mnemonic : VPUNPCKHQDQ -// Supported forms : (10 forms) -// -// * VPUNPCKHQDQ xmm, xmm, xmm [AVX] -// * VPUNPCKHQDQ m128, xmm, xmm [AVX] -// * VPUNPCKHQDQ ymm, ymm, ymm [AVX2] -// * VPUNPCKHQDQ m256, ymm, ymm [AVX2] -// * VPUNPCKHQDQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPUNPCKHQDQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPUNPCKHQDQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKHQDQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKHQDQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKHQDQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPUNPCKHQDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPUNPCKHQDQ", 3, Operands { v0, v1, v2 }) - // VPUNPCKHQDQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHQDQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x6d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKHQDQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHQDQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x6d) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKHQDQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6d) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPUNPCKHQDQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHQDQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6d) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPUNPCKHQDQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHQDQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6d) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPUNPCKHQDQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x6d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPUNPCKHQDQ") - } - return p -} - -// VPUNPCKHWD performs "Unpack and Interleave High-Order Words into Doublewords". -// -// Mnemonic : VPUNPCKHWD -// Supported forms : (10 forms) -// -// * VPUNPCKHWD xmm, xmm, xmm [AVX] -// * VPUNPCKHWD m128, xmm, xmm [AVX] -// * VPUNPCKHWD ymm, ymm, ymm [AVX2] -// * VPUNPCKHWD m256, ymm, ymm [AVX2] -// * VPUNPCKHWD zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPUNPCKHWD m512, zmm, zmm{k}{z} [AVX512BW] -// * VPUNPCKHWD xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKHWD m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKHWD ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKHWD m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPUNPCKHWD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPUNPCKHWD", 3, Operands { v0, v1, v2 }) - // VPUNPCKHWD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x69) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHWD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x69) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKHWD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x69) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHWD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x69) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKHWD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x69) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHWD m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x69) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPUNPCKHWD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x69) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHWD m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x69) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPUNPCKHWD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x69) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKHWD m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x69) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPUNPCKHWD") - } - return p -} - -// VPUNPCKLBW performs "Unpack and Interleave Low-Order Bytes into Words". -// -// Mnemonic : VPUNPCKLBW -// Supported forms : (10 forms) -// -// * VPUNPCKLBW xmm, xmm, xmm [AVX] -// * VPUNPCKLBW m128, xmm, xmm [AVX] -// * VPUNPCKLBW ymm, ymm, ymm [AVX2] -// * VPUNPCKLBW m256, ymm, ymm [AVX2] -// * VPUNPCKLBW zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPUNPCKLBW m512, zmm, zmm{k}{z} [AVX512BW] -// * VPUNPCKLBW xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKLBW m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKLBW ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKLBW m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPUNPCKLBW(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPUNPCKLBW", 3, Operands { v0, v1, v2 }) - // VPUNPCKLBW xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x60) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLBW m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x60) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKLBW ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x60) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLBW m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x60) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKLBW zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x60) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLBW m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x60) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPUNPCKLBW xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x60) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLBW m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x60) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPUNPCKLBW ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x60) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLBW m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x60) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPUNPCKLBW") - } - return p -} - -// VPUNPCKLDQ performs "Unpack and Interleave Low-Order Doublewords into Quadwords". -// -// Mnemonic : VPUNPCKLDQ -// Supported forms : (10 forms) -// -// * VPUNPCKLDQ xmm, xmm, xmm [AVX] -// * VPUNPCKLDQ m128, xmm, xmm [AVX] -// * VPUNPCKLDQ ymm, ymm, ymm [AVX2] -// * VPUNPCKLDQ m256, ymm, ymm [AVX2] -// * VPUNPCKLDQ m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPUNPCKLDQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPUNPCKLDQ m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKLDQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKLDQ m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKLDQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPUNPCKLDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPUNPCKLDQ", 3, Operands { v0, v1, v2 }) - // VPUNPCKLDQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x62) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLDQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x62) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKLDQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x62) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLDQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x62) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKLDQ m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x62) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPUNPCKLDQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x62) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLDQ m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x62) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPUNPCKLDQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x62) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLDQ m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x62) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPUNPCKLDQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x62) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPUNPCKLDQ") - } - return p -} - -// VPUNPCKLQDQ performs "Unpack and Interleave Low-Order Quadwords into Double Quadwords". -// -// Mnemonic : VPUNPCKLQDQ -// Supported forms : (10 forms) -// -// * VPUNPCKLQDQ xmm, xmm, xmm [AVX] -// * VPUNPCKLQDQ m128, xmm, xmm [AVX] -// * VPUNPCKLQDQ ymm, ymm, ymm [AVX2] -// * VPUNPCKLQDQ m256, ymm, ymm [AVX2] -// * VPUNPCKLQDQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPUNPCKLQDQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPUNPCKLQDQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKLQDQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKLQDQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPUNPCKLQDQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPUNPCKLQDQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPUNPCKLQDQ", 3, Operands { v0, v1, v2 }) - // VPUNPCKLQDQ xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLQDQ m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x6c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKLQDQ ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLQDQ m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x6c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKLQDQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6c) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPUNPCKLQDQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLQDQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6c) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPUNPCKLQDQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLQDQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x6c) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPUNPCKLQDQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x6c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPUNPCKLQDQ") - } - return p -} - -// VPUNPCKLWD performs "Unpack and Interleave Low-Order Words into Doublewords". -// -// Mnemonic : VPUNPCKLWD -// Supported forms : (10 forms) -// -// * VPUNPCKLWD xmm, xmm, xmm [AVX] -// * VPUNPCKLWD m128, xmm, xmm [AVX] -// * VPUNPCKLWD ymm, ymm, ymm [AVX2] -// * VPUNPCKLWD m256, ymm, ymm [AVX2] -// * VPUNPCKLWD zmm, zmm, zmm{k}{z} [AVX512BW] -// * VPUNPCKLWD m512, zmm, zmm{k}{z} [AVX512BW] -// * VPUNPCKLWD xmm, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKLWD m128, xmm, xmm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKLWD ymm, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// * VPUNPCKLWD m256, ymm, ymm{k}{z} [AVX512BW,AVX512VL] -// -func (self *Program) VPUNPCKLWD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPUNPCKLWD", 3, Operands { v0, v1, v2 }) - // VPUNPCKLWD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x61) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLWD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x61) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKLWD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x61) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLWD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x61) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPUNPCKLWD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x61) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLWD m512, zmm, zmm{k}{z} - if isM512(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x61) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPUNPCKLWD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x61) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLWD m128, xmm, xmm{k}{z} - if isM128(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x61) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPUNPCKLWD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x61) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPUNPCKLWD m256, ymm, ymm{k}{z} - if isM256(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512BW) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x61) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - if p.len == 0 { - panic("invalid operands for VPUNPCKLWD") - } - return p -} - -// VPXOR performs "Packed Bitwise Logical Exclusive OR". -// -// Mnemonic : VPXOR -// Supported forms : (4 forms) -// -// * VPXOR xmm, xmm, xmm [AVX] -// * VPXOR m128, xmm, xmm [AVX] -// * VPXOR ymm, ymm, ymm [AVX2] -// * VPXOR m256, ymm, ymm [AVX2] -// -func (self *Program) VPXOR(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPXOR", 3, Operands { v0, v1, v2 }) - // VPXOR xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xef) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPXOR m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xef) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VPXOR ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0xef) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPXOR m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX2) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0xef) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VPXOR") - } - return p -} - -// VPXORD performs "Bitwise Logical Exclusive OR of Packed Doubleword Integers". -// -// Mnemonic : VPXORD -// Supported forms : (6 forms) -// -// * VPXORD m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VPXORD zmm, zmm, zmm{k}{z} [AVX512F] -// * VPXORD m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPXORD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPXORD m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPXORD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPXORD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPXORD", 3, Operands { v0, v1, v2 }) - // VPXORD m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xef) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPXORD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xef) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPXORD m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xef) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPXORD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xef) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPXORD m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xef) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPXORD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xef) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPXORD") - } - return p -} - -// VPXORQ performs "Bitwise Logical Exclusive OR of Packed Quadword Integers". -// -// Mnemonic : VPXORQ -// Supported forms : (6 forms) -// -// * VPXORQ m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VPXORQ zmm, zmm, zmm{k}{z} [AVX512F] -// * VPXORQ m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPXORQ xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VPXORQ m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VPXORQ ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VPXORQ(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VPXORQ", 3, Operands { v0, v1, v2 }) - // VPXORQ m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xef) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VPXORQ zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xef) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPXORQ m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xef) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VPXORQ xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0xef) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VPXORQ m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0xef) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VPXORQ ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0xef) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VPXORQ") - } - return p -} - -// VRANGEPD performs "Range Restriction Calculation For Packed Pairs of Double-Precision Floating-Point Values". -// -// Mnemonic : VRANGEPD -// Supported forms : (7 forms) -// -// * VRANGEPD imm8, m512/m64bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VRANGEPD imm8, {sae}, zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VRANGEPD imm8, zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VRANGEPD imm8, m128/m64bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VRANGEPD imm8, xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VRANGEPD imm8, m256/m64bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VRANGEPD imm8, ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VRANGEPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRANGEPD", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VRANGEPD", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VRANGEPD takes 4 or 5 operands") - } - // VRANGEPD imm8, m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x50) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPD imm8, {sae}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMM(v3) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0xfd ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x50) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPD imm8, zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x50) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPD imm8, m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM128M64bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x50) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPD imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x50) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPD imm8, m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x50) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPD imm8, ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x50) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRANGEPD") - } - return p -} - -// VRANGEPS performs "Range Restriction Calculation For Packed Pairs of Single-Precision Floating-Point Values". -// -// Mnemonic : VRANGEPS -// Supported forms : (7 forms) -// -// * VRANGEPS imm8, m512/m32bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VRANGEPS imm8, {sae}, zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VRANGEPS imm8, zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VRANGEPS imm8, m128/m32bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VRANGEPS imm8, xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VRANGEPS imm8, m256/m32bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VRANGEPS imm8, ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VRANGEPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRANGEPS", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VRANGEPS", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VRANGEPS takes 4 or 5 operands") - } - // VRANGEPS imm8, m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x50) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPS imm8, {sae}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMM(v3) && isZMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0x7d ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x50) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPS imm8, zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x50) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPS imm8, m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM128M32bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x50) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPS imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x50) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPS imm8, m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x50) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGEPS imm8, ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x50) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRANGEPS") - } - return p -} - -// VRANGESD performs "Range Restriction Calculation For a pair of Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VRANGESD -// Supported forms : (3 forms) -// -// * VRANGESD imm8, m64, xmm, xmm{k}{z} [AVX512DQ] -// * VRANGESD imm8, {sae}, xmm, xmm, xmm{k}{z} [AVX512DQ] -// * VRANGESD imm8, xmm, xmm, xmm{k}{z} [AVX512DQ] -// -func (self *Program) VRANGESD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRANGESD", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VRANGESD", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VRANGESD takes 4 or 5 operands") - } - // VRANGESD imm8, m64, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM64(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x51) - m.mrsd(lcode(v[3]), addr(v[1]), 8) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGESD imm8, {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isXMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0xfd ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x51) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGESD imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x51) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRANGESD") - } - return p -} - -// VRANGESS performs "Range Restriction Calculation For a pair of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VRANGESS -// Supported forms : (3 forms) -// -// * VRANGESS imm8, m32, xmm, xmm{k}{z} [AVX512DQ] -// * VRANGESS imm8, {sae}, xmm, xmm, xmm{k}{z} [AVX512DQ] -// * VRANGESS imm8, xmm, xmm, xmm{k}{z} [AVX512DQ] -// -func (self *Program) VRANGESS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRANGESS", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VRANGESS", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VRANGESS takes 4 or 5 operands") - } - // VRANGESS imm8, m32, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM32(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x51) - m.mrsd(lcode(v[3]), addr(v[1]), 4) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGESS imm8, {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isXMMkz(vv[0]) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0x7d ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x51) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VRANGESS imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x51) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRANGESS") - } - return p -} - -// VRCP14PD performs "Compute Approximate Reciprocals of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VRCP14PD -// Supported forms : (6 forms) -// -// * VRCP14PD m512/m64bcst, zmm{k}{z} [AVX512F] -// * VRCP14PD zmm, zmm{k}{z} [AVX512F] -// * VRCP14PD m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VRCP14PD m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VRCP14PD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VRCP14PD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VRCP14PD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VRCP14PD", 2, Operands { v0, v1 }) - // VRCP14PD m512/m64bcst, zmm{k}{z} - if isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VRCP14PD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRCP14PD m128/m64bcst, xmm{k}{z} - if isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VRCP14PD m256/m64bcst, ymm{k}{z} - if isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VRCP14PD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRCP14PD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRCP14PD") - } - return p -} - -// VRCP14PS performs "Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VRCP14PS -// Supported forms : (6 forms) -// -// * VRCP14PS m512/m32bcst, zmm{k}{z} [AVX512F] -// * VRCP14PS zmm, zmm{k}{z} [AVX512F] -// * VRCP14PS m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VRCP14PS m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VRCP14PS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VRCP14PS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VRCP14PS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VRCP14PS", 2, Operands { v0, v1 }) - // VRCP14PS m512/m32bcst, zmm{k}{z} - if isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VRCP14PS zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRCP14PS m128/m32bcst, xmm{k}{z} - if isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VRCP14PS m256/m32bcst, ymm{k}{z} - if isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4c) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VRCP14PS xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRCP14PS ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x4c) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRCP14PS") - } - return p -} - -// VRCP14SD performs "Compute Approximate Reciprocal of a Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VRCP14SD -// Supported forms : (2 forms) -// -// * VRCP14SD xmm, xmm, xmm{k}{z} [AVX512F] -// * VRCP14SD m64, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VRCP14SD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VRCP14SD", 3, Operands { v0, v1, v2 }) - // VRCP14SD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x4d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VRCP14SD m64, xmm, xmm{k}{z} - if isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x4d) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VRCP14SD") - } - return p -} - -// VRCP14SS performs "Compute Approximate Reciprocal of a Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VRCP14SS -// Supported forms : (2 forms) -// -// * VRCP14SS xmm, xmm, xmm{k}{z} [AVX512F] -// * VRCP14SS m32, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VRCP14SS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VRCP14SS", 3, Operands { v0, v1, v2 }) - // VRCP14SS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x4d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VRCP14SS m32, xmm, xmm{k}{z} - if isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x4d) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VRCP14SS") - } - return p -} - -// VRCP28PD performs "Approximation to the Reciprocal of Packed Double-Precision Floating-Point Values with Less Than 2^-28 Relative Error". -// -// Mnemonic : VRCP28PD -// Supported forms : (3 forms) -// -// * VRCP28PD m512/m64bcst, zmm{k}{z} [AVX512ER] -// * VRCP28PD {sae}, zmm, zmm{k}{z} [AVX512ER] -// * VRCP28PD zmm, zmm{k}{z} [AVX512ER] -// -func (self *Program) VRCP28PD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRCP28PD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VRCP28PD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VRCP28PD takes 2 or 3 operands") - } - // VRCP28PD m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xca) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VRCP28PD {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0xca) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VRCP28PD zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xca) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRCP28PD") - } - return p -} - -// VRCP28PS performs "Approximation to the Reciprocal of Packed Single-Precision Floating-Point Values with Less Than 2^-28 Relative Error". -// -// Mnemonic : VRCP28PS -// Supported forms : (3 forms) -// -// * VRCP28PS m512/m32bcst, zmm{k}{z} [AVX512ER] -// * VRCP28PS {sae}, zmm, zmm{k}{z} [AVX512ER] -// * VRCP28PS zmm, zmm{k}{z} [AVX512ER] -// -func (self *Program) VRCP28PS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRCP28PS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VRCP28PS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VRCP28PS takes 2 or 3 operands") - } - // VRCP28PS m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xca) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VRCP28PS {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0xca) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VRCP28PS zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xca) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRCP28PS") - } - return p -} - -// VRCP28SD performs "Approximation to the Reciprocal of a Scalar Double-Precision Floating-Point Value with Less Than 2^-28 Relative Error". -// -// Mnemonic : VRCP28SD -// Supported forms : (3 forms) -// -// * VRCP28SD m64, xmm, xmm{k}{z} [AVX512ER] -// * VRCP28SD {sae}, xmm, xmm, xmm{k}{z} [AVX512ER] -// * VRCP28SD xmm, xmm, xmm{k}{z} [AVX512ER] -// -func (self *Program) VRCP28SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRCP28SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VRCP28SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VRCP28SD takes 3 or 4 operands") - } - // VRCP28SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xcb) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VRCP28SD {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xcb) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VRCP28SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xcb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRCP28SD") - } - return p -} - -// VRCP28SS performs "Approximation to the Reciprocal of a Scalar Single-Precision Floating-Point Value with Less Than 2^-28 Relative Error". -// -// Mnemonic : VRCP28SS -// Supported forms : (3 forms) -// -// * VRCP28SS m32, xmm, xmm{k}{z} [AVX512ER] -// * VRCP28SS {sae}, xmm, xmm, xmm{k}{z} [AVX512ER] -// * VRCP28SS xmm, xmm, xmm{k}{z} [AVX512ER] -// -func (self *Program) VRCP28SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRCP28SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VRCP28SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VRCP28SS takes 3 or 4 operands") - } - // VRCP28SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xcb) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VRCP28SS {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xcb) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VRCP28SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xcb) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRCP28SS") - } - return p -} - -// VRCPPS performs "Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VRCPPS -// Supported forms : (4 forms) -// -// * VRCPPS xmm, xmm [AVX] -// * VRCPPS m128, xmm [AVX] -// * VRCPPS ymm, ymm [AVX] -// * VRCPPS m256, ymm [AVX] -// -func (self *Program) VRCPPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VRCPPS", 2, Operands { v0, v1 }) - // VRCPPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x53) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRCPPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), addr(v[0]), 0) - m.emit(0x53) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VRCPPS ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), v[0], 0) - m.emit(0x53) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRCPPS m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), addr(v[0]), 0) - m.emit(0x53) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VRCPPS") - } - return p -} - -// VRCPSS performs "Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VRCPSS -// Supported forms : (2 forms) -// -// * VRCPSS xmm, xmm, xmm [AVX] -// * VRCPSS m32, xmm, xmm [AVX] -// -func (self *Program) VRCPSS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VRCPSS", 3, Operands { v0, v1, v2 }) - // VRCPSS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x53) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VRCPSS m32, xmm, xmm - if isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x53) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VRCPSS") - } - return p -} - -// VREDUCEPD performs "Perform Reduction Transformation on Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VREDUCEPD -// Supported forms : (6 forms) -// -// * VREDUCEPD imm8, m512/m64bcst, zmm{k}{z} [AVX512DQ] -// * VREDUCEPD imm8, zmm, zmm{k}{z} [AVX512DQ] -// * VREDUCEPD imm8, m128/m64bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VREDUCEPD imm8, m256/m64bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VREDUCEPD imm8, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VREDUCEPD imm8, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VREDUCEPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VREDUCEPD", 3, Operands { v0, v1, v2 }) - // VREDUCEPD imm8, m512/m64bcst, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPD imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPD imm8, m128/m64bcst, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPD imm8, m256/m64bcst, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPD imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPD imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VREDUCEPD") - } - return p -} - -// VREDUCEPS performs "Perform Reduction Transformation on Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VREDUCEPS -// Supported forms : (6 forms) -// -// * VREDUCEPS imm8, m512/m32bcst, zmm{k}{z} [AVX512DQ] -// * VREDUCEPS imm8, zmm, zmm{k}{z} [AVX512DQ] -// * VREDUCEPS imm8, m128/m32bcst, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VREDUCEPS imm8, m256/m32bcst, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VREDUCEPS imm8, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VREDUCEPS imm8, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VREDUCEPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VREDUCEPS", 3, Operands { v0, v1, v2 }) - // VREDUCEPS imm8, m512/m32bcst, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPS imm8, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPS imm8, m128/m32bcst, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPS imm8, m256/m32bcst, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x56) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPS imm8, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCEPS imm8, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x56) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VREDUCEPS") - } - return p -} - -// VREDUCESD performs "Perform Reduction Transformation on a Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VREDUCESD -// Supported forms : (2 forms) -// -// * VREDUCESD imm8, xmm, xmm, xmm{k}{z} [AVX512DQ] -// * VREDUCESD imm8, m64, xmm, xmm{k}{z} [AVX512DQ] -// -func (self *Program) VREDUCESD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VREDUCESD", 4, Operands { v0, v1, v2, v3 }) - // VREDUCESD imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x57) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCESD imm8, m64, xmm, xmm{k}{z} - if isImm8(v0) && isM64(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x57) - m.mrsd(lcode(v[3]), addr(v[1]), 8) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VREDUCESD") - } - return p -} - -// VREDUCESS performs "Perform Reduction Transformation on a Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VREDUCESS -// Supported forms : (2 forms) -// -// * VREDUCESS imm8, xmm, xmm, xmm{k}{z} [AVX512DQ] -// * VREDUCESS imm8, m32, xmm, xmm{k}{z} [AVX512DQ] -// -func (self *Program) VREDUCESS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VREDUCESS", 4, Operands { v0, v1, v2, v3 }) - // VREDUCESS imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0x57) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VREDUCESS imm8, m32, xmm, xmm{k}{z} - if isImm8(v0) && isM32(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x57) - m.mrsd(lcode(v[3]), addr(v[1]), 4) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VREDUCESS") - } - return p -} - -// VRNDSCALEPD performs "Round Packed Double-Precision Floating-Point Values To Include A Given Number Of Fraction Bits". -// -// Mnemonic : VRNDSCALEPD -// Supported forms : (7 forms) -// -// * VRNDSCALEPD imm8, m512/m64bcst, zmm{k}{z} [AVX512F] -// * VRNDSCALEPD imm8, {sae}, zmm, zmm{k}{z} [AVX512F] -// * VRNDSCALEPD imm8, zmm, zmm{k}{z} [AVX512F] -// * VRNDSCALEPD imm8, m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VRNDSCALEPD imm8, m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VRNDSCALEPD imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VRNDSCALEPD imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VRNDSCALEPD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRNDSCALEPD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VRNDSCALEPD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VRNDSCALEPD takes 3 or 4 operands") - } - // VRNDSCALEPD imm8, m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM512M64bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x09) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPD imm8, {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[3]) << 7) | kcode(v[3]) | 0x18) - m.emit(0x09) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPD imm8, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x09) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPD imm8, m128/m64bcst, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM128M64bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x09) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPD imm8, m256/m64bcst, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM256M64bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x09) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPD imm8, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x09) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPD imm8, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x09) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRNDSCALEPD") - } - return p -} - -// VRNDSCALEPS performs "Round Packed Single-Precision Floating-Point Values To Include A Given Number Of Fraction Bits". -// -// Mnemonic : VRNDSCALEPS -// Supported forms : (7 forms) -// -// * VRNDSCALEPS imm8, m512/m32bcst, zmm{k}{z} [AVX512F] -// * VRNDSCALEPS imm8, {sae}, zmm, zmm{k}{z} [AVX512F] -// * VRNDSCALEPS imm8, zmm, zmm{k}{z} [AVX512F] -// * VRNDSCALEPS imm8, m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VRNDSCALEPS imm8, m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VRNDSCALEPS imm8, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VRNDSCALEPS imm8, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VRNDSCALEPS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRNDSCALEPS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VRNDSCALEPS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VRNDSCALEPS takes 3 or 4 operands") - } - // VRNDSCALEPS imm8, m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM512M32bcst(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x08) - m.mrsd(lcode(v[2]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPS imm8, {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[3]) << 7) | kcode(v[3]) | 0x18) - m.emit(0x08) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPS imm8, zmm, zmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x48) - m.emit(0x08) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPS imm8, m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM128M32bcst(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x08) - m.mrsd(lcode(v[2]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPS imm8, m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM256M32bcst(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[2]), addr(v[1]), 0, kcode(v[2]), zcode(v[2]), bcode(v[1])) - m.emit(0x08) - m.mrsd(lcode(v[2]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPS imm8, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x08) - m.emit(0x08) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALEPS imm8, ymm, ymm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x28) - m.emit(0x08) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRNDSCALEPS") - } - return p -} - -// VRNDSCALESD performs "Round Scalar Double-Precision Floating-Point Value To Include A Given Number Of Fraction Bits". -// -// Mnemonic : VRNDSCALESD -// Supported forms : (3 forms) -// -// * VRNDSCALESD imm8, m64, xmm, xmm{k}{z} [AVX512F] -// * VRNDSCALESD imm8, {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VRNDSCALESD imm8, xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VRNDSCALESD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRNDSCALESD", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VRNDSCALESD", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VRNDSCALESD takes 4 or 5 operands") - } - // VRNDSCALESD imm8, m64, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM64(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x0b) - m.mrsd(lcode(v[3]), addr(v[1]), 8) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALESD imm8, {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0xfd ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALESD imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRNDSCALESD") - } - return p -} - -// VRNDSCALESS performs "Round Scalar Single-Precision Floating-Point Value To Include A Given Number Of Fraction Bits". -// -// Mnemonic : VRNDSCALESS -// Supported forms : (3 forms) -// -// * VRNDSCALESS imm8, m32, xmm, xmm{k}{z} [AVX512F] -// * VRNDSCALESS imm8, {sae}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VRNDSCALESS imm8, xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VRNDSCALESS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRNDSCALESS", 4, Operands { v0, v1, v2, v3 }) - case 1 : p = self.alloc("VRNDSCALESS", 5, Operands { v0, v1, v2, v3, vv[0] }) - default : panic("instruction VRNDSCALESS takes 4 or 5 operands") - } - // VRNDSCALESS imm8, m32, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isM32(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), 0) - m.emit(0x0a) - m.mrsd(lcode(v[3]), addr(v[1]), 4) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALESS imm8, {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isImm8(v0) && isSAE(v1) && isEVEXXMM(v2) && isEVEXXMM(v3) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[4]) << 7) | (ehcode(v[2]) << 5) | (ecode(v[4]) << 4))) - m.emit(0x7d ^ (hlcode(v[3]) << 3)) - m.emit((zcode(v[4]) << 7) | (0x08 ^ (ecode(v[3]) << 3)) | kcode(v[4]) | 0x10) - m.emit(0x0a) - m.emit(0xc0 | lcode(v[4]) << 3 | lcode(v[2])) - m.imm1(toImmAny(v[0])) - }) - } - // VRNDSCALESS imm8, xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x0a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRNDSCALESS") - } - return p -} - -// VROUNDPD performs "Round Packed Double Precision Floating-Point Values". -// -// Mnemonic : VROUNDPD -// Supported forms : (4 forms) -// -// * VROUNDPD imm8, xmm, xmm [AVX] -// * VROUNDPD imm8, m128, xmm [AVX] -// * VROUNDPD imm8, ymm, ymm [AVX] -// * VROUNDPD imm8, m256, ymm [AVX] -// -func (self *Program) VROUNDPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VROUNDPD", 3, Operands { v0, v1, v2 }) - // VROUNDPD imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79) - m.emit(0x09) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VROUNDPD imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[2]), addr(v[1]), 0) - m.emit(0x09) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VROUNDPD imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d) - m.emit(0x09) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VROUNDPD imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[2]), addr(v[1]), 0) - m.emit(0x09) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VROUNDPD") - } - return p -} - -// VROUNDPS performs "Round Packed Single Precision Floating-Point Values". -// -// Mnemonic : VROUNDPS -// Supported forms : (4 forms) -// -// * VROUNDPS imm8, xmm, xmm [AVX] -// * VROUNDPS imm8, m128, xmm [AVX] -// * VROUNDPS imm8, ymm, ymm [AVX] -// * VROUNDPS imm8, m256, ymm [AVX] -// -func (self *Program) VROUNDPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VROUNDPS", 3, Operands { v0, v1, v2 }) - // VROUNDPS imm8, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79) - m.emit(0x08) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VROUNDPS imm8, m128, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[2]), addr(v[1]), 0) - m.emit(0x08) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VROUNDPS imm8, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[2]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x7d) - m.emit(0x08) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VROUNDPS imm8, m256, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x05, hcode(v[2]), addr(v[1]), 0) - m.emit(0x08) - m.mrsd(lcode(v[2]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VROUNDPS") - } - return p -} - -// VROUNDSD performs "Round Scalar Double Precision Floating-Point Values". -// -// Mnemonic : VROUNDSD -// Supported forms : (2 forms) -// -// * VROUNDSD imm8, xmm, xmm, xmm [AVX] -// * VROUNDSD imm8, m64, xmm, xmm [AVX] -// -func (self *Program) VROUNDSD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VROUNDSD", 4, Operands { v0, v1, v2, v3 }) - // VROUNDSD imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x0b) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VROUNDSD imm8, m64, xmm, xmm - if isImm8(v0) && isM64(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0b) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VROUNDSD") - } - return p -} - -// VROUNDSS performs "Round Scalar Single Precision Floating-Point Values". -// -// Mnemonic : VROUNDSS -// Supported forms : (2 forms) -// -// * VROUNDSS imm8, xmm, xmm, xmm [AVX] -// * VROUNDSS imm8, m32, xmm, xmm [AVX] -// -func (self *Program) VROUNDSS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VROUNDSS", 4, Operands { v0, v1, v2, v3 }) - // VROUNDSS imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe3 ^ (hcode(v[3]) << 7) ^ (hcode(v[1]) << 5)) - m.emit(0x79 ^ (hlcode(v[2]) << 3)) - m.emit(0x0a) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VROUNDSS imm8, m32, xmm, xmm - if isImm8(v0) && isM32(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b11, 0x01, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0x0a) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VROUNDSS") - } - return p -} - -// VRSQRT14PD performs "Compute Approximate Reciprocals of Square Roots of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VRSQRT14PD -// Supported forms : (6 forms) -// -// * VRSQRT14PD m512/m64bcst, zmm{k}{z} [AVX512F] -// * VRSQRT14PD zmm, zmm{k}{z} [AVX512F] -// * VRSQRT14PD m128/m64bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VRSQRT14PD m256/m64bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VRSQRT14PD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VRSQRT14PD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VRSQRT14PD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VRSQRT14PD", 2, Operands { v0, v1 }) - // VRSQRT14PD m512/m64bcst, zmm{k}{z} - if isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VRSQRT14PD zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRSQRT14PD m128/m64bcst, xmm{k}{z} - if isM128M64bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VRSQRT14PD m256/m64bcst, ymm{k}{z} - if isM256M64bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VRSQRT14PD xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRSQRT14PD ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRT14PD") - } - return p -} - -// VRSQRT14PS performs "Compute Approximate Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VRSQRT14PS -// Supported forms : (6 forms) -// -// * VRSQRT14PS m512/m32bcst, zmm{k}{z} [AVX512F] -// * VRSQRT14PS zmm, zmm{k}{z} [AVX512F] -// * VRSQRT14PS m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VRSQRT14PS m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VRSQRT14PS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VRSQRT14PS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VRSQRT14PS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VRSQRT14PS", 2, Operands { v0, v1 }) - // VRSQRT14PS m512/m32bcst, zmm{k}{z} - if isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VRSQRT14PS zmm, zmm{k}{z} - if isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRSQRT14PS m128/m32bcst, xmm{k}{z} - if isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VRSQRT14PS m256/m32bcst, ymm{k}{z} - if isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x4e) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VRSQRT14PS xmm, xmm{k}{z} - if isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRSQRT14PS ymm, ymm{k}{z} - if isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x4e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRT14PS") - } - return p -} - -// VRSQRT14SD performs "Compute Approximate Reciprocal of a Square Root of a Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VRSQRT14SD -// Supported forms : (2 forms) -// -// * VRSQRT14SD xmm, xmm, xmm{k}{z} [AVX512F] -// * VRSQRT14SD m64, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VRSQRT14SD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VRSQRT14SD", 3, Operands { v0, v1, v2 }) - // VRSQRT14SD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x4f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VRSQRT14SD m64, xmm, xmm{k}{z} - if isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x4f) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRT14SD") - } - return p -} - -// VRSQRT14SS performs "Compute Approximate Reciprocal of a Square Root of a Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VRSQRT14SS -// Supported forms : (2 forms) -// -// * VRSQRT14SS xmm, xmm, xmm{k}{z} [AVX512F] -// * VRSQRT14SS m32, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VRSQRT14SS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VRSQRT14SS", 3, Operands { v0, v1, v2 }) - // VRSQRT14SS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x4f) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VRSQRT14SS m32, xmm, xmm{k}{z} - if isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x4f) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRT14SS") - } - return p -} - -// VRSQRT28PD performs "Approximation to the Reciprocal Square Root of Packed Double-Precision Floating-Point Values with Less Than 2^-28 Relative Error". -// -// Mnemonic : VRSQRT28PD -// Supported forms : (3 forms) -// -// * VRSQRT28PD m512/m64bcst, zmm{k}{z} [AVX512ER] -// * VRSQRT28PD {sae}, zmm, zmm{k}{z} [AVX512ER] -// * VRSQRT28PD zmm, zmm{k}{z} [AVX512ER] -// -func (self *Program) VRSQRT28PD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRSQRT28PD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VRSQRT28PD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VRSQRT28PD takes 2 or 3 operands") - } - // VRSQRT28PD m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xcc) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VRSQRT28PD {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0xcc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VRSQRT28PD zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xcc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRT28PD") - } - return p -} - -// VRSQRT28PS performs "Approximation to the Reciprocal Square Root of Packed Single-Precision Floating-Point Values with Less Than 2^-28 Relative Error". -// -// Mnemonic : VRSQRT28PS -// Supported forms : (3 forms) -// -// * VRSQRT28PS m512/m32bcst, zmm{k}{z} [AVX512ER] -// * VRSQRT28PS {sae}, zmm, zmm{k}{z} [AVX512ER] -// * VRSQRT28PS zmm, zmm{k}{z} [AVX512ER] -// -func (self *Program) VRSQRT28PS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRSQRT28PS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VRSQRT28PS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VRSQRT28PS takes 2 or 3 operands") - } - // VRSQRT28PS m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0xcc) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VRSQRT28PS {sae}, zmm, zmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[2]) << 7) | kcode(v[2]) | 0x18) - m.emit(0xcc) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VRSQRT28PS zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7d) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0xcc) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRT28PS") - } - return p -} - -// VRSQRT28SD performs "Approximation to the Reciprocal Square Root of a Scalar Double-Precision Floating-Point Value with Less Than 2^-28 Relative Error". -// -// Mnemonic : VRSQRT28SD -// Supported forms : (3 forms) -// -// * VRSQRT28SD m64, xmm, xmm{k}{z} [AVX512ER] -// * VRSQRT28SD {sae}, xmm, xmm, xmm{k}{z} [AVX512ER] -// * VRSQRT28SD xmm, xmm, xmm{k}{z} [AVX512ER] -// -func (self *Program) VRSQRT28SD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRSQRT28SD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VRSQRT28SD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VRSQRT28SD takes 3 or 4 operands") - } - // VRSQRT28SD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xcd) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VRSQRT28SD {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xcd) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VRSQRT28SD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xcd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRT28SD") - } - return p -} - -// VRSQRT28SS performs "Approximation to the Reciprocal Square Root of a Scalar Single-Precision Floating-Point Value with Less Than 2^-28 Relative Error". -// -// Mnemonic : VRSQRT28SS -// Supported forms : (3 forms) -// -// * VRSQRT28SS m32, xmm, xmm{k}{z} [AVX512ER] -// * VRSQRT28SS {sae}, xmm, xmm, xmm{k}{z} [AVX512ER] -// * VRSQRT28SS xmm, xmm, xmm{k}{z} [AVX512ER] -// -func (self *Program) VRSQRT28SS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VRSQRT28SS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VRSQRT28SS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VRSQRT28SS takes 3 or 4 operands") - } - // VRSQRT28SS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0xcd) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VRSQRT28SS {sae}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0xcd) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VRSQRT28SS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512ER) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0xcd) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRT28SS") - } - return p -} - -// VRSQRTPS performs "Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VRSQRTPS -// Supported forms : (4 forms) -// -// * VRSQRTPS xmm, xmm [AVX] -// * VRSQRTPS m128, xmm [AVX] -// * VRSQRTPS ymm, ymm [AVX] -// * VRSQRTPS m256, ymm [AVX] -// -func (self *Program) VRSQRTPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VRSQRTPS", 2, Operands { v0, v1 }) - // VRSQRTPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x52) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRSQRTPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), addr(v[0]), 0) - m.emit(0x52) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VRSQRTPS ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), v[0], 0) - m.emit(0x52) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VRSQRTPS m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), addr(v[0]), 0) - m.emit(0x52) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRTPS") - } - return p -} - -// VRSQRTSS performs "Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VRSQRTSS -// Supported forms : (2 forms) -// -// * VRSQRTSS xmm, xmm, xmm [AVX] -// * VRSQRTSS m32, xmm, xmm [AVX] -// -func (self *Program) VRSQRTSS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VRSQRTSS", 3, Operands { v0, v1, v2 }) - // VRSQRTSS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x52) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VRSQRTSS m32, xmm, xmm - if isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x52) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VRSQRTSS") - } - return p -} - -// VSCALEFPD performs "Scale Packed Double-Precision Floating-Point Values With Double-Precision Floating-Point Values". -// -// Mnemonic : VSCALEFPD -// Supported forms : (7 forms) -// -// * VSCALEFPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VSCALEFPD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSCALEFPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VSCALEFPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSCALEFPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSCALEFPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSCALEFPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSCALEFPD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSCALEFPD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSCALEFPD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSCALEFPD takes 3 or 4 operands") - } - // VSCALEFPD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x2c) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VSCALEFPD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSCALEFPD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSCALEFPD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x2c) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VSCALEFPD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSCALEFPD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x2c) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VSCALEFPD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSCALEFPD") - } - return p -} - -// VSCALEFPS performs "Scale Packed Single-Precision Floating-Point Values With Single-Precision Floating-Point Values". -// -// Mnemonic : VSCALEFPS -// Supported forms : (7 forms) -// -// * VSCALEFPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VSCALEFPS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSCALEFPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VSCALEFPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSCALEFPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSCALEFPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSCALEFPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSCALEFPS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSCALEFPS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSCALEFPS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSCALEFPS takes 3 or 4 operands") - } - // VSCALEFPS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x2c) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VSCALEFPS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSCALEFPS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSCALEFPS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x2c) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VSCALEFPS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSCALEFPS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x2c) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VSCALEFPS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x2c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSCALEFPS") - } - return p -} - -// VSCALEFSD performs "Scale Scalar Double-Precision Floating-Point Value With a Double-Precision Floating-Point Value". -// -// Mnemonic : VSCALEFSD -// Supported forms : (3 forms) -// -// * VSCALEFSD m64, xmm, xmm{k}{z} [AVX512F] -// * VSCALEFSD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VSCALEFSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VSCALEFSD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSCALEFSD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSCALEFSD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSCALEFSD takes 3 or 4 operands") - } - // VSCALEFSD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x2d) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VSCALEFSD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSCALEFSD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSCALEFSD") - } - return p -} - -// VSCALEFSS performs "Scale Scalar Single-Precision Floating-Point Value With a Single-Precision Floating-Point Value". -// -// Mnemonic : VSCALEFSS -// Supported forms : (3 forms) -// -// * VSCALEFSS m32, xmm, xmm{k}{z} [AVX512F] -// * VSCALEFSS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VSCALEFSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VSCALEFSS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSCALEFSS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSCALEFSS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSCALEFSS takes 3 or 4 operands") - } - // VSCALEFSS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x2d) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VSCALEFSS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSCALEFSS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf2 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7d ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x2d) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSCALEFSS") - } - return p -} - -// VSCATTERDPD performs "Scatter Packed Double-Precision Floating-Point Values with Signed Doubleword Indices". -// -// Mnemonic : VSCATTERDPD -// Supported forms : (3 forms) -// -// * VSCATTERDPD zmm, vm32y{k} [AVX512F] -// * VSCATTERDPD xmm, vm32x{k} [AVX512F,AVX512VL] -// * VSCATTERDPD ymm, vm32x{k} [AVX512F,AVX512VL] -// -func (self *Program) VSCATTERDPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VSCATTERDPD", 2, Operands { v0, v1 }) - // VSCATTERDPD zmm, vm32y{k} - if isZMM(v0) && isVMYk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa2) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VSCATTERDPD xmm, vm32x{k} - if isEVEXXMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa2) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VSCATTERDPD ymm, vm32x{k} - if isEVEXYMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa2) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERDPD") - } - return p -} - -// VSCATTERDPS performs "Scatter Packed Single-Precision Floating-Point Values with Signed Doubleword Indices". -// -// Mnemonic : VSCATTERDPS -// Supported forms : (3 forms) -// -// * VSCATTERDPS zmm, vm32z{k} [AVX512F] -// * VSCATTERDPS xmm, vm32x{k} [AVX512F,AVX512VL] -// * VSCATTERDPS ymm, vm32y{k} [AVX512F,AVX512VL] -// -func (self *Program) VSCATTERDPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VSCATTERDPS", 2, Operands { v0, v1 }) - // VSCATTERDPS zmm, vm32z{k} - if isZMM(v0) && isVMZk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa2) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VSCATTERDPS xmm, vm32x{k} - if isEVEXXMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa2) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VSCATTERDPS ymm, vm32y{k} - if isEVEXYMM(v0) && isVMYk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa2) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERDPS") - } - return p -} - -// VSCATTERPF0DPD performs "Sparse Prefetch Packed Double-Precision Floating-Point Data Values with Signed Doubleword Indices Using T0 Hint with Intent to Write". -// -// Mnemonic : VSCATTERPF0DPD -// Supported forms : (1 form) -// -// * VSCATTERPF0DPD vm32y{k} [AVX512PF] -// -func (self *Program) VSCATTERPF0DPD(v0 interface{}) *Instruction { - p := self.alloc("VSCATTERPF0DPD", 1, Operands { v0 }) - // VSCATTERPF0DPD vm32y{k} - if isVMYk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc6) - m.mrsd(5, addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERPF0DPD") - } - return p -} - -// VSCATTERPF0DPS performs "Sparse Prefetch Packed Single-Precision Floating-Point Data Values with Signed Doubleword Indices Using T0 Hint with Intent to Write". -// -// Mnemonic : VSCATTERPF0DPS -// Supported forms : (1 form) -// -// * VSCATTERPF0DPS vm32z{k} [AVX512PF] -// -func (self *Program) VSCATTERPF0DPS(v0 interface{}) *Instruction { - p := self.alloc("VSCATTERPF0DPS", 1, Operands { v0 }) - // VSCATTERPF0DPS vm32z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc6) - m.mrsd(5, addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERPF0DPS") - } - return p -} - -// VSCATTERPF0QPD performs "Sparse Prefetch Packed Double-Precision Floating-Point Data Values with Signed Quadword Indices Using T0 Hint with Intent to Write". -// -// Mnemonic : VSCATTERPF0QPD -// Supported forms : (1 form) -// -// * VSCATTERPF0QPD vm64z{k} [AVX512PF] -// -func (self *Program) VSCATTERPF0QPD(v0 interface{}) *Instruction { - p := self.alloc("VSCATTERPF0QPD", 1, Operands { v0 }) - // VSCATTERPF0QPD vm64z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc7) - m.mrsd(5, addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERPF0QPD") - } - return p -} - -// VSCATTERPF0QPS performs "Sparse Prefetch Packed Single-Precision Floating-Point Data Values with Signed Quadword Indices Using T0 Hint with Intent to Write". -// -// Mnemonic : VSCATTERPF0QPS -// Supported forms : (1 form) -// -// * VSCATTERPF0QPS vm64z{k} [AVX512PF] -// -func (self *Program) VSCATTERPF0QPS(v0 interface{}) *Instruction { - p := self.alloc("VSCATTERPF0QPS", 1, Operands { v0 }) - // VSCATTERPF0QPS vm64z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc7) - m.mrsd(5, addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERPF0QPS") - } - return p -} - -// VSCATTERPF1DPD performs "Sparse Prefetch Packed Double-Precision Floating-Point Data Values with Signed Doubleword Indices Using T1 Hint with Intent to Write". -// -// Mnemonic : VSCATTERPF1DPD -// Supported forms : (1 form) -// -// * VSCATTERPF1DPD vm32y{k} [AVX512PF] -// -func (self *Program) VSCATTERPF1DPD(v0 interface{}) *Instruction { - p := self.alloc("VSCATTERPF1DPD", 1, Operands { v0 }) - // VSCATTERPF1DPD vm32y{k} - if isVMYk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc6) - m.mrsd(6, addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERPF1DPD") - } - return p -} - -// VSCATTERPF1DPS performs "Sparse Prefetch Packed Single-Precision Floating-Point Data Values with Signed Doubleword Indices Using T1 Hint with Intent to Write". -// -// Mnemonic : VSCATTERPF1DPS -// Supported forms : (1 form) -// -// * VSCATTERPF1DPS vm32z{k} [AVX512PF] -// -func (self *Program) VSCATTERPF1DPS(v0 interface{}) *Instruction { - p := self.alloc("VSCATTERPF1DPS", 1, Operands { v0 }) - // VSCATTERPF1DPS vm32z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc6) - m.mrsd(6, addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERPF1DPS") - } - return p -} - -// VSCATTERPF1QPD performs "Sparse Prefetch Packed Double-Precision Floating-Point Data Values with Signed Quadword Indices Using T1 Hint with Intent to Write". -// -// Mnemonic : VSCATTERPF1QPD -// Supported forms : (1 form) -// -// * VSCATTERPF1QPD vm64z{k} [AVX512PF] -// -func (self *Program) VSCATTERPF1QPD(v0 interface{}) *Instruction { - p := self.alloc("VSCATTERPF1QPD", 1, Operands { v0 }) - // VSCATTERPF1QPD vm64z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc7) - m.mrsd(6, addr(v[0]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERPF1QPD") - } - return p -} - -// VSCATTERPF1QPS performs "Sparse Prefetch Packed Single-Precision Floating-Point Data Values with Signed Quadword Indices Using T1 Hint with Intent to Write". -// -// Mnemonic : VSCATTERPF1QPS -// Supported forms : (1 form) -// -// * VSCATTERPF1QPS vm64z{k} [AVX512PF] -// -func (self *Program) VSCATTERPF1QPS(v0 interface{}) *Instruction { - p := self.alloc("VSCATTERPF1QPS", 1, Operands { v0 }) - // VSCATTERPF1QPS vm64z{k} - if isVMZk(v0) { - self.require(ISA_AVX512PF) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, 0, addr(v[0]), 0, kcode(v[0]), 0, 0) - m.emit(0xc7) - m.mrsd(6, addr(v[0]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERPF1QPS") - } - return p -} - -// VSCATTERQPD performs "Scatter Packed Double-Precision Floating-Point Values with Signed Quadword Indices". -// -// Mnemonic : VSCATTERQPD -// Supported forms : (3 forms) -// -// * VSCATTERQPD zmm, vm64z{k} [AVX512F] -// * VSCATTERQPD xmm, vm64x{k} [AVX512F,AVX512VL] -// * VSCATTERQPD ymm, vm64y{k} [AVX512F,AVX512VL] -// -func (self *Program) VSCATTERQPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VSCATTERQPD", 2, Operands { v0, v1 }) - // VSCATTERQPD zmm, vm64z{k} - if isZMM(v0) && isVMZk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa3) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VSCATTERQPD xmm, vm64x{k} - if isEVEXXMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa3) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - // VSCATTERQPD ymm, vm64y{k} - if isEVEXYMM(v0) && isVMYk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x85, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa3) - m.mrsd(lcode(v[0]), addr(v[1]), 8) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERQPD") - } - return p -} - -// VSCATTERQPS performs "Scatter Packed Single-Precision Floating-Point Values with Signed Quadword Indices". -// -// Mnemonic : VSCATTERQPS -// Supported forms : (3 forms) -// -// * VSCATTERQPS ymm, vm64z{k} [AVX512F] -// * VSCATTERQPS xmm, vm64x{k} [AVX512F,AVX512VL] -// * VSCATTERQPS xmm, vm64y{k} [AVX512F,AVX512VL] -// -func (self *Program) VSCATTERQPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VSCATTERQPS", 2, Operands { v0, v1 }) - // VSCATTERQPS ymm, vm64z{k} - if isEVEXYMM(v0) && isVMZk(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b10, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa3) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VSCATTERQPS xmm, vm64x{k} - if isEVEXXMM(v0) && isVMXk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b00, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa3) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - // VSCATTERQPS xmm, vm64y{k} - if isEVEXXMM(v0) && isVMYk(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b10, 0x05, 0b01, ehcode(v[0]), addr(v[1]), 0, kcode(v[1]), 0, 0) - m.emit(0xa3) - m.mrsd(lcode(v[0]), addr(v[1]), 4) - }) - } - if p.len == 0 { - panic("invalid operands for VSCATTERQPS") - } - return p -} - -// VSHUFF32X4 performs "Shuffle 128-Bit Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VSHUFF32X4 -// Supported forms : (4 forms) -// -// * VSHUFF32X4 imm8, m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VSHUFF32X4 imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSHUFF32X4 imm8, m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSHUFF32X4 imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSHUFF32X4(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VSHUFF32X4", 4, Operands { v0, v1, v2, v3 }) - // VSHUFF32X4 imm8, m512/m32bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x23) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFF32X4 imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x23) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFF32X4 imm8, m256/m32bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x23) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFF32X4 imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x23) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSHUFF32X4") - } - return p -} - -// VSHUFF64X2 performs "Shuffle 128-Bit Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VSHUFF64X2 -// Supported forms : (4 forms) -// -// * VSHUFF64X2 imm8, m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VSHUFF64X2 imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSHUFF64X2 imm8, m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSHUFF64X2 imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSHUFF64X2(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VSHUFF64X2", 4, Operands { v0, v1, v2, v3 }) - // VSHUFF64X2 imm8, m512/m64bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x23) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFF64X2 imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x23) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFF64X2 imm8, m256/m64bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x23) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFF64X2 imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x23) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSHUFF64X2") - } - return p -} - -// VSHUFI32X4 performs "Shuffle 128-Bit Packed Doubleword Integer Values". -// -// Mnemonic : VSHUFI32X4 -// Supported forms : (4 forms) -// -// * VSHUFI32X4 imm8, m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VSHUFI32X4 imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSHUFI32X4 imm8, m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSHUFI32X4 imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSHUFI32X4(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VSHUFI32X4", 4, Operands { v0, v1, v2, v3 }) - // VSHUFI32X4 imm8, m512/m32bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x43) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFI32X4 imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x43) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFI32X4 imm8, m256/m32bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x05, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x43) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFI32X4 imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7d ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x43) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSHUFI32X4") - } - return p -} - -// VSHUFI64X2 performs "Shuffle 128-Bit Packed Quadword Integer Values". -// -// Mnemonic : VSHUFI64X2 -// Supported forms : (4 forms) -// -// * VSHUFI64X2 imm8, m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VSHUFI64X2 imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSHUFI64X2 imm8, m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSHUFI64X2 imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSHUFI64X2(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VSHUFI64X2", 4, Operands { v0, v1, v2, v3 }) - // VSHUFI64X2 imm8, m512/m64bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x43) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFI64X2 imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0x43) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFI64X2 imm8, m256/m64bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b11, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0x43) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFI64X2 imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf3 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0x43) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSHUFI64X2") - } - return p -} - -// VSHUFPD performs "Shuffle Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VSHUFPD -// Supported forms : (10 forms) -// -// * VSHUFPD imm8, xmm, xmm, xmm [AVX] -// * VSHUFPD imm8, m128, xmm, xmm [AVX] -// * VSHUFPD imm8, ymm, ymm, ymm [AVX] -// * VSHUFPD imm8, m256, ymm, ymm [AVX] -// * VSHUFPD imm8, m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VSHUFPD imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSHUFPD imm8, m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSHUFPD imm8, xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSHUFPD imm8, m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSHUFPD imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSHUFPD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VSHUFPD", 4, Operands { v0, v1, v2, v3 }) - // VSHUFPD imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPD imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPD imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPD imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPD imm8, m512/m64bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M64bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPD imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPD imm8, m128/m64bcst, xmm, xmm{k}{z} - if isImm8(v0) && isM128M64bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPD imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPD imm8, m256/m64bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M64bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPD imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSHUFPD") - } - return p -} - -// VSHUFPS performs "Shuffle Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VSHUFPS -// Supported forms : (10 forms) -// -// * VSHUFPS imm8, xmm, xmm, xmm [AVX] -// * VSHUFPS imm8, m128, xmm, xmm [AVX] -// * VSHUFPS imm8, ymm, ymm, ymm [AVX] -// * VSHUFPS imm8, m256, ymm, ymm [AVX] -// * VSHUFPS imm8, m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VSHUFPS imm8, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSHUFPS imm8, m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSHUFPS imm8, xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSHUFPS imm8, m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSHUFPS imm8, ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSHUFPS(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}) *Instruction { - p := self.alloc("VSHUFPS", 4, Operands { v0, v1, v2, v3 }) - // VSHUFPS imm8, xmm, xmm, xmm - if isImm8(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPS imm8, m128, xmm, xmm - if isImm8(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPS imm8, ymm, ymm, ymm - if isImm8(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[3]), v[1], hlcode(v[2])) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPS imm8, m256, ymm, ymm - if isImm8(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[3]), addr(v[1]), hlcode(v[2])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPS imm8, m512/m32bcst, zmm, zmm{k}{z} - if isImm8(v0) && isM512M32bcst(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 64) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPS imm8, zmm, zmm, zmm{k}{z} - if isImm8(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(v3) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x40) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPS imm8, m128/m32bcst, xmm, xmm{k}{z} - if isImm8(v0) && isM128M32bcst(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 16) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPS imm8, xmm, xmm, xmm{k}{z} - if isImm8(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x00) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPS imm8, m256/m32bcst, ymm, ymm{k}{z} - if isImm8(v0) && isM256M32bcst(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[3]), addr(v[1]), vcode(v[2]), kcode(v[3]), zcode(v[3]), bcode(v[1])) - m.emit(0xc6) - m.mrsd(lcode(v[3]), addr(v[1]), 32) - m.imm1(toImmAny(v[0])) - }) - } - // VSHUFPS imm8, ymm, ymm, ymm{k}{z} - if isImm8(v0) && isEVEXYMM(v1) && isEVEXYMM(v2) && isYMMkz(v3) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x20) - m.emit(0xc6) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSHUFPS") - } - return p -} - -// VSQRTPD performs "Compute Square Roots of Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VSQRTPD -// Supported forms : (11 forms) -// -// * VSQRTPD xmm, xmm [AVX] -// * VSQRTPD m128, xmm [AVX] -// * VSQRTPD ymm, ymm [AVX] -// * VSQRTPD m256, ymm [AVX] -// * VSQRTPD m512/m64bcst, zmm{k}{z} [AVX512F] -// * VSQRTPD {er}, zmm, zmm{k}{z} [AVX512F] -// * VSQRTPD zmm, zmm{k}{z} [AVX512F] -// * VSQRTPD m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VSQRTPD m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VSQRTPD xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSQRTPD ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSQRTPD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSQRTPD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VSQRTPD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VSQRTPD takes 2 or 3 operands") - } - // VSQRTPD xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VSQRTPD m128, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VSQRTPD ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), v[0], 0) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VSQRTPD m256, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[1]), addr(v[0]), 0) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VSQRTPD m512/m64bcst, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VSQRTPD {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x51) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VSQRTPD zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VSQRTPD m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VSQRTPD m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VSQRTPD xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VSQRTPD ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSQRTPD") - } - return p -} - -// VSQRTPS performs "Compute Square Roots of Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VSQRTPS -// Supported forms : (11 forms) -// -// * VSQRTPS xmm, xmm [AVX] -// * VSQRTPS m128, xmm [AVX] -// * VSQRTPS ymm, ymm [AVX] -// * VSQRTPS m256, ymm [AVX] -// * VSQRTPS m512/m32bcst, zmm{k}{z} [AVX512F] -// * VSQRTPS {er}, zmm, zmm{k}{z} [AVX512F] -// * VSQRTPS zmm, zmm{k}{z} [AVX512F] -// * VSQRTPS m128/m32bcst, xmm{k}{z} [AVX512F,AVX512VL] -// * VSQRTPS m256/m32bcst, ymm{k}{z} [AVX512F,AVX512VL] -// * VSQRTPS xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSQRTPS ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSQRTPS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSQRTPS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VSQRTPS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VSQRTPS takes 2 or 3 operands") - } - // VSQRTPS xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VSQRTPS m128, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), addr(v[0]), 0) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VSQRTPS ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), v[0], 0) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VSQRTPS m256, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[1]), addr(v[0]), 0) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VSQRTPS m512/m32bcst, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 64) - }) - } - // VSQRTPS {er}, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[2]) << 7) | (vcode(v[0]) << 5) | kcode(v[2]) | 0x18) - m.emit(0x51) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VSQRTPS zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMMkz(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x48) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VSQRTPS m128/m32bcst, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 16) - }) - } - // VSQRTPS m256/m32bcst, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[1]), addr(v[0]), 0, kcode(v[1]), zcode(v[1]), bcode(v[0])) - m.emit(0x51) - m.mrsd(lcode(v[1]), addr(v[0]), 32) - }) - } - // VSQRTPS xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isXMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x08) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VSQRTPS ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isYMMkz(v1) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit((zcode(v[1]) << 7) | kcode(v[1]) | 0x28) - m.emit(0x51) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSQRTPS") - } - return p -} - -// VSQRTSD performs "Compute Square Root of Scalar Double-Precision Floating-Point Value". -// -// Mnemonic : VSQRTSD -// Supported forms : (5 forms) -// -// * VSQRTSD xmm, xmm, xmm [AVX] -// * VSQRTSD m64, xmm, xmm [AVX] -// * VSQRTSD m64, xmm, xmm{k}{z} [AVX512F] -// * VSQRTSD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VSQRTSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VSQRTSD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSQRTSD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSQRTSD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSQRTSD takes 3 or 4 operands") - } - // VSQRTSD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x51) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSQRTSD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x51) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VSQRTSD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x51) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VSQRTSD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x51) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSQRTSD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x51) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSQRTSD") - } - return p -} - -// VSQRTSS performs "Compute Square Root of Scalar Single-Precision Floating-Point Value". -// -// Mnemonic : VSQRTSS -// Supported forms : (5 forms) -// -// * VSQRTSS xmm, xmm, xmm [AVX] -// * VSQRTSS m32, xmm, xmm [AVX] -// * VSQRTSS m32, xmm, xmm{k}{z} [AVX512F] -// * VSQRTSS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VSQRTSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VSQRTSS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSQRTSS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSQRTSS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSQRTSS takes 3 or 4 operands") - } - // VSQRTSS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x51) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSQRTSS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x51) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VSQRTSS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x51) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VSQRTSS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x51) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSQRTSS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x51) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSQRTSS") - } - return p -} - -// VSTMXCSR performs "Store MXCSR Register State". -// -// Mnemonic : VSTMXCSR -// Supported forms : (1 form) -// -// * VSTMXCSR m32 [AVX] -// -func (self *Program) VSTMXCSR(v0 interface{}) *Instruction { - p := self.alloc("VSTMXCSR", 1, Operands { v0 }) - // VSTMXCSR m32 - if isM32(v0) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, addr(v[0]), 0) - m.emit(0xae) - m.mrsd(3, addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VSTMXCSR") - } - return p -} - -// VSUBPD performs "Subtract Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VSUBPD -// Supported forms : (11 forms) -// -// * VSUBPD xmm, xmm, xmm [AVX] -// * VSUBPD m128, xmm, xmm [AVX] -// * VSUBPD ymm, ymm, ymm [AVX] -// * VSUBPD m256, ymm, ymm [AVX] -// * VSUBPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VSUBPD {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSUBPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VSUBPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSUBPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSUBPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSUBPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSUBPD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSUBPD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSUBPD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSUBPD takes 3 or 4 operands") - } - // VSUBPD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBPD m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VSUBPD ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBPD m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VSUBPD m512/m64bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VSUBPD {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xfd ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSUBPD zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBPD m128/m64bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VSUBPD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBPD m256/m64bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VSUBPD ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSUBPD") - } - return p -} - -// VSUBPS performs "Subtract Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VSUBPS -// Supported forms : (11 forms) -// -// * VSUBPS xmm, xmm, xmm [AVX] -// * VSUBPS m128, xmm, xmm [AVX] -// * VSUBPS ymm, ymm, ymm [AVX] -// * VSUBPS m256, ymm, ymm [AVX] -// * VSUBPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VSUBPS {er}, zmm, zmm, zmm{k}{z} [AVX512F] -// * VSUBPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VSUBPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSUBPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VSUBPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VSUBPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VSUBPS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSUBPS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSUBPS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSUBPS takes 3 or 4 operands") - } - // VSUBPS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBPS m128, xmm, xmm - if len(vv) == 0 && isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VSUBPS ymm, ymm, ymm - if len(vv) == 0 && isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBPS m256, ymm, ymm - if len(vv) == 0 && isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VSUBPS m512/m32bcst, zmm, zmm{k}{z} - if len(vv) == 0 && isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VSUBPS {er}, zmm, zmm, zmm{k}{z} - if len(vv) == 1 && isER(v0) && isZMM(v1) && isZMM(v2) && isZMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7c ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSUBPS zmm, zmm, zmm{k}{z} - if len(vv) == 0 && isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBPS m128/m32bcst, xmm, xmm{k}{z} - if len(vv) == 0 && isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VSUBPS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBPS m256/m32bcst, ymm, ymm{k}{z} - if len(vv) == 0 && isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VSUBPS ymm, ymm, ymm{k}{z} - if len(vv) == 0 && isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSUBPS") - } - return p -} - -// VSUBSD performs "Subtract Scalar Double-Precision Floating-Point Values". -// -// Mnemonic : VSUBSD -// Supported forms : (5 forms) -// -// * VSUBSD xmm, xmm, xmm [AVX] -// * VSUBSD m64, xmm, xmm [AVX] -// * VSUBSD m64, xmm, xmm{k}{z} [AVX512F] -// * VSUBSD {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VSUBSD xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VSUBSD(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSUBSD", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSUBSD", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSUBSD takes 3 or 4 operands") - } - // VSUBSD xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBSD m64, xmm, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(3, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VSUBSD m64, xmm, xmm{k}{z} - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x87, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 8) - }) - } - // VSUBSD {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0xff ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSUBSD xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xff ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSUBSD") - } - return p -} - -// VSUBSS performs "Subtract Scalar Single-Precision Floating-Point Values". -// -// Mnemonic : VSUBSS -// Supported forms : (5 forms) -// -// * VSUBSS xmm, xmm, xmm [AVX] -// * VSUBSS m32, xmm, xmm [AVX] -// * VSUBSS m32, xmm, xmm{k}{z} [AVX512F] -// * VSUBSS {er}, xmm, xmm, xmm{k}{z} [AVX512F] -// * VSUBSS xmm, xmm, xmm{k}{z} [AVX512F] -// -func (self *Program) VSUBSS(v0 interface{}, v1 interface{}, v2 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VSUBSS", 3, Operands { v0, v1, v2 }) - case 1 : p = self.alloc("VSUBSS", 4, Operands { v0, v1, v2, vv[0] }) - default : panic("instruction VSUBSS takes 3 or 4 operands") - } - // VSUBSS xmm, xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VSUBSS m32, xmm, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(2, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VSUBSS m32, xmm, xmm{k}{z} - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x06, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), 0) - m.emit(0x5c) - m.mrsd(lcode(v[2]), addr(v[0]), 4) - }) - } - // VSUBSS {er}, xmm, xmm, xmm{k}{z} - if len(vv) == 1 && isER(v0) && isEVEXXMM(v1) && isEVEXXMM(v2) && isXMMkz(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[3]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[3]) << 4))) - m.emit(0x7e ^ (hlcode(v[2]) << 3)) - m.emit((zcode(v[3]) << 7) | (vcode(v[0]) << 5) | (0x08 ^ (ecode(v[2]) << 3)) | kcode(v[3]) | 0x10) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[3]) << 3 | lcode(v[1])) - }) - } - // VSUBSS xmm, xmm, xmm{k}{z} - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7e ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x5c) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VSUBSS") - } - return p -} - -// VTESTPD performs "Packed Double-Precision Floating-Point Bit Test". -// -// Mnemonic : VTESTPD -// Supported forms : (4 forms) -// -// * VTESTPD xmm, xmm [AVX] -// * VTESTPD m128, xmm [AVX] -// * VTESTPD ymm, ymm [AVX] -// * VTESTPD m256, ymm [AVX] -// -func (self *Program) VTESTPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VTESTPD", 2, Operands { v0, v1 }) - // VTESTPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VTESTPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VTESTPD ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x0f) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VTESTPD m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x0f) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VTESTPD") - } - return p -} - -// VTESTPS performs "Packed Single-Precision Floating-Point Bit Test". -// -// Mnemonic : VTESTPS -// Supported forms : (4 forms) -// -// * VTESTPS xmm, xmm [AVX] -// * VTESTPS m128, xmm [AVX] -// * VTESTPS ymm, ymm [AVX] -// * VTESTPS m256, ymm [AVX] -// -func (self *Program) VTESTPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("VTESTPS", 2, Operands { v0, v1 }) - // VTESTPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x79) - m.emit(0x0e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VTESTPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x01, hcode(v[1]), addr(v[0]), 0) - m.emit(0x0e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VTESTPS ymm, ymm - if isYMM(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xc4) - m.emit(0xe2 ^ (hcode(v[1]) << 7) ^ (hcode(v[0]) << 5)) - m.emit(0x7d) - m.emit(0x0e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VTESTPS m256, ymm - if isM256(v0) && isYMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex3(0xc4, 0b10, 0x05, hcode(v[1]), addr(v[0]), 0) - m.emit(0x0e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for VTESTPS") - } - return p -} - -// VUCOMISD performs "Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS". -// -// Mnemonic : VUCOMISD -// Supported forms : (5 forms) -// -// * VUCOMISD xmm, xmm [AVX] -// * VUCOMISD m64, xmm [AVX] -// * VUCOMISD m64, xmm [AVX512F] -// * VUCOMISD {sae}, xmm, xmm [AVX512F] -// * VUCOMISD xmm, xmm [AVX512F] -// -func (self *Program) VUCOMISD(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VUCOMISD", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VUCOMISD", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VUCOMISD takes 2 or 3 operands") - } - // VUCOMISD xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), v[0], 0) - m.emit(0x2e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VUCOMISD m64, xmm - if len(vv) == 0 && isM64(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VUCOMISD m64, xmm - if len(vv) == 0 && isM64(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2e) - m.mrsd(lcode(v[1]), addr(v[0]), 8) - }) - } - // VUCOMISD {sae}, xmm, xmm - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd) - m.emit(0x18) - m.emit(0x2e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VUCOMISD xmm, xmm - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0xfd) - m.emit(0x48) - m.emit(0x2e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VUCOMISD") - } - return p -} - -// VUCOMISS performs "Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS". -// -// Mnemonic : VUCOMISS -// Supported forms : (5 forms) -// -// * VUCOMISS xmm, xmm [AVX] -// * VUCOMISS m32, xmm [AVX] -// * VUCOMISS m32, xmm [AVX512F] -// * VUCOMISS {sae}, xmm, xmm [AVX512F] -// * VUCOMISS xmm, xmm [AVX512F] -// -func (self *Program) VUCOMISS(v0 interface{}, v1 interface{}, vv ...interface{}) *Instruction { - var p *Instruction - switch len(vv) { - case 0 : p = self.alloc("VUCOMISS", 2, Operands { v0, v1 }) - case 1 : p = self.alloc("VUCOMISS", 3, Operands { v0, v1, vv[0] }) - default : panic("instruction VUCOMISS takes 2 or 3 operands") - } - // VUCOMISS xmm, xmm - if len(vv) == 0 && isXMM(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), v[0], 0) - m.emit(0x2e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // VUCOMISS m32, xmm - if len(vv) == 0 && isM32(v0) && isXMM(v1) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[1]), addr(v[0]), 0) - m.emit(0x2e) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // VUCOMISS m32, xmm - if len(vv) == 0 && isM32(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[1]), addr(v[0]), 0, 0, 0, 0) - m.emit(0x2e) - m.mrsd(lcode(v[1]), addr(v[0]), 4) - }) - } - // VUCOMISS {sae}, xmm, xmm - if len(vv) == 1 && isSAE(v0) && isEVEXXMM(v1) && isEVEXXMM(vv[0]) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[1]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c) - m.emit(0x18) - m.emit(0x2e) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[1])) - }) - } - // VUCOMISS xmm, xmm - if len(vv) == 0 && isEVEXXMM(v0) && isEVEXXMM(v1) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[1]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[1]) << 4))) - m.emit(0x7c) - m.emit(0x48) - m.emit(0x2e) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VUCOMISS") - } - return p -} - -// VUNPCKHPD performs "Unpack and Interleave High Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VUNPCKHPD -// Supported forms : (10 forms) -// -// * VUNPCKHPD xmm, xmm, xmm [AVX] -// * VUNPCKHPD m128, xmm, xmm [AVX] -// * VUNPCKHPD ymm, ymm, ymm [AVX] -// * VUNPCKHPD m256, ymm, ymm [AVX] -// * VUNPCKHPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VUNPCKHPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VUNPCKHPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKHPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKHPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKHPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VUNPCKHPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VUNPCKHPD", 3, Operands { v0, v1, v2 }) - // VUNPCKHPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKHPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VUNPCKHPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKHPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VUNPCKHPD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VUNPCKHPD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKHPD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VUNPCKHPD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKHPD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VUNPCKHPD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VUNPCKHPD") - } - return p -} - -// VUNPCKHPS performs "Unpack and Interleave High Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VUNPCKHPS -// Supported forms : (10 forms) -// -// * VUNPCKHPS xmm, xmm, xmm [AVX] -// * VUNPCKHPS m128, xmm, xmm [AVX] -// * VUNPCKHPS ymm, ymm, ymm [AVX] -// * VUNPCKHPS m256, ymm, ymm [AVX] -// * VUNPCKHPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VUNPCKHPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VUNPCKHPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKHPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKHPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKHPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VUNPCKHPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VUNPCKHPS", 3, Operands { v0, v1, v2 }) - // VUNPCKHPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKHPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VUNPCKHPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKHPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VUNPCKHPS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VUNPCKHPS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKHPS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VUNPCKHPS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKHPS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x15) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VUNPCKHPS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x15) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VUNPCKHPS") - } - return p -} - -// VUNPCKLPD performs "Unpack and Interleave Low Packed Double-Precision Floating-Point Values". -// -// Mnemonic : VUNPCKLPD -// Supported forms : (10 forms) -// -// * VUNPCKLPD xmm, xmm, xmm [AVX] -// * VUNPCKLPD m128, xmm, xmm [AVX] -// * VUNPCKLPD ymm, ymm, ymm [AVX] -// * VUNPCKLPD m256, ymm, ymm [AVX] -// * VUNPCKLPD m512/m64bcst, zmm, zmm{k}{z} [AVX512F] -// * VUNPCKLPD zmm, zmm, zmm{k}{z} [AVX512F] -// * VUNPCKLPD m128/m64bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKLPD xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKLPD m256/m64bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKLPD ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VUNPCKLPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VUNPCKLPD", 3, Operands { v0, v1, v2 }) - // VUNPCKLPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKLPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VUNPCKLPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKLPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VUNPCKLPD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VUNPCKLPD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKLPD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VUNPCKLPD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKLPD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VUNPCKLPD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VUNPCKLPD") - } - return p -} - -// VUNPCKLPS performs "Unpack and Interleave Low Packed Single-Precision Floating-Point Values". -// -// Mnemonic : VUNPCKLPS -// Supported forms : (10 forms) -// -// * VUNPCKLPS xmm, xmm, xmm [AVX] -// * VUNPCKLPS m128, xmm, xmm [AVX] -// * VUNPCKLPS ymm, ymm, ymm [AVX] -// * VUNPCKLPS m256, ymm, ymm [AVX] -// * VUNPCKLPS m512/m32bcst, zmm, zmm{k}{z} [AVX512F] -// * VUNPCKLPS zmm, zmm, zmm{k}{z} [AVX512F] -// * VUNPCKLPS m128/m32bcst, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKLPS xmm, xmm, xmm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKLPS m256/m32bcst, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// * VUNPCKLPS ymm, ymm, ymm{k}{z} [AVX512F,AVX512VL] -// -func (self *Program) VUNPCKLPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VUNPCKLPS", 3, Operands { v0, v1, v2 }) - // VUNPCKLPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKLPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VUNPCKLPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKLPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VUNPCKLPS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VUNPCKLPS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKLPS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VUNPCKLPS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VUNPCKLPS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x14) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VUNPCKLPS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512F) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x14) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VUNPCKLPS") - } - return p -} - -// VXORPD performs "Bitwise Logical XOR for Double-Precision Floating-Point Values". -// -// Mnemonic : VXORPD -// Supported forms : (10 forms) -// -// * VXORPD xmm, xmm, xmm [AVX] -// * VXORPD m128, xmm, xmm [AVX] -// * VXORPD ymm, ymm, ymm [AVX] -// * VXORPD m256, ymm, ymm [AVX] -// * VXORPD m512/m64bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VXORPD zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VXORPD m128/m64bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VXORPD xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VXORPD m256/m64bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VXORPD ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VXORPD(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VXORPD", 3, Operands { v0, v1, v2 }) - // VXORPD xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VXORPD m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(1, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VXORPD ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VXORPD m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(5, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VXORPD m512/m64bcst, zmm, zmm{k}{z} - if isM512M64bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VXORPD zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VXORPD m128/m64bcst, xmm, xmm{k}{z} - if isM128M64bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VXORPD xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VXORPD m256/m64bcst, ymm, ymm{k}{z} - if isM256M64bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x85, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VXORPD ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0xfd ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VXORPD") - } - return p -} - -// VXORPS performs "Bitwise Logical XOR for Single-Precision Floating-Point Values". -// -// Mnemonic : VXORPS -// Supported forms : (10 forms) -// -// * VXORPS xmm, xmm, xmm [AVX] -// * VXORPS m128, xmm, xmm [AVX] -// * VXORPS ymm, ymm, ymm [AVX] -// * VXORPS m256, ymm, ymm [AVX] -// * VXORPS m512/m32bcst, zmm, zmm{k}{z} [AVX512DQ] -// * VXORPS zmm, zmm, zmm{k}{z} [AVX512DQ] -// * VXORPS m128/m32bcst, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VXORPS xmm, xmm, xmm{k}{z} [AVX512DQ,AVX512VL] -// * VXORPS m256/m32bcst, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// * VXORPS ymm, ymm, ymm{k}{z} [AVX512DQ,AVX512VL] -// -func (self *Program) VXORPS(v0 interface{}, v1 interface{}, v2 interface{}) *Instruction { - p := self.alloc("VXORPS", 3, Operands { v0, v1, v2 }) - // VXORPS xmm, xmm, xmm - if isXMM(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VXORPS m128, xmm, xmm - if isM128(v0) && isXMM(v1) && isXMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VXORPS ymm, ymm, ymm - if isYMM(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), v[0], hlcode(v[1])) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VXORPS m256, ymm, ymm - if isM256(v0) && isYMM(v1) && isYMM(v2) { - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, hcode(v[2]), addr(v[0]), hlcode(v[1])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 1) - }) - } - // VXORPS m512/m32bcst, zmm, zmm{k}{z} - if isM512M32bcst(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b10, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 64) - }) - } - // VXORPS zmm, zmm, zmm{k}{z} - if isZMM(v0) && isZMM(v1) && isZMMkz(v2) { - self.require(ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x40) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VXORPS m128/m32bcst, xmm, xmm{k}{z} - if isM128M32bcst(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b00, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 16) - }) - } - // VXORPS xmm, xmm, xmm{k}{z} - if isEVEXXMM(v0) && isEVEXXMM(v1) && isXMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x00) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - // VXORPS m256/m32bcst, ymm, ymm{k}{z} - if isM256M32bcst(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.evex(0b01, 0x04, 0b01, ehcode(v[2]), addr(v[0]), vcode(v[1]), kcode(v[2]), zcode(v[2]), bcode(v[0])) - m.emit(0x57) - m.mrsd(lcode(v[2]), addr(v[0]), 32) - }) - } - // VXORPS ymm, ymm, ymm{k}{z} - if isEVEXYMM(v0) && isEVEXYMM(v1) && isYMMkz(v2) { - self.require(ISA_AVX512VL | ISA_AVX512DQ) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x62) - m.emit(0xf1 ^ ((hcode(v[2]) << 7) | (ehcode(v[0]) << 5) | (ecode(v[2]) << 4))) - m.emit(0x7c ^ (hlcode(v[1]) << 3)) - m.emit((zcode(v[2]) << 7) | (0x08 ^ (ecode(v[1]) << 3)) | kcode(v[2]) | 0x20) - m.emit(0x57) - m.emit(0xc0 | lcode(v[2]) << 3 | lcode(v[0])) - }) - } - if p.len == 0 { - panic("invalid operands for VXORPS") - } - return p -} - -// VZEROALL performs "Zero All YMM Registers". -// -// Mnemonic : VZEROALL -// Supported forms : (1 form) -// -// * VZEROALL [AVX] -// -func (self *Program) VZEROALL() *Instruction { - p := self.alloc("VZEROALL", 0, Operands { }) - // VZEROALL - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(4, 0, nil, 0) - m.emit(0x77) - }) - return p -} - -// VZEROUPPER performs "Zero Upper Bits of YMM Registers". -// -// Mnemonic : VZEROUPPER -// Supported forms : (1 form) -// -// * VZEROUPPER [AVX] -// -func (self *Program) VZEROUPPER() *Instruction { - p := self.alloc("VZEROUPPER", 0, Operands { }) - // VZEROUPPER - self.require(ISA_AVX) - p.domain = DomainAVX - p.add(0, func(m *_Encoding, v []interface{}) { - m.vex2(0, 0, nil, 0) - m.emit(0x77) - }) - return p -} - -// XADDB performs "Exchange and Add". -// -// Mnemonic : XADD -// Supported forms : (2 forms) -// -// * XADDB r8, r8 -// * XADDB r8, m8 -// -func (self *Program) XADDB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XADDB", 2, Operands { v0, v1 }) - // XADDB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x0f) - m.emit(0xc0) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // XADDB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x0f) - m.emit(0xc0) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XADDB") - } - return p -} - -// XADDL performs "Exchange and Add". -// -// Mnemonic : XADD -// Supported forms : (2 forms) -// -// * XADDL r32, r32 -// * XADDL r32, m32 -// -func (self *Program) XADDL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XADDL", 2, Operands { v0, v1 }) - // XADDL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xc1) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // XADDL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc1) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XADDL") - } - return p -} - -// XADDQ performs "Exchange and Add". -// -// Mnemonic : XADD -// Supported forms : (2 forms) -// -// * XADDQ r64, r64 -// * XADDQ r64, m64 -// -func (self *Program) XADDQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XADDQ", 2, Operands { v0, v1 }) - // XADDQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x0f) - m.emit(0xc1) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // XADDQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x0f) - m.emit(0xc1) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XADDQ") - } - return p -} - -// XADDW performs "Exchange and Add". -// -// Mnemonic : XADD -// Supported forms : (2 forms) -// -// * XADDW r16, r16 -// * XADDW r16, m16 -// -func (self *Program) XADDW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XADDW", 2, Operands { v0, v1 }) - // XADDW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x0f) - m.emit(0xc1) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - } - // XADDW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x0f) - m.emit(0xc1) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XADDW") - } - return p -} - -// XCHGB performs "Exchange Register/Memory with Register". -// -// Mnemonic : XCHG -// Supported forms : (3 forms) -// -// * XCHGB r8, r8 -// * XCHGB m8, r8 -// * XCHGB r8, m8 -// -func (self *Program) XCHGB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XCHGB", 2, Operands { v0, v1 }) - // XCHGB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x86) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x86) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XCHGB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x86) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // XCHGB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x86) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XCHGB") - } - return p -} - -// XCHGL performs "Exchange Register/Memory with Register". -// -// Mnemonic : XCHG -// Supported forms : (5 forms) -// -// * XCHGL r32, eax -// * XCHGL eax, r32 -// * XCHGL r32, r32 -// * XCHGL m32, r32 -// * XCHGL r32, m32 -// -func (self *Program) XCHGL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XCHGL", 2, Operands { v0, v1 }) - // XCHGL r32, eax - if isReg32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[0], false) - m.emit(0x90 | lcode(v[0])) - }) - } - // XCHGL eax, r32 - if v0 == EAX && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x90 | lcode(v[1])) - }) - } - // XCHGL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x87) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x87) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XCHGL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x87) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // XCHGL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x87) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XCHGL") - } - return p -} - -// XCHGQ performs "Exchange Register/Memory with Register". -// -// Mnemonic : XCHG -// Supported forms : (5 forms) -// -// * XCHGQ r64, rax -// * XCHGQ rax, r64 -// * XCHGQ r64, r64 -// * XCHGQ m64, r64 -// * XCHGQ r64, m64 -// -func (self *Program) XCHGQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XCHGQ", 2, Operands { v0, v1 }) - // XCHGQ r64, rax - if isReg64(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0])) - m.emit(0x90 | lcode(v[0])) - }) - } - // XCHGQ rax, r64 - if v0 == RAX && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x90 | lcode(v[1])) - }) - } - // XCHGQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x87) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x87) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XCHGQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x87) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // XCHGQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x87) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XCHGQ") - } - return p -} - -// XCHGW performs "Exchange Register/Memory with Register". -// -// Mnemonic : XCHG -// Supported forms : (5 forms) -// -// * XCHGW r16, ax -// * XCHGW ax, r16 -// * XCHGW r16, r16 -// * XCHGW m16, r16 -// * XCHGW r16, m16 -// -func (self *Program) XCHGW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XCHGW", 2, Operands { v0, v1 }) - // XCHGW r16, ax - if isReg16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[0], false) - m.emit(0x90 | lcode(v[0])) - }) - } - // XCHGW ax, r16 - if v0 == AX && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x90 | lcode(v[1])) - }) - } - // XCHGW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x87) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x87) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XCHGW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x87) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // XCHGW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x87) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XCHGW") - } - return p -} - -// XGETBV performs "Get Value of Extended Control Register". -// -// Mnemonic : XGETBV -// Supported forms : (1 form) -// -// * XGETBV -// -func (self *Program) XGETBV() *Instruction { - p := self.alloc("XGETBV", 0, Operands { }) - // XGETBV - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x0f) - m.emit(0x01) - m.emit(0xd0) - }) - return p -} - -// XLATB performs "Table Look-up Translation". -// -// Mnemonic : XLATB -// Supported forms : (2 forms) -// -// * XLATB -// * XLATB -// -func (self *Program) XLATB() *Instruction { - p := self.alloc("XLATB", 0, Operands { }) - // XLATB - p.domain = DomainMisc - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0xd7) - }) - // XLATB - p.domain = DomainMisc - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0xd7) - }) - return p -} - -// XORB performs "Logical Exclusive OR". -// -// Mnemonic : XOR -// Supported forms : (6 forms) -// -// * XORB imm8, al -// * XORB imm8, r8 -// * XORB r8, r8 -// * XORB m8, r8 -// * XORB imm8, m8 -// * XORB r8, m8 -// -func (self *Program) XORB(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XORB", 2, Operands { v0, v1 }) - // XORB imm8, al - if isImm8(v0) && v1 == AL { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x34) - m.imm1(toImmAny(v[0])) - }) - } - // XORB imm8, r8 - if isImm8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], isReg8REX(v[1])) - m.emit(0x80) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // XORB r8, r8 - if isReg8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x30) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], isReg8REX(v[0]) || isReg8REX(v[1])) - m.emit(0x32) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XORB m8, r8 - if isM8(v0) && isReg8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), isReg8REX(v[1])) - m.emit(0x32) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // XORB imm8, m8 - if isImm8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x80) - m.mrsd(6, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // XORB r8, m8 - if isReg8(v0) && isM8(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), isReg8REX(v[0])) - m.emit(0x30) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XORB") - } - return p -} - -// XORL performs "Logical Exclusive OR". -// -// Mnemonic : XOR -// Supported forms : (8 forms) -// -// * XORL imm32, eax -// * XORL imm8, r32 -// * XORL imm32, r32 -// * XORL r32, r32 -// * XORL m32, r32 -// * XORL imm8, m32 -// * XORL imm32, m32 -// * XORL r32, m32 -// -func (self *Program) XORL(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XORL", 2, Operands { v0, v1 }) - // XORL imm32, eax - if isImm32(v0) && v1 == EAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x35) - m.imm4(toImmAny(v[0])) - }) - } - // XORL imm8, r32 - if isImm8Ext(v0, 4) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // XORL imm32, r32 - if isImm32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xf0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // XORL r32, r32 - if isReg32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x31) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x33) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XORL m32, r32 - if isM32(v0) && isReg32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x33) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // XORL imm8, m32 - if isImm8Ext(v0, 4) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(6, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // XORL imm32, m32 - if isImm32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(6, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // XORL r32, m32 - if isReg32(v0) && isM32(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x31) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XORL") - } - return p -} - -// XORPD performs "Bitwise Logical XOR for Double-Precision Floating-Point Values". -// -// Mnemonic : XORPD -// Supported forms : (2 forms) -// -// * XORPD xmm, xmm [SSE2] -// * XORPD m128, xmm [SSE2] -// -func (self *Program) XORPD(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XORPD", 2, Operands { v0, v1 }) - // XORPD xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x57) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XORPD m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE2) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x57) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XORPD") - } - return p -} - -// XORPS performs "Bitwise Logical XOR for Single-Precision Floating-Point Values". -// -// Mnemonic : XORPS -// Supported forms : (2 forms) -// -// * XORPS xmm, xmm [SSE] -// * XORPS m128, xmm [SSE] -// -func (self *Program) XORPS(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XORPS", 2, Operands { v0, v1 }) - // XORPS xmm, xmm - if isXMM(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x0f) - m.emit(0x57) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XORPS m128, xmm - if isM128(v0) && isXMM(v1) { - self.require(ISA_SSE) - p.domain = DomainMMXSSE - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x0f) - m.emit(0x57) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XORPS") - } - return p -} - -// XORQ performs "Logical Exclusive OR". -// -// Mnemonic : XOR -// Supported forms : (8 forms) -// -// * XORQ imm32, rax -// * XORQ imm8, r64 -// * XORQ imm32, r64 -// * XORQ r64, r64 -// * XORQ m64, r64 -// * XORQ imm8, m64 -// * XORQ imm32, m64 -// * XORQ r64, m64 -// -func (self *Program) XORQ(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XORQ", 2, Operands { v0, v1 }) - // XORQ imm32, rax - if isImm32(v0) && v1 == RAX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48) - m.emit(0x35) - m.imm4(toImmAny(v[0])) - }) - } - // XORQ imm8, r64 - if isImm8Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x83) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // XORQ imm32, r64 - if isImm32Ext(v0, 8) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1])) - m.emit(0x81) - m.emit(0xf0 | lcode(v[1])) - m.imm4(toImmAny(v[0])) - }) - } - // XORQ r64, r64 - if isReg64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[0]) << 2 | hcode(v[1])) - m.emit(0x31) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x48 | hcode(v[1]) << 2 | hcode(v[0])) - m.emit(0x33) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XORQ m64, r64 - if isM64(v0) && isReg64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[1]), addr(v[0])) - m.emit(0x33) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // XORQ imm8, m64 - if isImm8Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x83) - m.mrsd(6, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // XORQ imm32, m64 - if isImm32Ext(v0, 8) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, 0, addr(v[1])) - m.emit(0x81) - m.mrsd(6, addr(v[1]), 1) - m.imm4(toImmAny(v[0])) - }) - } - // XORQ r64, m64 - if isReg64(v0) && isM64(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.rexm(1, hcode(v[0]), addr(v[1])) - m.emit(0x31) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XORQ") - } - return p -} - -// XORW performs "Logical Exclusive OR". -// -// Mnemonic : XOR -// Supported forms : (8 forms) -// -// * XORW imm16, ax -// * XORW imm8, r16 -// * XORW imm16, r16 -// * XORW r16, r16 -// * XORW m16, r16 -// * XORW imm8, m16 -// * XORW imm16, m16 -// * XORW r16, m16 -// -func (self *Program) XORW(v0 interface{}, v1 interface{}) *Instruction { - p := self.alloc("XORW", 2, Operands { v0, v1 }) - // XORW imm16, ax - if isImm16(v0) && v1 == AX { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.emit(0x35) - m.imm2(toImmAny(v[0])) - }) - } - // XORW imm8, r16 - if isImm8Ext(v0, 2) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x83) - m.emit(0xf0 | lcode(v[1])) - m.imm1(toImmAny(v[0])) - }) - } - // XORW imm16, r16 - if isImm16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, v[1], false) - m.emit(0x81) - m.emit(0xf0 | lcode(v[1])) - m.imm2(toImmAny(v[0])) - }) - } - // XORW r16, r16 - if isReg16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), v[1], false) - m.emit(0x31) - m.emit(0xc0 | lcode(v[0]) << 3 | lcode(v[1])) - }) - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), v[0], false) - m.emit(0x33) - m.emit(0xc0 | lcode(v[1]) << 3 | lcode(v[0])) - }) - } - // XORW m16, r16 - if isM16(v0) && isReg16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[1]), addr(v[0]), false) - m.emit(0x33) - m.mrsd(lcode(v[1]), addr(v[0]), 1) - }) - } - // XORW imm8, m16 - if isImm8Ext(v0, 2) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x83) - m.mrsd(6, addr(v[1]), 1) - m.imm1(toImmAny(v[0])) - }) - } - // XORW imm16, m16 - if isImm16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(0, addr(v[1]), false) - m.emit(0x81) - m.mrsd(6, addr(v[1]), 1) - m.imm2(toImmAny(v[0])) - }) - } - // XORW r16, m16 - if isReg16(v0) && isM16(v1) { - p.domain = DomainGeneric - p.add(0, func(m *_Encoding, v []interface{}) { - m.emit(0x66) - m.rexo(hcode(v[0]), addr(v[1]), false) - m.emit(0x31) - m.mrsd(lcode(v[0]), addr(v[1]), 1) - }) - } - if p.len == 0 { - panic("invalid operands for XORW") - } - return p -} diff --git a/vendor/github.com/cloudwego/iasm/x86_64/instructions_table.go b/vendor/github.com/cloudwego/iasm/x86_64/instructions_table.go deleted file mode 100644 index dfb652ae3..000000000 --- a/vendor/github.com/cloudwego/iasm/x86_64/instructions_table.go +++ /dev/null @@ -1,12307 +0,0 @@ -// -// 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. -// - -// Code generated by "mkasm_amd64.py", DO NOT EDIT. - -package x86_64 - -const ( - _N_args = 5 - _N_forms = 23 -) - -// Instructions maps all the instruction name to it's encoder function. -var Instructions = map[string]_InstructionEncoder { - "adcb" : __asm_proxy_ADCB__, - "adcl" : __asm_proxy_ADCL__, - "adcq" : __asm_proxy_ADCQ__, - "adcw" : __asm_proxy_ADCW__, - "adcxl" : __asm_proxy_ADCXL__, - "adcxq" : __asm_proxy_ADCXQ__, - "addb" : __asm_proxy_ADDB__, - "addl" : __asm_proxy_ADDL__, - "addpd" : __asm_proxy_ADDPD__, - "addps" : __asm_proxy_ADDPS__, - "addq" : __asm_proxy_ADDQ__, - "addsd" : __asm_proxy_ADDSD__, - "addss" : __asm_proxy_ADDSS__, - "addsubpd" : __asm_proxy_ADDSUBPD__, - "addsubps" : __asm_proxy_ADDSUBPS__, - "addw" : __asm_proxy_ADDW__, - "adoxl" : __asm_proxy_ADOXL__, - "adoxq" : __asm_proxy_ADOXQ__, - "aesdec" : __asm_proxy_AESDEC__, - "aesdeclast" : __asm_proxy_AESDECLAST__, - "aesenc" : __asm_proxy_AESENC__, - "aesenclast" : __asm_proxy_AESENCLAST__, - "aesimc" : __asm_proxy_AESIMC__, - "aeskeygenassist" : __asm_proxy_AESKEYGENASSIST__, - "andb" : __asm_proxy_ANDB__, - "andl" : __asm_proxy_ANDL__, - "andnl" : __asm_proxy_ANDNL__, - "andnpd" : __asm_proxy_ANDNPD__, - "andnps" : __asm_proxy_ANDNPS__, - "andnq" : __asm_proxy_ANDNQ__, - "andpd" : __asm_proxy_ANDPD__, - "andps" : __asm_proxy_ANDPS__, - "andq" : __asm_proxy_ANDQ__, - "andw" : __asm_proxy_ANDW__, - "bextr" : __asm_proxy_BEXTR__, - "blcfill" : __asm_proxy_BLCFILL__, - "blci" : __asm_proxy_BLCI__, - "blcic" : __asm_proxy_BLCIC__, - "blcmsk" : __asm_proxy_BLCMSK__, - "blcs" : __asm_proxy_BLCS__, - "blendpd" : __asm_proxy_BLENDPD__, - "blendps" : __asm_proxy_BLENDPS__, - "blendvpd" : __asm_proxy_BLENDVPD__, - "blendvps" : __asm_proxy_BLENDVPS__, - "blsfill" : __asm_proxy_BLSFILL__, - "blsi" : __asm_proxy_BLSI__, - "blsic" : __asm_proxy_BLSIC__, - "blsmsk" : __asm_proxy_BLSMSK__, - "blsr" : __asm_proxy_BLSR__, - "bsfl" : __asm_proxy_BSFL__, - "bsfq" : __asm_proxy_BSFQ__, - "bsfw" : __asm_proxy_BSFW__, - "bsrl" : __asm_proxy_BSRL__, - "bsrq" : __asm_proxy_BSRQ__, - "bsrw" : __asm_proxy_BSRW__, - "bswapl" : __asm_proxy_BSWAPL__, - "bswapq" : __asm_proxy_BSWAPQ__, - "btcl" : __asm_proxy_BTCL__, - "btcq" : __asm_proxy_BTCQ__, - "btcw" : __asm_proxy_BTCW__, - "btl" : __asm_proxy_BTL__, - "btq" : __asm_proxy_BTQ__, - "btrl" : __asm_proxy_BTRL__, - "btrq" : __asm_proxy_BTRQ__, - "btrw" : __asm_proxy_BTRW__, - "btsl" : __asm_proxy_BTSL__, - "btsq" : __asm_proxy_BTSQ__, - "btsw" : __asm_proxy_BTSW__, - "btw" : __asm_proxy_BTW__, - "bzhi" : __asm_proxy_BZHI__, - "call" : __asm_proxy_CALL__, - "callq" : __asm_proxy_CALLQ__, - "cbtw" : __asm_proxy_CBTW__, - "clc" : __asm_proxy_CLC__, - "cld" : __asm_proxy_CLD__, - "clflush" : __asm_proxy_CLFLUSH__, - "clflushopt" : __asm_proxy_CLFLUSHOPT__, - "cltd" : __asm_proxy_CLTD__, - "cltq" : __asm_proxy_CLTQ__, - "clwb" : __asm_proxy_CLWB__, - "clzero" : __asm_proxy_CLZERO__, - "cmc" : __asm_proxy_CMC__, - "cmova" : __asm_proxy_CMOVA__, - "cmovae" : __asm_proxy_CMOVAE__, - "cmovb" : __asm_proxy_CMOVB__, - "cmovbe" : __asm_proxy_CMOVBE__, - "cmovc" : __asm_proxy_CMOVC__, - "cmove" : __asm_proxy_CMOVE__, - "cmovg" : __asm_proxy_CMOVG__, - "cmovge" : __asm_proxy_CMOVGE__, - "cmovl" : __asm_proxy_CMOVL__, - "cmovle" : __asm_proxy_CMOVLE__, - "cmovna" : __asm_proxy_CMOVNA__, - "cmovnae" : __asm_proxy_CMOVNAE__, - "cmovnb" : __asm_proxy_CMOVNB__, - "cmovnbe" : __asm_proxy_CMOVNBE__, - "cmovnc" : __asm_proxy_CMOVNC__, - "cmovne" : __asm_proxy_CMOVNE__, - "cmovng" : __asm_proxy_CMOVNG__, - "cmovnge" : __asm_proxy_CMOVNGE__, - "cmovnl" : __asm_proxy_CMOVNL__, - "cmovnle" : __asm_proxy_CMOVNLE__, - "cmovno" : __asm_proxy_CMOVNO__, - "cmovnp" : __asm_proxy_CMOVNP__, - "cmovns" : __asm_proxy_CMOVNS__, - "cmovnz" : __asm_proxy_CMOVNZ__, - "cmovo" : __asm_proxy_CMOVO__, - "cmovp" : __asm_proxy_CMOVP__, - "cmovpe" : __asm_proxy_CMOVPE__, - "cmovpo" : __asm_proxy_CMOVPO__, - "cmovs" : __asm_proxy_CMOVS__, - "cmovz" : __asm_proxy_CMOVZ__, - "cmpb" : __asm_proxy_CMPB__, - "cmpl" : __asm_proxy_CMPL__, - "cmppd" : __asm_proxy_CMPPD__, - "cmpps" : __asm_proxy_CMPPS__, - "cmpq" : __asm_proxy_CMPQ__, - "cmpsd" : __asm_proxy_CMPSD__, - "cmpss" : __asm_proxy_CMPSS__, - "cmpw" : __asm_proxy_CMPW__, - "cmpxchg16b" : __asm_proxy_CMPXCHG16B__, - "cmpxchg8b" : __asm_proxy_CMPXCHG8B__, - "cmpxchgb" : __asm_proxy_CMPXCHGB__, - "cmpxchgl" : __asm_proxy_CMPXCHGL__, - "cmpxchgq" : __asm_proxy_CMPXCHGQ__, - "cmpxchgw" : __asm_proxy_CMPXCHGW__, - "comisd" : __asm_proxy_COMISD__, - "comiss" : __asm_proxy_COMISS__, - "cpuid" : __asm_proxy_CPUID__, - "cqto" : __asm_proxy_CQTO__, - "crc32b" : __asm_proxy_CRC32B__, - "crc32l" : __asm_proxy_CRC32L__, - "crc32q" : __asm_proxy_CRC32Q__, - "crc32w" : __asm_proxy_CRC32W__, - "cvtdq2pd" : __asm_proxy_CVTDQ2PD__, - "cvtdq2ps" : __asm_proxy_CVTDQ2PS__, - "cvtpd2dq" : __asm_proxy_CVTPD2DQ__, - "cvtpd2pi" : __asm_proxy_CVTPD2PI__, - "cvtpd2ps" : __asm_proxy_CVTPD2PS__, - "cvtpi2pd" : __asm_proxy_CVTPI2PD__, - "cvtpi2ps" : __asm_proxy_CVTPI2PS__, - "cvtps2dq" : __asm_proxy_CVTPS2DQ__, - "cvtps2pd" : __asm_proxy_CVTPS2PD__, - "cvtps2pi" : __asm_proxy_CVTPS2PI__, - "cvtsd2si" : __asm_proxy_CVTSD2SI__, - "cvtsd2ss" : __asm_proxy_CVTSD2SS__, - "cvtsi2sd" : __asm_proxy_CVTSI2SD__, - "cvtsi2ss" : __asm_proxy_CVTSI2SS__, - "cvtss2sd" : __asm_proxy_CVTSS2SD__, - "cvtss2si" : __asm_proxy_CVTSS2SI__, - "cvttpd2dq" : __asm_proxy_CVTTPD2DQ__, - "cvttpd2pi" : __asm_proxy_CVTTPD2PI__, - "cvttps2dq" : __asm_proxy_CVTTPS2DQ__, - "cvttps2pi" : __asm_proxy_CVTTPS2PI__, - "cvttsd2si" : __asm_proxy_CVTTSD2SI__, - "cvttss2si" : __asm_proxy_CVTTSS2SI__, - "cwtd" : __asm_proxy_CWTD__, - "cwtl" : __asm_proxy_CWTL__, - "decb" : __asm_proxy_DECB__, - "decl" : __asm_proxy_DECL__, - "decq" : __asm_proxy_DECQ__, - "decw" : __asm_proxy_DECW__, - "divb" : __asm_proxy_DIVB__, - "divl" : __asm_proxy_DIVL__, - "divpd" : __asm_proxy_DIVPD__, - "divps" : __asm_proxy_DIVPS__, - "divq" : __asm_proxy_DIVQ__, - "divsd" : __asm_proxy_DIVSD__, - "divss" : __asm_proxy_DIVSS__, - "divw" : __asm_proxy_DIVW__, - "dppd" : __asm_proxy_DPPD__, - "dpps" : __asm_proxy_DPPS__, - "emms" : __asm_proxy_EMMS__, - "extractps" : __asm_proxy_EXTRACTPS__, - "extrq" : __asm_proxy_EXTRQ__, - "femms" : __asm_proxy_FEMMS__, - "haddpd" : __asm_proxy_HADDPD__, - "haddps" : __asm_proxy_HADDPS__, - "hsubpd" : __asm_proxy_HSUBPD__, - "hsubps" : __asm_proxy_HSUBPS__, - "idivb" : __asm_proxy_IDIVB__, - "idivl" : __asm_proxy_IDIVL__, - "idivq" : __asm_proxy_IDIVQ__, - "idivw" : __asm_proxy_IDIVW__, - "imulb" : __asm_proxy_IMULB__, - "imull" : __asm_proxy_IMULL__, - "imulq" : __asm_proxy_IMULQ__, - "imulw" : __asm_proxy_IMULW__, - "incb" : __asm_proxy_INCB__, - "incl" : __asm_proxy_INCL__, - "incq" : __asm_proxy_INCQ__, - "incw" : __asm_proxy_INCW__, - "insertps" : __asm_proxy_INSERTPS__, - "insertq" : __asm_proxy_INSERTQ__, - "int" : __asm_proxy_INT__, - "ja" : __asm_proxy_JA__, - "jae" : __asm_proxy_JAE__, - "jb" : __asm_proxy_JB__, - "jbe" : __asm_proxy_JBE__, - "jc" : __asm_proxy_JC__, - "je" : __asm_proxy_JE__, - "jecxz" : __asm_proxy_JECXZ__, - "jg" : __asm_proxy_JG__, - "jge" : __asm_proxy_JGE__, - "jl" : __asm_proxy_JL__, - "jle" : __asm_proxy_JLE__, - "jmp" : __asm_proxy_JMP__, - "jmpq" : __asm_proxy_JMPQ__, - "jna" : __asm_proxy_JNA__, - "jnae" : __asm_proxy_JNAE__, - "jnb" : __asm_proxy_JNB__, - "jnbe" : __asm_proxy_JNBE__, - "jnc" : __asm_proxy_JNC__, - "jne" : __asm_proxy_JNE__, - "jng" : __asm_proxy_JNG__, - "jnge" : __asm_proxy_JNGE__, - "jnl" : __asm_proxy_JNL__, - "jnle" : __asm_proxy_JNLE__, - "jno" : __asm_proxy_JNO__, - "jnp" : __asm_proxy_JNP__, - "jns" : __asm_proxy_JNS__, - "jnz" : __asm_proxy_JNZ__, - "jo" : __asm_proxy_JO__, - "jp" : __asm_proxy_JP__, - "jpe" : __asm_proxy_JPE__, - "jpo" : __asm_proxy_JPO__, - "jrcxz" : __asm_proxy_JRCXZ__, - "js" : __asm_proxy_JS__, - "jz" : __asm_proxy_JZ__, - "kaddb" : __asm_proxy_KADDB__, - "kaddd" : __asm_proxy_KADDD__, - "kaddq" : __asm_proxy_KADDQ__, - "kaddw" : __asm_proxy_KADDW__, - "kandb" : __asm_proxy_KANDB__, - "kandd" : __asm_proxy_KANDD__, - "kandnb" : __asm_proxy_KANDNB__, - "kandnd" : __asm_proxy_KANDND__, - "kandnq" : __asm_proxy_KANDNQ__, - "kandnw" : __asm_proxy_KANDNW__, - "kandq" : __asm_proxy_KANDQ__, - "kandw" : __asm_proxy_KANDW__, - "kmovb" : __asm_proxy_KMOVB__, - "kmovd" : __asm_proxy_KMOVD__, - "kmovq" : __asm_proxy_KMOVQ__, - "kmovw" : __asm_proxy_KMOVW__, - "knotb" : __asm_proxy_KNOTB__, - "knotd" : __asm_proxy_KNOTD__, - "knotq" : __asm_proxy_KNOTQ__, - "knotw" : __asm_proxy_KNOTW__, - "korb" : __asm_proxy_KORB__, - "kord" : __asm_proxy_KORD__, - "korq" : __asm_proxy_KORQ__, - "kortestb" : __asm_proxy_KORTESTB__, - "kortestd" : __asm_proxy_KORTESTD__, - "kortestq" : __asm_proxy_KORTESTQ__, - "kortestw" : __asm_proxy_KORTESTW__, - "korw" : __asm_proxy_KORW__, - "kshiftlb" : __asm_proxy_KSHIFTLB__, - "kshiftld" : __asm_proxy_KSHIFTLD__, - "kshiftlq" : __asm_proxy_KSHIFTLQ__, - "kshiftlw" : __asm_proxy_KSHIFTLW__, - "kshiftrb" : __asm_proxy_KSHIFTRB__, - "kshiftrd" : __asm_proxy_KSHIFTRD__, - "kshiftrq" : __asm_proxy_KSHIFTRQ__, - "kshiftrw" : __asm_proxy_KSHIFTRW__, - "ktestb" : __asm_proxy_KTESTB__, - "ktestd" : __asm_proxy_KTESTD__, - "ktestq" : __asm_proxy_KTESTQ__, - "ktestw" : __asm_proxy_KTESTW__, - "kunpckbw" : __asm_proxy_KUNPCKBW__, - "kunpckdq" : __asm_proxy_KUNPCKDQ__, - "kunpckwd" : __asm_proxy_KUNPCKWD__, - "kxnorb" : __asm_proxy_KXNORB__, - "kxnord" : __asm_proxy_KXNORD__, - "kxnorq" : __asm_proxy_KXNORQ__, - "kxnorw" : __asm_proxy_KXNORW__, - "kxorb" : __asm_proxy_KXORB__, - "kxord" : __asm_proxy_KXORD__, - "kxorq" : __asm_proxy_KXORQ__, - "kxorw" : __asm_proxy_KXORW__, - "lddqu" : __asm_proxy_LDDQU__, - "ldmxcsr" : __asm_proxy_LDMXCSR__, - "leal" : __asm_proxy_LEAL__, - "leaq" : __asm_proxy_LEAQ__, - "leaw" : __asm_proxy_LEAW__, - "lfence" : __asm_proxy_LFENCE__, - "lzcntl" : __asm_proxy_LZCNTL__, - "lzcntq" : __asm_proxy_LZCNTQ__, - "lzcntw" : __asm_proxy_LZCNTW__, - "maskmovdqu" : __asm_proxy_MASKMOVDQU__, - "maskmovq" : __asm_proxy_MASKMOVQ__, - "maxpd" : __asm_proxy_MAXPD__, - "maxps" : __asm_proxy_MAXPS__, - "maxsd" : __asm_proxy_MAXSD__, - "maxss" : __asm_proxy_MAXSS__, - "mfence" : __asm_proxy_MFENCE__, - "minpd" : __asm_proxy_MINPD__, - "minps" : __asm_proxy_MINPS__, - "minsd" : __asm_proxy_MINSD__, - "minss" : __asm_proxy_MINSS__, - "monitor" : __asm_proxy_MONITOR__, - "monitorx" : __asm_proxy_MONITORX__, - "movapd" : __asm_proxy_MOVAPD__, - "movaps" : __asm_proxy_MOVAPS__, - "movb" : __asm_proxy_MOVB__, - "movbel" : __asm_proxy_MOVBEL__, - "movbeq" : __asm_proxy_MOVBEQ__, - "movbew" : __asm_proxy_MOVBEW__, - "movd" : __asm_proxy_MOVD__, - "movddup" : __asm_proxy_MOVDDUP__, - "movdq2q" : __asm_proxy_MOVDQ2Q__, - "movdqa" : __asm_proxy_MOVDQA__, - "movdqu" : __asm_proxy_MOVDQU__, - "movhlps" : __asm_proxy_MOVHLPS__, - "movhpd" : __asm_proxy_MOVHPD__, - "movhps" : __asm_proxy_MOVHPS__, - "movl" : __asm_proxy_MOVL__, - "movlhps" : __asm_proxy_MOVLHPS__, - "movlpd" : __asm_proxy_MOVLPD__, - "movlps" : __asm_proxy_MOVLPS__, - "movmskpd" : __asm_proxy_MOVMSKPD__, - "movmskps" : __asm_proxy_MOVMSKPS__, - "movntdq" : __asm_proxy_MOVNTDQ__, - "movntdqa" : __asm_proxy_MOVNTDQA__, - "movntil" : __asm_proxy_MOVNTIL__, - "movntiq" : __asm_proxy_MOVNTIQ__, - "movntpd" : __asm_proxy_MOVNTPD__, - "movntps" : __asm_proxy_MOVNTPS__, - "movntq" : __asm_proxy_MOVNTQ__, - "movntsd" : __asm_proxy_MOVNTSD__, - "movntss" : __asm_proxy_MOVNTSS__, - "movq" : __asm_proxy_MOVQ__, - "movq2dq" : __asm_proxy_MOVQ2DQ__, - "movsbl" : __asm_proxy_MOVSBL__, - "movsbq" : __asm_proxy_MOVSBQ__, - "movsbw" : __asm_proxy_MOVSBW__, - "movsd" : __asm_proxy_MOVSD__, - "movshdup" : __asm_proxy_MOVSHDUP__, - "movsldup" : __asm_proxy_MOVSLDUP__, - "movslq" : __asm_proxy_MOVSLQ__, - "movss" : __asm_proxy_MOVSS__, - "movswl" : __asm_proxy_MOVSWL__, - "movswq" : __asm_proxy_MOVSWQ__, - "movupd" : __asm_proxy_MOVUPD__, - "movups" : __asm_proxy_MOVUPS__, - "movw" : __asm_proxy_MOVW__, - "movzbl" : __asm_proxy_MOVZBL__, - "movzbq" : __asm_proxy_MOVZBQ__, - "movzbw" : __asm_proxy_MOVZBW__, - "movzwl" : __asm_proxy_MOVZWL__, - "movzwq" : __asm_proxy_MOVZWQ__, - "mpsadbw" : __asm_proxy_MPSADBW__, - "mulb" : __asm_proxy_MULB__, - "mull" : __asm_proxy_MULL__, - "mulpd" : __asm_proxy_MULPD__, - "mulps" : __asm_proxy_MULPS__, - "mulq" : __asm_proxy_MULQ__, - "mulsd" : __asm_proxy_MULSD__, - "mulss" : __asm_proxy_MULSS__, - "mulw" : __asm_proxy_MULW__, - "mulxl" : __asm_proxy_MULXL__, - "mulxq" : __asm_proxy_MULXQ__, - "mwait" : __asm_proxy_MWAIT__, - "mwaitx" : __asm_proxy_MWAITX__, - "negb" : __asm_proxy_NEGB__, - "negl" : __asm_proxy_NEGL__, - "negq" : __asm_proxy_NEGQ__, - "negw" : __asm_proxy_NEGW__, - "nop" : __asm_proxy_NOP__, - "notb" : __asm_proxy_NOTB__, - "notl" : __asm_proxy_NOTL__, - "notq" : __asm_proxy_NOTQ__, - "notw" : __asm_proxy_NOTW__, - "orb" : __asm_proxy_ORB__, - "orl" : __asm_proxy_ORL__, - "orpd" : __asm_proxy_ORPD__, - "orps" : __asm_proxy_ORPS__, - "orq" : __asm_proxy_ORQ__, - "orw" : __asm_proxy_ORW__, - "pabsb" : __asm_proxy_PABSB__, - "pabsd" : __asm_proxy_PABSD__, - "pabsw" : __asm_proxy_PABSW__, - "packssdw" : __asm_proxy_PACKSSDW__, - "packsswb" : __asm_proxy_PACKSSWB__, - "packusdw" : __asm_proxy_PACKUSDW__, - "packuswb" : __asm_proxy_PACKUSWB__, - "paddb" : __asm_proxy_PADDB__, - "paddd" : __asm_proxy_PADDD__, - "paddq" : __asm_proxy_PADDQ__, - "paddsb" : __asm_proxy_PADDSB__, - "paddsw" : __asm_proxy_PADDSW__, - "paddusb" : __asm_proxy_PADDUSB__, - "paddusw" : __asm_proxy_PADDUSW__, - "paddw" : __asm_proxy_PADDW__, - "palignr" : __asm_proxy_PALIGNR__, - "pand" : __asm_proxy_PAND__, - "pandn" : __asm_proxy_PANDN__, - "pause" : __asm_proxy_PAUSE__, - "pavgb" : __asm_proxy_PAVGB__, - "pavgusb" : __asm_proxy_PAVGUSB__, - "pavgw" : __asm_proxy_PAVGW__, - "pblendvb" : __asm_proxy_PBLENDVB__, - "pblendw" : __asm_proxy_PBLENDW__, - "pclmulqdq" : __asm_proxy_PCLMULQDQ__, - "pcmpeqb" : __asm_proxy_PCMPEQB__, - "pcmpeqd" : __asm_proxy_PCMPEQD__, - "pcmpeqq" : __asm_proxy_PCMPEQQ__, - "pcmpeqw" : __asm_proxy_PCMPEQW__, - "pcmpestri" : __asm_proxy_PCMPESTRI__, - "pcmpestrm" : __asm_proxy_PCMPESTRM__, - "pcmpgtb" : __asm_proxy_PCMPGTB__, - "pcmpgtd" : __asm_proxy_PCMPGTD__, - "pcmpgtq" : __asm_proxy_PCMPGTQ__, - "pcmpgtw" : __asm_proxy_PCMPGTW__, - "pcmpistri" : __asm_proxy_PCMPISTRI__, - "pcmpistrm" : __asm_proxy_PCMPISTRM__, - "pdep" : __asm_proxy_PDEP__, - "pext" : __asm_proxy_PEXT__, - "pextrb" : __asm_proxy_PEXTRB__, - "pextrd" : __asm_proxy_PEXTRD__, - "pextrq" : __asm_proxy_PEXTRQ__, - "pextrw" : __asm_proxy_PEXTRW__, - "pf2id" : __asm_proxy_PF2ID__, - "pf2iw" : __asm_proxy_PF2IW__, - "pfacc" : __asm_proxy_PFACC__, - "pfadd" : __asm_proxy_PFADD__, - "pfcmpeq" : __asm_proxy_PFCMPEQ__, - "pfcmpge" : __asm_proxy_PFCMPGE__, - "pfcmpgt" : __asm_proxy_PFCMPGT__, - "pfmax" : __asm_proxy_PFMAX__, - "pfmin" : __asm_proxy_PFMIN__, - "pfmul" : __asm_proxy_PFMUL__, - "pfnacc" : __asm_proxy_PFNACC__, - "pfpnacc" : __asm_proxy_PFPNACC__, - "pfrcp" : __asm_proxy_PFRCP__, - "pfrcpit1" : __asm_proxy_PFRCPIT1__, - "pfrcpit2" : __asm_proxy_PFRCPIT2__, - "pfrsqit1" : __asm_proxy_PFRSQIT1__, - "pfrsqrt" : __asm_proxy_PFRSQRT__, - "pfsub" : __asm_proxy_PFSUB__, - "pfsubr" : __asm_proxy_PFSUBR__, - "phaddd" : __asm_proxy_PHADDD__, - "phaddsw" : __asm_proxy_PHADDSW__, - "phaddw" : __asm_proxy_PHADDW__, - "phminposuw" : __asm_proxy_PHMINPOSUW__, - "phsubd" : __asm_proxy_PHSUBD__, - "phsubsw" : __asm_proxy_PHSUBSW__, - "phsubw" : __asm_proxy_PHSUBW__, - "pi2fd" : __asm_proxy_PI2FD__, - "pi2fw" : __asm_proxy_PI2FW__, - "pinsrb" : __asm_proxy_PINSRB__, - "pinsrd" : __asm_proxy_PINSRD__, - "pinsrq" : __asm_proxy_PINSRQ__, - "pinsrw" : __asm_proxy_PINSRW__, - "pmaddubsw" : __asm_proxy_PMADDUBSW__, - "pmaddwd" : __asm_proxy_PMADDWD__, - "pmaxsb" : __asm_proxy_PMAXSB__, - "pmaxsd" : __asm_proxy_PMAXSD__, - "pmaxsw" : __asm_proxy_PMAXSW__, - "pmaxub" : __asm_proxy_PMAXUB__, - "pmaxud" : __asm_proxy_PMAXUD__, - "pmaxuw" : __asm_proxy_PMAXUW__, - "pminsb" : __asm_proxy_PMINSB__, - "pminsd" : __asm_proxy_PMINSD__, - "pminsw" : __asm_proxy_PMINSW__, - "pminub" : __asm_proxy_PMINUB__, - "pminud" : __asm_proxy_PMINUD__, - "pminuw" : __asm_proxy_PMINUW__, - "pmovmskb" : __asm_proxy_PMOVMSKB__, - "pmovsxbd" : __asm_proxy_PMOVSXBD__, - "pmovsxbq" : __asm_proxy_PMOVSXBQ__, - "pmovsxbw" : __asm_proxy_PMOVSXBW__, - "pmovsxdq" : __asm_proxy_PMOVSXDQ__, - "pmovsxwd" : __asm_proxy_PMOVSXWD__, - "pmovsxwq" : __asm_proxy_PMOVSXWQ__, - "pmovzxbd" : __asm_proxy_PMOVZXBD__, - "pmovzxbq" : __asm_proxy_PMOVZXBQ__, - "pmovzxbw" : __asm_proxy_PMOVZXBW__, - "pmovzxdq" : __asm_proxy_PMOVZXDQ__, - "pmovzxwd" : __asm_proxy_PMOVZXWD__, - "pmovzxwq" : __asm_proxy_PMOVZXWQ__, - "pmuldq" : __asm_proxy_PMULDQ__, - "pmulhrsw" : __asm_proxy_PMULHRSW__, - "pmulhrw" : __asm_proxy_PMULHRW__, - "pmulhuw" : __asm_proxy_PMULHUW__, - "pmulhw" : __asm_proxy_PMULHW__, - "pmulld" : __asm_proxy_PMULLD__, - "pmullw" : __asm_proxy_PMULLW__, - "pmuludq" : __asm_proxy_PMULUDQ__, - "popcntl" : __asm_proxy_POPCNTL__, - "popcntq" : __asm_proxy_POPCNTQ__, - "popcntw" : __asm_proxy_POPCNTW__, - "popq" : __asm_proxy_POPQ__, - "popw" : __asm_proxy_POPW__, - "por" : __asm_proxy_POR__, - "prefetch" : __asm_proxy_PREFETCH__, - "prefetchnta" : __asm_proxy_PREFETCHNTA__, - "prefetcht0" : __asm_proxy_PREFETCHT0__, - "prefetcht1" : __asm_proxy_PREFETCHT1__, - "prefetcht2" : __asm_proxy_PREFETCHT2__, - "prefetchw" : __asm_proxy_PREFETCHW__, - "prefetchwt1" : __asm_proxy_PREFETCHWT1__, - "psadbw" : __asm_proxy_PSADBW__, - "pshufb" : __asm_proxy_PSHUFB__, - "pshufd" : __asm_proxy_PSHUFD__, - "pshufhw" : __asm_proxy_PSHUFHW__, - "pshuflw" : __asm_proxy_PSHUFLW__, - "pshufw" : __asm_proxy_PSHUFW__, - "psignb" : __asm_proxy_PSIGNB__, - "psignd" : __asm_proxy_PSIGND__, - "psignw" : __asm_proxy_PSIGNW__, - "pslld" : __asm_proxy_PSLLD__, - "pslldq" : __asm_proxy_PSLLDQ__, - "psllq" : __asm_proxy_PSLLQ__, - "psllw" : __asm_proxy_PSLLW__, - "psrad" : __asm_proxy_PSRAD__, - "psraw" : __asm_proxy_PSRAW__, - "psrld" : __asm_proxy_PSRLD__, - "psrldq" : __asm_proxy_PSRLDQ__, - "psrlq" : __asm_proxy_PSRLQ__, - "psrlw" : __asm_proxy_PSRLW__, - "psubb" : __asm_proxy_PSUBB__, - "psubd" : __asm_proxy_PSUBD__, - "psubq" : __asm_proxy_PSUBQ__, - "psubsb" : __asm_proxy_PSUBSB__, - "psubsw" : __asm_proxy_PSUBSW__, - "psubusb" : __asm_proxy_PSUBUSB__, - "psubusw" : __asm_proxy_PSUBUSW__, - "psubw" : __asm_proxy_PSUBW__, - "pswapd" : __asm_proxy_PSWAPD__, - "ptest" : __asm_proxy_PTEST__, - "punpckhbw" : __asm_proxy_PUNPCKHBW__, - "punpckhdq" : __asm_proxy_PUNPCKHDQ__, - "punpckhqdq" : __asm_proxy_PUNPCKHQDQ__, - "punpckhwd" : __asm_proxy_PUNPCKHWD__, - "punpcklbw" : __asm_proxy_PUNPCKLBW__, - "punpckldq" : __asm_proxy_PUNPCKLDQ__, - "punpcklqdq" : __asm_proxy_PUNPCKLQDQ__, - "punpcklwd" : __asm_proxy_PUNPCKLWD__, - "pushq" : __asm_proxy_PUSHQ__, - "pushw" : __asm_proxy_PUSHW__, - "pxor" : __asm_proxy_PXOR__, - "rclb" : __asm_proxy_RCLB__, - "rcll" : __asm_proxy_RCLL__, - "rclq" : __asm_proxy_RCLQ__, - "rclw" : __asm_proxy_RCLW__, - "rcpps" : __asm_proxy_RCPPS__, - "rcpss" : __asm_proxy_RCPSS__, - "rcrb" : __asm_proxy_RCRB__, - "rcrl" : __asm_proxy_RCRL__, - "rcrq" : __asm_proxy_RCRQ__, - "rcrw" : __asm_proxy_RCRW__, - "rdrand" : __asm_proxy_RDRAND__, - "rdseed" : __asm_proxy_RDSEED__, - "rdtsc" : __asm_proxy_RDTSC__, - "rdtscp" : __asm_proxy_RDTSCP__, - "ret" : __asm_proxy_RET__, - "rolb" : __asm_proxy_ROLB__, - "roll" : __asm_proxy_ROLL__, - "rolq" : __asm_proxy_ROLQ__, - "rolw" : __asm_proxy_ROLW__, - "rorb" : __asm_proxy_RORB__, - "rorl" : __asm_proxy_RORL__, - "rorq" : __asm_proxy_RORQ__, - "rorw" : __asm_proxy_RORW__, - "rorxl" : __asm_proxy_RORXL__, - "rorxq" : __asm_proxy_RORXQ__, - "roundpd" : __asm_proxy_ROUNDPD__, - "roundps" : __asm_proxy_ROUNDPS__, - "roundsd" : __asm_proxy_ROUNDSD__, - "roundss" : __asm_proxy_ROUNDSS__, - "rsqrtps" : __asm_proxy_RSQRTPS__, - "rsqrtss" : __asm_proxy_RSQRTSS__, - "salb" : __asm_proxy_SALB__, - "sall" : __asm_proxy_SALL__, - "salq" : __asm_proxy_SALQ__, - "salw" : __asm_proxy_SALW__, - "sarb" : __asm_proxy_SARB__, - "sarl" : __asm_proxy_SARL__, - "sarq" : __asm_proxy_SARQ__, - "sarw" : __asm_proxy_SARW__, - "sarxl" : __asm_proxy_SARXL__, - "sarxq" : __asm_proxy_SARXQ__, - "sbbb" : __asm_proxy_SBBB__, - "sbbl" : __asm_proxy_SBBL__, - "sbbq" : __asm_proxy_SBBQ__, - "sbbw" : __asm_proxy_SBBW__, - "seta" : __asm_proxy_SETA__, - "setae" : __asm_proxy_SETAE__, - "setb" : __asm_proxy_SETB__, - "setbe" : __asm_proxy_SETBE__, - "setc" : __asm_proxy_SETC__, - "sete" : __asm_proxy_SETE__, - "setg" : __asm_proxy_SETG__, - "setge" : __asm_proxy_SETGE__, - "setl" : __asm_proxy_SETL__, - "setle" : __asm_proxy_SETLE__, - "setna" : __asm_proxy_SETNA__, - "setnae" : __asm_proxy_SETNAE__, - "setnb" : __asm_proxy_SETNB__, - "setnbe" : __asm_proxy_SETNBE__, - "setnc" : __asm_proxy_SETNC__, - "setne" : __asm_proxy_SETNE__, - "setng" : __asm_proxy_SETNG__, - "setnge" : __asm_proxy_SETNGE__, - "setnl" : __asm_proxy_SETNL__, - "setnle" : __asm_proxy_SETNLE__, - "setno" : __asm_proxy_SETNO__, - "setnp" : __asm_proxy_SETNP__, - "setns" : __asm_proxy_SETNS__, - "setnz" : __asm_proxy_SETNZ__, - "seto" : __asm_proxy_SETO__, - "setp" : __asm_proxy_SETP__, - "setpe" : __asm_proxy_SETPE__, - "setpo" : __asm_proxy_SETPO__, - "sets" : __asm_proxy_SETS__, - "setz" : __asm_proxy_SETZ__, - "sfence" : __asm_proxy_SFENCE__, - "sha1msg1" : __asm_proxy_SHA1MSG1__, - "sha1msg2" : __asm_proxy_SHA1MSG2__, - "sha1nexte" : __asm_proxy_SHA1NEXTE__, - "sha1rnds4" : __asm_proxy_SHA1RNDS4__, - "sha256msg1" : __asm_proxy_SHA256MSG1__, - "sha256msg2" : __asm_proxy_SHA256MSG2__, - "sha256rnds2" : __asm_proxy_SHA256RNDS2__, - "shlb" : __asm_proxy_SHLB__, - "shldl" : __asm_proxy_SHLDL__, - "shldq" : __asm_proxy_SHLDQ__, - "shldw" : __asm_proxy_SHLDW__, - "shll" : __asm_proxy_SHLL__, - "shlq" : __asm_proxy_SHLQ__, - "shlw" : __asm_proxy_SHLW__, - "shlxl" : __asm_proxy_SHLXL__, - "shlxq" : __asm_proxy_SHLXQ__, - "shrb" : __asm_proxy_SHRB__, - "shrdl" : __asm_proxy_SHRDL__, - "shrdq" : __asm_proxy_SHRDQ__, - "shrdw" : __asm_proxy_SHRDW__, - "shrl" : __asm_proxy_SHRL__, - "shrq" : __asm_proxy_SHRQ__, - "shrw" : __asm_proxy_SHRW__, - "shrxl" : __asm_proxy_SHRXL__, - "shrxq" : __asm_proxy_SHRXQ__, - "shufpd" : __asm_proxy_SHUFPD__, - "shufps" : __asm_proxy_SHUFPS__, - "sqrtpd" : __asm_proxy_SQRTPD__, - "sqrtps" : __asm_proxy_SQRTPS__, - "sqrtsd" : __asm_proxy_SQRTSD__, - "sqrtss" : __asm_proxy_SQRTSS__, - "stc" : __asm_proxy_STC__, - "std" : __asm_proxy_STD__, - "stmxcsr" : __asm_proxy_STMXCSR__, - "subb" : __asm_proxy_SUBB__, - "subl" : __asm_proxy_SUBL__, - "subpd" : __asm_proxy_SUBPD__, - "subps" : __asm_proxy_SUBPS__, - "subq" : __asm_proxy_SUBQ__, - "subsd" : __asm_proxy_SUBSD__, - "subss" : __asm_proxy_SUBSS__, - "subw" : __asm_proxy_SUBW__, - "syscall" : __asm_proxy_SYSCALL__, - "t1mskc" : __asm_proxy_T1MSKC__, - "testb" : __asm_proxy_TESTB__, - "testl" : __asm_proxy_TESTL__, - "testq" : __asm_proxy_TESTQ__, - "testw" : __asm_proxy_TESTW__, - "tzcntl" : __asm_proxy_TZCNTL__, - "tzcntq" : __asm_proxy_TZCNTQ__, - "tzcntw" : __asm_proxy_TZCNTW__, - "tzmsk" : __asm_proxy_TZMSK__, - "ucomisd" : __asm_proxy_UCOMISD__, - "ucomiss" : __asm_proxy_UCOMISS__, - "ud2" : __asm_proxy_UD2__, - "unpckhpd" : __asm_proxy_UNPCKHPD__, - "unpckhps" : __asm_proxy_UNPCKHPS__, - "unpcklpd" : __asm_proxy_UNPCKLPD__, - "unpcklps" : __asm_proxy_UNPCKLPS__, - "vaddpd" : __asm_proxy_VADDPD__, - "vaddps" : __asm_proxy_VADDPS__, - "vaddsd" : __asm_proxy_VADDSD__, - "vaddss" : __asm_proxy_VADDSS__, - "vaddsubpd" : __asm_proxy_VADDSUBPD__, - "vaddsubps" : __asm_proxy_VADDSUBPS__, - "vaesdec" : __asm_proxy_VAESDEC__, - "vaesdeclast" : __asm_proxy_VAESDECLAST__, - "vaesenc" : __asm_proxy_VAESENC__, - "vaesenclast" : __asm_proxy_VAESENCLAST__, - "vaesimc" : __asm_proxy_VAESIMC__, - "vaeskeygenassist" : __asm_proxy_VAESKEYGENASSIST__, - "valignd" : __asm_proxy_VALIGND__, - "valignq" : __asm_proxy_VALIGNQ__, - "vandnpd" : __asm_proxy_VANDNPD__, - "vandnps" : __asm_proxy_VANDNPS__, - "vandpd" : __asm_proxy_VANDPD__, - "vandps" : __asm_proxy_VANDPS__, - "vblendmpd" : __asm_proxy_VBLENDMPD__, - "vblendmps" : __asm_proxy_VBLENDMPS__, - "vblendpd" : __asm_proxy_VBLENDPD__, - "vblendps" : __asm_proxy_VBLENDPS__, - "vblendvpd" : __asm_proxy_VBLENDVPD__, - "vblendvps" : __asm_proxy_VBLENDVPS__, - "vbroadcastf128" : __asm_proxy_VBROADCASTF128__, - "vbroadcastf32x2" : __asm_proxy_VBROADCASTF32X2__, - "vbroadcastf32x4" : __asm_proxy_VBROADCASTF32X4__, - "vbroadcastf32x8" : __asm_proxy_VBROADCASTF32X8__, - "vbroadcastf64x2" : __asm_proxy_VBROADCASTF64X2__, - "vbroadcastf64x4" : __asm_proxy_VBROADCASTF64X4__, - "vbroadcasti128" : __asm_proxy_VBROADCASTI128__, - "vbroadcasti32x2" : __asm_proxy_VBROADCASTI32X2__, - "vbroadcasti32x4" : __asm_proxy_VBROADCASTI32X4__, - "vbroadcasti32x8" : __asm_proxy_VBROADCASTI32X8__, - "vbroadcasti64x2" : __asm_proxy_VBROADCASTI64X2__, - "vbroadcasti64x4" : __asm_proxy_VBROADCASTI64X4__, - "vbroadcastsd" : __asm_proxy_VBROADCASTSD__, - "vbroadcastss" : __asm_proxy_VBROADCASTSS__, - "vcmppd" : __asm_proxy_VCMPPD__, - "vcmpps" : __asm_proxy_VCMPPS__, - "vcmpsd" : __asm_proxy_VCMPSD__, - "vcmpss" : __asm_proxy_VCMPSS__, - "vcomisd" : __asm_proxy_VCOMISD__, - "vcomiss" : __asm_proxy_VCOMISS__, - "vcompresspd" : __asm_proxy_VCOMPRESSPD__, - "vcompressps" : __asm_proxy_VCOMPRESSPS__, - "vcvtdq2pd" : __asm_proxy_VCVTDQ2PD__, - "vcvtdq2ps" : __asm_proxy_VCVTDQ2PS__, - "vcvtpd2dq" : __asm_proxy_VCVTPD2DQ__, - "vcvtpd2ps" : __asm_proxy_VCVTPD2PS__, - "vcvtpd2qq" : __asm_proxy_VCVTPD2QQ__, - "vcvtpd2udq" : __asm_proxy_VCVTPD2UDQ__, - "vcvtpd2uqq" : __asm_proxy_VCVTPD2UQQ__, - "vcvtph2ps" : __asm_proxy_VCVTPH2PS__, - "vcvtps2dq" : __asm_proxy_VCVTPS2DQ__, - "vcvtps2pd" : __asm_proxy_VCVTPS2PD__, - "vcvtps2ph" : __asm_proxy_VCVTPS2PH__, - "vcvtps2qq" : __asm_proxy_VCVTPS2QQ__, - "vcvtps2udq" : __asm_proxy_VCVTPS2UDQ__, - "vcvtps2uqq" : __asm_proxy_VCVTPS2UQQ__, - "vcvtqq2pd" : __asm_proxy_VCVTQQ2PD__, - "vcvtqq2ps" : __asm_proxy_VCVTQQ2PS__, - "vcvtsd2si" : __asm_proxy_VCVTSD2SI__, - "vcvtsd2ss" : __asm_proxy_VCVTSD2SS__, - "vcvtsd2usi" : __asm_proxy_VCVTSD2USI__, - "vcvtsi2sd" : __asm_proxy_VCVTSI2SD__, - "vcvtsi2ss" : __asm_proxy_VCVTSI2SS__, - "vcvtss2sd" : __asm_proxy_VCVTSS2SD__, - "vcvtss2si" : __asm_proxy_VCVTSS2SI__, - "vcvtss2usi" : __asm_proxy_VCVTSS2USI__, - "vcvttpd2dq" : __asm_proxy_VCVTTPD2DQ__, - "vcvttpd2qq" : __asm_proxy_VCVTTPD2QQ__, - "vcvttpd2udq" : __asm_proxy_VCVTTPD2UDQ__, - "vcvttpd2uqq" : __asm_proxy_VCVTTPD2UQQ__, - "vcvttps2dq" : __asm_proxy_VCVTTPS2DQ__, - "vcvttps2qq" : __asm_proxy_VCVTTPS2QQ__, - "vcvttps2udq" : __asm_proxy_VCVTTPS2UDQ__, - "vcvttps2uqq" : __asm_proxy_VCVTTPS2UQQ__, - "vcvttsd2si" : __asm_proxy_VCVTTSD2SI__, - "vcvttsd2usi" : __asm_proxy_VCVTTSD2USI__, - "vcvttss2si" : __asm_proxy_VCVTTSS2SI__, - "vcvttss2usi" : __asm_proxy_VCVTTSS2USI__, - "vcvtudq2pd" : __asm_proxy_VCVTUDQ2PD__, - "vcvtudq2ps" : __asm_proxy_VCVTUDQ2PS__, - "vcvtuqq2pd" : __asm_proxy_VCVTUQQ2PD__, - "vcvtuqq2ps" : __asm_proxy_VCVTUQQ2PS__, - "vcvtusi2sd" : __asm_proxy_VCVTUSI2SD__, - "vcvtusi2ss" : __asm_proxy_VCVTUSI2SS__, - "vdbpsadbw" : __asm_proxy_VDBPSADBW__, - "vdivpd" : __asm_proxy_VDIVPD__, - "vdivps" : __asm_proxy_VDIVPS__, - "vdivsd" : __asm_proxy_VDIVSD__, - "vdivss" : __asm_proxy_VDIVSS__, - "vdppd" : __asm_proxy_VDPPD__, - "vdpps" : __asm_proxy_VDPPS__, - "vexp2pd" : __asm_proxy_VEXP2PD__, - "vexp2ps" : __asm_proxy_VEXP2PS__, - "vexpandpd" : __asm_proxy_VEXPANDPD__, - "vexpandps" : __asm_proxy_VEXPANDPS__, - "vextractf128" : __asm_proxy_VEXTRACTF128__, - "vextractf32x4" : __asm_proxy_VEXTRACTF32X4__, - "vextractf32x8" : __asm_proxy_VEXTRACTF32X8__, - "vextractf64x2" : __asm_proxy_VEXTRACTF64X2__, - "vextractf64x4" : __asm_proxy_VEXTRACTF64X4__, - "vextracti128" : __asm_proxy_VEXTRACTI128__, - "vextracti32x4" : __asm_proxy_VEXTRACTI32X4__, - "vextracti32x8" : __asm_proxy_VEXTRACTI32X8__, - "vextracti64x2" : __asm_proxy_VEXTRACTI64X2__, - "vextracti64x4" : __asm_proxy_VEXTRACTI64X4__, - "vextractps" : __asm_proxy_VEXTRACTPS__, - "vfixupimmpd" : __asm_proxy_VFIXUPIMMPD__, - "vfixupimmps" : __asm_proxy_VFIXUPIMMPS__, - "vfixupimmsd" : __asm_proxy_VFIXUPIMMSD__, - "vfixupimmss" : __asm_proxy_VFIXUPIMMSS__, - "vfmadd132pd" : __asm_proxy_VFMADD132PD__, - "vfmadd132ps" : __asm_proxy_VFMADD132PS__, - "vfmadd132sd" : __asm_proxy_VFMADD132SD__, - "vfmadd132ss" : __asm_proxy_VFMADD132SS__, - "vfmadd213pd" : __asm_proxy_VFMADD213PD__, - "vfmadd213ps" : __asm_proxy_VFMADD213PS__, - "vfmadd213sd" : __asm_proxy_VFMADD213SD__, - "vfmadd213ss" : __asm_proxy_VFMADD213SS__, - "vfmadd231pd" : __asm_proxy_VFMADD231PD__, - "vfmadd231ps" : __asm_proxy_VFMADD231PS__, - "vfmadd231sd" : __asm_proxy_VFMADD231SD__, - "vfmadd231ss" : __asm_proxy_VFMADD231SS__, - "vfmaddpd" : __asm_proxy_VFMADDPD__, - "vfmaddps" : __asm_proxy_VFMADDPS__, - "vfmaddsd" : __asm_proxy_VFMADDSD__, - "vfmaddss" : __asm_proxy_VFMADDSS__, - "vfmaddsub132pd" : __asm_proxy_VFMADDSUB132PD__, - "vfmaddsub132ps" : __asm_proxy_VFMADDSUB132PS__, - "vfmaddsub213pd" : __asm_proxy_VFMADDSUB213PD__, - "vfmaddsub213ps" : __asm_proxy_VFMADDSUB213PS__, - "vfmaddsub231pd" : __asm_proxy_VFMADDSUB231PD__, - "vfmaddsub231ps" : __asm_proxy_VFMADDSUB231PS__, - "vfmaddsubpd" : __asm_proxy_VFMADDSUBPD__, - "vfmaddsubps" : __asm_proxy_VFMADDSUBPS__, - "vfmsub132pd" : __asm_proxy_VFMSUB132PD__, - "vfmsub132ps" : __asm_proxy_VFMSUB132PS__, - "vfmsub132sd" : __asm_proxy_VFMSUB132SD__, - "vfmsub132ss" : __asm_proxy_VFMSUB132SS__, - "vfmsub213pd" : __asm_proxy_VFMSUB213PD__, - "vfmsub213ps" : __asm_proxy_VFMSUB213PS__, - "vfmsub213sd" : __asm_proxy_VFMSUB213SD__, - "vfmsub213ss" : __asm_proxy_VFMSUB213SS__, - "vfmsub231pd" : __asm_proxy_VFMSUB231PD__, - "vfmsub231ps" : __asm_proxy_VFMSUB231PS__, - "vfmsub231sd" : __asm_proxy_VFMSUB231SD__, - "vfmsub231ss" : __asm_proxy_VFMSUB231SS__, - "vfmsubadd132pd" : __asm_proxy_VFMSUBADD132PD__, - "vfmsubadd132ps" : __asm_proxy_VFMSUBADD132PS__, - "vfmsubadd213pd" : __asm_proxy_VFMSUBADD213PD__, - "vfmsubadd213ps" : __asm_proxy_VFMSUBADD213PS__, - "vfmsubadd231pd" : __asm_proxy_VFMSUBADD231PD__, - "vfmsubadd231ps" : __asm_proxy_VFMSUBADD231PS__, - "vfmsubaddpd" : __asm_proxy_VFMSUBADDPD__, - "vfmsubaddps" : __asm_proxy_VFMSUBADDPS__, - "vfmsubpd" : __asm_proxy_VFMSUBPD__, - "vfmsubps" : __asm_proxy_VFMSUBPS__, - "vfmsubsd" : __asm_proxy_VFMSUBSD__, - "vfmsubss" : __asm_proxy_VFMSUBSS__, - "vfnmadd132pd" : __asm_proxy_VFNMADD132PD__, - "vfnmadd132ps" : __asm_proxy_VFNMADD132PS__, - "vfnmadd132sd" : __asm_proxy_VFNMADD132SD__, - "vfnmadd132ss" : __asm_proxy_VFNMADD132SS__, - "vfnmadd213pd" : __asm_proxy_VFNMADD213PD__, - "vfnmadd213ps" : __asm_proxy_VFNMADD213PS__, - "vfnmadd213sd" : __asm_proxy_VFNMADD213SD__, - "vfnmadd213ss" : __asm_proxy_VFNMADD213SS__, - "vfnmadd231pd" : __asm_proxy_VFNMADD231PD__, - "vfnmadd231ps" : __asm_proxy_VFNMADD231PS__, - "vfnmadd231sd" : __asm_proxy_VFNMADD231SD__, - "vfnmadd231ss" : __asm_proxy_VFNMADD231SS__, - "vfnmaddpd" : __asm_proxy_VFNMADDPD__, - "vfnmaddps" : __asm_proxy_VFNMADDPS__, - "vfnmaddsd" : __asm_proxy_VFNMADDSD__, - "vfnmaddss" : __asm_proxy_VFNMADDSS__, - "vfnmsub132pd" : __asm_proxy_VFNMSUB132PD__, - "vfnmsub132ps" : __asm_proxy_VFNMSUB132PS__, - "vfnmsub132sd" : __asm_proxy_VFNMSUB132SD__, - "vfnmsub132ss" : __asm_proxy_VFNMSUB132SS__, - "vfnmsub213pd" : __asm_proxy_VFNMSUB213PD__, - "vfnmsub213ps" : __asm_proxy_VFNMSUB213PS__, - "vfnmsub213sd" : __asm_proxy_VFNMSUB213SD__, - "vfnmsub213ss" : __asm_proxy_VFNMSUB213SS__, - "vfnmsub231pd" : __asm_proxy_VFNMSUB231PD__, - "vfnmsub231ps" : __asm_proxy_VFNMSUB231PS__, - "vfnmsub231sd" : __asm_proxy_VFNMSUB231SD__, - "vfnmsub231ss" : __asm_proxy_VFNMSUB231SS__, - "vfnmsubpd" : __asm_proxy_VFNMSUBPD__, - "vfnmsubps" : __asm_proxy_VFNMSUBPS__, - "vfnmsubsd" : __asm_proxy_VFNMSUBSD__, - "vfnmsubss" : __asm_proxy_VFNMSUBSS__, - "vfpclasspd" : __asm_proxy_VFPCLASSPD__, - "vfpclassps" : __asm_proxy_VFPCLASSPS__, - "vfpclasssd" : __asm_proxy_VFPCLASSSD__, - "vfpclassss" : __asm_proxy_VFPCLASSSS__, - "vfrczpd" : __asm_proxy_VFRCZPD__, - "vfrczps" : __asm_proxy_VFRCZPS__, - "vfrczsd" : __asm_proxy_VFRCZSD__, - "vfrczss" : __asm_proxy_VFRCZSS__, - "vgatherdpd" : __asm_proxy_VGATHERDPD__, - "vgatherdps" : __asm_proxy_VGATHERDPS__, - "vgatherpf0dpd" : __asm_proxy_VGATHERPF0DPD__, - "vgatherpf0dps" : __asm_proxy_VGATHERPF0DPS__, - "vgatherpf0qpd" : __asm_proxy_VGATHERPF0QPD__, - "vgatherpf0qps" : __asm_proxy_VGATHERPF0QPS__, - "vgatherpf1dpd" : __asm_proxy_VGATHERPF1DPD__, - "vgatherpf1dps" : __asm_proxy_VGATHERPF1DPS__, - "vgatherpf1qpd" : __asm_proxy_VGATHERPF1QPD__, - "vgatherpf1qps" : __asm_proxy_VGATHERPF1QPS__, - "vgatherqpd" : __asm_proxy_VGATHERQPD__, - "vgatherqps" : __asm_proxy_VGATHERQPS__, - "vgetexppd" : __asm_proxy_VGETEXPPD__, - "vgetexpps" : __asm_proxy_VGETEXPPS__, - "vgetexpsd" : __asm_proxy_VGETEXPSD__, - "vgetexpss" : __asm_proxy_VGETEXPSS__, - "vgetmantpd" : __asm_proxy_VGETMANTPD__, - "vgetmantps" : __asm_proxy_VGETMANTPS__, - "vgetmantsd" : __asm_proxy_VGETMANTSD__, - "vgetmantss" : __asm_proxy_VGETMANTSS__, - "vhaddpd" : __asm_proxy_VHADDPD__, - "vhaddps" : __asm_proxy_VHADDPS__, - "vhsubpd" : __asm_proxy_VHSUBPD__, - "vhsubps" : __asm_proxy_VHSUBPS__, - "vinsertf128" : __asm_proxy_VINSERTF128__, - "vinsertf32x4" : __asm_proxy_VINSERTF32X4__, - "vinsertf32x8" : __asm_proxy_VINSERTF32X8__, - "vinsertf64x2" : __asm_proxy_VINSERTF64X2__, - "vinsertf64x4" : __asm_proxy_VINSERTF64X4__, - "vinserti128" : __asm_proxy_VINSERTI128__, - "vinserti32x4" : __asm_proxy_VINSERTI32X4__, - "vinserti32x8" : __asm_proxy_VINSERTI32X8__, - "vinserti64x2" : __asm_proxy_VINSERTI64X2__, - "vinserti64x4" : __asm_proxy_VINSERTI64X4__, - "vinsertps" : __asm_proxy_VINSERTPS__, - "vlddqu" : __asm_proxy_VLDDQU__, - "vldmxcsr" : __asm_proxy_VLDMXCSR__, - "vmaskmovdqu" : __asm_proxy_VMASKMOVDQU__, - "vmaskmovpd" : __asm_proxy_VMASKMOVPD__, - "vmaskmovps" : __asm_proxy_VMASKMOVPS__, - "vmaxpd" : __asm_proxy_VMAXPD__, - "vmaxps" : __asm_proxy_VMAXPS__, - "vmaxsd" : __asm_proxy_VMAXSD__, - "vmaxss" : __asm_proxy_VMAXSS__, - "vminpd" : __asm_proxy_VMINPD__, - "vminps" : __asm_proxy_VMINPS__, - "vminsd" : __asm_proxy_VMINSD__, - "vminss" : __asm_proxy_VMINSS__, - "vmovapd" : __asm_proxy_VMOVAPD__, - "vmovaps" : __asm_proxy_VMOVAPS__, - "vmovd" : __asm_proxy_VMOVD__, - "vmovddup" : __asm_proxy_VMOVDDUP__, - "vmovdqa" : __asm_proxy_VMOVDQA__, - "vmovdqa32" : __asm_proxy_VMOVDQA32__, - "vmovdqa64" : __asm_proxy_VMOVDQA64__, - "vmovdqu" : __asm_proxy_VMOVDQU__, - "vmovdqu16" : __asm_proxy_VMOVDQU16__, - "vmovdqu32" : __asm_proxy_VMOVDQU32__, - "vmovdqu64" : __asm_proxy_VMOVDQU64__, - "vmovdqu8" : __asm_proxy_VMOVDQU8__, - "vmovhlps" : __asm_proxy_VMOVHLPS__, - "vmovhpd" : __asm_proxy_VMOVHPD__, - "vmovhps" : __asm_proxy_VMOVHPS__, - "vmovlhps" : __asm_proxy_VMOVLHPS__, - "vmovlpd" : __asm_proxy_VMOVLPD__, - "vmovlps" : __asm_proxy_VMOVLPS__, - "vmovmskpd" : __asm_proxy_VMOVMSKPD__, - "vmovmskps" : __asm_proxy_VMOVMSKPS__, - "vmovntdq" : __asm_proxy_VMOVNTDQ__, - "vmovntdqa" : __asm_proxy_VMOVNTDQA__, - "vmovntpd" : __asm_proxy_VMOVNTPD__, - "vmovntps" : __asm_proxy_VMOVNTPS__, - "vmovq" : __asm_proxy_VMOVQ__, - "vmovsd" : __asm_proxy_VMOVSD__, - "vmovshdup" : __asm_proxy_VMOVSHDUP__, - "vmovsldup" : __asm_proxy_VMOVSLDUP__, - "vmovss" : __asm_proxy_VMOVSS__, - "vmovupd" : __asm_proxy_VMOVUPD__, - "vmovups" : __asm_proxy_VMOVUPS__, - "vmpsadbw" : __asm_proxy_VMPSADBW__, - "vmulpd" : __asm_proxy_VMULPD__, - "vmulps" : __asm_proxy_VMULPS__, - "vmulsd" : __asm_proxy_VMULSD__, - "vmulss" : __asm_proxy_VMULSS__, - "vorpd" : __asm_proxy_VORPD__, - "vorps" : __asm_proxy_VORPS__, - "vpabsb" : __asm_proxy_VPABSB__, - "vpabsd" : __asm_proxy_VPABSD__, - "vpabsq" : __asm_proxy_VPABSQ__, - "vpabsw" : __asm_proxy_VPABSW__, - "vpackssdw" : __asm_proxy_VPACKSSDW__, - "vpacksswb" : __asm_proxy_VPACKSSWB__, - "vpackusdw" : __asm_proxy_VPACKUSDW__, - "vpackuswb" : __asm_proxy_VPACKUSWB__, - "vpaddb" : __asm_proxy_VPADDB__, - "vpaddd" : __asm_proxy_VPADDD__, - "vpaddq" : __asm_proxy_VPADDQ__, - "vpaddsb" : __asm_proxy_VPADDSB__, - "vpaddsw" : __asm_proxy_VPADDSW__, - "vpaddusb" : __asm_proxy_VPADDUSB__, - "vpaddusw" : __asm_proxy_VPADDUSW__, - "vpaddw" : __asm_proxy_VPADDW__, - "vpalignr" : __asm_proxy_VPALIGNR__, - "vpand" : __asm_proxy_VPAND__, - "vpandd" : __asm_proxy_VPANDD__, - "vpandn" : __asm_proxy_VPANDN__, - "vpandnd" : __asm_proxy_VPANDND__, - "vpandnq" : __asm_proxy_VPANDNQ__, - "vpandq" : __asm_proxy_VPANDQ__, - "vpavgb" : __asm_proxy_VPAVGB__, - "vpavgw" : __asm_proxy_VPAVGW__, - "vpblendd" : __asm_proxy_VPBLENDD__, - "vpblendmb" : __asm_proxy_VPBLENDMB__, - "vpblendmd" : __asm_proxy_VPBLENDMD__, - "vpblendmq" : __asm_proxy_VPBLENDMQ__, - "vpblendmw" : __asm_proxy_VPBLENDMW__, - "vpblendvb" : __asm_proxy_VPBLENDVB__, - "vpblendw" : __asm_proxy_VPBLENDW__, - "vpbroadcastb" : __asm_proxy_VPBROADCASTB__, - "vpbroadcastd" : __asm_proxy_VPBROADCASTD__, - "vpbroadcastmb2q" : __asm_proxy_VPBROADCASTMB2Q__, - "vpbroadcastmw2d" : __asm_proxy_VPBROADCASTMW2D__, - "vpbroadcastq" : __asm_proxy_VPBROADCASTQ__, - "vpbroadcastw" : __asm_proxy_VPBROADCASTW__, - "vpclmulqdq" : __asm_proxy_VPCLMULQDQ__, - "vpcmov" : __asm_proxy_VPCMOV__, - "vpcmpb" : __asm_proxy_VPCMPB__, - "vpcmpd" : __asm_proxy_VPCMPD__, - "vpcmpeqb" : __asm_proxy_VPCMPEQB__, - "vpcmpeqd" : __asm_proxy_VPCMPEQD__, - "vpcmpeqq" : __asm_proxy_VPCMPEQQ__, - "vpcmpeqw" : __asm_proxy_VPCMPEQW__, - "vpcmpestri" : __asm_proxy_VPCMPESTRI__, - "vpcmpestrm" : __asm_proxy_VPCMPESTRM__, - "vpcmpgtb" : __asm_proxy_VPCMPGTB__, - "vpcmpgtd" : __asm_proxy_VPCMPGTD__, - "vpcmpgtq" : __asm_proxy_VPCMPGTQ__, - "vpcmpgtw" : __asm_proxy_VPCMPGTW__, - "vpcmpistri" : __asm_proxy_VPCMPISTRI__, - "vpcmpistrm" : __asm_proxy_VPCMPISTRM__, - "vpcmpq" : __asm_proxy_VPCMPQ__, - "vpcmpub" : __asm_proxy_VPCMPUB__, - "vpcmpud" : __asm_proxy_VPCMPUD__, - "vpcmpuq" : __asm_proxy_VPCMPUQ__, - "vpcmpuw" : __asm_proxy_VPCMPUW__, - "vpcmpw" : __asm_proxy_VPCMPW__, - "vpcomb" : __asm_proxy_VPCOMB__, - "vpcomd" : __asm_proxy_VPCOMD__, - "vpcompressd" : __asm_proxy_VPCOMPRESSD__, - "vpcompressq" : __asm_proxy_VPCOMPRESSQ__, - "vpcomq" : __asm_proxy_VPCOMQ__, - "vpcomub" : __asm_proxy_VPCOMUB__, - "vpcomud" : __asm_proxy_VPCOMUD__, - "vpcomuq" : __asm_proxy_VPCOMUQ__, - "vpcomuw" : __asm_proxy_VPCOMUW__, - "vpcomw" : __asm_proxy_VPCOMW__, - "vpconflictd" : __asm_proxy_VPCONFLICTD__, - "vpconflictq" : __asm_proxy_VPCONFLICTQ__, - "vperm2f128" : __asm_proxy_VPERM2F128__, - "vperm2i128" : __asm_proxy_VPERM2I128__, - "vpermb" : __asm_proxy_VPERMB__, - "vpermd" : __asm_proxy_VPERMD__, - "vpermi2b" : __asm_proxy_VPERMI2B__, - "vpermi2d" : __asm_proxy_VPERMI2D__, - "vpermi2pd" : __asm_proxy_VPERMI2PD__, - "vpermi2ps" : __asm_proxy_VPERMI2PS__, - "vpermi2q" : __asm_proxy_VPERMI2Q__, - "vpermi2w" : __asm_proxy_VPERMI2W__, - "vpermil2pd" : __asm_proxy_VPERMIL2PD__, - "vpermil2ps" : __asm_proxy_VPERMIL2PS__, - "vpermilpd" : __asm_proxy_VPERMILPD__, - "vpermilps" : __asm_proxy_VPERMILPS__, - "vpermpd" : __asm_proxy_VPERMPD__, - "vpermps" : __asm_proxy_VPERMPS__, - "vpermq" : __asm_proxy_VPERMQ__, - "vpermt2b" : __asm_proxy_VPERMT2B__, - "vpermt2d" : __asm_proxy_VPERMT2D__, - "vpermt2pd" : __asm_proxy_VPERMT2PD__, - "vpermt2ps" : __asm_proxy_VPERMT2PS__, - "vpermt2q" : __asm_proxy_VPERMT2Q__, - "vpermt2w" : __asm_proxy_VPERMT2W__, - "vpermw" : __asm_proxy_VPERMW__, - "vpexpandd" : __asm_proxy_VPEXPANDD__, - "vpexpandq" : __asm_proxy_VPEXPANDQ__, - "vpextrb" : __asm_proxy_VPEXTRB__, - "vpextrd" : __asm_proxy_VPEXTRD__, - "vpextrq" : __asm_proxy_VPEXTRQ__, - "vpextrw" : __asm_proxy_VPEXTRW__, - "vpgatherdd" : __asm_proxy_VPGATHERDD__, - "vpgatherdq" : __asm_proxy_VPGATHERDQ__, - "vpgatherqd" : __asm_proxy_VPGATHERQD__, - "vpgatherqq" : __asm_proxy_VPGATHERQQ__, - "vphaddbd" : __asm_proxy_VPHADDBD__, - "vphaddbq" : __asm_proxy_VPHADDBQ__, - "vphaddbw" : __asm_proxy_VPHADDBW__, - "vphaddd" : __asm_proxy_VPHADDD__, - "vphadddq" : __asm_proxy_VPHADDDQ__, - "vphaddsw" : __asm_proxy_VPHADDSW__, - "vphaddubd" : __asm_proxy_VPHADDUBD__, - "vphaddubq" : __asm_proxy_VPHADDUBQ__, - "vphaddubw" : __asm_proxy_VPHADDUBW__, - "vphaddudq" : __asm_proxy_VPHADDUDQ__, - "vphadduwd" : __asm_proxy_VPHADDUWD__, - "vphadduwq" : __asm_proxy_VPHADDUWQ__, - "vphaddw" : __asm_proxy_VPHADDW__, - "vphaddwd" : __asm_proxy_VPHADDWD__, - "vphaddwq" : __asm_proxy_VPHADDWQ__, - "vphminposuw" : __asm_proxy_VPHMINPOSUW__, - "vphsubbw" : __asm_proxy_VPHSUBBW__, - "vphsubd" : __asm_proxy_VPHSUBD__, - "vphsubdq" : __asm_proxy_VPHSUBDQ__, - "vphsubsw" : __asm_proxy_VPHSUBSW__, - "vphsubw" : __asm_proxy_VPHSUBW__, - "vphsubwd" : __asm_proxy_VPHSUBWD__, - "vpinsrb" : __asm_proxy_VPINSRB__, - "vpinsrd" : __asm_proxy_VPINSRD__, - "vpinsrq" : __asm_proxy_VPINSRQ__, - "vpinsrw" : __asm_proxy_VPINSRW__, - "vplzcntd" : __asm_proxy_VPLZCNTD__, - "vplzcntq" : __asm_proxy_VPLZCNTQ__, - "vpmacsdd" : __asm_proxy_VPMACSDD__, - "vpmacsdqh" : __asm_proxy_VPMACSDQH__, - "vpmacsdql" : __asm_proxy_VPMACSDQL__, - "vpmacssdd" : __asm_proxy_VPMACSSDD__, - "vpmacssdqh" : __asm_proxy_VPMACSSDQH__, - "vpmacssdql" : __asm_proxy_VPMACSSDQL__, - "vpmacsswd" : __asm_proxy_VPMACSSWD__, - "vpmacssww" : __asm_proxy_VPMACSSWW__, - "vpmacswd" : __asm_proxy_VPMACSWD__, - "vpmacsww" : __asm_proxy_VPMACSWW__, - "vpmadcsswd" : __asm_proxy_VPMADCSSWD__, - "vpmadcswd" : __asm_proxy_VPMADCSWD__, - "vpmadd52huq" : __asm_proxy_VPMADD52HUQ__, - "vpmadd52luq" : __asm_proxy_VPMADD52LUQ__, - "vpmaddubsw" : __asm_proxy_VPMADDUBSW__, - "vpmaddwd" : __asm_proxy_VPMADDWD__, - "vpmaskmovd" : __asm_proxy_VPMASKMOVD__, - "vpmaskmovq" : __asm_proxy_VPMASKMOVQ__, - "vpmaxsb" : __asm_proxy_VPMAXSB__, - "vpmaxsd" : __asm_proxy_VPMAXSD__, - "vpmaxsq" : __asm_proxy_VPMAXSQ__, - "vpmaxsw" : __asm_proxy_VPMAXSW__, - "vpmaxub" : __asm_proxy_VPMAXUB__, - "vpmaxud" : __asm_proxy_VPMAXUD__, - "vpmaxuq" : __asm_proxy_VPMAXUQ__, - "vpmaxuw" : __asm_proxy_VPMAXUW__, - "vpminsb" : __asm_proxy_VPMINSB__, - "vpminsd" : __asm_proxy_VPMINSD__, - "vpminsq" : __asm_proxy_VPMINSQ__, - "vpminsw" : __asm_proxy_VPMINSW__, - "vpminub" : __asm_proxy_VPMINUB__, - "vpminud" : __asm_proxy_VPMINUD__, - "vpminuq" : __asm_proxy_VPMINUQ__, - "vpminuw" : __asm_proxy_VPMINUW__, - "vpmovb2m" : __asm_proxy_VPMOVB2M__, - "vpmovd2m" : __asm_proxy_VPMOVD2M__, - "vpmovdb" : __asm_proxy_VPMOVDB__, - "vpmovdw" : __asm_proxy_VPMOVDW__, - "vpmovm2b" : __asm_proxy_VPMOVM2B__, - "vpmovm2d" : __asm_proxy_VPMOVM2D__, - "vpmovm2q" : __asm_proxy_VPMOVM2Q__, - "vpmovm2w" : __asm_proxy_VPMOVM2W__, - "vpmovmskb" : __asm_proxy_VPMOVMSKB__, - "vpmovq2m" : __asm_proxy_VPMOVQ2M__, - "vpmovqb" : __asm_proxy_VPMOVQB__, - "vpmovqd" : __asm_proxy_VPMOVQD__, - "vpmovqw" : __asm_proxy_VPMOVQW__, - "vpmovsdb" : __asm_proxy_VPMOVSDB__, - "vpmovsdw" : __asm_proxy_VPMOVSDW__, - "vpmovsqb" : __asm_proxy_VPMOVSQB__, - "vpmovsqd" : __asm_proxy_VPMOVSQD__, - "vpmovsqw" : __asm_proxy_VPMOVSQW__, - "vpmovswb" : __asm_proxy_VPMOVSWB__, - "vpmovsxbd" : __asm_proxy_VPMOVSXBD__, - "vpmovsxbq" : __asm_proxy_VPMOVSXBQ__, - "vpmovsxbw" : __asm_proxy_VPMOVSXBW__, - "vpmovsxdq" : __asm_proxy_VPMOVSXDQ__, - "vpmovsxwd" : __asm_proxy_VPMOVSXWD__, - "vpmovsxwq" : __asm_proxy_VPMOVSXWQ__, - "vpmovusdb" : __asm_proxy_VPMOVUSDB__, - "vpmovusdw" : __asm_proxy_VPMOVUSDW__, - "vpmovusqb" : __asm_proxy_VPMOVUSQB__, - "vpmovusqd" : __asm_proxy_VPMOVUSQD__, - "vpmovusqw" : __asm_proxy_VPMOVUSQW__, - "vpmovuswb" : __asm_proxy_VPMOVUSWB__, - "vpmovw2m" : __asm_proxy_VPMOVW2M__, - "vpmovwb" : __asm_proxy_VPMOVWB__, - "vpmovzxbd" : __asm_proxy_VPMOVZXBD__, - "vpmovzxbq" : __asm_proxy_VPMOVZXBQ__, - "vpmovzxbw" : __asm_proxy_VPMOVZXBW__, - "vpmovzxdq" : __asm_proxy_VPMOVZXDQ__, - "vpmovzxwd" : __asm_proxy_VPMOVZXWD__, - "vpmovzxwq" : __asm_proxy_VPMOVZXWQ__, - "vpmuldq" : __asm_proxy_VPMULDQ__, - "vpmulhrsw" : __asm_proxy_VPMULHRSW__, - "vpmulhuw" : __asm_proxy_VPMULHUW__, - "vpmulhw" : __asm_proxy_VPMULHW__, - "vpmulld" : __asm_proxy_VPMULLD__, - "vpmullq" : __asm_proxy_VPMULLQ__, - "vpmullw" : __asm_proxy_VPMULLW__, - "vpmultishiftqb" : __asm_proxy_VPMULTISHIFTQB__, - "vpmuludq" : __asm_proxy_VPMULUDQ__, - "vpopcntd" : __asm_proxy_VPOPCNTD__, - "vpopcntq" : __asm_proxy_VPOPCNTQ__, - "vpor" : __asm_proxy_VPOR__, - "vpord" : __asm_proxy_VPORD__, - "vporq" : __asm_proxy_VPORQ__, - "vpperm" : __asm_proxy_VPPERM__, - "vprold" : __asm_proxy_VPROLD__, - "vprolq" : __asm_proxy_VPROLQ__, - "vprolvd" : __asm_proxy_VPROLVD__, - "vprolvq" : __asm_proxy_VPROLVQ__, - "vprord" : __asm_proxy_VPRORD__, - "vprorq" : __asm_proxy_VPRORQ__, - "vprorvd" : __asm_proxy_VPRORVD__, - "vprorvq" : __asm_proxy_VPRORVQ__, - "vprotb" : __asm_proxy_VPROTB__, - "vprotd" : __asm_proxy_VPROTD__, - "vprotq" : __asm_proxy_VPROTQ__, - "vprotw" : __asm_proxy_VPROTW__, - "vpsadbw" : __asm_proxy_VPSADBW__, - "vpscatterdd" : __asm_proxy_VPSCATTERDD__, - "vpscatterdq" : __asm_proxy_VPSCATTERDQ__, - "vpscatterqd" : __asm_proxy_VPSCATTERQD__, - "vpscatterqq" : __asm_proxy_VPSCATTERQQ__, - "vpshab" : __asm_proxy_VPSHAB__, - "vpshad" : __asm_proxy_VPSHAD__, - "vpshaq" : __asm_proxy_VPSHAQ__, - "vpshaw" : __asm_proxy_VPSHAW__, - "vpshlb" : __asm_proxy_VPSHLB__, - "vpshld" : __asm_proxy_VPSHLD__, - "vpshlq" : __asm_proxy_VPSHLQ__, - "vpshlw" : __asm_proxy_VPSHLW__, - "vpshufb" : __asm_proxy_VPSHUFB__, - "vpshufd" : __asm_proxy_VPSHUFD__, - "vpshufhw" : __asm_proxy_VPSHUFHW__, - "vpshuflw" : __asm_proxy_VPSHUFLW__, - "vpsignb" : __asm_proxy_VPSIGNB__, - "vpsignd" : __asm_proxy_VPSIGND__, - "vpsignw" : __asm_proxy_VPSIGNW__, - "vpslld" : __asm_proxy_VPSLLD__, - "vpslldq" : __asm_proxy_VPSLLDQ__, - "vpsllq" : __asm_proxy_VPSLLQ__, - "vpsllvd" : __asm_proxy_VPSLLVD__, - "vpsllvq" : __asm_proxy_VPSLLVQ__, - "vpsllvw" : __asm_proxy_VPSLLVW__, - "vpsllw" : __asm_proxy_VPSLLW__, - "vpsrad" : __asm_proxy_VPSRAD__, - "vpsraq" : __asm_proxy_VPSRAQ__, - "vpsravd" : __asm_proxy_VPSRAVD__, - "vpsravq" : __asm_proxy_VPSRAVQ__, - "vpsravw" : __asm_proxy_VPSRAVW__, - "vpsraw" : __asm_proxy_VPSRAW__, - "vpsrld" : __asm_proxy_VPSRLD__, - "vpsrldq" : __asm_proxy_VPSRLDQ__, - "vpsrlq" : __asm_proxy_VPSRLQ__, - "vpsrlvd" : __asm_proxy_VPSRLVD__, - "vpsrlvq" : __asm_proxy_VPSRLVQ__, - "vpsrlvw" : __asm_proxy_VPSRLVW__, - "vpsrlw" : __asm_proxy_VPSRLW__, - "vpsubb" : __asm_proxy_VPSUBB__, - "vpsubd" : __asm_proxy_VPSUBD__, - "vpsubq" : __asm_proxy_VPSUBQ__, - "vpsubsb" : __asm_proxy_VPSUBSB__, - "vpsubsw" : __asm_proxy_VPSUBSW__, - "vpsubusb" : __asm_proxy_VPSUBUSB__, - "vpsubusw" : __asm_proxy_VPSUBUSW__, - "vpsubw" : __asm_proxy_VPSUBW__, - "vpternlogd" : __asm_proxy_VPTERNLOGD__, - "vpternlogq" : __asm_proxy_VPTERNLOGQ__, - "vptest" : __asm_proxy_VPTEST__, - "vptestmb" : __asm_proxy_VPTESTMB__, - "vptestmd" : __asm_proxy_VPTESTMD__, - "vptestmq" : __asm_proxy_VPTESTMQ__, - "vptestmw" : __asm_proxy_VPTESTMW__, - "vptestnmb" : __asm_proxy_VPTESTNMB__, - "vptestnmd" : __asm_proxy_VPTESTNMD__, - "vptestnmq" : __asm_proxy_VPTESTNMQ__, - "vptestnmw" : __asm_proxy_VPTESTNMW__, - "vpunpckhbw" : __asm_proxy_VPUNPCKHBW__, - "vpunpckhdq" : __asm_proxy_VPUNPCKHDQ__, - "vpunpckhqdq" : __asm_proxy_VPUNPCKHQDQ__, - "vpunpckhwd" : __asm_proxy_VPUNPCKHWD__, - "vpunpcklbw" : __asm_proxy_VPUNPCKLBW__, - "vpunpckldq" : __asm_proxy_VPUNPCKLDQ__, - "vpunpcklqdq" : __asm_proxy_VPUNPCKLQDQ__, - "vpunpcklwd" : __asm_proxy_VPUNPCKLWD__, - "vpxor" : __asm_proxy_VPXOR__, - "vpxord" : __asm_proxy_VPXORD__, - "vpxorq" : __asm_proxy_VPXORQ__, - "vrangepd" : __asm_proxy_VRANGEPD__, - "vrangeps" : __asm_proxy_VRANGEPS__, - "vrangesd" : __asm_proxy_VRANGESD__, - "vrangess" : __asm_proxy_VRANGESS__, - "vrcp14pd" : __asm_proxy_VRCP14PD__, - "vrcp14ps" : __asm_proxy_VRCP14PS__, - "vrcp14sd" : __asm_proxy_VRCP14SD__, - "vrcp14ss" : __asm_proxy_VRCP14SS__, - "vrcp28pd" : __asm_proxy_VRCP28PD__, - "vrcp28ps" : __asm_proxy_VRCP28PS__, - "vrcp28sd" : __asm_proxy_VRCP28SD__, - "vrcp28ss" : __asm_proxy_VRCP28SS__, - "vrcpps" : __asm_proxy_VRCPPS__, - "vrcpss" : __asm_proxy_VRCPSS__, - "vreducepd" : __asm_proxy_VREDUCEPD__, - "vreduceps" : __asm_proxy_VREDUCEPS__, - "vreducesd" : __asm_proxy_VREDUCESD__, - "vreducess" : __asm_proxy_VREDUCESS__, - "vrndscalepd" : __asm_proxy_VRNDSCALEPD__, - "vrndscaleps" : __asm_proxy_VRNDSCALEPS__, - "vrndscalesd" : __asm_proxy_VRNDSCALESD__, - "vrndscaless" : __asm_proxy_VRNDSCALESS__, - "vroundpd" : __asm_proxy_VROUNDPD__, - "vroundps" : __asm_proxy_VROUNDPS__, - "vroundsd" : __asm_proxy_VROUNDSD__, - "vroundss" : __asm_proxy_VROUNDSS__, - "vrsqrt14pd" : __asm_proxy_VRSQRT14PD__, - "vrsqrt14ps" : __asm_proxy_VRSQRT14PS__, - "vrsqrt14sd" : __asm_proxy_VRSQRT14SD__, - "vrsqrt14ss" : __asm_proxy_VRSQRT14SS__, - "vrsqrt28pd" : __asm_proxy_VRSQRT28PD__, - "vrsqrt28ps" : __asm_proxy_VRSQRT28PS__, - "vrsqrt28sd" : __asm_proxy_VRSQRT28SD__, - "vrsqrt28ss" : __asm_proxy_VRSQRT28SS__, - "vrsqrtps" : __asm_proxy_VRSQRTPS__, - "vrsqrtss" : __asm_proxy_VRSQRTSS__, - "vscalefpd" : __asm_proxy_VSCALEFPD__, - "vscalefps" : __asm_proxy_VSCALEFPS__, - "vscalefsd" : __asm_proxy_VSCALEFSD__, - "vscalefss" : __asm_proxy_VSCALEFSS__, - "vscatterdpd" : __asm_proxy_VSCATTERDPD__, - "vscatterdps" : __asm_proxy_VSCATTERDPS__, - "vscatterpf0dpd" : __asm_proxy_VSCATTERPF0DPD__, - "vscatterpf0dps" : __asm_proxy_VSCATTERPF0DPS__, - "vscatterpf0qpd" : __asm_proxy_VSCATTERPF0QPD__, - "vscatterpf0qps" : __asm_proxy_VSCATTERPF0QPS__, - "vscatterpf1dpd" : __asm_proxy_VSCATTERPF1DPD__, - "vscatterpf1dps" : __asm_proxy_VSCATTERPF1DPS__, - "vscatterpf1qpd" : __asm_proxy_VSCATTERPF1QPD__, - "vscatterpf1qps" : __asm_proxy_VSCATTERPF1QPS__, - "vscatterqpd" : __asm_proxy_VSCATTERQPD__, - "vscatterqps" : __asm_proxy_VSCATTERQPS__, - "vshuff32x4" : __asm_proxy_VSHUFF32X4__, - "vshuff64x2" : __asm_proxy_VSHUFF64X2__, - "vshufi32x4" : __asm_proxy_VSHUFI32X4__, - "vshufi64x2" : __asm_proxy_VSHUFI64X2__, - "vshufpd" : __asm_proxy_VSHUFPD__, - "vshufps" : __asm_proxy_VSHUFPS__, - "vsqrtpd" : __asm_proxy_VSQRTPD__, - "vsqrtps" : __asm_proxy_VSQRTPS__, - "vsqrtsd" : __asm_proxy_VSQRTSD__, - "vsqrtss" : __asm_proxy_VSQRTSS__, - "vstmxcsr" : __asm_proxy_VSTMXCSR__, - "vsubpd" : __asm_proxy_VSUBPD__, - "vsubps" : __asm_proxy_VSUBPS__, - "vsubsd" : __asm_proxy_VSUBSD__, - "vsubss" : __asm_proxy_VSUBSS__, - "vtestpd" : __asm_proxy_VTESTPD__, - "vtestps" : __asm_proxy_VTESTPS__, - "vucomisd" : __asm_proxy_VUCOMISD__, - "vucomiss" : __asm_proxy_VUCOMISS__, - "vunpckhpd" : __asm_proxy_VUNPCKHPD__, - "vunpckhps" : __asm_proxy_VUNPCKHPS__, - "vunpcklpd" : __asm_proxy_VUNPCKLPD__, - "vunpcklps" : __asm_proxy_VUNPCKLPS__, - "vxorpd" : __asm_proxy_VXORPD__, - "vxorps" : __asm_proxy_VXORPS__, - "vzeroall" : __asm_proxy_VZEROALL__, - "vzeroupper" : __asm_proxy_VZEROUPPER__, - "xaddb" : __asm_proxy_XADDB__, - "xaddl" : __asm_proxy_XADDL__, - "xaddq" : __asm_proxy_XADDQ__, - "xaddw" : __asm_proxy_XADDW__, - "xchgb" : __asm_proxy_XCHGB__, - "xchgl" : __asm_proxy_XCHGL__, - "xchgq" : __asm_proxy_XCHGQ__, - "xchgw" : __asm_proxy_XCHGW__, - "xgetbv" : __asm_proxy_XGETBV__, - "xlatb" : __asm_proxy_XLATB__, - "xorb" : __asm_proxy_XORB__, - "xorl" : __asm_proxy_XORL__, - "xorpd" : __asm_proxy_XORPD__, - "xorps" : __asm_proxy_XORPS__, - "xorq" : __asm_proxy_XORQ__, - "xorw" : __asm_proxy_XORW__, -} - -func __asm_proxy_ADCB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADCB(v[0], v[1]) - } else { - panic("instruction ADCB takes exactly 2 operands") - } -} - -func __asm_proxy_ADCL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADCL(v[0], v[1]) - } else { - panic("instruction ADCL takes exactly 2 operands") - } -} - -func __asm_proxy_ADCQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADCQ(v[0], v[1]) - } else { - panic("instruction ADCQ takes exactly 2 operands") - } -} - -func __asm_proxy_ADCW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADCW(v[0], v[1]) - } else { - panic("instruction ADCW takes exactly 2 operands") - } -} - -func __asm_proxy_ADCXL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADCXL(v[0], v[1]) - } else { - panic("instruction ADCXL takes exactly 2 operands") - } -} - -func __asm_proxy_ADCXQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADCXQ(v[0], v[1]) - } else { - panic("instruction ADCXQ takes exactly 2 operands") - } -} - -func __asm_proxy_ADDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDB(v[0], v[1]) - } else { - panic("instruction ADDB takes exactly 2 operands") - } -} - -func __asm_proxy_ADDL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDL(v[0], v[1]) - } else { - panic("instruction ADDL takes exactly 2 operands") - } -} - -func __asm_proxy_ADDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDPD(v[0], v[1]) - } else { - panic("instruction ADDPD takes exactly 2 operands") - } -} - -func __asm_proxy_ADDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDPS(v[0], v[1]) - } else { - panic("instruction ADDPS takes exactly 2 operands") - } -} - -func __asm_proxy_ADDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDQ(v[0], v[1]) - } else { - panic("instruction ADDQ takes exactly 2 operands") - } -} - -func __asm_proxy_ADDSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDSD(v[0], v[1]) - } else { - panic("instruction ADDSD takes exactly 2 operands") - } -} - -func __asm_proxy_ADDSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDSS(v[0], v[1]) - } else { - panic("instruction ADDSS takes exactly 2 operands") - } -} - -func __asm_proxy_ADDSUBPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDSUBPD(v[0], v[1]) - } else { - panic("instruction ADDSUBPD takes exactly 2 operands") - } -} - -func __asm_proxy_ADDSUBPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDSUBPS(v[0], v[1]) - } else { - panic("instruction ADDSUBPS takes exactly 2 operands") - } -} - -func __asm_proxy_ADDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADDW(v[0], v[1]) - } else { - panic("instruction ADDW takes exactly 2 operands") - } -} - -func __asm_proxy_ADOXL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADOXL(v[0], v[1]) - } else { - panic("instruction ADOXL takes exactly 2 operands") - } -} - -func __asm_proxy_ADOXQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ADOXQ(v[0], v[1]) - } else { - panic("instruction ADOXQ takes exactly 2 operands") - } -} - -func __asm_proxy_AESDEC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.AESDEC(v[0], v[1]) - } else { - panic("instruction AESDEC takes exactly 2 operands") - } -} - -func __asm_proxy_AESDECLAST__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.AESDECLAST(v[0], v[1]) - } else { - panic("instruction AESDECLAST takes exactly 2 operands") - } -} - -func __asm_proxy_AESENC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.AESENC(v[0], v[1]) - } else { - panic("instruction AESENC takes exactly 2 operands") - } -} - -func __asm_proxy_AESENCLAST__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.AESENCLAST(v[0], v[1]) - } else { - panic("instruction AESENCLAST takes exactly 2 operands") - } -} - -func __asm_proxy_AESIMC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.AESIMC(v[0], v[1]) - } else { - panic("instruction AESIMC takes exactly 2 operands") - } -} - -func __asm_proxy_AESKEYGENASSIST__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.AESKEYGENASSIST(v[0], v[1], v[2]) - } else { - panic("instruction AESKEYGENASSIST takes exactly 3 operands") - } -} - -func __asm_proxy_ANDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ANDB(v[0], v[1]) - } else { - panic("instruction ANDB takes exactly 2 operands") - } -} - -func __asm_proxy_ANDL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ANDL(v[0], v[1]) - } else { - panic("instruction ANDL takes exactly 2 operands") - } -} - -func __asm_proxy_ANDNL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.ANDNL(v[0], v[1], v[2]) - } else { - panic("instruction ANDNL takes exactly 3 operands") - } -} - -func __asm_proxy_ANDNPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ANDNPD(v[0], v[1]) - } else { - panic("instruction ANDNPD takes exactly 2 operands") - } -} - -func __asm_proxy_ANDNPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ANDNPS(v[0], v[1]) - } else { - panic("instruction ANDNPS takes exactly 2 operands") - } -} - -func __asm_proxy_ANDNQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.ANDNQ(v[0], v[1], v[2]) - } else { - panic("instruction ANDNQ takes exactly 3 operands") - } -} - -func __asm_proxy_ANDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ANDPD(v[0], v[1]) - } else { - panic("instruction ANDPD takes exactly 2 operands") - } -} - -func __asm_proxy_ANDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ANDPS(v[0], v[1]) - } else { - panic("instruction ANDPS takes exactly 2 operands") - } -} - -func __asm_proxy_ANDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ANDQ(v[0], v[1]) - } else { - panic("instruction ANDQ takes exactly 2 operands") - } -} - -func __asm_proxy_ANDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ANDW(v[0], v[1]) - } else { - panic("instruction ANDW takes exactly 2 operands") - } -} - -func __asm_proxy_BEXTR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.BEXTR(v[0], v[1], v[2]) - } else { - panic("instruction BEXTR takes exactly 3 operands") - } -} - -func __asm_proxy_BLCFILL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLCFILL(v[0], v[1]) - } else { - panic("instruction BLCFILL takes exactly 2 operands") - } -} - -func __asm_proxy_BLCI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLCI(v[0], v[1]) - } else { - panic("instruction BLCI takes exactly 2 operands") - } -} - -func __asm_proxy_BLCIC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLCIC(v[0], v[1]) - } else { - panic("instruction BLCIC takes exactly 2 operands") - } -} - -func __asm_proxy_BLCMSK__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLCMSK(v[0], v[1]) - } else { - panic("instruction BLCMSK takes exactly 2 operands") - } -} - -func __asm_proxy_BLCS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLCS(v[0], v[1]) - } else { - panic("instruction BLCS takes exactly 2 operands") - } -} - -func __asm_proxy_BLENDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.BLENDPD(v[0], v[1], v[2]) - } else { - panic("instruction BLENDPD takes exactly 3 operands") - } -} - -func __asm_proxy_BLENDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.BLENDPS(v[0], v[1], v[2]) - } else { - panic("instruction BLENDPS takes exactly 3 operands") - } -} - -func __asm_proxy_BLENDVPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.BLENDVPD(v[0], v[1], v[2]) - } else { - panic("instruction BLENDVPD takes exactly 3 operands") - } -} - -func __asm_proxy_BLENDVPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.BLENDVPS(v[0], v[1], v[2]) - } else { - panic("instruction BLENDVPS takes exactly 3 operands") - } -} - -func __asm_proxy_BLSFILL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLSFILL(v[0], v[1]) - } else { - panic("instruction BLSFILL takes exactly 2 operands") - } -} - -func __asm_proxy_BLSI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLSI(v[0], v[1]) - } else { - panic("instruction BLSI takes exactly 2 operands") - } -} - -func __asm_proxy_BLSIC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLSIC(v[0], v[1]) - } else { - panic("instruction BLSIC takes exactly 2 operands") - } -} - -func __asm_proxy_BLSMSK__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLSMSK(v[0], v[1]) - } else { - panic("instruction BLSMSK takes exactly 2 operands") - } -} - -func __asm_proxy_BLSR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BLSR(v[0], v[1]) - } else { - panic("instruction BLSR takes exactly 2 operands") - } -} - -func __asm_proxy_BSFL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BSFL(v[0], v[1]) - } else { - panic("instruction BSFL takes exactly 2 operands") - } -} - -func __asm_proxy_BSFQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BSFQ(v[0], v[1]) - } else { - panic("instruction BSFQ takes exactly 2 operands") - } -} - -func __asm_proxy_BSFW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BSFW(v[0], v[1]) - } else { - panic("instruction BSFW takes exactly 2 operands") - } -} - -func __asm_proxy_BSRL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BSRL(v[0], v[1]) - } else { - panic("instruction BSRL takes exactly 2 operands") - } -} - -func __asm_proxy_BSRQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BSRQ(v[0], v[1]) - } else { - panic("instruction BSRQ takes exactly 2 operands") - } -} - -func __asm_proxy_BSRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BSRW(v[0], v[1]) - } else { - panic("instruction BSRW takes exactly 2 operands") - } -} - -func __asm_proxy_BSWAPL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.BSWAPL(v[0]) - } else { - panic("instruction BSWAPL takes exactly 1 operand") - } -} - -func __asm_proxy_BSWAPQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.BSWAPQ(v[0]) - } else { - panic("instruction BSWAPQ takes exactly 1 operand") - } -} - -func __asm_proxy_BTCL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTCL(v[0], v[1]) - } else { - panic("instruction BTCL takes exactly 2 operands") - } -} - -func __asm_proxy_BTCQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTCQ(v[0], v[1]) - } else { - panic("instruction BTCQ takes exactly 2 operands") - } -} - -func __asm_proxy_BTCW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTCW(v[0], v[1]) - } else { - panic("instruction BTCW takes exactly 2 operands") - } -} - -func __asm_proxy_BTL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTL(v[0], v[1]) - } else { - panic("instruction BTL takes exactly 2 operands") - } -} - -func __asm_proxy_BTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTQ(v[0], v[1]) - } else { - panic("instruction BTQ takes exactly 2 operands") - } -} - -func __asm_proxy_BTRL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTRL(v[0], v[1]) - } else { - panic("instruction BTRL takes exactly 2 operands") - } -} - -func __asm_proxy_BTRQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTRQ(v[0], v[1]) - } else { - panic("instruction BTRQ takes exactly 2 operands") - } -} - -func __asm_proxy_BTRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTRW(v[0], v[1]) - } else { - panic("instruction BTRW takes exactly 2 operands") - } -} - -func __asm_proxy_BTSL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTSL(v[0], v[1]) - } else { - panic("instruction BTSL takes exactly 2 operands") - } -} - -func __asm_proxy_BTSQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTSQ(v[0], v[1]) - } else { - panic("instruction BTSQ takes exactly 2 operands") - } -} - -func __asm_proxy_BTSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTSW(v[0], v[1]) - } else { - panic("instruction BTSW takes exactly 2 operands") - } -} - -func __asm_proxy_BTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.BTW(v[0], v[1]) - } else { - panic("instruction BTW takes exactly 2 operands") - } -} - -func __asm_proxy_BZHI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.BZHI(v[0], v[1], v[2]) - } else { - panic("instruction BZHI takes exactly 3 operands") - } -} - -func __asm_proxy_CALL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.CALL(v[0]) - } else { - panic("instruction CALL takes exactly 1 operand") - } -} - -func __asm_proxy_CALLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.CALLQ(v[0]) - } else { - panic("instruction CALLQ takes exactly 1 operand") - } -} - -func __asm_proxy_CBTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CBTW() - } else { - panic("instruction CBTW takes no operands") - } -} - -func __asm_proxy_CLC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CLC() - } else { - panic("instruction CLC takes no operands") - } -} - -func __asm_proxy_CLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CLD() - } else { - panic("instruction CLD takes no operands") - } -} - -func __asm_proxy_CLFLUSH__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.CLFLUSH(v[0]) - } else { - panic("instruction CLFLUSH takes exactly 1 operand") - } -} - -func __asm_proxy_CLFLUSHOPT__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.CLFLUSHOPT(v[0]) - } else { - panic("instruction CLFLUSHOPT takes exactly 1 operand") - } -} - -func __asm_proxy_CLTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CLTD() - } else { - panic("instruction CLTD takes no operands") - } -} - -func __asm_proxy_CLTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CLTQ() - } else { - panic("instruction CLTQ takes no operands") - } -} - -func __asm_proxy_CLWB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.CLWB(v[0]) - } else { - panic("instruction CLWB takes exactly 1 operand") - } -} - -func __asm_proxy_CLZERO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CLZERO() - } else { - panic("instruction CLZERO takes no operands") - } -} - -func __asm_proxy_CMC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CMC() - } else { - panic("instruction CMC takes no operands") - } -} - -func __asm_proxy_CMOVA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVA(v[0], v[1]) - } else { - panic("instruction CMOVA takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVAE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVAE(v[0], v[1]) - } else { - panic("instruction CMOVAE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVB(v[0], v[1]) - } else { - panic("instruction CMOVB takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVBE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVBE(v[0], v[1]) - } else { - panic("instruction CMOVBE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVC(v[0], v[1]) - } else { - panic("instruction CMOVC takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVE(v[0], v[1]) - } else { - panic("instruction CMOVE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVG__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVG(v[0], v[1]) - } else { - panic("instruction CMOVG takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVGE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVGE(v[0], v[1]) - } else { - panic("instruction CMOVGE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVL(v[0], v[1]) - } else { - panic("instruction CMOVL takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVLE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVLE(v[0], v[1]) - } else { - panic("instruction CMOVLE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNA(v[0], v[1]) - } else { - panic("instruction CMOVNA takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNAE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNAE(v[0], v[1]) - } else { - panic("instruction CMOVNAE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNB(v[0], v[1]) - } else { - panic("instruction CMOVNB takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNBE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNBE(v[0], v[1]) - } else { - panic("instruction CMOVNBE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNC(v[0], v[1]) - } else { - panic("instruction CMOVNC takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNE(v[0], v[1]) - } else { - panic("instruction CMOVNE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNG__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNG(v[0], v[1]) - } else { - panic("instruction CMOVNG takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNGE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNGE(v[0], v[1]) - } else { - panic("instruction CMOVNGE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNL(v[0], v[1]) - } else { - panic("instruction CMOVNL takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNLE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNLE(v[0], v[1]) - } else { - panic("instruction CMOVNLE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNO(v[0], v[1]) - } else { - panic("instruction CMOVNO takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNP(v[0], v[1]) - } else { - panic("instruction CMOVNP takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNS(v[0], v[1]) - } else { - panic("instruction CMOVNS takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVNZ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVNZ(v[0], v[1]) - } else { - panic("instruction CMOVNZ takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVO(v[0], v[1]) - } else { - panic("instruction CMOVO takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVP(v[0], v[1]) - } else { - panic("instruction CMOVP takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVPE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVPE(v[0], v[1]) - } else { - panic("instruction CMOVPE takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVPO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVPO(v[0], v[1]) - } else { - panic("instruction CMOVPO takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVS(v[0], v[1]) - } else { - panic("instruction CMOVS takes exactly 2 operands") - } -} - -func __asm_proxy_CMOVZ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMOVZ(v[0], v[1]) - } else { - panic("instruction CMOVZ takes exactly 2 operands") - } -} - -func __asm_proxy_CMPB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMPB(v[0], v[1]) - } else { - panic("instruction CMPB takes exactly 2 operands") - } -} - -func __asm_proxy_CMPL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMPL(v[0], v[1]) - } else { - panic("instruction CMPL takes exactly 2 operands") - } -} - -func __asm_proxy_CMPPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.CMPPD(v[0], v[1], v[2]) - } else { - panic("instruction CMPPD takes exactly 3 operands") - } -} - -func __asm_proxy_CMPPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.CMPPS(v[0], v[1], v[2]) - } else { - panic("instruction CMPPS takes exactly 3 operands") - } -} - -func __asm_proxy_CMPQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMPQ(v[0], v[1]) - } else { - panic("instruction CMPQ takes exactly 2 operands") - } -} - -func __asm_proxy_CMPSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.CMPSD(v[0], v[1], v[2]) - } else { - panic("instruction CMPSD takes exactly 3 operands") - } -} - -func __asm_proxy_CMPSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.CMPSS(v[0], v[1], v[2]) - } else { - panic("instruction CMPSS takes exactly 3 operands") - } -} - -func __asm_proxy_CMPW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMPW(v[0], v[1]) - } else { - panic("instruction CMPW takes exactly 2 operands") - } -} - -func __asm_proxy_CMPXCHG16B__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.CMPXCHG16B(v[0]) - } else { - panic("instruction CMPXCHG16B takes exactly 1 operand") - } -} - -func __asm_proxy_CMPXCHG8B__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.CMPXCHG8B(v[0]) - } else { - panic("instruction CMPXCHG8B takes exactly 1 operand") - } -} - -func __asm_proxy_CMPXCHGB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMPXCHGB(v[0], v[1]) - } else { - panic("instruction CMPXCHGB takes exactly 2 operands") - } -} - -func __asm_proxy_CMPXCHGL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMPXCHGL(v[0], v[1]) - } else { - panic("instruction CMPXCHGL takes exactly 2 operands") - } -} - -func __asm_proxy_CMPXCHGQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMPXCHGQ(v[0], v[1]) - } else { - panic("instruction CMPXCHGQ takes exactly 2 operands") - } -} - -func __asm_proxy_CMPXCHGW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CMPXCHGW(v[0], v[1]) - } else { - panic("instruction CMPXCHGW takes exactly 2 operands") - } -} - -func __asm_proxy_COMISD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.COMISD(v[0], v[1]) - } else { - panic("instruction COMISD takes exactly 2 operands") - } -} - -func __asm_proxy_COMISS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.COMISS(v[0], v[1]) - } else { - panic("instruction COMISS takes exactly 2 operands") - } -} - -func __asm_proxy_CPUID__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CPUID() - } else { - panic("instruction CPUID takes no operands") - } -} - -func __asm_proxy_CQTO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CQTO() - } else { - panic("instruction CQTO takes no operands") - } -} - -func __asm_proxy_CRC32B__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CRC32B(v[0], v[1]) - } else { - panic("instruction CRC32B takes exactly 2 operands") - } -} - -func __asm_proxy_CRC32L__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CRC32L(v[0], v[1]) - } else { - panic("instruction CRC32L takes exactly 2 operands") - } -} - -func __asm_proxy_CRC32Q__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CRC32Q(v[0], v[1]) - } else { - panic("instruction CRC32Q takes exactly 2 operands") - } -} - -func __asm_proxy_CRC32W__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CRC32W(v[0], v[1]) - } else { - panic("instruction CRC32W takes exactly 2 operands") - } -} - -func __asm_proxy_CVTDQ2PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTDQ2PD(v[0], v[1]) - } else { - panic("instruction CVTDQ2PD takes exactly 2 operands") - } -} - -func __asm_proxy_CVTDQ2PS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTDQ2PS(v[0], v[1]) - } else { - panic("instruction CVTDQ2PS takes exactly 2 operands") - } -} - -func __asm_proxy_CVTPD2DQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTPD2DQ(v[0], v[1]) - } else { - panic("instruction CVTPD2DQ takes exactly 2 operands") - } -} - -func __asm_proxy_CVTPD2PI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTPD2PI(v[0], v[1]) - } else { - panic("instruction CVTPD2PI takes exactly 2 operands") - } -} - -func __asm_proxy_CVTPD2PS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTPD2PS(v[0], v[1]) - } else { - panic("instruction CVTPD2PS takes exactly 2 operands") - } -} - -func __asm_proxy_CVTPI2PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTPI2PD(v[0], v[1]) - } else { - panic("instruction CVTPI2PD takes exactly 2 operands") - } -} - -func __asm_proxy_CVTPI2PS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTPI2PS(v[0], v[1]) - } else { - panic("instruction CVTPI2PS takes exactly 2 operands") - } -} - -func __asm_proxy_CVTPS2DQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTPS2DQ(v[0], v[1]) - } else { - panic("instruction CVTPS2DQ takes exactly 2 operands") - } -} - -func __asm_proxy_CVTPS2PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTPS2PD(v[0], v[1]) - } else { - panic("instruction CVTPS2PD takes exactly 2 operands") - } -} - -func __asm_proxy_CVTPS2PI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTPS2PI(v[0], v[1]) - } else { - panic("instruction CVTPS2PI takes exactly 2 operands") - } -} - -func __asm_proxy_CVTSD2SI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTSD2SI(v[0], v[1]) - } else { - panic("instruction CVTSD2SI takes exactly 2 operands") - } -} - -func __asm_proxy_CVTSD2SS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTSD2SS(v[0], v[1]) - } else { - panic("instruction CVTSD2SS takes exactly 2 operands") - } -} - -func __asm_proxy_CVTSI2SD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTSI2SD(v[0], v[1]) - } else { - panic("instruction CVTSI2SD takes exactly 2 operands") - } -} - -func __asm_proxy_CVTSI2SS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTSI2SS(v[0], v[1]) - } else { - panic("instruction CVTSI2SS takes exactly 2 operands") - } -} - -func __asm_proxy_CVTSS2SD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTSS2SD(v[0], v[1]) - } else { - panic("instruction CVTSS2SD takes exactly 2 operands") - } -} - -func __asm_proxy_CVTSS2SI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTSS2SI(v[0], v[1]) - } else { - panic("instruction CVTSS2SI takes exactly 2 operands") - } -} - -func __asm_proxy_CVTTPD2DQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTTPD2DQ(v[0], v[1]) - } else { - panic("instruction CVTTPD2DQ takes exactly 2 operands") - } -} - -func __asm_proxy_CVTTPD2PI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTTPD2PI(v[0], v[1]) - } else { - panic("instruction CVTTPD2PI takes exactly 2 operands") - } -} - -func __asm_proxy_CVTTPS2DQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTTPS2DQ(v[0], v[1]) - } else { - panic("instruction CVTTPS2DQ takes exactly 2 operands") - } -} - -func __asm_proxy_CVTTPS2PI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTTPS2PI(v[0], v[1]) - } else { - panic("instruction CVTTPS2PI takes exactly 2 operands") - } -} - -func __asm_proxy_CVTTSD2SI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTTSD2SI(v[0], v[1]) - } else { - panic("instruction CVTTSD2SI takes exactly 2 operands") - } -} - -func __asm_proxy_CVTTSS2SI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.CVTTSS2SI(v[0], v[1]) - } else { - panic("instruction CVTTSS2SI takes exactly 2 operands") - } -} - -func __asm_proxy_CWTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CWTD() - } else { - panic("instruction CWTD takes no operands") - } -} - -func __asm_proxy_CWTL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.CWTL() - } else { - panic("instruction CWTL takes no operands") - } -} - -func __asm_proxy_DECB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.DECB(v[0]) - } else { - panic("instruction DECB takes exactly 1 operand") - } -} - -func __asm_proxy_DECL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.DECL(v[0]) - } else { - panic("instruction DECL takes exactly 1 operand") - } -} - -func __asm_proxy_DECQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.DECQ(v[0]) - } else { - panic("instruction DECQ takes exactly 1 operand") - } -} - -func __asm_proxy_DECW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.DECW(v[0]) - } else { - panic("instruction DECW takes exactly 1 operand") - } -} - -func __asm_proxy_DIVB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.DIVB(v[0]) - } else { - panic("instruction DIVB takes exactly 1 operand") - } -} - -func __asm_proxy_DIVL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.DIVL(v[0]) - } else { - panic("instruction DIVL takes exactly 1 operand") - } -} - -func __asm_proxy_DIVPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.DIVPD(v[0], v[1]) - } else { - panic("instruction DIVPD takes exactly 2 operands") - } -} - -func __asm_proxy_DIVPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.DIVPS(v[0], v[1]) - } else { - panic("instruction DIVPS takes exactly 2 operands") - } -} - -func __asm_proxy_DIVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.DIVQ(v[0]) - } else { - panic("instruction DIVQ takes exactly 1 operand") - } -} - -func __asm_proxy_DIVSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.DIVSD(v[0], v[1]) - } else { - panic("instruction DIVSD takes exactly 2 operands") - } -} - -func __asm_proxy_DIVSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.DIVSS(v[0], v[1]) - } else { - panic("instruction DIVSS takes exactly 2 operands") - } -} - -func __asm_proxy_DIVW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.DIVW(v[0]) - } else { - panic("instruction DIVW takes exactly 1 operand") - } -} - -func __asm_proxy_DPPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.DPPD(v[0], v[1], v[2]) - } else { - panic("instruction DPPD takes exactly 3 operands") - } -} - -func __asm_proxy_DPPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.DPPS(v[0], v[1], v[2]) - } else { - panic("instruction DPPS takes exactly 3 operands") - } -} - -func __asm_proxy_EMMS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.EMMS() - } else { - panic("instruction EMMS takes no operands") - } -} - -func __asm_proxy_EXTRACTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.EXTRACTPS(v[0], v[1], v[2]) - } else { - panic("instruction EXTRACTPS takes exactly 3 operands") - } -} - -func __asm_proxy_EXTRQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.EXTRQ(v[0], v[1]) - case 3 : return p.EXTRQ(v[0], v[1], v[2]) - default : panic("instruction EXTRQ takes 2 or 3 operands") - } -} - -func __asm_proxy_FEMMS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.FEMMS() - } else { - panic("instruction FEMMS takes no operands") - } -} - -func __asm_proxy_HADDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.HADDPD(v[0], v[1]) - } else { - panic("instruction HADDPD takes exactly 2 operands") - } -} - -func __asm_proxy_HADDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.HADDPS(v[0], v[1]) - } else { - panic("instruction HADDPS takes exactly 2 operands") - } -} - -func __asm_proxy_HSUBPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.HSUBPD(v[0], v[1]) - } else { - panic("instruction HSUBPD takes exactly 2 operands") - } -} - -func __asm_proxy_HSUBPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.HSUBPS(v[0], v[1]) - } else { - panic("instruction HSUBPS takes exactly 2 operands") - } -} - -func __asm_proxy_IDIVB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.IDIVB(v[0]) - } else { - panic("instruction IDIVB takes exactly 1 operand") - } -} - -func __asm_proxy_IDIVL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.IDIVL(v[0]) - } else { - panic("instruction IDIVL takes exactly 1 operand") - } -} - -func __asm_proxy_IDIVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.IDIVQ(v[0]) - } else { - panic("instruction IDIVQ takes exactly 1 operand") - } -} - -func __asm_proxy_IDIVW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.IDIVW(v[0]) - } else { - panic("instruction IDIVW takes exactly 1 operand") - } -} - -func __asm_proxy_IMULB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.IMULB(v[0]) - } else { - panic("instruction IMULB takes exactly 1 operand") - } -} - -func __asm_proxy_IMULL__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 1 : return p.IMULL(v[0]) - case 2 : return p.IMULL(v[0], v[1]) - case 3 : return p.IMULL(v[0], v[1], v[2]) - default : panic("instruction IMULL takes 1 or 2 or 3 operands") - } -} - -func __asm_proxy_IMULQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 1 : return p.IMULQ(v[0]) - case 2 : return p.IMULQ(v[0], v[1]) - case 3 : return p.IMULQ(v[0], v[1], v[2]) - default : panic("instruction IMULQ takes 1 or 2 or 3 operands") - } -} - -func __asm_proxy_IMULW__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 1 : return p.IMULW(v[0]) - case 2 : return p.IMULW(v[0], v[1]) - case 3 : return p.IMULW(v[0], v[1], v[2]) - default : panic("instruction IMULW takes 1 or 2 or 3 operands") - } -} - -func __asm_proxy_INCB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.INCB(v[0]) - } else { - panic("instruction INCB takes exactly 1 operand") - } -} - -func __asm_proxy_INCL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.INCL(v[0]) - } else { - panic("instruction INCL takes exactly 1 operand") - } -} - -func __asm_proxy_INCQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.INCQ(v[0]) - } else { - panic("instruction INCQ takes exactly 1 operand") - } -} - -func __asm_proxy_INCW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.INCW(v[0]) - } else { - panic("instruction INCW takes exactly 1 operand") - } -} - -func __asm_proxy_INSERTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.INSERTPS(v[0], v[1], v[2]) - } else { - panic("instruction INSERTPS takes exactly 3 operands") - } -} - -func __asm_proxy_INSERTQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.INSERTQ(v[0], v[1]) - case 4 : return p.INSERTQ(v[0], v[1], v[2], v[3]) - default : panic("instruction INSERTQ takes 2 or 4 operands") - } -} - -func __asm_proxy_INT__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.INT(v[0]) - } else { - panic("instruction INT takes exactly 1 operand") - } -} - -func __asm_proxy_JA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JA(v[0]) - } else { - panic("instruction JA takes exactly 1 operand") - } -} - -func __asm_proxy_JAE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JAE(v[0]) - } else { - panic("instruction JAE takes exactly 1 operand") - } -} - -func __asm_proxy_JB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JB(v[0]) - } else { - panic("instruction JB takes exactly 1 operand") - } -} - -func __asm_proxy_JBE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JBE(v[0]) - } else { - panic("instruction JBE takes exactly 1 operand") - } -} - -func __asm_proxy_JC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JC(v[0]) - } else { - panic("instruction JC takes exactly 1 operand") - } -} - -func __asm_proxy_JE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JE(v[0]) - } else { - panic("instruction JE takes exactly 1 operand") - } -} - -func __asm_proxy_JECXZ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JECXZ(v[0]) - } else { - panic("instruction JECXZ takes exactly 1 operand") - } -} - -func __asm_proxy_JG__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JG(v[0]) - } else { - panic("instruction JG takes exactly 1 operand") - } -} - -func __asm_proxy_JGE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JGE(v[0]) - } else { - panic("instruction JGE takes exactly 1 operand") - } -} - -func __asm_proxy_JL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JL(v[0]) - } else { - panic("instruction JL takes exactly 1 operand") - } -} - -func __asm_proxy_JLE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JLE(v[0]) - } else { - panic("instruction JLE takes exactly 1 operand") - } -} - -func __asm_proxy_JMP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JMP(v[0]) - } else { - panic("instruction JMP takes exactly 1 operand") - } -} - -func __asm_proxy_JMPQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JMPQ(v[0]) - } else { - panic("instruction JMPQ takes exactly 1 operand") - } -} - -func __asm_proxy_JNA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNA(v[0]) - } else { - panic("instruction JNA takes exactly 1 operand") - } -} - -func __asm_proxy_JNAE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNAE(v[0]) - } else { - panic("instruction JNAE takes exactly 1 operand") - } -} - -func __asm_proxy_JNB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNB(v[0]) - } else { - panic("instruction JNB takes exactly 1 operand") - } -} - -func __asm_proxy_JNBE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNBE(v[0]) - } else { - panic("instruction JNBE takes exactly 1 operand") - } -} - -func __asm_proxy_JNC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNC(v[0]) - } else { - panic("instruction JNC takes exactly 1 operand") - } -} - -func __asm_proxy_JNE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNE(v[0]) - } else { - panic("instruction JNE takes exactly 1 operand") - } -} - -func __asm_proxy_JNG__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNG(v[0]) - } else { - panic("instruction JNG takes exactly 1 operand") - } -} - -func __asm_proxy_JNGE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNGE(v[0]) - } else { - panic("instruction JNGE takes exactly 1 operand") - } -} - -func __asm_proxy_JNL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNL(v[0]) - } else { - panic("instruction JNL takes exactly 1 operand") - } -} - -func __asm_proxy_JNLE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNLE(v[0]) - } else { - panic("instruction JNLE takes exactly 1 operand") - } -} - -func __asm_proxy_JNO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNO(v[0]) - } else { - panic("instruction JNO takes exactly 1 operand") - } -} - -func __asm_proxy_JNP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNP(v[0]) - } else { - panic("instruction JNP takes exactly 1 operand") - } -} - -func __asm_proxy_JNS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNS(v[0]) - } else { - panic("instruction JNS takes exactly 1 operand") - } -} - -func __asm_proxy_JNZ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JNZ(v[0]) - } else { - panic("instruction JNZ takes exactly 1 operand") - } -} - -func __asm_proxy_JO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JO(v[0]) - } else { - panic("instruction JO takes exactly 1 operand") - } -} - -func __asm_proxy_JP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JP(v[0]) - } else { - panic("instruction JP takes exactly 1 operand") - } -} - -func __asm_proxy_JPE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JPE(v[0]) - } else { - panic("instruction JPE takes exactly 1 operand") - } -} - -func __asm_proxy_JPO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JPO(v[0]) - } else { - panic("instruction JPO takes exactly 1 operand") - } -} - -func __asm_proxy_JRCXZ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JRCXZ(v[0]) - } else { - panic("instruction JRCXZ takes exactly 1 operand") - } -} - -func __asm_proxy_JS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JS(v[0]) - } else { - panic("instruction JS takes exactly 1 operand") - } -} - -func __asm_proxy_JZ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.JZ(v[0]) - } else { - panic("instruction JZ takes exactly 1 operand") - } -} - -func __asm_proxy_KADDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KADDB(v[0], v[1], v[2]) - } else { - panic("instruction KADDB takes exactly 3 operands") - } -} - -func __asm_proxy_KADDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KADDD(v[0], v[1], v[2]) - } else { - panic("instruction KADDD takes exactly 3 operands") - } -} - -func __asm_proxy_KADDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KADDQ(v[0], v[1], v[2]) - } else { - panic("instruction KADDQ takes exactly 3 operands") - } -} - -func __asm_proxy_KADDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KADDW(v[0], v[1], v[2]) - } else { - panic("instruction KADDW takes exactly 3 operands") - } -} - -func __asm_proxy_KANDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KANDB(v[0], v[1], v[2]) - } else { - panic("instruction KANDB takes exactly 3 operands") - } -} - -func __asm_proxy_KANDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KANDD(v[0], v[1], v[2]) - } else { - panic("instruction KANDD takes exactly 3 operands") - } -} - -func __asm_proxy_KANDNB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KANDNB(v[0], v[1], v[2]) - } else { - panic("instruction KANDNB takes exactly 3 operands") - } -} - -func __asm_proxy_KANDND__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KANDND(v[0], v[1], v[2]) - } else { - panic("instruction KANDND takes exactly 3 operands") - } -} - -func __asm_proxy_KANDNQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KANDNQ(v[0], v[1], v[2]) - } else { - panic("instruction KANDNQ takes exactly 3 operands") - } -} - -func __asm_proxy_KANDNW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KANDNW(v[0], v[1], v[2]) - } else { - panic("instruction KANDNW takes exactly 3 operands") - } -} - -func __asm_proxy_KANDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KANDQ(v[0], v[1], v[2]) - } else { - panic("instruction KANDQ takes exactly 3 operands") - } -} - -func __asm_proxy_KANDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KANDW(v[0], v[1], v[2]) - } else { - panic("instruction KANDW takes exactly 3 operands") - } -} - -func __asm_proxy_KMOVB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KMOVB(v[0], v[1]) - } else { - panic("instruction KMOVB takes exactly 2 operands") - } -} - -func __asm_proxy_KMOVD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KMOVD(v[0], v[1]) - } else { - panic("instruction KMOVD takes exactly 2 operands") - } -} - -func __asm_proxy_KMOVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KMOVQ(v[0], v[1]) - } else { - panic("instruction KMOVQ takes exactly 2 operands") - } -} - -func __asm_proxy_KMOVW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KMOVW(v[0], v[1]) - } else { - panic("instruction KMOVW takes exactly 2 operands") - } -} - -func __asm_proxy_KNOTB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KNOTB(v[0], v[1]) - } else { - panic("instruction KNOTB takes exactly 2 operands") - } -} - -func __asm_proxy_KNOTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KNOTD(v[0], v[1]) - } else { - panic("instruction KNOTD takes exactly 2 operands") - } -} - -func __asm_proxy_KNOTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KNOTQ(v[0], v[1]) - } else { - panic("instruction KNOTQ takes exactly 2 operands") - } -} - -func __asm_proxy_KNOTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KNOTW(v[0], v[1]) - } else { - panic("instruction KNOTW takes exactly 2 operands") - } -} - -func __asm_proxy_KORB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KORB(v[0], v[1], v[2]) - } else { - panic("instruction KORB takes exactly 3 operands") - } -} - -func __asm_proxy_KORD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KORD(v[0], v[1], v[2]) - } else { - panic("instruction KORD takes exactly 3 operands") - } -} - -func __asm_proxy_KORQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KORQ(v[0], v[1], v[2]) - } else { - panic("instruction KORQ takes exactly 3 operands") - } -} - -func __asm_proxy_KORTESTB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KORTESTB(v[0], v[1]) - } else { - panic("instruction KORTESTB takes exactly 2 operands") - } -} - -func __asm_proxy_KORTESTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KORTESTD(v[0], v[1]) - } else { - panic("instruction KORTESTD takes exactly 2 operands") - } -} - -func __asm_proxy_KORTESTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KORTESTQ(v[0], v[1]) - } else { - panic("instruction KORTESTQ takes exactly 2 operands") - } -} - -func __asm_proxy_KORTESTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KORTESTW(v[0], v[1]) - } else { - panic("instruction KORTESTW takes exactly 2 operands") - } -} - -func __asm_proxy_KORW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KORW(v[0], v[1], v[2]) - } else { - panic("instruction KORW takes exactly 3 operands") - } -} - -func __asm_proxy_KSHIFTLB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KSHIFTLB(v[0], v[1], v[2]) - } else { - panic("instruction KSHIFTLB takes exactly 3 operands") - } -} - -func __asm_proxy_KSHIFTLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KSHIFTLD(v[0], v[1], v[2]) - } else { - panic("instruction KSHIFTLD takes exactly 3 operands") - } -} - -func __asm_proxy_KSHIFTLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KSHIFTLQ(v[0], v[1], v[2]) - } else { - panic("instruction KSHIFTLQ takes exactly 3 operands") - } -} - -func __asm_proxy_KSHIFTLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KSHIFTLW(v[0], v[1], v[2]) - } else { - panic("instruction KSHIFTLW takes exactly 3 operands") - } -} - -func __asm_proxy_KSHIFTRB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KSHIFTRB(v[0], v[1], v[2]) - } else { - panic("instruction KSHIFTRB takes exactly 3 operands") - } -} - -func __asm_proxy_KSHIFTRD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KSHIFTRD(v[0], v[1], v[2]) - } else { - panic("instruction KSHIFTRD takes exactly 3 operands") - } -} - -func __asm_proxy_KSHIFTRQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KSHIFTRQ(v[0], v[1], v[2]) - } else { - panic("instruction KSHIFTRQ takes exactly 3 operands") - } -} - -func __asm_proxy_KSHIFTRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KSHIFTRW(v[0], v[1], v[2]) - } else { - panic("instruction KSHIFTRW takes exactly 3 operands") - } -} - -func __asm_proxy_KTESTB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KTESTB(v[0], v[1]) - } else { - panic("instruction KTESTB takes exactly 2 operands") - } -} - -func __asm_proxy_KTESTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KTESTD(v[0], v[1]) - } else { - panic("instruction KTESTD takes exactly 2 operands") - } -} - -func __asm_proxy_KTESTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KTESTQ(v[0], v[1]) - } else { - panic("instruction KTESTQ takes exactly 2 operands") - } -} - -func __asm_proxy_KTESTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.KTESTW(v[0], v[1]) - } else { - panic("instruction KTESTW takes exactly 2 operands") - } -} - -func __asm_proxy_KUNPCKBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KUNPCKBW(v[0], v[1], v[2]) - } else { - panic("instruction KUNPCKBW takes exactly 3 operands") - } -} - -func __asm_proxy_KUNPCKDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KUNPCKDQ(v[0], v[1], v[2]) - } else { - panic("instruction KUNPCKDQ takes exactly 3 operands") - } -} - -func __asm_proxy_KUNPCKWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KUNPCKWD(v[0], v[1], v[2]) - } else { - panic("instruction KUNPCKWD takes exactly 3 operands") - } -} - -func __asm_proxy_KXNORB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KXNORB(v[0], v[1], v[2]) - } else { - panic("instruction KXNORB takes exactly 3 operands") - } -} - -func __asm_proxy_KXNORD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KXNORD(v[0], v[1], v[2]) - } else { - panic("instruction KXNORD takes exactly 3 operands") - } -} - -func __asm_proxy_KXNORQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KXNORQ(v[0], v[1], v[2]) - } else { - panic("instruction KXNORQ takes exactly 3 operands") - } -} - -func __asm_proxy_KXNORW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KXNORW(v[0], v[1], v[2]) - } else { - panic("instruction KXNORW takes exactly 3 operands") - } -} - -func __asm_proxy_KXORB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KXORB(v[0], v[1], v[2]) - } else { - panic("instruction KXORB takes exactly 3 operands") - } -} - -func __asm_proxy_KXORD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KXORD(v[0], v[1], v[2]) - } else { - panic("instruction KXORD takes exactly 3 operands") - } -} - -func __asm_proxy_KXORQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KXORQ(v[0], v[1], v[2]) - } else { - panic("instruction KXORQ takes exactly 3 operands") - } -} - -func __asm_proxy_KXORW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.KXORW(v[0], v[1], v[2]) - } else { - panic("instruction KXORW takes exactly 3 operands") - } -} - -func __asm_proxy_LDDQU__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.LDDQU(v[0], v[1]) - } else { - panic("instruction LDDQU takes exactly 2 operands") - } -} - -func __asm_proxy_LDMXCSR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.LDMXCSR(v[0]) - } else { - panic("instruction LDMXCSR takes exactly 1 operand") - } -} - -func __asm_proxy_LEAL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.LEAL(v[0], v[1]) - } else { - panic("instruction LEAL takes exactly 2 operands") - } -} - -func __asm_proxy_LEAQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.LEAQ(v[0], v[1]) - } else { - panic("instruction LEAQ takes exactly 2 operands") - } -} - -func __asm_proxy_LEAW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.LEAW(v[0], v[1]) - } else { - panic("instruction LEAW takes exactly 2 operands") - } -} - -func __asm_proxy_LFENCE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.LFENCE() - } else { - panic("instruction LFENCE takes no operands") - } -} - -func __asm_proxy_LZCNTL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.LZCNTL(v[0], v[1]) - } else { - panic("instruction LZCNTL takes exactly 2 operands") - } -} - -func __asm_proxy_LZCNTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.LZCNTQ(v[0], v[1]) - } else { - panic("instruction LZCNTQ takes exactly 2 operands") - } -} - -func __asm_proxy_LZCNTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.LZCNTW(v[0], v[1]) - } else { - panic("instruction LZCNTW takes exactly 2 operands") - } -} - -func __asm_proxy_MASKMOVDQU__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MASKMOVDQU(v[0], v[1]) - } else { - panic("instruction MASKMOVDQU takes exactly 2 operands") - } -} - -func __asm_proxy_MASKMOVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MASKMOVQ(v[0], v[1]) - } else { - panic("instruction MASKMOVQ takes exactly 2 operands") - } -} - -func __asm_proxy_MAXPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MAXPD(v[0], v[1]) - } else { - panic("instruction MAXPD takes exactly 2 operands") - } -} - -func __asm_proxy_MAXPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MAXPS(v[0], v[1]) - } else { - panic("instruction MAXPS takes exactly 2 operands") - } -} - -func __asm_proxy_MAXSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MAXSD(v[0], v[1]) - } else { - panic("instruction MAXSD takes exactly 2 operands") - } -} - -func __asm_proxy_MAXSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MAXSS(v[0], v[1]) - } else { - panic("instruction MAXSS takes exactly 2 operands") - } -} - -func __asm_proxy_MFENCE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.MFENCE() - } else { - panic("instruction MFENCE takes no operands") - } -} - -func __asm_proxy_MINPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MINPD(v[0], v[1]) - } else { - panic("instruction MINPD takes exactly 2 operands") - } -} - -func __asm_proxy_MINPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MINPS(v[0], v[1]) - } else { - panic("instruction MINPS takes exactly 2 operands") - } -} - -func __asm_proxy_MINSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MINSD(v[0], v[1]) - } else { - panic("instruction MINSD takes exactly 2 operands") - } -} - -func __asm_proxy_MINSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MINSS(v[0], v[1]) - } else { - panic("instruction MINSS takes exactly 2 operands") - } -} - -func __asm_proxy_MONITOR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.MONITOR() - } else { - panic("instruction MONITOR takes no operands") - } -} - -func __asm_proxy_MONITORX__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.MONITORX() - } else { - panic("instruction MONITORX takes no operands") - } -} - -func __asm_proxy_MOVAPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVAPD(v[0], v[1]) - } else { - panic("instruction MOVAPD takes exactly 2 operands") - } -} - -func __asm_proxy_MOVAPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVAPS(v[0], v[1]) - } else { - panic("instruction MOVAPS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVB(v[0], v[1]) - } else { - panic("instruction MOVB takes exactly 2 operands") - } -} - -func __asm_proxy_MOVBEL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVBEL(v[0], v[1]) - } else { - panic("instruction MOVBEL takes exactly 2 operands") - } -} - -func __asm_proxy_MOVBEQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVBEQ(v[0], v[1]) - } else { - panic("instruction MOVBEQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVBEW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVBEW(v[0], v[1]) - } else { - panic("instruction MOVBEW takes exactly 2 operands") - } -} - -func __asm_proxy_MOVD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVD(v[0], v[1]) - } else { - panic("instruction MOVD takes exactly 2 operands") - } -} - -func __asm_proxy_MOVDDUP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVDDUP(v[0], v[1]) - } else { - panic("instruction MOVDDUP takes exactly 2 operands") - } -} - -func __asm_proxy_MOVDQ2Q__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVDQ2Q(v[0], v[1]) - } else { - panic("instruction MOVDQ2Q takes exactly 2 operands") - } -} - -func __asm_proxy_MOVDQA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVDQA(v[0], v[1]) - } else { - panic("instruction MOVDQA takes exactly 2 operands") - } -} - -func __asm_proxy_MOVDQU__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVDQU(v[0], v[1]) - } else { - panic("instruction MOVDQU takes exactly 2 operands") - } -} - -func __asm_proxy_MOVHLPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVHLPS(v[0], v[1]) - } else { - panic("instruction MOVHLPS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVHPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVHPD(v[0], v[1]) - } else { - panic("instruction MOVHPD takes exactly 2 operands") - } -} - -func __asm_proxy_MOVHPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVHPS(v[0], v[1]) - } else { - panic("instruction MOVHPS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVL(v[0], v[1]) - } else { - panic("instruction MOVL takes exactly 2 operands") - } -} - -func __asm_proxy_MOVLHPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVLHPS(v[0], v[1]) - } else { - panic("instruction MOVLHPS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVLPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVLPD(v[0], v[1]) - } else { - panic("instruction MOVLPD takes exactly 2 operands") - } -} - -func __asm_proxy_MOVLPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVLPS(v[0], v[1]) - } else { - panic("instruction MOVLPS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVMSKPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVMSKPD(v[0], v[1]) - } else { - panic("instruction MOVMSKPD takes exactly 2 operands") - } -} - -func __asm_proxy_MOVMSKPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVMSKPS(v[0], v[1]) - } else { - panic("instruction MOVMSKPS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVNTDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVNTDQ(v[0], v[1]) - } else { - panic("instruction MOVNTDQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVNTDQA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVNTDQA(v[0], v[1]) - } else { - panic("instruction MOVNTDQA takes exactly 2 operands") - } -} - -func __asm_proxy_MOVNTIL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVNTIL(v[0], v[1]) - } else { - panic("instruction MOVNTIL takes exactly 2 operands") - } -} - -func __asm_proxy_MOVNTIQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVNTIQ(v[0], v[1]) - } else { - panic("instruction MOVNTIQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVNTPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVNTPD(v[0], v[1]) - } else { - panic("instruction MOVNTPD takes exactly 2 operands") - } -} - -func __asm_proxy_MOVNTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVNTPS(v[0], v[1]) - } else { - panic("instruction MOVNTPS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVNTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVNTQ(v[0], v[1]) - } else { - panic("instruction MOVNTQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVNTSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVNTSD(v[0], v[1]) - } else { - panic("instruction MOVNTSD takes exactly 2 operands") - } -} - -func __asm_proxy_MOVNTSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVNTSS(v[0], v[1]) - } else { - panic("instruction MOVNTSS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVQ(v[0], v[1]) - } else { - panic("instruction MOVQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVQ2DQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVQ2DQ(v[0], v[1]) - } else { - panic("instruction MOVQ2DQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSBL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSBL(v[0], v[1]) - } else { - panic("instruction MOVSBL takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSBQ(v[0], v[1]) - } else { - panic("instruction MOVSBQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSBW(v[0], v[1]) - } else { - panic("instruction MOVSBW takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSD(v[0], v[1]) - } else { - panic("instruction MOVSD takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSHDUP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSHDUP(v[0], v[1]) - } else { - panic("instruction MOVSHDUP takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSLDUP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSLDUP(v[0], v[1]) - } else { - panic("instruction MOVSLDUP takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSLQ(v[0], v[1]) - } else { - panic("instruction MOVSLQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSS(v[0], v[1]) - } else { - panic("instruction MOVSS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSWL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSWL(v[0], v[1]) - } else { - panic("instruction MOVSWL takes exactly 2 operands") - } -} - -func __asm_proxy_MOVSWQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVSWQ(v[0], v[1]) - } else { - panic("instruction MOVSWQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVUPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVUPD(v[0], v[1]) - } else { - panic("instruction MOVUPD takes exactly 2 operands") - } -} - -func __asm_proxy_MOVUPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVUPS(v[0], v[1]) - } else { - panic("instruction MOVUPS takes exactly 2 operands") - } -} - -func __asm_proxy_MOVW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVW(v[0], v[1]) - } else { - panic("instruction MOVW takes exactly 2 operands") - } -} - -func __asm_proxy_MOVZBL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVZBL(v[0], v[1]) - } else { - panic("instruction MOVZBL takes exactly 2 operands") - } -} - -func __asm_proxy_MOVZBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVZBQ(v[0], v[1]) - } else { - panic("instruction MOVZBQ takes exactly 2 operands") - } -} - -func __asm_proxy_MOVZBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVZBW(v[0], v[1]) - } else { - panic("instruction MOVZBW takes exactly 2 operands") - } -} - -func __asm_proxy_MOVZWL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVZWL(v[0], v[1]) - } else { - panic("instruction MOVZWL takes exactly 2 operands") - } -} - -func __asm_proxy_MOVZWQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MOVZWQ(v[0], v[1]) - } else { - panic("instruction MOVZWQ takes exactly 2 operands") - } -} - -func __asm_proxy_MPSADBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.MPSADBW(v[0], v[1], v[2]) - } else { - panic("instruction MPSADBW takes exactly 3 operands") - } -} - -func __asm_proxy_MULB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.MULB(v[0]) - } else { - panic("instruction MULB takes exactly 1 operand") - } -} - -func __asm_proxy_MULL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.MULL(v[0]) - } else { - panic("instruction MULL takes exactly 1 operand") - } -} - -func __asm_proxy_MULPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MULPD(v[0], v[1]) - } else { - panic("instruction MULPD takes exactly 2 operands") - } -} - -func __asm_proxy_MULPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MULPS(v[0], v[1]) - } else { - panic("instruction MULPS takes exactly 2 operands") - } -} - -func __asm_proxy_MULQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.MULQ(v[0]) - } else { - panic("instruction MULQ takes exactly 1 operand") - } -} - -func __asm_proxy_MULSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MULSD(v[0], v[1]) - } else { - panic("instruction MULSD takes exactly 2 operands") - } -} - -func __asm_proxy_MULSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.MULSS(v[0], v[1]) - } else { - panic("instruction MULSS takes exactly 2 operands") - } -} - -func __asm_proxy_MULW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.MULW(v[0]) - } else { - panic("instruction MULW takes exactly 1 operand") - } -} - -func __asm_proxy_MULXL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.MULXL(v[0], v[1], v[2]) - } else { - panic("instruction MULXL takes exactly 3 operands") - } -} - -func __asm_proxy_MULXQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.MULXQ(v[0], v[1], v[2]) - } else { - panic("instruction MULXQ takes exactly 3 operands") - } -} - -func __asm_proxy_MWAIT__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.MWAIT() - } else { - panic("instruction MWAIT takes no operands") - } -} - -func __asm_proxy_MWAITX__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.MWAITX() - } else { - panic("instruction MWAITX takes no operands") - } -} - -func __asm_proxy_NEGB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.NEGB(v[0]) - } else { - panic("instruction NEGB takes exactly 1 operand") - } -} - -func __asm_proxy_NEGL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.NEGL(v[0]) - } else { - panic("instruction NEGL takes exactly 1 operand") - } -} - -func __asm_proxy_NEGQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.NEGQ(v[0]) - } else { - panic("instruction NEGQ takes exactly 1 operand") - } -} - -func __asm_proxy_NEGW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.NEGW(v[0]) - } else { - panic("instruction NEGW takes exactly 1 operand") - } -} - -func __asm_proxy_NOP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.NOP() - } else { - panic("instruction NOP takes no operands") - } -} - -func __asm_proxy_NOTB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.NOTB(v[0]) - } else { - panic("instruction NOTB takes exactly 1 operand") - } -} - -func __asm_proxy_NOTL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.NOTL(v[0]) - } else { - panic("instruction NOTL takes exactly 1 operand") - } -} - -func __asm_proxy_NOTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.NOTQ(v[0]) - } else { - panic("instruction NOTQ takes exactly 1 operand") - } -} - -func __asm_proxy_NOTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.NOTW(v[0]) - } else { - panic("instruction NOTW takes exactly 1 operand") - } -} - -func __asm_proxy_ORB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ORB(v[0], v[1]) - } else { - panic("instruction ORB takes exactly 2 operands") - } -} - -func __asm_proxy_ORL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ORL(v[0], v[1]) - } else { - panic("instruction ORL takes exactly 2 operands") - } -} - -func __asm_proxy_ORPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ORPD(v[0], v[1]) - } else { - panic("instruction ORPD takes exactly 2 operands") - } -} - -func __asm_proxy_ORPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ORPS(v[0], v[1]) - } else { - panic("instruction ORPS takes exactly 2 operands") - } -} - -func __asm_proxy_ORQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ORQ(v[0], v[1]) - } else { - panic("instruction ORQ takes exactly 2 operands") - } -} - -func __asm_proxy_ORW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ORW(v[0], v[1]) - } else { - panic("instruction ORW takes exactly 2 operands") - } -} - -func __asm_proxy_PABSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PABSB(v[0], v[1]) - } else { - panic("instruction PABSB takes exactly 2 operands") - } -} - -func __asm_proxy_PABSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PABSD(v[0], v[1]) - } else { - panic("instruction PABSD takes exactly 2 operands") - } -} - -func __asm_proxy_PABSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PABSW(v[0], v[1]) - } else { - panic("instruction PABSW takes exactly 2 operands") - } -} - -func __asm_proxy_PACKSSDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PACKSSDW(v[0], v[1]) - } else { - panic("instruction PACKSSDW takes exactly 2 operands") - } -} - -func __asm_proxy_PACKSSWB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PACKSSWB(v[0], v[1]) - } else { - panic("instruction PACKSSWB takes exactly 2 operands") - } -} - -func __asm_proxy_PACKUSDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PACKUSDW(v[0], v[1]) - } else { - panic("instruction PACKUSDW takes exactly 2 operands") - } -} - -func __asm_proxy_PACKUSWB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PACKUSWB(v[0], v[1]) - } else { - panic("instruction PACKUSWB takes exactly 2 operands") - } -} - -func __asm_proxy_PADDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PADDB(v[0], v[1]) - } else { - panic("instruction PADDB takes exactly 2 operands") - } -} - -func __asm_proxy_PADDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PADDD(v[0], v[1]) - } else { - panic("instruction PADDD takes exactly 2 operands") - } -} - -func __asm_proxy_PADDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PADDQ(v[0], v[1]) - } else { - panic("instruction PADDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PADDSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PADDSB(v[0], v[1]) - } else { - panic("instruction PADDSB takes exactly 2 operands") - } -} - -func __asm_proxy_PADDSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PADDSW(v[0], v[1]) - } else { - panic("instruction PADDSW takes exactly 2 operands") - } -} - -func __asm_proxy_PADDUSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PADDUSB(v[0], v[1]) - } else { - panic("instruction PADDUSB takes exactly 2 operands") - } -} - -func __asm_proxy_PADDUSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PADDUSW(v[0], v[1]) - } else { - panic("instruction PADDUSW takes exactly 2 operands") - } -} - -func __asm_proxy_PADDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PADDW(v[0], v[1]) - } else { - panic("instruction PADDW takes exactly 2 operands") - } -} - -func __asm_proxy_PALIGNR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PALIGNR(v[0], v[1], v[2]) - } else { - panic("instruction PALIGNR takes exactly 3 operands") - } -} - -func __asm_proxy_PAND__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PAND(v[0], v[1]) - } else { - panic("instruction PAND takes exactly 2 operands") - } -} - -func __asm_proxy_PANDN__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PANDN(v[0], v[1]) - } else { - panic("instruction PANDN takes exactly 2 operands") - } -} - -func __asm_proxy_PAUSE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.PAUSE() - } else { - panic("instruction PAUSE takes no operands") - } -} - -func __asm_proxy_PAVGB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PAVGB(v[0], v[1]) - } else { - panic("instruction PAVGB takes exactly 2 operands") - } -} - -func __asm_proxy_PAVGUSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PAVGUSB(v[0], v[1]) - } else { - panic("instruction PAVGUSB takes exactly 2 operands") - } -} - -func __asm_proxy_PAVGW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PAVGW(v[0], v[1]) - } else { - panic("instruction PAVGW takes exactly 2 operands") - } -} - -func __asm_proxy_PBLENDVB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PBLENDVB(v[0], v[1], v[2]) - } else { - panic("instruction PBLENDVB takes exactly 3 operands") - } -} - -func __asm_proxy_PBLENDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PBLENDW(v[0], v[1], v[2]) - } else { - panic("instruction PBLENDW takes exactly 3 operands") - } -} - -func __asm_proxy_PCLMULQDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PCLMULQDQ(v[0], v[1], v[2]) - } else { - panic("instruction PCLMULQDQ takes exactly 3 operands") - } -} - -func __asm_proxy_PCMPEQB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PCMPEQB(v[0], v[1]) - } else { - panic("instruction PCMPEQB takes exactly 2 operands") - } -} - -func __asm_proxy_PCMPEQD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PCMPEQD(v[0], v[1]) - } else { - panic("instruction PCMPEQD takes exactly 2 operands") - } -} - -func __asm_proxy_PCMPEQQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PCMPEQQ(v[0], v[1]) - } else { - panic("instruction PCMPEQQ takes exactly 2 operands") - } -} - -func __asm_proxy_PCMPEQW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PCMPEQW(v[0], v[1]) - } else { - panic("instruction PCMPEQW takes exactly 2 operands") - } -} - -func __asm_proxy_PCMPESTRI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PCMPESTRI(v[0], v[1], v[2]) - } else { - panic("instruction PCMPESTRI takes exactly 3 operands") - } -} - -func __asm_proxy_PCMPESTRM__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PCMPESTRM(v[0], v[1], v[2]) - } else { - panic("instruction PCMPESTRM takes exactly 3 operands") - } -} - -func __asm_proxy_PCMPGTB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PCMPGTB(v[0], v[1]) - } else { - panic("instruction PCMPGTB takes exactly 2 operands") - } -} - -func __asm_proxy_PCMPGTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PCMPGTD(v[0], v[1]) - } else { - panic("instruction PCMPGTD takes exactly 2 operands") - } -} - -func __asm_proxy_PCMPGTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PCMPGTQ(v[0], v[1]) - } else { - panic("instruction PCMPGTQ takes exactly 2 operands") - } -} - -func __asm_proxy_PCMPGTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PCMPGTW(v[0], v[1]) - } else { - panic("instruction PCMPGTW takes exactly 2 operands") - } -} - -func __asm_proxy_PCMPISTRI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PCMPISTRI(v[0], v[1], v[2]) - } else { - panic("instruction PCMPISTRI takes exactly 3 operands") - } -} - -func __asm_proxy_PCMPISTRM__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PCMPISTRM(v[0], v[1], v[2]) - } else { - panic("instruction PCMPISTRM takes exactly 3 operands") - } -} - -func __asm_proxy_PDEP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PDEP(v[0], v[1], v[2]) - } else { - panic("instruction PDEP takes exactly 3 operands") - } -} - -func __asm_proxy_PEXT__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PEXT(v[0], v[1], v[2]) - } else { - panic("instruction PEXT takes exactly 3 operands") - } -} - -func __asm_proxy_PEXTRB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PEXTRB(v[0], v[1], v[2]) - } else { - panic("instruction PEXTRB takes exactly 3 operands") - } -} - -func __asm_proxy_PEXTRD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PEXTRD(v[0], v[1], v[2]) - } else { - panic("instruction PEXTRD takes exactly 3 operands") - } -} - -func __asm_proxy_PEXTRQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PEXTRQ(v[0], v[1], v[2]) - } else { - panic("instruction PEXTRQ takes exactly 3 operands") - } -} - -func __asm_proxy_PEXTRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PEXTRW(v[0], v[1], v[2]) - } else { - panic("instruction PEXTRW takes exactly 3 operands") - } -} - -func __asm_proxy_PF2ID__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PF2ID(v[0], v[1]) - } else { - panic("instruction PF2ID takes exactly 2 operands") - } -} - -func __asm_proxy_PF2IW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PF2IW(v[0], v[1]) - } else { - panic("instruction PF2IW takes exactly 2 operands") - } -} - -func __asm_proxy_PFACC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFACC(v[0], v[1]) - } else { - panic("instruction PFACC takes exactly 2 operands") - } -} - -func __asm_proxy_PFADD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFADD(v[0], v[1]) - } else { - panic("instruction PFADD takes exactly 2 operands") - } -} - -func __asm_proxy_PFCMPEQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFCMPEQ(v[0], v[1]) - } else { - panic("instruction PFCMPEQ takes exactly 2 operands") - } -} - -func __asm_proxy_PFCMPGE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFCMPGE(v[0], v[1]) - } else { - panic("instruction PFCMPGE takes exactly 2 operands") - } -} - -func __asm_proxy_PFCMPGT__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFCMPGT(v[0], v[1]) - } else { - panic("instruction PFCMPGT takes exactly 2 operands") - } -} - -func __asm_proxy_PFMAX__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFMAX(v[0], v[1]) - } else { - panic("instruction PFMAX takes exactly 2 operands") - } -} - -func __asm_proxy_PFMIN__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFMIN(v[0], v[1]) - } else { - panic("instruction PFMIN takes exactly 2 operands") - } -} - -func __asm_proxy_PFMUL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFMUL(v[0], v[1]) - } else { - panic("instruction PFMUL takes exactly 2 operands") - } -} - -func __asm_proxy_PFNACC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFNACC(v[0], v[1]) - } else { - panic("instruction PFNACC takes exactly 2 operands") - } -} - -func __asm_proxy_PFPNACC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFPNACC(v[0], v[1]) - } else { - panic("instruction PFPNACC takes exactly 2 operands") - } -} - -func __asm_proxy_PFRCP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFRCP(v[0], v[1]) - } else { - panic("instruction PFRCP takes exactly 2 operands") - } -} - -func __asm_proxy_PFRCPIT1__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFRCPIT1(v[0], v[1]) - } else { - panic("instruction PFRCPIT1 takes exactly 2 operands") - } -} - -func __asm_proxy_PFRCPIT2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFRCPIT2(v[0], v[1]) - } else { - panic("instruction PFRCPIT2 takes exactly 2 operands") - } -} - -func __asm_proxy_PFRSQIT1__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFRSQIT1(v[0], v[1]) - } else { - panic("instruction PFRSQIT1 takes exactly 2 operands") - } -} - -func __asm_proxy_PFRSQRT__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFRSQRT(v[0], v[1]) - } else { - panic("instruction PFRSQRT takes exactly 2 operands") - } -} - -func __asm_proxy_PFSUB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFSUB(v[0], v[1]) - } else { - panic("instruction PFSUB takes exactly 2 operands") - } -} - -func __asm_proxy_PFSUBR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PFSUBR(v[0], v[1]) - } else { - panic("instruction PFSUBR takes exactly 2 operands") - } -} - -func __asm_proxy_PHADDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PHADDD(v[0], v[1]) - } else { - panic("instruction PHADDD takes exactly 2 operands") - } -} - -func __asm_proxy_PHADDSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PHADDSW(v[0], v[1]) - } else { - panic("instruction PHADDSW takes exactly 2 operands") - } -} - -func __asm_proxy_PHADDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PHADDW(v[0], v[1]) - } else { - panic("instruction PHADDW takes exactly 2 operands") - } -} - -func __asm_proxy_PHMINPOSUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PHMINPOSUW(v[0], v[1]) - } else { - panic("instruction PHMINPOSUW takes exactly 2 operands") - } -} - -func __asm_proxy_PHSUBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PHSUBD(v[0], v[1]) - } else { - panic("instruction PHSUBD takes exactly 2 operands") - } -} - -func __asm_proxy_PHSUBSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PHSUBSW(v[0], v[1]) - } else { - panic("instruction PHSUBSW takes exactly 2 operands") - } -} - -func __asm_proxy_PHSUBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PHSUBW(v[0], v[1]) - } else { - panic("instruction PHSUBW takes exactly 2 operands") - } -} - -func __asm_proxy_PI2FD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PI2FD(v[0], v[1]) - } else { - panic("instruction PI2FD takes exactly 2 operands") - } -} - -func __asm_proxy_PI2FW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PI2FW(v[0], v[1]) - } else { - panic("instruction PI2FW takes exactly 2 operands") - } -} - -func __asm_proxy_PINSRB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PINSRB(v[0], v[1], v[2]) - } else { - panic("instruction PINSRB takes exactly 3 operands") - } -} - -func __asm_proxy_PINSRD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PINSRD(v[0], v[1], v[2]) - } else { - panic("instruction PINSRD takes exactly 3 operands") - } -} - -func __asm_proxy_PINSRQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PINSRQ(v[0], v[1], v[2]) - } else { - panic("instruction PINSRQ takes exactly 3 operands") - } -} - -func __asm_proxy_PINSRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PINSRW(v[0], v[1], v[2]) - } else { - panic("instruction PINSRW takes exactly 3 operands") - } -} - -func __asm_proxy_PMADDUBSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMADDUBSW(v[0], v[1]) - } else { - panic("instruction PMADDUBSW takes exactly 2 operands") - } -} - -func __asm_proxy_PMADDWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMADDWD(v[0], v[1]) - } else { - panic("instruction PMADDWD takes exactly 2 operands") - } -} - -func __asm_proxy_PMAXSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMAXSB(v[0], v[1]) - } else { - panic("instruction PMAXSB takes exactly 2 operands") - } -} - -func __asm_proxy_PMAXSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMAXSD(v[0], v[1]) - } else { - panic("instruction PMAXSD takes exactly 2 operands") - } -} - -func __asm_proxy_PMAXSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMAXSW(v[0], v[1]) - } else { - panic("instruction PMAXSW takes exactly 2 operands") - } -} - -func __asm_proxy_PMAXUB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMAXUB(v[0], v[1]) - } else { - panic("instruction PMAXUB takes exactly 2 operands") - } -} - -func __asm_proxy_PMAXUD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMAXUD(v[0], v[1]) - } else { - panic("instruction PMAXUD takes exactly 2 operands") - } -} - -func __asm_proxy_PMAXUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMAXUW(v[0], v[1]) - } else { - panic("instruction PMAXUW takes exactly 2 operands") - } -} - -func __asm_proxy_PMINSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMINSB(v[0], v[1]) - } else { - panic("instruction PMINSB takes exactly 2 operands") - } -} - -func __asm_proxy_PMINSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMINSD(v[0], v[1]) - } else { - panic("instruction PMINSD takes exactly 2 operands") - } -} - -func __asm_proxy_PMINSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMINSW(v[0], v[1]) - } else { - panic("instruction PMINSW takes exactly 2 operands") - } -} - -func __asm_proxy_PMINUB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMINUB(v[0], v[1]) - } else { - panic("instruction PMINUB takes exactly 2 operands") - } -} - -func __asm_proxy_PMINUD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMINUD(v[0], v[1]) - } else { - panic("instruction PMINUD takes exactly 2 operands") - } -} - -func __asm_proxy_PMINUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMINUW(v[0], v[1]) - } else { - panic("instruction PMINUW takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVMSKB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVMSKB(v[0], v[1]) - } else { - panic("instruction PMOVMSKB takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVSXBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVSXBD(v[0], v[1]) - } else { - panic("instruction PMOVSXBD takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVSXBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVSXBQ(v[0], v[1]) - } else { - panic("instruction PMOVSXBQ takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVSXBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVSXBW(v[0], v[1]) - } else { - panic("instruction PMOVSXBW takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVSXDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVSXDQ(v[0], v[1]) - } else { - panic("instruction PMOVSXDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVSXWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVSXWD(v[0], v[1]) - } else { - panic("instruction PMOVSXWD takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVSXWQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVSXWQ(v[0], v[1]) - } else { - panic("instruction PMOVSXWQ takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVZXBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVZXBD(v[0], v[1]) - } else { - panic("instruction PMOVZXBD takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVZXBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVZXBQ(v[0], v[1]) - } else { - panic("instruction PMOVZXBQ takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVZXBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVZXBW(v[0], v[1]) - } else { - panic("instruction PMOVZXBW takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVZXDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVZXDQ(v[0], v[1]) - } else { - panic("instruction PMOVZXDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVZXWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVZXWD(v[0], v[1]) - } else { - panic("instruction PMOVZXWD takes exactly 2 operands") - } -} - -func __asm_proxy_PMOVZXWQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMOVZXWQ(v[0], v[1]) - } else { - panic("instruction PMOVZXWQ takes exactly 2 operands") - } -} - -func __asm_proxy_PMULDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMULDQ(v[0], v[1]) - } else { - panic("instruction PMULDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PMULHRSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMULHRSW(v[0], v[1]) - } else { - panic("instruction PMULHRSW takes exactly 2 operands") - } -} - -func __asm_proxy_PMULHRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMULHRW(v[0], v[1]) - } else { - panic("instruction PMULHRW takes exactly 2 operands") - } -} - -func __asm_proxy_PMULHUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMULHUW(v[0], v[1]) - } else { - panic("instruction PMULHUW takes exactly 2 operands") - } -} - -func __asm_proxy_PMULHW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMULHW(v[0], v[1]) - } else { - panic("instruction PMULHW takes exactly 2 operands") - } -} - -func __asm_proxy_PMULLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMULLD(v[0], v[1]) - } else { - panic("instruction PMULLD takes exactly 2 operands") - } -} - -func __asm_proxy_PMULLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMULLW(v[0], v[1]) - } else { - panic("instruction PMULLW takes exactly 2 operands") - } -} - -func __asm_proxy_PMULUDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PMULUDQ(v[0], v[1]) - } else { - panic("instruction PMULUDQ takes exactly 2 operands") - } -} - -func __asm_proxy_POPCNTL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.POPCNTL(v[0], v[1]) - } else { - panic("instruction POPCNTL takes exactly 2 operands") - } -} - -func __asm_proxy_POPCNTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.POPCNTQ(v[0], v[1]) - } else { - panic("instruction POPCNTQ takes exactly 2 operands") - } -} - -func __asm_proxy_POPCNTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.POPCNTW(v[0], v[1]) - } else { - panic("instruction POPCNTW takes exactly 2 operands") - } -} - -func __asm_proxy_POPQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.POPQ(v[0]) - } else { - panic("instruction POPQ takes exactly 1 operand") - } -} - -func __asm_proxy_POPW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.POPW(v[0]) - } else { - panic("instruction POPW takes exactly 1 operand") - } -} - -func __asm_proxy_POR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.POR(v[0], v[1]) - } else { - panic("instruction POR takes exactly 2 operands") - } -} - -func __asm_proxy_PREFETCH__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.PREFETCH(v[0]) - } else { - panic("instruction PREFETCH takes exactly 1 operand") - } -} - -func __asm_proxy_PREFETCHNTA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.PREFETCHNTA(v[0]) - } else { - panic("instruction PREFETCHNTA takes exactly 1 operand") - } -} - -func __asm_proxy_PREFETCHT0__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.PREFETCHT0(v[0]) - } else { - panic("instruction PREFETCHT0 takes exactly 1 operand") - } -} - -func __asm_proxy_PREFETCHT1__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.PREFETCHT1(v[0]) - } else { - panic("instruction PREFETCHT1 takes exactly 1 operand") - } -} - -func __asm_proxy_PREFETCHT2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.PREFETCHT2(v[0]) - } else { - panic("instruction PREFETCHT2 takes exactly 1 operand") - } -} - -func __asm_proxy_PREFETCHW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.PREFETCHW(v[0]) - } else { - panic("instruction PREFETCHW takes exactly 1 operand") - } -} - -func __asm_proxy_PREFETCHWT1__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.PREFETCHWT1(v[0]) - } else { - panic("instruction PREFETCHWT1 takes exactly 1 operand") - } -} - -func __asm_proxy_PSADBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSADBW(v[0], v[1]) - } else { - panic("instruction PSADBW takes exactly 2 operands") - } -} - -func __asm_proxy_PSHUFB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSHUFB(v[0], v[1]) - } else { - panic("instruction PSHUFB takes exactly 2 operands") - } -} - -func __asm_proxy_PSHUFD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PSHUFD(v[0], v[1], v[2]) - } else { - panic("instruction PSHUFD takes exactly 3 operands") - } -} - -func __asm_proxy_PSHUFHW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PSHUFHW(v[0], v[1], v[2]) - } else { - panic("instruction PSHUFHW takes exactly 3 operands") - } -} - -func __asm_proxy_PSHUFLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PSHUFLW(v[0], v[1], v[2]) - } else { - panic("instruction PSHUFLW takes exactly 3 operands") - } -} - -func __asm_proxy_PSHUFW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.PSHUFW(v[0], v[1], v[2]) - } else { - panic("instruction PSHUFW takes exactly 3 operands") - } -} - -func __asm_proxy_PSIGNB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSIGNB(v[0], v[1]) - } else { - panic("instruction PSIGNB takes exactly 2 operands") - } -} - -func __asm_proxy_PSIGND__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSIGND(v[0], v[1]) - } else { - panic("instruction PSIGND takes exactly 2 operands") - } -} - -func __asm_proxy_PSIGNW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSIGNW(v[0], v[1]) - } else { - panic("instruction PSIGNW takes exactly 2 operands") - } -} - -func __asm_proxy_PSLLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSLLD(v[0], v[1]) - } else { - panic("instruction PSLLD takes exactly 2 operands") - } -} - -func __asm_proxy_PSLLDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSLLDQ(v[0], v[1]) - } else { - panic("instruction PSLLDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PSLLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSLLQ(v[0], v[1]) - } else { - panic("instruction PSLLQ takes exactly 2 operands") - } -} - -func __asm_proxy_PSLLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSLLW(v[0], v[1]) - } else { - panic("instruction PSLLW takes exactly 2 operands") - } -} - -func __asm_proxy_PSRAD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSRAD(v[0], v[1]) - } else { - panic("instruction PSRAD takes exactly 2 operands") - } -} - -func __asm_proxy_PSRAW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSRAW(v[0], v[1]) - } else { - panic("instruction PSRAW takes exactly 2 operands") - } -} - -func __asm_proxy_PSRLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSRLD(v[0], v[1]) - } else { - panic("instruction PSRLD takes exactly 2 operands") - } -} - -func __asm_proxy_PSRLDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSRLDQ(v[0], v[1]) - } else { - panic("instruction PSRLDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PSRLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSRLQ(v[0], v[1]) - } else { - panic("instruction PSRLQ takes exactly 2 operands") - } -} - -func __asm_proxy_PSRLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSRLW(v[0], v[1]) - } else { - panic("instruction PSRLW takes exactly 2 operands") - } -} - -func __asm_proxy_PSUBB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSUBB(v[0], v[1]) - } else { - panic("instruction PSUBB takes exactly 2 operands") - } -} - -func __asm_proxy_PSUBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSUBD(v[0], v[1]) - } else { - panic("instruction PSUBD takes exactly 2 operands") - } -} - -func __asm_proxy_PSUBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSUBQ(v[0], v[1]) - } else { - panic("instruction PSUBQ takes exactly 2 operands") - } -} - -func __asm_proxy_PSUBSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSUBSB(v[0], v[1]) - } else { - panic("instruction PSUBSB takes exactly 2 operands") - } -} - -func __asm_proxy_PSUBSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSUBSW(v[0], v[1]) - } else { - panic("instruction PSUBSW takes exactly 2 operands") - } -} - -func __asm_proxy_PSUBUSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSUBUSB(v[0], v[1]) - } else { - panic("instruction PSUBUSB takes exactly 2 operands") - } -} - -func __asm_proxy_PSUBUSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSUBUSW(v[0], v[1]) - } else { - panic("instruction PSUBUSW takes exactly 2 operands") - } -} - -func __asm_proxy_PSUBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSUBW(v[0], v[1]) - } else { - panic("instruction PSUBW takes exactly 2 operands") - } -} - -func __asm_proxy_PSWAPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PSWAPD(v[0], v[1]) - } else { - panic("instruction PSWAPD takes exactly 2 operands") - } -} - -func __asm_proxy_PTEST__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PTEST(v[0], v[1]) - } else { - panic("instruction PTEST takes exactly 2 operands") - } -} - -func __asm_proxy_PUNPCKHBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PUNPCKHBW(v[0], v[1]) - } else { - panic("instruction PUNPCKHBW takes exactly 2 operands") - } -} - -func __asm_proxy_PUNPCKHDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PUNPCKHDQ(v[0], v[1]) - } else { - panic("instruction PUNPCKHDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PUNPCKHQDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PUNPCKHQDQ(v[0], v[1]) - } else { - panic("instruction PUNPCKHQDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PUNPCKHWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PUNPCKHWD(v[0], v[1]) - } else { - panic("instruction PUNPCKHWD takes exactly 2 operands") - } -} - -func __asm_proxy_PUNPCKLBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PUNPCKLBW(v[0], v[1]) - } else { - panic("instruction PUNPCKLBW takes exactly 2 operands") - } -} - -func __asm_proxy_PUNPCKLDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PUNPCKLDQ(v[0], v[1]) - } else { - panic("instruction PUNPCKLDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PUNPCKLQDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PUNPCKLQDQ(v[0], v[1]) - } else { - panic("instruction PUNPCKLQDQ takes exactly 2 operands") - } -} - -func __asm_proxy_PUNPCKLWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PUNPCKLWD(v[0], v[1]) - } else { - panic("instruction PUNPCKLWD takes exactly 2 operands") - } -} - -func __asm_proxy_PUSHQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.PUSHQ(v[0]) - } else { - panic("instruction PUSHQ takes exactly 1 operand") - } -} - -func __asm_proxy_PUSHW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.PUSHW(v[0]) - } else { - panic("instruction PUSHW takes exactly 1 operand") - } -} - -func __asm_proxy_PXOR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.PXOR(v[0], v[1]) - } else { - panic("instruction PXOR takes exactly 2 operands") - } -} - -func __asm_proxy_RCLB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCLB(v[0], v[1]) - } else { - panic("instruction RCLB takes exactly 2 operands") - } -} - -func __asm_proxy_RCLL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCLL(v[0], v[1]) - } else { - panic("instruction RCLL takes exactly 2 operands") - } -} - -func __asm_proxy_RCLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCLQ(v[0], v[1]) - } else { - panic("instruction RCLQ takes exactly 2 operands") - } -} - -func __asm_proxy_RCLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCLW(v[0], v[1]) - } else { - panic("instruction RCLW takes exactly 2 operands") - } -} - -func __asm_proxy_RCPPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCPPS(v[0], v[1]) - } else { - panic("instruction RCPPS takes exactly 2 operands") - } -} - -func __asm_proxy_RCPSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCPSS(v[0], v[1]) - } else { - panic("instruction RCPSS takes exactly 2 operands") - } -} - -func __asm_proxy_RCRB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCRB(v[0], v[1]) - } else { - panic("instruction RCRB takes exactly 2 operands") - } -} - -func __asm_proxy_RCRL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCRL(v[0], v[1]) - } else { - panic("instruction RCRL takes exactly 2 operands") - } -} - -func __asm_proxy_RCRQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCRQ(v[0], v[1]) - } else { - panic("instruction RCRQ takes exactly 2 operands") - } -} - -func __asm_proxy_RCRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RCRW(v[0], v[1]) - } else { - panic("instruction RCRW takes exactly 2 operands") - } -} - -func __asm_proxy_RDRAND__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.RDRAND(v[0]) - } else { - panic("instruction RDRAND takes exactly 1 operand") - } -} - -func __asm_proxy_RDSEED__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.RDSEED(v[0]) - } else { - panic("instruction RDSEED takes exactly 1 operand") - } -} - -func __asm_proxy_RDTSC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.RDTSC() - } else { - panic("instruction RDTSC takes no operands") - } -} - -func __asm_proxy_RDTSCP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.RDTSCP() - } else { - panic("instruction RDTSCP takes no operands") - } -} - -func __asm_proxy_RET__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 0 : return p.RET() - case 1 : return p.RET(v[0]) - default : panic("instruction RET takes 0 or 1 operands") - } -} - -func __asm_proxy_ROLB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ROLB(v[0], v[1]) - } else { - panic("instruction ROLB takes exactly 2 operands") - } -} - -func __asm_proxy_ROLL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ROLL(v[0], v[1]) - } else { - panic("instruction ROLL takes exactly 2 operands") - } -} - -func __asm_proxy_ROLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ROLQ(v[0], v[1]) - } else { - panic("instruction ROLQ takes exactly 2 operands") - } -} - -func __asm_proxy_ROLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.ROLW(v[0], v[1]) - } else { - panic("instruction ROLW takes exactly 2 operands") - } -} - -func __asm_proxy_RORB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RORB(v[0], v[1]) - } else { - panic("instruction RORB takes exactly 2 operands") - } -} - -func __asm_proxy_RORL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RORL(v[0], v[1]) - } else { - panic("instruction RORL takes exactly 2 operands") - } -} - -func __asm_proxy_RORQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RORQ(v[0], v[1]) - } else { - panic("instruction RORQ takes exactly 2 operands") - } -} - -func __asm_proxy_RORW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RORW(v[0], v[1]) - } else { - panic("instruction RORW takes exactly 2 operands") - } -} - -func __asm_proxy_RORXL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.RORXL(v[0], v[1], v[2]) - } else { - panic("instruction RORXL takes exactly 3 operands") - } -} - -func __asm_proxy_RORXQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.RORXQ(v[0], v[1], v[2]) - } else { - panic("instruction RORXQ takes exactly 3 operands") - } -} - -func __asm_proxy_ROUNDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.ROUNDPD(v[0], v[1], v[2]) - } else { - panic("instruction ROUNDPD takes exactly 3 operands") - } -} - -func __asm_proxy_ROUNDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.ROUNDPS(v[0], v[1], v[2]) - } else { - panic("instruction ROUNDPS takes exactly 3 operands") - } -} - -func __asm_proxy_ROUNDSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.ROUNDSD(v[0], v[1], v[2]) - } else { - panic("instruction ROUNDSD takes exactly 3 operands") - } -} - -func __asm_proxy_ROUNDSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.ROUNDSS(v[0], v[1], v[2]) - } else { - panic("instruction ROUNDSS takes exactly 3 operands") - } -} - -func __asm_proxy_RSQRTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RSQRTPS(v[0], v[1]) - } else { - panic("instruction RSQRTPS takes exactly 2 operands") - } -} - -func __asm_proxy_RSQRTSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.RSQRTSS(v[0], v[1]) - } else { - panic("instruction RSQRTSS takes exactly 2 operands") - } -} - -func __asm_proxy_SALB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SALB(v[0], v[1]) - } else { - panic("instruction SALB takes exactly 2 operands") - } -} - -func __asm_proxy_SALL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SALL(v[0], v[1]) - } else { - panic("instruction SALL takes exactly 2 operands") - } -} - -func __asm_proxy_SALQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SALQ(v[0], v[1]) - } else { - panic("instruction SALQ takes exactly 2 operands") - } -} - -func __asm_proxy_SALW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SALW(v[0], v[1]) - } else { - panic("instruction SALW takes exactly 2 operands") - } -} - -func __asm_proxy_SARB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SARB(v[0], v[1]) - } else { - panic("instruction SARB takes exactly 2 operands") - } -} - -func __asm_proxy_SARL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SARL(v[0], v[1]) - } else { - panic("instruction SARL takes exactly 2 operands") - } -} - -func __asm_proxy_SARQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SARQ(v[0], v[1]) - } else { - panic("instruction SARQ takes exactly 2 operands") - } -} - -func __asm_proxy_SARW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SARW(v[0], v[1]) - } else { - panic("instruction SARW takes exactly 2 operands") - } -} - -func __asm_proxy_SARXL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SARXL(v[0], v[1], v[2]) - } else { - panic("instruction SARXL takes exactly 3 operands") - } -} - -func __asm_proxy_SARXQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SARXQ(v[0], v[1], v[2]) - } else { - panic("instruction SARXQ takes exactly 3 operands") - } -} - -func __asm_proxy_SBBB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SBBB(v[0], v[1]) - } else { - panic("instruction SBBB takes exactly 2 operands") - } -} - -func __asm_proxy_SBBL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SBBL(v[0], v[1]) - } else { - panic("instruction SBBL takes exactly 2 operands") - } -} - -func __asm_proxy_SBBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SBBQ(v[0], v[1]) - } else { - panic("instruction SBBQ takes exactly 2 operands") - } -} - -func __asm_proxy_SBBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SBBW(v[0], v[1]) - } else { - panic("instruction SBBW takes exactly 2 operands") - } -} - -func __asm_proxy_SETA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETA(v[0]) - } else { - panic("instruction SETA takes exactly 1 operand") - } -} - -func __asm_proxy_SETAE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETAE(v[0]) - } else { - panic("instruction SETAE takes exactly 1 operand") - } -} - -func __asm_proxy_SETB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETB(v[0]) - } else { - panic("instruction SETB takes exactly 1 operand") - } -} - -func __asm_proxy_SETBE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETBE(v[0]) - } else { - panic("instruction SETBE takes exactly 1 operand") - } -} - -func __asm_proxy_SETC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETC(v[0]) - } else { - panic("instruction SETC takes exactly 1 operand") - } -} - -func __asm_proxy_SETE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETE(v[0]) - } else { - panic("instruction SETE takes exactly 1 operand") - } -} - -func __asm_proxy_SETG__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETG(v[0]) - } else { - panic("instruction SETG takes exactly 1 operand") - } -} - -func __asm_proxy_SETGE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETGE(v[0]) - } else { - panic("instruction SETGE takes exactly 1 operand") - } -} - -func __asm_proxy_SETL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETL(v[0]) - } else { - panic("instruction SETL takes exactly 1 operand") - } -} - -func __asm_proxy_SETLE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETLE(v[0]) - } else { - panic("instruction SETLE takes exactly 1 operand") - } -} - -func __asm_proxy_SETNA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNA(v[0]) - } else { - panic("instruction SETNA takes exactly 1 operand") - } -} - -func __asm_proxy_SETNAE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNAE(v[0]) - } else { - panic("instruction SETNAE takes exactly 1 operand") - } -} - -func __asm_proxy_SETNB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNB(v[0]) - } else { - panic("instruction SETNB takes exactly 1 operand") - } -} - -func __asm_proxy_SETNBE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNBE(v[0]) - } else { - panic("instruction SETNBE takes exactly 1 operand") - } -} - -func __asm_proxy_SETNC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNC(v[0]) - } else { - panic("instruction SETNC takes exactly 1 operand") - } -} - -func __asm_proxy_SETNE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNE(v[0]) - } else { - panic("instruction SETNE takes exactly 1 operand") - } -} - -func __asm_proxy_SETNG__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNG(v[0]) - } else { - panic("instruction SETNG takes exactly 1 operand") - } -} - -func __asm_proxy_SETNGE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNGE(v[0]) - } else { - panic("instruction SETNGE takes exactly 1 operand") - } -} - -func __asm_proxy_SETNL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNL(v[0]) - } else { - panic("instruction SETNL takes exactly 1 operand") - } -} - -func __asm_proxy_SETNLE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNLE(v[0]) - } else { - panic("instruction SETNLE takes exactly 1 operand") - } -} - -func __asm_proxy_SETNO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNO(v[0]) - } else { - panic("instruction SETNO takes exactly 1 operand") - } -} - -func __asm_proxy_SETNP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNP(v[0]) - } else { - panic("instruction SETNP takes exactly 1 operand") - } -} - -func __asm_proxy_SETNS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNS(v[0]) - } else { - panic("instruction SETNS takes exactly 1 operand") - } -} - -func __asm_proxy_SETNZ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETNZ(v[0]) - } else { - panic("instruction SETNZ takes exactly 1 operand") - } -} - -func __asm_proxy_SETO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETO(v[0]) - } else { - panic("instruction SETO takes exactly 1 operand") - } -} - -func __asm_proxy_SETP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETP(v[0]) - } else { - panic("instruction SETP takes exactly 1 operand") - } -} - -func __asm_proxy_SETPE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETPE(v[0]) - } else { - panic("instruction SETPE takes exactly 1 operand") - } -} - -func __asm_proxy_SETPO__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETPO(v[0]) - } else { - panic("instruction SETPO takes exactly 1 operand") - } -} - -func __asm_proxy_SETS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETS(v[0]) - } else { - panic("instruction SETS takes exactly 1 operand") - } -} - -func __asm_proxy_SETZ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.SETZ(v[0]) - } else { - panic("instruction SETZ takes exactly 1 operand") - } -} - -func __asm_proxy_SFENCE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.SFENCE() - } else { - panic("instruction SFENCE takes no operands") - } -} - -func __asm_proxy_SHA1MSG1__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHA1MSG1(v[0], v[1]) - } else { - panic("instruction SHA1MSG1 takes exactly 2 operands") - } -} - -func __asm_proxy_SHA1MSG2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHA1MSG2(v[0], v[1]) - } else { - panic("instruction SHA1MSG2 takes exactly 2 operands") - } -} - -func __asm_proxy_SHA1NEXTE__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHA1NEXTE(v[0], v[1]) - } else { - panic("instruction SHA1NEXTE takes exactly 2 operands") - } -} - -func __asm_proxy_SHA1RNDS4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHA1RNDS4(v[0], v[1], v[2]) - } else { - panic("instruction SHA1RNDS4 takes exactly 3 operands") - } -} - -func __asm_proxy_SHA256MSG1__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHA256MSG1(v[0], v[1]) - } else { - panic("instruction SHA256MSG1 takes exactly 2 operands") - } -} - -func __asm_proxy_SHA256MSG2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHA256MSG2(v[0], v[1]) - } else { - panic("instruction SHA256MSG2 takes exactly 2 operands") - } -} - -func __asm_proxy_SHA256RNDS2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHA256RNDS2(v[0], v[1], v[2]) - } else { - panic("instruction SHA256RNDS2 takes exactly 3 operands") - } -} - -func __asm_proxy_SHLB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHLB(v[0], v[1]) - } else { - panic("instruction SHLB takes exactly 2 operands") - } -} - -func __asm_proxy_SHLDL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHLDL(v[0], v[1], v[2]) - } else { - panic("instruction SHLDL takes exactly 3 operands") - } -} - -func __asm_proxy_SHLDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHLDQ(v[0], v[1], v[2]) - } else { - panic("instruction SHLDQ takes exactly 3 operands") - } -} - -func __asm_proxy_SHLDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHLDW(v[0], v[1], v[2]) - } else { - panic("instruction SHLDW takes exactly 3 operands") - } -} - -func __asm_proxy_SHLL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHLL(v[0], v[1]) - } else { - panic("instruction SHLL takes exactly 2 operands") - } -} - -func __asm_proxy_SHLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHLQ(v[0], v[1]) - } else { - panic("instruction SHLQ takes exactly 2 operands") - } -} - -func __asm_proxy_SHLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHLW(v[0], v[1]) - } else { - panic("instruction SHLW takes exactly 2 operands") - } -} - -func __asm_proxy_SHLXL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHLXL(v[0], v[1], v[2]) - } else { - panic("instruction SHLXL takes exactly 3 operands") - } -} - -func __asm_proxy_SHLXQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHLXQ(v[0], v[1], v[2]) - } else { - panic("instruction SHLXQ takes exactly 3 operands") - } -} - -func __asm_proxy_SHRB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHRB(v[0], v[1]) - } else { - panic("instruction SHRB takes exactly 2 operands") - } -} - -func __asm_proxy_SHRDL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHRDL(v[0], v[1], v[2]) - } else { - panic("instruction SHRDL takes exactly 3 operands") - } -} - -func __asm_proxy_SHRDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHRDQ(v[0], v[1], v[2]) - } else { - panic("instruction SHRDQ takes exactly 3 operands") - } -} - -func __asm_proxy_SHRDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHRDW(v[0], v[1], v[2]) - } else { - panic("instruction SHRDW takes exactly 3 operands") - } -} - -func __asm_proxy_SHRL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHRL(v[0], v[1]) - } else { - panic("instruction SHRL takes exactly 2 operands") - } -} - -func __asm_proxy_SHRQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHRQ(v[0], v[1]) - } else { - panic("instruction SHRQ takes exactly 2 operands") - } -} - -func __asm_proxy_SHRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SHRW(v[0], v[1]) - } else { - panic("instruction SHRW takes exactly 2 operands") - } -} - -func __asm_proxy_SHRXL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHRXL(v[0], v[1], v[2]) - } else { - panic("instruction SHRXL takes exactly 3 operands") - } -} - -func __asm_proxy_SHRXQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHRXQ(v[0], v[1], v[2]) - } else { - panic("instruction SHRXQ takes exactly 3 operands") - } -} - -func __asm_proxy_SHUFPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHUFPD(v[0], v[1], v[2]) - } else { - panic("instruction SHUFPD takes exactly 3 operands") - } -} - -func __asm_proxy_SHUFPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.SHUFPS(v[0], v[1], v[2]) - } else { - panic("instruction SHUFPS takes exactly 3 operands") - } -} - -func __asm_proxy_SQRTPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SQRTPD(v[0], v[1]) - } else { - panic("instruction SQRTPD takes exactly 2 operands") - } -} - -func __asm_proxy_SQRTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SQRTPS(v[0], v[1]) - } else { - panic("instruction SQRTPS takes exactly 2 operands") - } -} - -func __asm_proxy_SQRTSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SQRTSD(v[0], v[1]) - } else { - panic("instruction SQRTSD takes exactly 2 operands") - } -} - -func __asm_proxy_SQRTSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SQRTSS(v[0], v[1]) - } else { - panic("instruction SQRTSS takes exactly 2 operands") - } -} - -func __asm_proxy_STC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.STC() - } else { - panic("instruction STC takes no operands") - } -} - -func __asm_proxy_STD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.STD() - } else { - panic("instruction STD takes no operands") - } -} - -func __asm_proxy_STMXCSR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.STMXCSR(v[0]) - } else { - panic("instruction STMXCSR takes exactly 1 operand") - } -} - -func __asm_proxy_SUBB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SUBB(v[0], v[1]) - } else { - panic("instruction SUBB takes exactly 2 operands") - } -} - -func __asm_proxy_SUBL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SUBL(v[0], v[1]) - } else { - panic("instruction SUBL takes exactly 2 operands") - } -} - -func __asm_proxy_SUBPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SUBPD(v[0], v[1]) - } else { - panic("instruction SUBPD takes exactly 2 operands") - } -} - -func __asm_proxy_SUBPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SUBPS(v[0], v[1]) - } else { - panic("instruction SUBPS takes exactly 2 operands") - } -} - -func __asm_proxy_SUBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SUBQ(v[0], v[1]) - } else { - panic("instruction SUBQ takes exactly 2 operands") - } -} - -func __asm_proxy_SUBSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SUBSD(v[0], v[1]) - } else { - panic("instruction SUBSD takes exactly 2 operands") - } -} - -func __asm_proxy_SUBSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SUBSS(v[0], v[1]) - } else { - panic("instruction SUBSS takes exactly 2 operands") - } -} - -func __asm_proxy_SUBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.SUBW(v[0], v[1]) - } else { - panic("instruction SUBW takes exactly 2 operands") - } -} - -func __asm_proxy_SYSCALL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.SYSCALL() - } else { - panic("instruction SYSCALL takes no operands") - } -} - -func __asm_proxy_T1MSKC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.T1MSKC(v[0], v[1]) - } else { - panic("instruction T1MSKC takes exactly 2 operands") - } -} - -func __asm_proxy_TESTB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.TESTB(v[0], v[1]) - } else { - panic("instruction TESTB takes exactly 2 operands") - } -} - -func __asm_proxy_TESTL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.TESTL(v[0], v[1]) - } else { - panic("instruction TESTL takes exactly 2 operands") - } -} - -func __asm_proxy_TESTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.TESTQ(v[0], v[1]) - } else { - panic("instruction TESTQ takes exactly 2 operands") - } -} - -func __asm_proxy_TESTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.TESTW(v[0], v[1]) - } else { - panic("instruction TESTW takes exactly 2 operands") - } -} - -func __asm_proxy_TZCNTL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.TZCNTL(v[0], v[1]) - } else { - panic("instruction TZCNTL takes exactly 2 operands") - } -} - -func __asm_proxy_TZCNTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.TZCNTQ(v[0], v[1]) - } else { - panic("instruction TZCNTQ takes exactly 2 operands") - } -} - -func __asm_proxy_TZCNTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.TZCNTW(v[0], v[1]) - } else { - panic("instruction TZCNTW takes exactly 2 operands") - } -} - -func __asm_proxy_TZMSK__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.TZMSK(v[0], v[1]) - } else { - panic("instruction TZMSK takes exactly 2 operands") - } -} - -func __asm_proxy_UCOMISD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.UCOMISD(v[0], v[1]) - } else { - panic("instruction UCOMISD takes exactly 2 operands") - } -} - -func __asm_proxy_UCOMISS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.UCOMISS(v[0], v[1]) - } else { - panic("instruction UCOMISS takes exactly 2 operands") - } -} - -func __asm_proxy_UD2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.UD2() - } else { - panic("instruction UD2 takes no operands") - } -} - -func __asm_proxy_UNPCKHPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.UNPCKHPD(v[0], v[1]) - } else { - panic("instruction UNPCKHPD takes exactly 2 operands") - } -} - -func __asm_proxy_UNPCKHPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.UNPCKHPS(v[0], v[1]) - } else { - panic("instruction UNPCKHPS takes exactly 2 operands") - } -} - -func __asm_proxy_UNPCKLPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.UNPCKLPD(v[0], v[1]) - } else { - panic("instruction UNPCKLPD takes exactly 2 operands") - } -} - -func __asm_proxy_UNPCKLPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.UNPCKLPS(v[0], v[1]) - } else { - panic("instruction UNPCKLPS takes exactly 2 operands") - } -} - -func __asm_proxy_VADDPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VADDPD(v[0], v[1], v[2]) - case 4 : return p.VADDPD(v[0], v[1], v[2], v[3]) - default : panic("instruction VADDPD takes 3 or 4 operands") - } -} - -func __asm_proxy_VADDPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VADDPS(v[0], v[1], v[2]) - case 4 : return p.VADDPS(v[0], v[1], v[2], v[3]) - default : panic("instruction VADDPS takes 3 or 4 operands") - } -} - -func __asm_proxy_VADDSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VADDSD(v[0], v[1], v[2]) - case 4 : return p.VADDSD(v[0], v[1], v[2], v[3]) - default : panic("instruction VADDSD takes 3 or 4 operands") - } -} - -func __asm_proxy_VADDSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VADDSS(v[0], v[1], v[2]) - case 4 : return p.VADDSS(v[0], v[1], v[2], v[3]) - default : panic("instruction VADDSS takes 3 or 4 operands") - } -} - -func __asm_proxy_VADDSUBPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VADDSUBPD(v[0], v[1], v[2]) - } else { - panic("instruction VADDSUBPD takes exactly 3 operands") - } -} - -func __asm_proxy_VADDSUBPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VADDSUBPS(v[0], v[1], v[2]) - } else { - panic("instruction VADDSUBPS takes exactly 3 operands") - } -} - -func __asm_proxy_VAESDEC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VAESDEC(v[0], v[1], v[2]) - } else { - panic("instruction VAESDEC takes exactly 3 operands") - } -} - -func __asm_proxy_VAESDECLAST__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VAESDECLAST(v[0], v[1], v[2]) - } else { - panic("instruction VAESDECLAST takes exactly 3 operands") - } -} - -func __asm_proxy_VAESENC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VAESENC(v[0], v[1], v[2]) - } else { - panic("instruction VAESENC takes exactly 3 operands") - } -} - -func __asm_proxy_VAESENCLAST__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VAESENCLAST(v[0], v[1], v[2]) - } else { - panic("instruction VAESENCLAST takes exactly 3 operands") - } -} - -func __asm_proxy_VAESIMC__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VAESIMC(v[0], v[1]) - } else { - panic("instruction VAESIMC takes exactly 2 operands") - } -} - -func __asm_proxy_VAESKEYGENASSIST__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VAESKEYGENASSIST(v[0], v[1], v[2]) - } else { - panic("instruction VAESKEYGENASSIST takes exactly 3 operands") - } -} - -func __asm_proxy_VALIGND__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VALIGND(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VALIGND takes exactly 4 operands") - } -} - -func __asm_proxy_VALIGNQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VALIGNQ(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VALIGNQ takes exactly 4 operands") - } -} - -func __asm_proxy_VANDNPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VANDNPD(v[0], v[1], v[2]) - } else { - panic("instruction VANDNPD takes exactly 3 operands") - } -} - -func __asm_proxy_VANDNPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VANDNPS(v[0], v[1], v[2]) - } else { - panic("instruction VANDNPS takes exactly 3 operands") - } -} - -func __asm_proxy_VANDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VANDPD(v[0], v[1], v[2]) - } else { - panic("instruction VANDPD takes exactly 3 operands") - } -} - -func __asm_proxy_VANDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VANDPS(v[0], v[1], v[2]) - } else { - panic("instruction VANDPS takes exactly 3 operands") - } -} - -func __asm_proxy_VBLENDMPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VBLENDMPD(v[0], v[1], v[2]) - } else { - panic("instruction VBLENDMPD takes exactly 3 operands") - } -} - -func __asm_proxy_VBLENDMPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VBLENDMPS(v[0], v[1], v[2]) - } else { - panic("instruction VBLENDMPS takes exactly 3 operands") - } -} - -func __asm_proxy_VBLENDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VBLENDPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VBLENDPD takes exactly 4 operands") - } -} - -func __asm_proxy_VBLENDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VBLENDPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VBLENDPS takes exactly 4 operands") - } -} - -func __asm_proxy_VBLENDVPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VBLENDVPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VBLENDVPD takes exactly 4 operands") - } -} - -func __asm_proxy_VBLENDVPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VBLENDVPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VBLENDVPS takes exactly 4 operands") - } -} - -func __asm_proxy_VBROADCASTF128__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTF128(v[0], v[1]) - } else { - panic("instruction VBROADCASTF128 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTF32X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTF32X2(v[0], v[1]) - } else { - panic("instruction VBROADCASTF32X2 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTF32X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTF32X4(v[0], v[1]) - } else { - panic("instruction VBROADCASTF32X4 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTF32X8__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTF32X8(v[0], v[1]) - } else { - panic("instruction VBROADCASTF32X8 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTF64X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTF64X2(v[0], v[1]) - } else { - panic("instruction VBROADCASTF64X2 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTF64X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTF64X4(v[0], v[1]) - } else { - panic("instruction VBROADCASTF64X4 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTI128__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTI128(v[0], v[1]) - } else { - panic("instruction VBROADCASTI128 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTI32X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTI32X2(v[0], v[1]) - } else { - panic("instruction VBROADCASTI32X2 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTI32X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTI32X4(v[0], v[1]) - } else { - panic("instruction VBROADCASTI32X4 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTI32X8__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTI32X8(v[0], v[1]) - } else { - panic("instruction VBROADCASTI32X8 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTI64X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTI64X2(v[0], v[1]) - } else { - panic("instruction VBROADCASTI64X2 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTI64X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTI64X4(v[0], v[1]) - } else { - panic("instruction VBROADCASTI64X4 takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTSD(v[0], v[1]) - } else { - panic("instruction VBROADCASTSD takes exactly 2 operands") - } -} - -func __asm_proxy_VBROADCASTSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VBROADCASTSS(v[0], v[1]) - } else { - panic("instruction VBROADCASTSS takes exactly 2 operands") - } -} - -func __asm_proxy_VCMPPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VCMPPD(v[0], v[1], v[2], v[3]) - case 5 : return p.VCMPPD(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VCMPPD takes 4 or 5 operands") - } -} - -func __asm_proxy_VCMPPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VCMPPS(v[0], v[1], v[2], v[3]) - case 5 : return p.VCMPPS(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VCMPPS takes 4 or 5 operands") - } -} - -func __asm_proxy_VCMPSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VCMPSD(v[0], v[1], v[2], v[3]) - case 5 : return p.VCMPSD(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VCMPSD takes 4 or 5 operands") - } -} - -func __asm_proxy_VCMPSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VCMPSS(v[0], v[1], v[2], v[3]) - case 5 : return p.VCMPSS(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VCMPSS takes 4 or 5 operands") - } -} - -func __asm_proxy_VCOMISD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCOMISD(v[0], v[1]) - case 3 : return p.VCOMISD(v[0], v[1], v[2]) - default : panic("instruction VCOMISD takes 2 or 3 operands") - } -} - -func __asm_proxy_VCOMISS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCOMISS(v[0], v[1]) - case 3 : return p.VCOMISS(v[0], v[1], v[2]) - default : panic("instruction VCOMISS takes 2 or 3 operands") - } -} - -func __asm_proxy_VCOMPRESSPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VCOMPRESSPD(v[0], v[1]) - } else { - panic("instruction VCOMPRESSPD takes exactly 2 operands") - } -} - -func __asm_proxy_VCOMPRESSPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VCOMPRESSPS(v[0], v[1]) - } else { - panic("instruction VCOMPRESSPS takes exactly 2 operands") - } -} - -func __asm_proxy_VCVTDQ2PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VCVTDQ2PD(v[0], v[1]) - } else { - panic("instruction VCVTDQ2PD takes exactly 2 operands") - } -} - -func __asm_proxy_VCVTDQ2PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTDQ2PS(v[0], v[1]) - case 3 : return p.VCVTDQ2PS(v[0], v[1], v[2]) - default : panic("instruction VCVTDQ2PS takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPD2DQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPD2DQ(v[0], v[1]) - case 3 : return p.VCVTPD2DQ(v[0], v[1], v[2]) - default : panic("instruction VCVTPD2DQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPD2PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPD2PS(v[0], v[1]) - case 3 : return p.VCVTPD2PS(v[0], v[1], v[2]) - default : panic("instruction VCVTPD2PS takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPD2QQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPD2QQ(v[0], v[1]) - case 3 : return p.VCVTPD2QQ(v[0], v[1], v[2]) - default : panic("instruction VCVTPD2QQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPD2UDQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPD2UDQ(v[0], v[1]) - case 3 : return p.VCVTPD2UDQ(v[0], v[1], v[2]) - default : panic("instruction VCVTPD2UDQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPD2UQQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPD2UQQ(v[0], v[1]) - case 3 : return p.VCVTPD2UQQ(v[0], v[1], v[2]) - default : panic("instruction VCVTPD2UQQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPH2PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPH2PS(v[0], v[1]) - case 3 : return p.VCVTPH2PS(v[0], v[1], v[2]) - default : panic("instruction VCVTPH2PS takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPS2DQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPS2DQ(v[0], v[1]) - case 3 : return p.VCVTPS2DQ(v[0], v[1], v[2]) - default : panic("instruction VCVTPS2DQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPS2PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPS2PD(v[0], v[1]) - case 3 : return p.VCVTPS2PD(v[0], v[1], v[2]) - default : panic("instruction VCVTPS2PD takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPS2PH__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VCVTPS2PH(v[0], v[1], v[2]) - case 4 : return p.VCVTPS2PH(v[0], v[1], v[2], v[3]) - default : panic("instruction VCVTPS2PH takes 3 or 4 operands") - } -} - -func __asm_proxy_VCVTPS2QQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPS2QQ(v[0], v[1]) - case 3 : return p.VCVTPS2QQ(v[0], v[1], v[2]) - default : panic("instruction VCVTPS2QQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPS2UDQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPS2UDQ(v[0], v[1]) - case 3 : return p.VCVTPS2UDQ(v[0], v[1], v[2]) - default : panic("instruction VCVTPS2UDQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTPS2UQQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTPS2UQQ(v[0], v[1]) - case 3 : return p.VCVTPS2UQQ(v[0], v[1], v[2]) - default : panic("instruction VCVTPS2UQQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTQQ2PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTQQ2PD(v[0], v[1]) - case 3 : return p.VCVTQQ2PD(v[0], v[1], v[2]) - default : panic("instruction VCVTQQ2PD takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTQQ2PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTQQ2PS(v[0], v[1]) - case 3 : return p.VCVTQQ2PS(v[0], v[1], v[2]) - default : panic("instruction VCVTQQ2PS takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTSD2SI__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTSD2SI(v[0], v[1]) - case 3 : return p.VCVTSD2SI(v[0], v[1], v[2]) - default : panic("instruction VCVTSD2SI takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTSD2SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VCVTSD2SS(v[0], v[1], v[2]) - case 4 : return p.VCVTSD2SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VCVTSD2SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VCVTSD2USI__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTSD2USI(v[0], v[1]) - case 3 : return p.VCVTSD2USI(v[0], v[1], v[2]) - default : panic("instruction VCVTSD2USI takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTSI2SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VCVTSI2SD(v[0], v[1], v[2]) - case 4 : return p.VCVTSI2SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VCVTSI2SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VCVTSI2SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VCVTSI2SS(v[0], v[1], v[2]) - case 4 : return p.VCVTSI2SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VCVTSI2SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VCVTSS2SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VCVTSS2SD(v[0], v[1], v[2]) - case 4 : return p.VCVTSS2SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VCVTSS2SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VCVTSS2SI__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTSS2SI(v[0], v[1]) - case 3 : return p.VCVTSS2SI(v[0], v[1], v[2]) - default : panic("instruction VCVTSS2SI takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTSS2USI__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTSS2USI(v[0], v[1]) - case 3 : return p.VCVTSS2USI(v[0], v[1], v[2]) - default : panic("instruction VCVTSS2USI takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTPD2DQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTPD2DQ(v[0], v[1]) - case 3 : return p.VCVTTPD2DQ(v[0], v[1], v[2]) - default : panic("instruction VCVTTPD2DQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTPD2QQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTPD2QQ(v[0], v[1]) - case 3 : return p.VCVTTPD2QQ(v[0], v[1], v[2]) - default : panic("instruction VCVTTPD2QQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTPD2UDQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTPD2UDQ(v[0], v[1]) - case 3 : return p.VCVTTPD2UDQ(v[0], v[1], v[2]) - default : panic("instruction VCVTTPD2UDQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTPD2UQQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTPD2UQQ(v[0], v[1]) - case 3 : return p.VCVTTPD2UQQ(v[0], v[1], v[2]) - default : panic("instruction VCVTTPD2UQQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTPS2DQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTPS2DQ(v[0], v[1]) - case 3 : return p.VCVTTPS2DQ(v[0], v[1], v[2]) - default : panic("instruction VCVTTPS2DQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTPS2QQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTPS2QQ(v[0], v[1]) - case 3 : return p.VCVTTPS2QQ(v[0], v[1], v[2]) - default : panic("instruction VCVTTPS2QQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTPS2UDQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTPS2UDQ(v[0], v[1]) - case 3 : return p.VCVTTPS2UDQ(v[0], v[1], v[2]) - default : panic("instruction VCVTTPS2UDQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTPS2UQQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTPS2UQQ(v[0], v[1]) - case 3 : return p.VCVTTPS2UQQ(v[0], v[1], v[2]) - default : panic("instruction VCVTTPS2UQQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTSD2SI__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTSD2SI(v[0], v[1]) - case 3 : return p.VCVTTSD2SI(v[0], v[1], v[2]) - default : panic("instruction VCVTTSD2SI takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTSD2USI__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTSD2USI(v[0], v[1]) - case 3 : return p.VCVTTSD2USI(v[0], v[1], v[2]) - default : panic("instruction VCVTTSD2USI takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTSS2SI__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTSS2SI(v[0], v[1]) - case 3 : return p.VCVTTSS2SI(v[0], v[1], v[2]) - default : panic("instruction VCVTTSS2SI takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTTSS2USI__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTTSS2USI(v[0], v[1]) - case 3 : return p.VCVTTSS2USI(v[0], v[1], v[2]) - default : panic("instruction VCVTTSS2USI takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTUDQ2PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VCVTUDQ2PD(v[0], v[1]) - } else { - panic("instruction VCVTUDQ2PD takes exactly 2 operands") - } -} - -func __asm_proxy_VCVTUDQ2PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTUDQ2PS(v[0], v[1]) - case 3 : return p.VCVTUDQ2PS(v[0], v[1], v[2]) - default : panic("instruction VCVTUDQ2PS takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTUQQ2PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTUQQ2PD(v[0], v[1]) - case 3 : return p.VCVTUQQ2PD(v[0], v[1], v[2]) - default : panic("instruction VCVTUQQ2PD takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTUQQ2PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VCVTUQQ2PS(v[0], v[1]) - case 3 : return p.VCVTUQQ2PS(v[0], v[1], v[2]) - default : panic("instruction VCVTUQQ2PS takes 2 or 3 operands") - } -} - -func __asm_proxy_VCVTUSI2SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VCVTUSI2SD(v[0], v[1], v[2]) - case 4 : return p.VCVTUSI2SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VCVTUSI2SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VCVTUSI2SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VCVTUSI2SS(v[0], v[1], v[2]) - case 4 : return p.VCVTUSI2SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VCVTUSI2SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VDBPSADBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VDBPSADBW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VDBPSADBW takes exactly 4 operands") - } -} - -func __asm_proxy_VDIVPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VDIVPD(v[0], v[1], v[2]) - case 4 : return p.VDIVPD(v[0], v[1], v[2], v[3]) - default : panic("instruction VDIVPD takes 3 or 4 operands") - } -} - -func __asm_proxy_VDIVPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VDIVPS(v[0], v[1], v[2]) - case 4 : return p.VDIVPS(v[0], v[1], v[2], v[3]) - default : panic("instruction VDIVPS takes 3 or 4 operands") - } -} - -func __asm_proxy_VDIVSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VDIVSD(v[0], v[1], v[2]) - case 4 : return p.VDIVSD(v[0], v[1], v[2], v[3]) - default : panic("instruction VDIVSD takes 3 or 4 operands") - } -} - -func __asm_proxy_VDIVSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VDIVSS(v[0], v[1], v[2]) - case 4 : return p.VDIVSS(v[0], v[1], v[2], v[3]) - default : panic("instruction VDIVSS takes 3 or 4 operands") - } -} - -func __asm_proxy_VDPPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VDPPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VDPPD takes exactly 4 operands") - } -} - -func __asm_proxy_VDPPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VDPPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VDPPS takes exactly 4 operands") - } -} - -func __asm_proxy_VEXP2PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VEXP2PD(v[0], v[1]) - case 3 : return p.VEXP2PD(v[0], v[1], v[2]) - default : panic("instruction VEXP2PD takes 2 or 3 operands") - } -} - -func __asm_proxy_VEXP2PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VEXP2PS(v[0], v[1]) - case 3 : return p.VEXP2PS(v[0], v[1], v[2]) - default : panic("instruction VEXP2PS takes 2 or 3 operands") - } -} - -func __asm_proxy_VEXPANDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VEXPANDPD(v[0], v[1]) - } else { - panic("instruction VEXPANDPD takes exactly 2 operands") - } -} - -func __asm_proxy_VEXPANDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VEXPANDPS(v[0], v[1]) - } else { - panic("instruction VEXPANDPS takes exactly 2 operands") - } -} - -func __asm_proxy_VEXTRACTF128__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTF128(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTF128 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTF32X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTF32X4(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTF32X4 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTF32X8__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTF32X8(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTF32X8 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTF64X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTF64X2(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTF64X2 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTF64X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTF64X4(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTF64X4 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTI128__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTI128(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTI128 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTI32X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTI32X4(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTI32X4 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTI32X8__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTI32X8(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTI32X8 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTI64X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTI64X2(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTI64X2 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTI64X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTI64X4(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTI64X4 takes exactly 3 operands") - } -} - -func __asm_proxy_VEXTRACTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VEXTRACTPS(v[0], v[1], v[2]) - } else { - panic("instruction VEXTRACTPS takes exactly 3 operands") - } -} - -func __asm_proxy_VFIXUPIMMPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VFIXUPIMMPD(v[0], v[1], v[2], v[3]) - case 5 : return p.VFIXUPIMMPD(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VFIXUPIMMPD takes 4 or 5 operands") - } -} - -func __asm_proxy_VFIXUPIMMPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VFIXUPIMMPS(v[0], v[1], v[2], v[3]) - case 5 : return p.VFIXUPIMMPS(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VFIXUPIMMPS takes 4 or 5 operands") - } -} - -func __asm_proxy_VFIXUPIMMSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VFIXUPIMMSD(v[0], v[1], v[2], v[3]) - case 5 : return p.VFIXUPIMMSD(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VFIXUPIMMSD takes 4 or 5 operands") - } -} - -func __asm_proxy_VFIXUPIMMSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VFIXUPIMMSS(v[0], v[1], v[2], v[3]) - case 5 : return p.VFIXUPIMMSS(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VFIXUPIMMSS takes 4 or 5 operands") - } -} - -func __asm_proxy_VFMADD132PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD132PD(v[0], v[1], v[2]) - case 4 : return p.VFMADD132PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD132PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD132PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD132PS(v[0], v[1], v[2]) - case 4 : return p.VFMADD132PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD132PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD132SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD132SD(v[0], v[1], v[2]) - case 4 : return p.VFMADD132SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD132SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD132SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD132SS(v[0], v[1], v[2]) - case 4 : return p.VFMADD132SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD132SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD213PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD213PD(v[0], v[1], v[2]) - case 4 : return p.VFMADD213PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD213PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD213PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD213PS(v[0], v[1], v[2]) - case 4 : return p.VFMADD213PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD213PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD213SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD213SD(v[0], v[1], v[2]) - case 4 : return p.VFMADD213SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD213SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD213SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD213SS(v[0], v[1], v[2]) - case 4 : return p.VFMADD213SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD213SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD231PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD231PD(v[0], v[1], v[2]) - case 4 : return p.VFMADD231PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD231PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD231PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD231PS(v[0], v[1], v[2]) - case 4 : return p.VFMADD231PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD231PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD231SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD231SD(v[0], v[1], v[2]) - case 4 : return p.VFMADD231SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD231SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADD231SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADD231SS(v[0], v[1], v[2]) - case 4 : return p.VFMADD231SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADD231SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMADDPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMADDPD takes exactly 4 operands") - } -} - -func __asm_proxy_VFMADDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMADDPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMADDPS takes exactly 4 operands") - } -} - -func __asm_proxy_VFMADDSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMADDSD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMADDSD takes exactly 4 operands") - } -} - -func __asm_proxy_VFMADDSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMADDSS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMADDSS takes exactly 4 operands") - } -} - -func __asm_proxy_VFMADDSUB132PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADDSUB132PD(v[0], v[1], v[2]) - case 4 : return p.VFMADDSUB132PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADDSUB132PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADDSUB132PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADDSUB132PS(v[0], v[1], v[2]) - case 4 : return p.VFMADDSUB132PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADDSUB132PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADDSUB213PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADDSUB213PD(v[0], v[1], v[2]) - case 4 : return p.VFMADDSUB213PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADDSUB213PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADDSUB213PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADDSUB213PS(v[0], v[1], v[2]) - case 4 : return p.VFMADDSUB213PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADDSUB213PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADDSUB231PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADDSUB231PD(v[0], v[1], v[2]) - case 4 : return p.VFMADDSUB231PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADDSUB231PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADDSUB231PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMADDSUB231PS(v[0], v[1], v[2]) - case 4 : return p.VFMADDSUB231PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMADDSUB231PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMADDSUBPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMADDSUBPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMADDSUBPD takes exactly 4 operands") - } -} - -func __asm_proxy_VFMADDSUBPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMADDSUBPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMADDSUBPS takes exactly 4 operands") - } -} - -func __asm_proxy_VFMSUB132PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB132PD(v[0], v[1], v[2]) - case 4 : return p.VFMSUB132PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB132PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB132PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB132PS(v[0], v[1], v[2]) - case 4 : return p.VFMSUB132PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB132PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB132SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB132SD(v[0], v[1], v[2]) - case 4 : return p.VFMSUB132SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB132SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB132SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB132SS(v[0], v[1], v[2]) - case 4 : return p.VFMSUB132SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB132SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB213PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB213PD(v[0], v[1], v[2]) - case 4 : return p.VFMSUB213PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB213PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB213PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB213PS(v[0], v[1], v[2]) - case 4 : return p.VFMSUB213PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB213PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB213SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB213SD(v[0], v[1], v[2]) - case 4 : return p.VFMSUB213SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB213SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB213SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB213SS(v[0], v[1], v[2]) - case 4 : return p.VFMSUB213SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB213SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB231PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB231PD(v[0], v[1], v[2]) - case 4 : return p.VFMSUB231PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB231PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB231PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB231PS(v[0], v[1], v[2]) - case 4 : return p.VFMSUB231PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB231PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB231SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB231SD(v[0], v[1], v[2]) - case 4 : return p.VFMSUB231SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB231SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUB231SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUB231SS(v[0], v[1], v[2]) - case 4 : return p.VFMSUB231SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUB231SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUBADD132PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUBADD132PD(v[0], v[1], v[2]) - case 4 : return p.VFMSUBADD132PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUBADD132PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUBADD132PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUBADD132PS(v[0], v[1], v[2]) - case 4 : return p.VFMSUBADD132PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUBADD132PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUBADD213PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUBADD213PD(v[0], v[1], v[2]) - case 4 : return p.VFMSUBADD213PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUBADD213PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUBADD213PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUBADD213PS(v[0], v[1], v[2]) - case 4 : return p.VFMSUBADD213PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUBADD213PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUBADD231PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUBADD231PD(v[0], v[1], v[2]) - case 4 : return p.VFMSUBADD231PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUBADD231PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUBADD231PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFMSUBADD231PS(v[0], v[1], v[2]) - case 4 : return p.VFMSUBADD231PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFMSUBADD231PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFMSUBADDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMSUBADDPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMSUBADDPD takes exactly 4 operands") - } -} - -func __asm_proxy_VFMSUBADDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMSUBADDPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMSUBADDPS takes exactly 4 operands") - } -} - -func __asm_proxy_VFMSUBPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMSUBPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMSUBPD takes exactly 4 operands") - } -} - -func __asm_proxy_VFMSUBPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMSUBPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMSUBPS takes exactly 4 operands") - } -} - -func __asm_proxy_VFMSUBSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMSUBSD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMSUBSD takes exactly 4 operands") - } -} - -func __asm_proxy_VFMSUBSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFMSUBSS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFMSUBSS takes exactly 4 operands") - } -} - -func __asm_proxy_VFNMADD132PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD132PD(v[0], v[1], v[2]) - case 4 : return p.VFNMADD132PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD132PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD132PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD132PS(v[0], v[1], v[2]) - case 4 : return p.VFNMADD132PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD132PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD132SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD132SD(v[0], v[1], v[2]) - case 4 : return p.VFNMADD132SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD132SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD132SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD132SS(v[0], v[1], v[2]) - case 4 : return p.VFNMADD132SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD132SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD213PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD213PD(v[0], v[1], v[2]) - case 4 : return p.VFNMADD213PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD213PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD213PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD213PS(v[0], v[1], v[2]) - case 4 : return p.VFNMADD213PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD213PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD213SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD213SD(v[0], v[1], v[2]) - case 4 : return p.VFNMADD213SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD213SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD213SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD213SS(v[0], v[1], v[2]) - case 4 : return p.VFNMADD213SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD213SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD231PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD231PD(v[0], v[1], v[2]) - case 4 : return p.VFNMADD231PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD231PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD231PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD231PS(v[0], v[1], v[2]) - case 4 : return p.VFNMADD231PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD231PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD231SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD231SD(v[0], v[1], v[2]) - case 4 : return p.VFNMADD231SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD231SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADD231SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMADD231SS(v[0], v[1], v[2]) - case 4 : return p.VFNMADD231SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMADD231SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMADDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFNMADDPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFNMADDPD takes exactly 4 operands") - } -} - -func __asm_proxy_VFNMADDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFNMADDPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFNMADDPS takes exactly 4 operands") - } -} - -func __asm_proxy_VFNMADDSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFNMADDSD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFNMADDSD takes exactly 4 operands") - } -} - -func __asm_proxy_VFNMADDSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFNMADDSS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFNMADDSS takes exactly 4 operands") - } -} - -func __asm_proxy_VFNMSUB132PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB132PD(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB132PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB132PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB132PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB132PS(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB132PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB132PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB132SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB132SD(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB132SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB132SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB132SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB132SS(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB132SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB132SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB213PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB213PD(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB213PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB213PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB213PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB213PS(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB213PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB213PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB213SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB213SD(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB213SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB213SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB213SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB213SS(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB213SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB213SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB231PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB231PD(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB231PD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB231PD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB231PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB231PS(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB231PS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB231PS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB231SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB231SD(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB231SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB231SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUB231SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VFNMSUB231SS(v[0], v[1], v[2]) - case 4 : return p.VFNMSUB231SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VFNMSUB231SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VFNMSUBPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFNMSUBPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFNMSUBPD takes exactly 4 operands") - } -} - -func __asm_proxy_VFNMSUBPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFNMSUBPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFNMSUBPS takes exactly 4 operands") - } -} - -func __asm_proxy_VFNMSUBSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFNMSUBSD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFNMSUBSD takes exactly 4 operands") - } -} - -func __asm_proxy_VFNMSUBSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VFNMSUBSS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VFNMSUBSS takes exactly 4 operands") - } -} - -func __asm_proxy_VFPCLASSPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VFPCLASSPD(v[0], v[1], v[2]) - } else { - panic("instruction VFPCLASSPD takes exactly 3 operands") - } -} - -func __asm_proxy_VFPCLASSPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VFPCLASSPS(v[0], v[1], v[2]) - } else { - panic("instruction VFPCLASSPS takes exactly 3 operands") - } -} - -func __asm_proxy_VFPCLASSSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VFPCLASSSD(v[0], v[1], v[2]) - } else { - panic("instruction VFPCLASSSD takes exactly 3 operands") - } -} - -func __asm_proxy_VFPCLASSSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VFPCLASSSS(v[0], v[1], v[2]) - } else { - panic("instruction VFPCLASSSS takes exactly 3 operands") - } -} - -func __asm_proxy_VFRCZPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VFRCZPD(v[0], v[1]) - } else { - panic("instruction VFRCZPD takes exactly 2 operands") - } -} - -func __asm_proxy_VFRCZPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VFRCZPS(v[0], v[1]) - } else { - panic("instruction VFRCZPS takes exactly 2 operands") - } -} - -func __asm_proxy_VFRCZSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VFRCZSD(v[0], v[1]) - } else { - panic("instruction VFRCZSD takes exactly 2 operands") - } -} - -func __asm_proxy_VFRCZSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VFRCZSS(v[0], v[1]) - } else { - panic("instruction VFRCZSS takes exactly 2 operands") - } -} - -func __asm_proxy_VGATHERDPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VGATHERDPD(v[0], v[1]) - case 3 : return p.VGATHERDPD(v[0], v[1], v[2]) - default : panic("instruction VGATHERDPD takes 2 or 3 operands") - } -} - -func __asm_proxy_VGATHERDPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VGATHERDPS(v[0], v[1]) - case 3 : return p.VGATHERDPS(v[0], v[1], v[2]) - default : panic("instruction VGATHERDPS takes 2 or 3 operands") - } -} - -func __asm_proxy_VGATHERPF0DPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VGATHERPF0DPD(v[0]) - } else { - panic("instruction VGATHERPF0DPD takes exactly 1 operand") - } -} - -func __asm_proxy_VGATHERPF0DPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VGATHERPF0DPS(v[0]) - } else { - panic("instruction VGATHERPF0DPS takes exactly 1 operand") - } -} - -func __asm_proxy_VGATHERPF0QPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VGATHERPF0QPD(v[0]) - } else { - panic("instruction VGATHERPF0QPD takes exactly 1 operand") - } -} - -func __asm_proxy_VGATHERPF0QPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VGATHERPF0QPS(v[0]) - } else { - panic("instruction VGATHERPF0QPS takes exactly 1 operand") - } -} - -func __asm_proxy_VGATHERPF1DPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VGATHERPF1DPD(v[0]) - } else { - panic("instruction VGATHERPF1DPD takes exactly 1 operand") - } -} - -func __asm_proxy_VGATHERPF1DPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VGATHERPF1DPS(v[0]) - } else { - panic("instruction VGATHERPF1DPS takes exactly 1 operand") - } -} - -func __asm_proxy_VGATHERPF1QPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VGATHERPF1QPD(v[0]) - } else { - panic("instruction VGATHERPF1QPD takes exactly 1 operand") - } -} - -func __asm_proxy_VGATHERPF1QPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VGATHERPF1QPS(v[0]) - } else { - panic("instruction VGATHERPF1QPS takes exactly 1 operand") - } -} - -func __asm_proxy_VGATHERQPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VGATHERQPD(v[0], v[1]) - case 3 : return p.VGATHERQPD(v[0], v[1], v[2]) - default : panic("instruction VGATHERQPD takes 2 or 3 operands") - } -} - -func __asm_proxy_VGATHERQPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VGATHERQPS(v[0], v[1]) - case 3 : return p.VGATHERQPS(v[0], v[1], v[2]) - default : panic("instruction VGATHERQPS takes 2 or 3 operands") - } -} - -func __asm_proxy_VGETEXPPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VGETEXPPD(v[0], v[1]) - case 3 : return p.VGETEXPPD(v[0], v[1], v[2]) - default : panic("instruction VGETEXPPD takes 2 or 3 operands") - } -} - -func __asm_proxy_VGETEXPPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VGETEXPPS(v[0], v[1]) - case 3 : return p.VGETEXPPS(v[0], v[1], v[2]) - default : panic("instruction VGETEXPPS takes 2 or 3 operands") - } -} - -func __asm_proxy_VGETEXPSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VGETEXPSD(v[0], v[1], v[2]) - case 4 : return p.VGETEXPSD(v[0], v[1], v[2], v[3]) - default : panic("instruction VGETEXPSD takes 3 or 4 operands") - } -} - -func __asm_proxy_VGETEXPSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VGETEXPSS(v[0], v[1], v[2]) - case 4 : return p.VGETEXPSS(v[0], v[1], v[2], v[3]) - default : panic("instruction VGETEXPSS takes 3 or 4 operands") - } -} - -func __asm_proxy_VGETMANTPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VGETMANTPD(v[0], v[1], v[2]) - case 4 : return p.VGETMANTPD(v[0], v[1], v[2], v[3]) - default : panic("instruction VGETMANTPD takes 3 or 4 operands") - } -} - -func __asm_proxy_VGETMANTPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VGETMANTPS(v[0], v[1], v[2]) - case 4 : return p.VGETMANTPS(v[0], v[1], v[2], v[3]) - default : panic("instruction VGETMANTPS takes 3 or 4 operands") - } -} - -func __asm_proxy_VGETMANTSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VGETMANTSD(v[0], v[1], v[2], v[3]) - case 5 : return p.VGETMANTSD(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VGETMANTSD takes 4 or 5 operands") - } -} - -func __asm_proxy_VGETMANTSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VGETMANTSS(v[0], v[1], v[2], v[3]) - case 5 : return p.VGETMANTSS(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VGETMANTSS takes 4 or 5 operands") - } -} - -func __asm_proxy_VHADDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VHADDPD(v[0], v[1], v[2]) - } else { - panic("instruction VHADDPD takes exactly 3 operands") - } -} - -func __asm_proxy_VHADDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VHADDPS(v[0], v[1], v[2]) - } else { - panic("instruction VHADDPS takes exactly 3 operands") - } -} - -func __asm_proxy_VHSUBPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VHSUBPD(v[0], v[1], v[2]) - } else { - panic("instruction VHSUBPD takes exactly 3 operands") - } -} - -func __asm_proxy_VHSUBPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VHSUBPS(v[0], v[1], v[2]) - } else { - panic("instruction VHSUBPS takes exactly 3 operands") - } -} - -func __asm_proxy_VINSERTF128__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTF128(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTF128 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTF32X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTF32X4(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTF32X4 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTF32X8__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTF32X8(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTF32X8 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTF64X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTF64X2(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTF64X2 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTF64X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTF64X4(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTF64X4 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTI128__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTI128(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTI128 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTI32X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTI32X4(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTI32X4 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTI32X8__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTI32X8(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTI32X8 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTI64X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTI64X2(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTI64X2 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTI64X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTI64X4(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTI64X4 takes exactly 4 operands") - } -} - -func __asm_proxy_VINSERTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VINSERTPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VINSERTPS takes exactly 4 operands") - } -} - -func __asm_proxy_VLDDQU__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VLDDQU(v[0], v[1]) - } else { - panic("instruction VLDDQU takes exactly 2 operands") - } -} - -func __asm_proxy_VLDMXCSR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VLDMXCSR(v[0]) - } else { - panic("instruction VLDMXCSR takes exactly 1 operand") - } -} - -func __asm_proxy_VMASKMOVDQU__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMASKMOVDQU(v[0], v[1]) - } else { - panic("instruction VMASKMOVDQU takes exactly 2 operands") - } -} - -func __asm_proxy_VMASKMOVPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VMASKMOVPD(v[0], v[1], v[2]) - } else { - panic("instruction VMASKMOVPD takes exactly 3 operands") - } -} - -func __asm_proxy_VMASKMOVPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VMASKMOVPS(v[0], v[1], v[2]) - } else { - panic("instruction VMASKMOVPS takes exactly 3 operands") - } -} - -func __asm_proxy_VMAXPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMAXPD(v[0], v[1], v[2]) - case 4 : return p.VMAXPD(v[0], v[1], v[2], v[3]) - default : panic("instruction VMAXPD takes 3 or 4 operands") - } -} - -func __asm_proxy_VMAXPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMAXPS(v[0], v[1], v[2]) - case 4 : return p.VMAXPS(v[0], v[1], v[2], v[3]) - default : panic("instruction VMAXPS takes 3 or 4 operands") - } -} - -func __asm_proxy_VMAXSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMAXSD(v[0], v[1], v[2]) - case 4 : return p.VMAXSD(v[0], v[1], v[2], v[3]) - default : panic("instruction VMAXSD takes 3 or 4 operands") - } -} - -func __asm_proxy_VMAXSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMAXSS(v[0], v[1], v[2]) - case 4 : return p.VMAXSS(v[0], v[1], v[2], v[3]) - default : panic("instruction VMAXSS takes 3 or 4 operands") - } -} - -func __asm_proxy_VMINPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMINPD(v[0], v[1], v[2]) - case 4 : return p.VMINPD(v[0], v[1], v[2], v[3]) - default : panic("instruction VMINPD takes 3 or 4 operands") - } -} - -func __asm_proxy_VMINPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMINPS(v[0], v[1], v[2]) - case 4 : return p.VMINPS(v[0], v[1], v[2], v[3]) - default : panic("instruction VMINPS takes 3 or 4 operands") - } -} - -func __asm_proxy_VMINSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMINSD(v[0], v[1], v[2]) - case 4 : return p.VMINSD(v[0], v[1], v[2], v[3]) - default : panic("instruction VMINSD takes 3 or 4 operands") - } -} - -func __asm_proxy_VMINSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMINSS(v[0], v[1], v[2]) - case 4 : return p.VMINSS(v[0], v[1], v[2], v[3]) - default : panic("instruction VMINSS takes 3 or 4 operands") - } -} - -func __asm_proxy_VMOVAPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVAPD(v[0], v[1]) - } else { - panic("instruction VMOVAPD takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVAPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVAPS(v[0], v[1]) - } else { - panic("instruction VMOVAPS takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVD(v[0], v[1]) - } else { - panic("instruction VMOVD takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVDDUP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVDDUP(v[0], v[1]) - } else { - panic("instruction VMOVDDUP takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVDQA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVDQA(v[0], v[1]) - } else { - panic("instruction VMOVDQA takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVDQA32__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVDQA32(v[0], v[1]) - } else { - panic("instruction VMOVDQA32 takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVDQA64__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVDQA64(v[0], v[1]) - } else { - panic("instruction VMOVDQA64 takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVDQU__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVDQU(v[0], v[1]) - } else { - panic("instruction VMOVDQU takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVDQU16__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVDQU16(v[0], v[1]) - } else { - panic("instruction VMOVDQU16 takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVDQU32__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVDQU32(v[0], v[1]) - } else { - panic("instruction VMOVDQU32 takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVDQU64__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVDQU64(v[0], v[1]) - } else { - panic("instruction VMOVDQU64 takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVDQU8__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVDQU8(v[0], v[1]) - } else { - panic("instruction VMOVDQU8 takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVHLPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VMOVHLPS(v[0], v[1], v[2]) - } else { - panic("instruction VMOVHLPS takes exactly 3 operands") - } -} - -func __asm_proxy_VMOVHPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VMOVHPD(v[0], v[1]) - case 3 : return p.VMOVHPD(v[0], v[1], v[2]) - default : panic("instruction VMOVHPD takes 2 or 3 operands") - } -} - -func __asm_proxy_VMOVHPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VMOVHPS(v[0], v[1]) - case 3 : return p.VMOVHPS(v[0], v[1], v[2]) - default : panic("instruction VMOVHPS takes 2 or 3 operands") - } -} - -func __asm_proxy_VMOVLHPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VMOVLHPS(v[0], v[1], v[2]) - } else { - panic("instruction VMOVLHPS takes exactly 3 operands") - } -} - -func __asm_proxy_VMOVLPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VMOVLPD(v[0], v[1]) - case 3 : return p.VMOVLPD(v[0], v[1], v[2]) - default : panic("instruction VMOVLPD takes 2 or 3 operands") - } -} - -func __asm_proxy_VMOVLPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VMOVLPS(v[0], v[1]) - case 3 : return p.VMOVLPS(v[0], v[1], v[2]) - default : panic("instruction VMOVLPS takes 2 or 3 operands") - } -} - -func __asm_proxy_VMOVMSKPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVMSKPD(v[0], v[1]) - } else { - panic("instruction VMOVMSKPD takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVMSKPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVMSKPS(v[0], v[1]) - } else { - panic("instruction VMOVMSKPS takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVNTDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVNTDQ(v[0], v[1]) - } else { - panic("instruction VMOVNTDQ takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVNTDQA__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVNTDQA(v[0], v[1]) - } else { - panic("instruction VMOVNTDQA takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVNTPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVNTPD(v[0], v[1]) - } else { - panic("instruction VMOVNTPD takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVNTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVNTPS(v[0], v[1]) - } else { - panic("instruction VMOVNTPS takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVQ(v[0], v[1]) - } else { - panic("instruction VMOVQ takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VMOVSD(v[0], v[1]) - case 3 : return p.VMOVSD(v[0], v[1], v[2]) - default : panic("instruction VMOVSD takes 2 or 3 operands") - } -} - -func __asm_proxy_VMOVSHDUP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVSHDUP(v[0], v[1]) - } else { - panic("instruction VMOVSHDUP takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVSLDUP__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVSLDUP(v[0], v[1]) - } else { - panic("instruction VMOVSLDUP takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VMOVSS(v[0], v[1]) - case 3 : return p.VMOVSS(v[0], v[1], v[2]) - default : panic("instruction VMOVSS takes 2 or 3 operands") - } -} - -func __asm_proxy_VMOVUPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVUPD(v[0], v[1]) - } else { - panic("instruction VMOVUPD takes exactly 2 operands") - } -} - -func __asm_proxy_VMOVUPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VMOVUPS(v[0], v[1]) - } else { - panic("instruction VMOVUPS takes exactly 2 operands") - } -} - -func __asm_proxy_VMPSADBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VMPSADBW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VMPSADBW takes exactly 4 operands") - } -} - -func __asm_proxy_VMULPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMULPD(v[0], v[1], v[2]) - case 4 : return p.VMULPD(v[0], v[1], v[2], v[3]) - default : panic("instruction VMULPD takes 3 or 4 operands") - } -} - -func __asm_proxy_VMULPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMULPS(v[0], v[1], v[2]) - case 4 : return p.VMULPS(v[0], v[1], v[2], v[3]) - default : panic("instruction VMULPS takes 3 or 4 operands") - } -} - -func __asm_proxy_VMULSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMULSD(v[0], v[1], v[2]) - case 4 : return p.VMULSD(v[0], v[1], v[2], v[3]) - default : panic("instruction VMULSD takes 3 or 4 operands") - } -} - -func __asm_proxy_VMULSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VMULSS(v[0], v[1], v[2]) - case 4 : return p.VMULSS(v[0], v[1], v[2], v[3]) - default : panic("instruction VMULSS takes 3 or 4 operands") - } -} - -func __asm_proxy_VORPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VORPD(v[0], v[1], v[2]) - } else { - panic("instruction VORPD takes exactly 3 operands") - } -} - -func __asm_proxy_VORPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VORPS(v[0], v[1], v[2]) - } else { - panic("instruction VORPS takes exactly 3 operands") - } -} - -func __asm_proxy_VPABSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPABSB(v[0], v[1]) - } else { - panic("instruction VPABSB takes exactly 2 operands") - } -} - -func __asm_proxy_VPABSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPABSD(v[0], v[1]) - } else { - panic("instruction VPABSD takes exactly 2 operands") - } -} - -func __asm_proxy_VPABSQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPABSQ(v[0], v[1]) - } else { - panic("instruction VPABSQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPABSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPABSW(v[0], v[1]) - } else { - panic("instruction VPABSW takes exactly 2 operands") - } -} - -func __asm_proxy_VPACKSSDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPACKSSDW(v[0], v[1], v[2]) - } else { - panic("instruction VPACKSSDW takes exactly 3 operands") - } -} - -func __asm_proxy_VPACKSSWB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPACKSSWB(v[0], v[1], v[2]) - } else { - panic("instruction VPACKSSWB takes exactly 3 operands") - } -} - -func __asm_proxy_VPACKUSDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPACKUSDW(v[0], v[1], v[2]) - } else { - panic("instruction VPACKUSDW takes exactly 3 operands") - } -} - -func __asm_proxy_VPACKUSWB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPACKUSWB(v[0], v[1], v[2]) - } else { - panic("instruction VPACKUSWB takes exactly 3 operands") - } -} - -func __asm_proxy_VPADDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPADDB(v[0], v[1], v[2]) - } else { - panic("instruction VPADDB takes exactly 3 operands") - } -} - -func __asm_proxy_VPADDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPADDD(v[0], v[1], v[2]) - } else { - panic("instruction VPADDD takes exactly 3 operands") - } -} - -func __asm_proxy_VPADDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPADDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPADDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPADDSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPADDSB(v[0], v[1], v[2]) - } else { - panic("instruction VPADDSB takes exactly 3 operands") - } -} - -func __asm_proxy_VPADDSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPADDSW(v[0], v[1], v[2]) - } else { - panic("instruction VPADDSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPADDUSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPADDUSB(v[0], v[1], v[2]) - } else { - panic("instruction VPADDUSB takes exactly 3 operands") - } -} - -func __asm_proxy_VPADDUSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPADDUSW(v[0], v[1], v[2]) - } else { - panic("instruction VPADDUSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPADDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPADDW(v[0], v[1], v[2]) - } else { - panic("instruction VPADDW takes exactly 3 operands") - } -} - -func __asm_proxy_VPALIGNR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPALIGNR(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPALIGNR takes exactly 4 operands") - } -} - -func __asm_proxy_VPAND__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPAND(v[0], v[1], v[2]) - } else { - panic("instruction VPAND takes exactly 3 operands") - } -} - -func __asm_proxy_VPANDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPANDD(v[0], v[1], v[2]) - } else { - panic("instruction VPANDD takes exactly 3 operands") - } -} - -func __asm_proxy_VPANDN__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPANDN(v[0], v[1], v[2]) - } else { - panic("instruction VPANDN takes exactly 3 operands") - } -} - -func __asm_proxy_VPANDND__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPANDND(v[0], v[1], v[2]) - } else { - panic("instruction VPANDND takes exactly 3 operands") - } -} - -func __asm_proxy_VPANDNQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPANDNQ(v[0], v[1], v[2]) - } else { - panic("instruction VPANDNQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPANDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPANDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPANDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPAVGB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPAVGB(v[0], v[1], v[2]) - } else { - panic("instruction VPAVGB takes exactly 3 operands") - } -} - -func __asm_proxy_VPAVGW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPAVGW(v[0], v[1], v[2]) - } else { - panic("instruction VPAVGW takes exactly 3 operands") - } -} - -func __asm_proxy_VPBLENDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPBLENDD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPBLENDD takes exactly 4 operands") - } -} - -func __asm_proxy_VPBLENDMB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPBLENDMB(v[0], v[1], v[2]) - } else { - panic("instruction VPBLENDMB takes exactly 3 operands") - } -} - -func __asm_proxy_VPBLENDMD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPBLENDMD(v[0], v[1], v[2]) - } else { - panic("instruction VPBLENDMD takes exactly 3 operands") - } -} - -func __asm_proxy_VPBLENDMQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPBLENDMQ(v[0], v[1], v[2]) - } else { - panic("instruction VPBLENDMQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPBLENDMW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPBLENDMW(v[0], v[1], v[2]) - } else { - panic("instruction VPBLENDMW takes exactly 3 operands") - } -} - -func __asm_proxy_VPBLENDVB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPBLENDVB(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPBLENDVB takes exactly 4 operands") - } -} - -func __asm_proxy_VPBLENDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPBLENDW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPBLENDW takes exactly 4 operands") - } -} - -func __asm_proxy_VPBROADCASTB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPBROADCASTB(v[0], v[1]) - } else { - panic("instruction VPBROADCASTB takes exactly 2 operands") - } -} - -func __asm_proxy_VPBROADCASTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPBROADCASTD(v[0], v[1]) - } else { - panic("instruction VPBROADCASTD takes exactly 2 operands") - } -} - -func __asm_proxy_VPBROADCASTMB2Q__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPBROADCASTMB2Q(v[0], v[1]) - } else { - panic("instruction VPBROADCASTMB2Q takes exactly 2 operands") - } -} - -func __asm_proxy_VPBROADCASTMW2D__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPBROADCASTMW2D(v[0], v[1]) - } else { - panic("instruction VPBROADCASTMW2D takes exactly 2 operands") - } -} - -func __asm_proxy_VPBROADCASTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPBROADCASTQ(v[0], v[1]) - } else { - panic("instruction VPBROADCASTQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPBROADCASTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPBROADCASTW(v[0], v[1]) - } else { - panic("instruction VPBROADCASTW takes exactly 2 operands") - } -} - -func __asm_proxy_VPCLMULQDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCLMULQDQ(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCLMULQDQ takes exactly 4 operands") - } -} - -func __asm_proxy_VPCMOV__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCMOV(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCMOV takes exactly 4 operands") - } -} - -func __asm_proxy_VPCMPB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCMPB(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCMPB takes exactly 4 operands") - } -} - -func __asm_proxy_VPCMPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCMPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCMPD takes exactly 4 operands") - } -} - -func __asm_proxy_VPCMPEQB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPEQB(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPEQB takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPEQD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPEQD(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPEQD takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPEQQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPEQQ(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPEQQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPEQW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPEQW(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPEQW takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPESTRI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPESTRI(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPESTRI takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPESTRM__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPESTRM(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPESTRM takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPGTB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPGTB(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPGTB takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPGTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPGTD(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPGTD takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPGTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPGTQ(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPGTQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPGTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPGTW(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPGTW takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPISTRI__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPISTRI(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPISTRI takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPISTRM__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPCMPISTRM(v[0], v[1], v[2]) - } else { - panic("instruction VPCMPISTRM takes exactly 3 operands") - } -} - -func __asm_proxy_VPCMPQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCMPQ(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCMPQ takes exactly 4 operands") - } -} - -func __asm_proxy_VPCMPUB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCMPUB(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCMPUB takes exactly 4 operands") - } -} - -func __asm_proxy_VPCMPUD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCMPUD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCMPUD takes exactly 4 operands") - } -} - -func __asm_proxy_VPCMPUQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCMPUQ(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCMPUQ takes exactly 4 operands") - } -} - -func __asm_proxy_VPCMPUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCMPUW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCMPUW takes exactly 4 operands") - } -} - -func __asm_proxy_VPCMPW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCMPW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCMPW takes exactly 4 operands") - } -} - -func __asm_proxy_VPCOMB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCOMB(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCOMB takes exactly 4 operands") - } -} - -func __asm_proxy_VPCOMD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCOMD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCOMD takes exactly 4 operands") - } -} - -func __asm_proxy_VPCOMPRESSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPCOMPRESSD(v[0], v[1]) - } else { - panic("instruction VPCOMPRESSD takes exactly 2 operands") - } -} - -func __asm_proxy_VPCOMPRESSQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPCOMPRESSQ(v[0], v[1]) - } else { - panic("instruction VPCOMPRESSQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPCOMQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCOMQ(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCOMQ takes exactly 4 operands") - } -} - -func __asm_proxy_VPCOMUB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCOMUB(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCOMUB takes exactly 4 operands") - } -} - -func __asm_proxy_VPCOMUD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCOMUD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCOMUD takes exactly 4 operands") - } -} - -func __asm_proxy_VPCOMUQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCOMUQ(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCOMUQ takes exactly 4 operands") - } -} - -func __asm_proxy_VPCOMUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCOMUW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCOMUW takes exactly 4 operands") - } -} - -func __asm_proxy_VPCOMW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPCOMW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPCOMW takes exactly 4 operands") - } -} - -func __asm_proxy_VPCONFLICTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPCONFLICTD(v[0], v[1]) - } else { - panic("instruction VPCONFLICTD takes exactly 2 operands") - } -} - -func __asm_proxy_VPCONFLICTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPCONFLICTQ(v[0], v[1]) - } else { - panic("instruction VPCONFLICTQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPERM2F128__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPERM2F128(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPERM2F128 takes exactly 4 operands") - } -} - -func __asm_proxy_VPERM2I128__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPERM2I128(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPERM2I128 takes exactly 4 operands") - } -} - -func __asm_proxy_VPERMB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMB(v[0], v[1], v[2]) - } else { - panic("instruction VPERMB takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMD(v[0], v[1], v[2]) - } else { - panic("instruction VPERMD takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMI2B__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMI2B(v[0], v[1], v[2]) - } else { - panic("instruction VPERMI2B takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMI2D__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMI2D(v[0], v[1], v[2]) - } else { - panic("instruction VPERMI2D takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMI2PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMI2PD(v[0], v[1], v[2]) - } else { - panic("instruction VPERMI2PD takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMI2PS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMI2PS(v[0], v[1], v[2]) - } else { - panic("instruction VPERMI2PS takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMI2Q__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMI2Q(v[0], v[1], v[2]) - } else { - panic("instruction VPERMI2Q takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMI2W__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMI2W(v[0], v[1], v[2]) - } else { - panic("instruction VPERMI2W takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMIL2PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 5 { - return p.VPERMIL2PD(v[0], v[1], v[2], v[3], v[4]) - } else { - panic("instruction VPERMIL2PD takes exactly 5 operands") - } -} - -func __asm_proxy_VPERMIL2PS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 5 { - return p.VPERMIL2PS(v[0], v[1], v[2], v[3], v[4]) - } else { - panic("instruction VPERMIL2PS takes exactly 5 operands") - } -} - -func __asm_proxy_VPERMILPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMILPD(v[0], v[1], v[2]) - } else { - panic("instruction VPERMILPD takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMILPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMILPS(v[0], v[1], v[2]) - } else { - panic("instruction VPERMILPS takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMPD(v[0], v[1], v[2]) - } else { - panic("instruction VPERMPD takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMPS(v[0], v[1], v[2]) - } else { - panic("instruction VPERMPS takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMQ(v[0], v[1], v[2]) - } else { - panic("instruction VPERMQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMT2B__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMT2B(v[0], v[1], v[2]) - } else { - panic("instruction VPERMT2B takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMT2D__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMT2D(v[0], v[1], v[2]) - } else { - panic("instruction VPERMT2D takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMT2PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMT2PD(v[0], v[1], v[2]) - } else { - panic("instruction VPERMT2PD takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMT2PS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMT2PS(v[0], v[1], v[2]) - } else { - panic("instruction VPERMT2PS takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMT2Q__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMT2Q(v[0], v[1], v[2]) - } else { - panic("instruction VPERMT2Q takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMT2W__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMT2W(v[0], v[1], v[2]) - } else { - panic("instruction VPERMT2W takes exactly 3 operands") - } -} - -func __asm_proxy_VPERMW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPERMW(v[0], v[1], v[2]) - } else { - panic("instruction VPERMW takes exactly 3 operands") - } -} - -func __asm_proxy_VPEXPANDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPEXPANDD(v[0], v[1]) - } else { - panic("instruction VPEXPANDD takes exactly 2 operands") - } -} - -func __asm_proxy_VPEXPANDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPEXPANDQ(v[0], v[1]) - } else { - panic("instruction VPEXPANDQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPEXTRB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPEXTRB(v[0], v[1], v[2]) - } else { - panic("instruction VPEXTRB takes exactly 3 operands") - } -} - -func __asm_proxy_VPEXTRD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPEXTRD(v[0], v[1], v[2]) - } else { - panic("instruction VPEXTRD takes exactly 3 operands") - } -} - -func __asm_proxy_VPEXTRQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPEXTRQ(v[0], v[1], v[2]) - } else { - panic("instruction VPEXTRQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPEXTRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPEXTRW(v[0], v[1], v[2]) - } else { - panic("instruction VPEXTRW takes exactly 3 operands") - } -} - -func __asm_proxy_VPGATHERDD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VPGATHERDD(v[0], v[1]) - case 3 : return p.VPGATHERDD(v[0], v[1], v[2]) - default : panic("instruction VPGATHERDD takes 2 or 3 operands") - } -} - -func __asm_proxy_VPGATHERDQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VPGATHERDQ(v[0], v[1]) - case 3 : return p.VPGATHERDQ(v[0], v[1], v[2]) - default : panic("instruction VPGATHERDQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VPGATHERQD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VPGATHERQD(v[0], v[1]) - case 3 : return p.VPGATHERQD(v[0], v[1], v[2]) - default : panic("instruction VPGATHERQD takes 2 or 3 operands") - } -} - -func __asm_proxy_VPGATHERQQ__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VPGATHERQQ(v[0], v[1]) - case 3 : return p.VPGATHERQQ(v[0], v[1], v[2]) - default : panic("instruction VPGATHERQQ takes 2 or 3 operands") - } -} - -func __asm_proxy_VPHADDBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDBD(v[0], v[1]) - } else { - panic("instruction VPHADDBD takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDBQ(v[0], v[1]) - } else { - panic("instruction VPHADDBQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDBW(v[0], v[1]) - } else { - panic("instruction VPHADDBW takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPHADDD(v[0], v[1], v[2]) - } else { - panic("instruction VPHADDD takes exactly 3 operands") - } -} - -func __asm_proxy_VPHADDDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDDQ(v[0], v[1]) - } else { - panic("instruction VPHADDDQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPHADDSW(v[0], v[1], v[2]) - } else { - panic("instruction VPHADDSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPHADDUBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDUBD(v[0], v[1]) - } else { - panic("instruction VPHADDUBD takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDUBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDUBQ(v[0], v[1]) - } else { - panic("instruction VPHADDUBQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDUBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDUBW(v[0], v[1]) - } else { - panic("instruction VPHADDUBW takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDUDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDUDQ(v[0], v[1]) - } else { - panic("instruction VPHADDUDQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDUWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDUWD(v[0], v[1]) - } else { - panic("instruction VPHADDUWD takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDUWQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDUWQ(v[0], v[1]) - } else { - panic("instruction VPHADDUWQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPHADDW(v[0], v[1], v[2]) - } else { - panic("instruction VPHADDW takes exactly 3 operands") - } -} - -func __asm_proxy_VPHADDWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDWD(v[0], v[1]) - } else { - panic("instruction VPHADDWD takes exactly 2 operands") - } -} - -func __asm_proxy_VPHADDWQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHADDWQ(v[0], v[1]) - } else { - panic("instruction VPHADDWQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPHMINPOSUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHMINPOSUW(v[0], v[1]) - } else { - panic("instruction VPHMINPOSUW takes exactly 2 operands") - } -} - -func __asm_proxy_VPHSUBBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHSUBBW(v[0], v[1]) - } else { - panic("instruction VPHSUBBW takes exactly 2 operands") - } -} - -func __asm_proxy_VPHSUBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPHSUBD(v[0], v[1], v[2]) - } else { - panic("instruction VPHSUBD takes exactly 3 operands") - } -} - -func __asm_proxy_VPHSUBDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHSUBDQ(v[0], v[1]) - } else { - panic("instruction VPHSUBDQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPHSUBSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPHSUBSW(v[0], v[1], v[2]) - } else { - panic("instruction VPHSUBSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPHSUBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPHSUBW(v[0], v[1], v[2]) - } else { - panic("instruction VPHSUBW takes exactly 3 operands") - } -} - -func __asm_proxy_VPHSUBWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPHSUBWD(v[0], v[1]) - } else { - panic("instruction VPHSUBWD takes exactly 2 operands") - } -} - -func __asm_proxy_VPINSRB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPINSRB(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPINSRB takes exactly 4 operands") - } -} - -func __asm_proxy_VPINSRD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPINSRD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPINSRD takes exactly 4 operands") - } -} - -func __asm_proxy_VPINSRQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPINSRQ(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPINSRQ takes exactly 4 operands") - } -} - -func __asm_proxy_VPINSRW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPINSRW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPINSRW takes exactly 4 operands") - } -} - -func __asm_proxy_VPLZCNTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPLZCNTD(v[0], v[1]) - } else { - panic("instruction VPLZCNTD takes exactly 2 operands") - } -} - -func __asm_proxy_VPLZCNTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPLZCNTQ(v[0], v[1]) - } else { - panic("instruction VPLZCNTQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPMACSDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSDD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSDD takes exactly 4 operands") - } -} - -func __asm_proxy_VPMACSDQH__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSDQH(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSDQH takes exactly 4 operands") - } -} - -func __asm_proxy_VPMACSDQL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSDQL(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSDQL takes exactly 4 operands") - } -} - -func __asm_proxy_VPMACSSDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSSDD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSSDD takes exactly 4 operands") - } -} - -func __asm_proxy_VPMACSSDQH__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSSDQH(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSSDQH takes exactly 4 operands") - } -} - -func __asm_proxy_VPMACSSDQL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSSDQL(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSSDQL takes exactly 4 operands") - } -} - -func __asm_proxy_VPMACSSWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSSWD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSSWD takes exactly 4 operands") - } -} - -func __asm_proxy_VPMACSSWW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSSWW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSSWW takes exactly 4 operands") - } -} - -func __asm_proxy_VPMACSWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSWD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSWD takes exactly 4 operands") - } -} - -func __asm_proxy_VPMACSWW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMACSWW(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMACSWW takes exactly 4 operands") - } -} - -func __asm_proxy_VPMADCSSWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMADCSSWD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMADCSSWD takes exactly 4 operands") - } -} - -func __asm_proxy_VPMADCSWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPMADCSWD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPMADCSWD takes exactly 4 operands") - } -} - -func __asm_proxy_VPMADD52HUQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMADD52HUQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMADD52HUQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPMADD52LUQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMADD52LUQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMADD52LUQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPMADDUBSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMADDUBSW(v[0], v[1], v[2]) - } else { - panic("instruction VPMADDUBSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPMADDWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMADDWD(v[0], v[1], v[2]) - } else { - panic("instruction VPMADDWD takes exactly 3 operands") - } -} - -func __asm_proxy_VPMASKMOVD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMASKMOVD(v[0], v[1], v[2]) - } else { - panic("instruction VPMASKMOVD takes exactly 3 operands") - } -} - -func __asm_proxy_VPMASKMOVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMASKMOVQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMASKMOVQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPMAXSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMAXSB(v[0], v[1], v[2]) - } else { - panic("instruction VPMAXSB takes exactly 3 operands") - } -} - -func __asm_proxy_VPMAXSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMAXSD(v[0], v[1], v[2]) - } else { - panic("instruction VPMAXSD takes exactly 3 operands") - } -} - -func __asm_proxy_VPMAXSQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMAXSQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMAXSQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPMAXSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMAXSW(v[0], v[1], v[2]) - } else { - panic("instruction VPMAXSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPMAXUB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMAXUB(v[0], v[1], v[2]) - } else { - panic("instruction VPMAXUB takes exactly 3 operands") - } -} - -func __asm_proxy_VPMAXUD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMAXUD(v[0], v[1], v[2]) - } else { - panic("instruction VPMAXUD takes exactly 3 operands") - } -} - -func __asm_proxy_VPMAXUQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMAXUQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMAXUQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPMAXUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMAXUW(v[0], v[1], v[2]) - } else { - panic("instruction VPMAXUW takes exactly 3 operands") - } -} - -func __asm_proxy_VPMINSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMINSB(v[0], v[1], v[2]) - } else { - panic("instruction VPMINSB takes exactly 3 operands") - } -} - -func __asm_proxy_VPMINSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMINSD(v[0], v[1], v[2]) - } else { - panic("instruction VPMINSD takes exactly 3 operands") - } -} - -func __asm_proxy_VPMINSQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMINSQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMINSQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPMINSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMINSW(v[0], v[1], v[2]) - } else { - panic("instruction VPMINSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPMINUB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMINUB(v[0], v[1], v[2]) - } else { - panic("instruction VPMINUB takes exactly 3 operands") - } -} - -func __asm_proxy_VPMINUD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMINUD(v[0], v[1], v[2]) - } else { - panic("instruction VPMINUD takes exactly 3 operands") - } -} - -func __asm_proxy_VPMINUQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMINUQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMINUQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPMINUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMINUW(v[0], v[1], v[2]) - } else { - panic("instruction VPMINUW takes exactly 3 operands") - } -} - -func __asm_proxy_VPMOVB2M__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVB2M(v[0], v[1]) - } else { - panic("instruction VPMOVB2M takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVD2M__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVD2M(v[0], v[1]) - } else { - panic("instruction VPMOVD2M takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVDB(v[0], v[1]) - } else { - panic("instruction VPMOVDB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVDW(v[0], v[1]) - } else { - panic("instruction VPMOVDW takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVM2B__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVM2B(v[0], v[1]) - } else { - panic("instruction VPMOVM2B takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVM2D__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVM2D(v[0], v[1]) - } else { - panic("instruction VPMOVM2D takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVM2Q__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVM2Q(v[0], v[1]) - } else { - panic("instruction VPMOVM2Q takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVM2W__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVM2W(v[0], v[1]) - } else { - panic("instruction VPMOVM2W takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVMSKB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVMSKB(v[0], v[1]) - } else { - panic("instruction VPMOVMSKB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVQ2M__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVQ2M(v[0], v[1]) - } else { - panic("instruction VPMOVQ2M takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVQB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVQB(v[0], v[1]) - } else { - panic("instruction VPMOVQB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVQD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVQD(v[0], v[1]) - } else { - panic("instruction VPMOVQD takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVQW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVQW(v[0], v[1]) - } else { - panic("instruction VPMOVQW takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSDB(v[0], v[1]) - } else { - panic("instruction VPMOVSDB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSDW(v[0], v[1]) - } else { - panic("instruction VPMOVSDW takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSQB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSQB(v[0], v[1]) - } else { - panic("instruction VPMOVSQB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSQD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSQD(v[0], v[1]) - } else { - panic("instruction VPMOVSQD takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSQW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSQW(v[0], v[1]) - } else { - panic("instruction VPMOVSQW takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSWB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSWB(v[0], v[1]) - } else { - panic("instruction VPMOVSWB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSXBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSXBD(v[0], v[1]) - } else { - panic("instruction VPMOVSXBD takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSXBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSXBQ(v[0], v[1]) - } else { - panic("instruction VPMOVSXBQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSXBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSXBW(v[0], v[1]) - } else { - panic("instruction VPMOVSXBW takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSXDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSXDQ(v[0], v[1]) - } else { - panic("instruction VPMOVSXDQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSXWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSXWD(v[0], v[1]) - } else { - panic("instruction VPMOVSXWD takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVSXWQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVSXWQ(v[0], v[1]) - } else { - panic("instruction VPMOVSXWQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVUSDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVUSDB(v[0], v[1]) - } else { - panic("instruction VPMOVUSDB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVUSDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVUSDW(v[0], v[1]) - } else { - panic("instruction VPMOVUSDW takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVUSQB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVUSQB(v[0], v[1]) - } else { - panic("instruction VPMOVUSQB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVUSQD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVUSQD(v[0], v[1]) - } else { - panic("instruction VPMOVUSQD takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVUSQW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVUSQW(v[0], v[1]) - } else { - panic("instruction VPMOVUSQW takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVUSWB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVUSWB(v[0], v[1]) - } else { - panic("instruction VPMOVUSWB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVW2M__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVW2M(v[0], v[1]) - } else { - panic("instruction VPMOVW2M takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVWB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVWB(v[0], v[1]) - } else { - panic("instruction VPMOVWB takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVZXBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVZXBD(v[0], v[1]) - } else { - panic("instruction VPMOVZXBD takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVZXBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVZXBQ(v[0], v[1]) - } else { - panic("instruction VPMOVZXBQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVZXBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVZXBW(v[0], v[1]) - } else { - panic("instruction VPMOVZXBW takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVZXDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVZXDQ(v[0], v[1]) - } else { - panic("instruction VPMOVZXDQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVZXWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVZXWD(v[0], v[1]) - } else { - panic("instruction VPMOVZXWD takes exactly 2 operands") - } -} - -func __asm_proxy_VPMOVZXWQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPMOVZXWQ(v[0], v[1]) - } else { - panic("instruction VPMOVZXWQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPMULDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMULDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMULDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPMULHRSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMULHRSW(v[0], v[1], v[2]) - } else { - panic("instruction VPMULHRSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPMULHUW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMULHUW(v[0], v[1], v[2]) - } else { - panic("instruction VPMULHUW takes exactly 3 operands") - } -} - -func __asm_proxy_VPMULHW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMULHW(v[0], v[1], v[2]) - } else { - panic("instruction VPMULHW takes exactly 3 operands") - } -} - -func __asm_proxy_VPMULLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMULLD(v[0], v[1], v[2]) - } else { - panic("instruction VPMULLD takes exactly 3 operands") - } -} - -func __asm_proxy_VPMULLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMULLQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMULLQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPMULLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMULLW(v[0], v[1], v[2]) - } else { - panic("instruction VPMULLW takes exactly 3 operands") - } -} - -func __asm_proxy_VPMULTISHIFTQB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMULTISHIFTQB(v[0], v[1], v[2]) - } else { - panic("instruction VPMULTISHIFTQB takes exactly 3 operands") - } -} - -func __asm_proxy_VPMULUDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPMULUDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPMULUDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPOPCNTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPOPCNTD(v[0], v[1]) - } else { - panic("instruction VPOPCNTD takes exactly 2 operands") - } -} - -func __asm_proxy_VPOPCNTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPOPCNTQ(v[0], v[1]) - } else { - panic("instruction VPOPCNTQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPOR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPOR(v[0], v[1], v[2]) - } else { - panic("instruction VPOR takes exactly 3 operands") - } -} - -func __asm_proxy_VPORD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPORD(v[0], v[1], v[2]) - } else { - panic("instruction VPORD takes exactly 3 operands") - } -} - -func __asm_proxy_VPORQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPORQ(v[0], v[1], v[2]) - } else { - panic("instruction VPORQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPPERM__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPPERM(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPPERM takes exactly 4 operands") - } -} - -func __asm_proxy_VPROLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPROLD(v[0], v[1], v[2]) - } else { - panic("instruction VPROLD takes exactly 3 operands") - } -} - -func __asm_proxy_VPROLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPROLQ(v[0], v[1], v[2]) - } else { - panic("instruction VPROLQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPROLVD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPROLVD(v[0], v[1], v[2]) - } else { - panic("instruction VPROLVD takes exactly 3 operands") - } -} - -func __asm_proxy_VPROLVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPROLVQ(v[0], v[1], v[2]) - } else { - panic("instruction VPROLVQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPRORD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPRORD(v[0], v[1], v[2]) - } else { - panic("instruction VPRORD takes exactly 3 operands") - } -} - -func __asm_proxy_VPRORQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPRORQ(v[0], v[1], v[2]) - } else { - panic("instruction VPRORQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPRORVD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPRORVD(v[0], v[1], v[2]) - } else { - panic("instruction VPRORVD takes exactly 3 operands") - } -} - -func __asm_proxy_VPRORVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPRORVQ(v[0], v[1], v[2]) - } else { - panic("instruction VPRORVQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPROTB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPROTB(v[0], v[1], v[2]) - } else { - panic("instruction VPROTB takes exactly 3 operands") - } -} - -func __asm_proxy_VPROTD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPROTD(v[0], v[1], v[2]) - } else { - panic("instruction VPROTD takes exactly 3 operands") - } -} - -func __asm_proxy_VPROTQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPROTQ(v[0], v[1], v[2]) - } else { - panic("instruction VPROTQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPROTW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPROTW(v[0], v[1], v[2]) - } else { - panic("instruction VPROTW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSADBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSADBW(v[0], v[1], v[2]) - } else { - panic("instruction VPSADBW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSCATTERDD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPSCATTERDD(v[0], v[1]) - } else { - panic("instruction VPSCATTERDD takes exactly 2 operands") - } -} - -func __asm_proxy_VPSCATTERDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPSCATTERDQ(v[0], v[1]) - } else { - panic("instruction VPSCATTERDQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPSCATTERQD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPSCATTERQD(v[0], v[1]) - } else { - panic("instruction VPSCATTERQD takes exactly 2 operands") - } -} - -func __asm_proxy_VPSCATTERQQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPSCATTERQQ(v[0], v[1]) - } else { - panic("instruction VPSCATTERQQ takes exactly 2 operands") - } -} - -func __asm_proxy_VPSHAB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHAB(v[0], v[1], v[2]) - } else { - panic("instruction VPSHAB takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHAD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHAD(v[0], v[1], v[2]) - } else { - panic("instruction VPSHAD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHAQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHAQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSHAQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHAW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHAW(v[0], v[1], v[2]) - } else { - panic("instruction VPSHAW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHLB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHLB(v[0], v[1], v[2]) - } else { - panic("instruction VPSHLB takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHLD(v[0], v[1], v[2]) - } else { - panic("instruction VPSHLD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHLQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSHLQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHLW(v[0], v[1], v[2]) - } else { - panic("instruction VPSHLW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHUFB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHUFB(v[0], v[1], v[2]) - } else { - panic("instruction VPSHUFB takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHUFD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHUFD(v[0], v[1], v[2]) - } else { - panic("instruction VPSHUFD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHUFHW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHUFHW(v[0], v[1], v[2]) - } else { - panic("instruction VPSHUFHW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSHUFLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSHUFLW(v[0], v[1], v[2]) - } else { - panic("instruction VPSHUFLW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSIGNB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSIGNB(v[0], v[1], v[2]) - } else { - panic("instruction VPSIGNB takes exactly 3 operands") - } -} - -func __asm_proxy_VPSIGND__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSIGND(v[0], v[1], v[2]) - } else { - panic("instruction VPSIGND takes exactly 3 operands") - } -} - -func __asm_proxy_VPSIGNW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSIGNW(v[0], v[1], v[2]) - } else { - panic("instruction VPSIGNW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSLLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSLLD(v[0], v[1], v[2]) - } else { - panic("instruction VPSLLD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSLLDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSLLDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSLLDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSLLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSLLQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSLLQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSLLVD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSLLVD(v[0], v[1], v[2]) - } else { - panic("instruction VPSLLVD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSLLVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSLLVQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSLLVQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSLLVW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSLLVW(v[0], v[1], v[2]) - } else { - panic("instruction VPSLLVW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSLLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSLLW(v[0], v[1], v[2]) - } else { - panic("instruction VPSLLW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRAD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRAD(v[0], v[1], v[2]) - } else { - panic("instruction VPSRAD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRAQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRAQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSRAQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRAVD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRAVD(v[0], v[1], v[2]) - } else { - panic("instruction VPSRAVD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRAVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRAVQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSRAVQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRAVW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRAVW(v[0], v[1], v[2]) - } else { - panic("instruction VPSRAVW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRAW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRAW(v[0], v[1], v[2]) - } else { - panic("instruction VPSRAW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRLD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRLD(v[0], v[1], v[2]) - } else { - panic("instruction VPSRLD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRLDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRLDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSRLDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRLQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRLQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSRLQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRLVD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRLVD(v[0], v[1], v[2]) - } else { - panic("instruction VPSRLVD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRLVQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRLVQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSRLVQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRLVW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRLVW(v[0], v[1], v[2]) - } else { - panic("instruction VPSRLVW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSRLW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSRLW(v[0], v[1], v[2]) - } else { - panic("instruction VPSRLW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSUBB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSUBB(v[0], v[1], v[2]) - } else { - panic("instruction VPSUBB takes exactly 3 operands") - } -} - -func __asm_proxy_VPSUBD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSUBD(v[0], v[1], v[2]) - } else { - panic("instruction VPSUBD takes exactly 3 operands") - } -} - -func __asm_proxy_VPSUBQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSUBQ(v[0], v[1], v[2]) - } else { - panic("instruction VPSUBQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPSUBSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSUBSB(v[0], v[1], v[2]) - } else { - panic("instruction VPSUBSB takes exactly 3 operands") - } -} - -func __asm_proxy_VPSUBSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSUBSW(v[0], v[1], v[2]) - } else { - panic("instruction VPSUBSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSUBUSB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSUBUSB(v[0], v[1], v[2]) - } else { - panic("instruction VPSUBUSB takes exactly 3 operands") - } -} - -func __asm_proxy_VPSUBUSW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSUBUSW(v[0], v[1], v[2]) - } else { - panic("instruction VPSUBUSW takes exactly 3 operands") - } -} - -func __asm_proxy_VPSUBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPSUBW(v[0], v[1], v[2]) - } else { - panic("instruction VPSUBW takes exactly 3 operands") - } -} - -func __asm_proxy_VPTERNLOGD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPTERNLOGD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPTERNLOGD takes exactly 4 operands") - } -} - -func __asm_proxy_VPTERNLOGQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VPTERNLOGQ(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VPTERNLOGQ takes exactly 4 operands") - } -} - -func __asm_proxy_VPTEST__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VPTEST(v[0], v[1]) - } else { - panic("instruction VPTEST takes exactly 2 operands") - } -} - -func __asm_proxy_VPTESTMB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPTESTMB(v[0], v[1], v[2]) - } else { - panic("instruction VPTESTMB takes exactly 3 operands") - } -} - -func __asm_proxy_VPTESTMD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPTESTMD(v[0], v[1], v[2]) - } else { - panic("instruction VPTESTMD takes exactly 3 operands") - } -} - -func __asm_proxy_VPTESTMQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPTESTMQ(v[0], v[1], v[2]) - } else { - panic("instruction VPTESTMQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPTESTMW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPTESTMW(v[0], v[1], v[2]) - } else { - panic("instruction VPTESTMW takes exactly 3 operands") - } -} - -func __asm_proxy_VPTESTNMB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPTESTNMB(v[0], v[1], v[2]) - } else { - panic("instruction VPTESTNMB takes exactly 3 operands") - } -} - -func __asm_proxy_VPTESTNMD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPTESTNMD(v[0], v[1], v[2]) - } else { - panic("instruction VPTESTNMD takes exactly 3 operands") - } -} - -func __asm_proxy_VPTESTNMQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPTESTNMQ(v[0], v[1], v[2]) - } else { - panic("instruction VPTESTNMQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPTESTNMW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPTESTNMW(v[0], v[1], v[2]) - } else { - panic("instruction VPTESTNMW takes exactly 3 operands") - } -} - -func __asm_proxy_VPUNPCKHBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPUNPCKHBW(v[0], v[1], v[2]) - } else { - panic("instruction VPUNPCKHBW takes exactly 3 operands") - } -} - -func __asm_proxy_VPUNPCKHDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPUNPCKHDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPUNPCKHDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPUNPCKHQDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPUNPCKHQDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPUNPCKHQDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPUNPCKHWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPUNPCKHWD(v[0], v[1], v[2]) - } else { - panic("instruction VPUNPCKHWD takes exactly 3 operands") - } -} - -func __asm_proxy_VPUNPCKLBW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPUNPCKLBW(v[0], v[1], v[2]) - } else { - panic("instruction VPUNPCKLBW takes exactly 3 operands") - } -} - -func __asm_proxy_VPUNPCKLDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPUNPCKLDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPUNPCKLDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPUNPCKLQDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPUNPCKLQDQ(v[0], v[1], v[2]) - } else { - panic("instruction VPUNPCKLQDQ takes exactly 3 operands") - } -} - -func __asm_proxy_VPUNPCKLWD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPUNPCKLWD(v[0], v[1], v[2]) - } else { - panic("instruction VPUNPCKLWD takes exactly 3 operands") - } -} - -func __asm_proxy_VPXOR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPXOR(v[0], v[1], v[2]) - } else { - panic("instruction VPXOR takes exactly 3 operands") - } -} - -func __asm_proxy_VPXORD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPXORD(v[0], v[1], v[2]) - } else { - panic("instruction VPXORD takes exactly 3 operands") - } -} - -func __asm_proxy_VPXORQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VPXORQ(v[0], v[1], v[2]) - } else { - panic("instruction VPXORQ takes exactly 3 operands") - } -} - -func __asm_proxy_VRANGEPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VRANGEPD(v[0], v[1], v[2], v[3]) - case 5 : return p.VRANGEPD(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VRANGEPD takes 4 or 5 operands") - } -} - -func __asm_proxy_VRANGEPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VRANGEPS(v[0], v[1], v[2], v[3]) - case 5 : return p.VRANGEPS(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VRANGEPS takes 4 or 5 operands") - } -} - -func __asm_proxy_VRANGESD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VRANGESD(v[0], v[1], v[2], v[3]) - case 5 : return p.VRANGESD(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VRANGESD takes 4 or 5 operands") - } -} - -func __asm_proxy_VRANGESS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VRANGESS(v[0], v[1], v[2], v[3]) - case 5 : return p.VRANGESS(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VRANGESS takes 4 or 5 operands") - } -} - -func __asm_proxy_VRCP14PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VRCP14PD(v[0], v[1]) - } else { - panic("instruction VRCP14PD takes exactly 2 operands") - } -} - -func __asm_proxy_VRCP14PS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VRCP14PS(v[0], v[1]) - } else { - panic("instruction VRCP14PS takes exactly 2 operands") - } -} - -func __asm_proxy_VRCP14SD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VRCP14SD(v[0], v[1], v[2]) - } else { - panic("instruction VRCP14SD takes exactly 3 operands") - } -} - -func __asm_proxy_VRCP14SS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VRCP14SS(v[0], v[1], v[2]) - } else { - panic("instruction VRCP14SS takes exactly 3 operands") - } -} - -func __asm_proxy_VRCP28PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VRCP28PD(v[0], v[1]) - case 3 : return p.VRCP28PD(v[0], v[1], v[2]) - default : panic("instruction VRCP28PD takes 2 or 3 operands") - } -} - -func __asm_proxy_VRCP28PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VRCP28PS(v[0], v[1]) - case 3 : return p.VRCP28PS(v[0], v[1], v[2]) - default : panic("instruction VRCP28PS takes 2 or 3 operands") - } -} - -func __asm_proxy_VRCP28SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VRCP28SD(v[0], v[1], v[2]) - case 4 : return p.VRCP28SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VRCP28SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VRCP28SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VRCP28SS(v[0], v[1], v[2]) - case 4 : return p.VRCP28SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VRCP28SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VRCPPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VRCPPS(v[0], v[1]) - } else { - panic("instruction VRCPPS takes exactly 2 operands") - } -} - -func __asm_proxy_VRCPSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VRCPSS(v[0], v[1], v[2]) - } else { - panic("instruction VRCPSS takes exactly 3 operands") - } -} - -func __asm_proxy_VREDUCEPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VREDUCEPD(v[0], v[1], v[2]) - } else { - panic("instruction VREDUCEPD takes exactly 3 operands") - } -} - -func __asm_proxy_VREDUCEPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VREDUCEPS(v[0], v[1], v[2]) - } else { - panic("instruction VREDUCEPS takes exactly 3 operands") - } -} - -func __asm_proxy_VREDUCESD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VREDUCESD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VREDUCESD takes exactly 4 operands") - } -} - -func __asm_proxy_VREDUCESS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VREDUCESS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VREDUCESS takes exactly 4 operands") - } -} - -func __asm_proxy_VRNDSCALEPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VRNDSCALEPD(v[0], v[1], v[2]) - case 4 : return p.VRNDSCALEPD(v[0], v[1], v[2], v[3]) - default : panic("instruction VRNDSCALEPD takes 3 or 4 operands") - } -} - -func __asm_proxy_VRNDSCALEPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VRNDSCALEPS(v[0], v[1], v[2]) - case 4 : return p.VRNDSCALEPS(v[0], v[1], v[2], v[3]) - default : panic("instruction VRNDSCALEPS takes 3 or 4 operands") - } -} - -func __asm_proxy_VRNDSCALESD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VRNDSCALESD(v[0], v[1], v[2], v[3]) - case 5 : return p.VRNDSCALESD(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VRNDSCALESD takes 4 or 5 operands") - } -} - -func __asm_proxy_VRNDSCALESS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 4 : return p.VRNDSCALESS(v[0], v[1], v[2], v[3]) - case 5 : return p.VRNDSCALESS(v[0], v[1], v[2], v[3], v[4]) - default : panic("instruction VRNDSCALESS takes 4 or 5 operands") - } -} - -func __asm_proxy_VROUNDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VROUNDPD(v[0], v[1], v[2]) - } else { - panic("instruction VROUNDPD takes exactly 3 operands") - } -} - -func __asm_proxy_VROUNDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VROUNDPS(v[0], v[1], v[2]) - } else { - panic("instruction VROUNDPS takes exactly 3 operands") - } -} - -func __asm_proxy_VROUNDSD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VROUNDSD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VROUNDSD takes exactly 4 operands") - } -} - -func __asm_proxy_VROUNDSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VROUNDSS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VROUNDSS takes exactly 4 operands") - } -} - -func __asm_proxy_VRSQRT14PD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VRSQRT14PD(v[0], v[1]) - } else { - panic("instruction VRSQRT14PD takes exactly 2 operands") - } -} - -func __asm_proxy_VRSQRT14PS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VRSQRT14PS(v[0], v[1]) - } else { - panic("instruction VRSQRT14PS takes exactly 2 operands") - } -} - -func __asm_proxy_VRSQRT14SD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VRSQRT14SD(v[0], v[1], v[2]) - } else { - panic("instruction VRSQRT14SD takes exactly 3 operands") - } -} - -func __asm_proxy_VRSQRT14SS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VRSQRT14SS(v[0], v[1], v[2]) - } else { - panic("instruction VRSQRT14SS takes exactly 3 operands") - } -} - -func __asm_proxy_VRSQRT28PD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VRSQRT28PD(v[0], v[1]) - case 3 : return p.VRSQRT28PD(v[0], v[1], v[2]) - default : panic("instruction VRSQRT28PD takes 2 or 3 operands") - } -} - -func __asm_proxy_VRSQRT28PS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VRSQRT28PS(v[0], v[1]) - case 3 : return p.VRSQRT28PS(v[0], v[1], v[2]) - default : panic("instruction VRSQRT28PS takes 2 or 3 operands") - } -} - -func __asm_proxy_VRSQRT28SD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VRSQRT28SD(v[0], v[1], v[2]) - case 4 : return p.VRSQRT28SD(v[0], v[1], v[2], v[3]) - default : panic("instruction VRSQRT28SD takes 3 or 4 operands") - } -} - -func __asm_proxy_VRSQRT28SS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VRSQRT28SS(v[0], v[1], v[2]) - case 4 : return p.VRSQRT28SS(v[0], v[1], v[2], v[3]) - default : panic("instruction VRSQRT28SS takes 3 or 4 operands") - } -} - -func __asm_proxy_VRSQRTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VRSQRTPS(v[0], v[1]) - } else { - panic("instruction VRSQRTPS takes exactly 2 operands") - } -} - -func __asm_proxy_VRSQRTSS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VRSQRTSS(v[0], v[1], v[2]) - } else { - panic("instruction VRSQRTSS takes exactly 3 operands") - } -} - -func __asm_proxy_VSCALEFPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSCALEFPD(v[0], v[1], v[2]) - case 4 : return p.VSCALEFPD(v[0], v[1], v[2], v[3]) - default : panic("instruction VSCALEFPD takes 3 or 4 operands") - } -} - -func __asm_proxy_VSCALEFPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSCALEFPS(v[0], v[1], v[2]) - case 4 : return p.VSCALEFPS(v[0], v[1], v[2], v[3]) - default : panic("instruction VSCALEFPS takes 3 or 4 operands") - } -} - -func __asm_proxy_VSCALEFSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSCALEFSD(v[0], v[1], v[2]) - case 4 : return p.VSCALEFSD(v[0], v[1], v[2], v[3]) - default : panic("instruction VSCALEFSD takes 3 or 4 operands") - } -} - -func __asm_proxy_VSCALEFSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSCALEFSS(v[0], v[1], v[2]) - case 4 : return p.VSCALEFSS(v[0], v[1], v[2], v[3]) - default : panic("instruction VSCALEFSS takes 3 or 4 operands") - } -} - -func __asm_proxy_VSCATTERDPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VSCATTERDPD(v[0], v[1]) - } else { - panic("instruction VSCATTERDPD takes exactly 2 operands") - } -} - -func __asm_proxy_VSCATTERDPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VSCATTERDPS(v[0], v[1]) - } else { - panic("instruction VSCATTERDPS takes exactly 2 operands") - } -} - -func __asm_proxy_VSCATTERPF0DPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VSCATTERPF0DPD(v[0]) - } else { - panic("instruction VSCATTERPF0DPD takes exactly 1 operand") - } -} - -func __asm_proxy_VSCATTERPF0DPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VSCATTERPF0DPS(v[0]) - } else { - panic("instruction VSCATTERPF0DPS takes exactly 1 operand") - } -} - -func __asm_proxy_VSCATTERPF0QPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VSCATTERPF0QPD(v[0]) - } else { - panic("instruction VSCATTERPF0QPD takes exactly 1 operand") - } -} - -func __asm_proxy_VSCATTERPF0QPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VSCATTERPF0QPS(v[0]) - } else { - panic("instruction VSCATTERPF0QPS takes exactly 1 operand") - } -} - -func __asm_proxy_VSCATTERPF1DPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VSCATTERPF1DPD(v[0]) - } else { - panic("instruction VSCATTERPF1DPD takes exactly 1 operand") - } -} - -func __asm_proxy_VSCATTERPF1DPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VSCATTERPF1DPS(v[0]) - } else { - panic("instruction VSCATTERPF1DPS takes exactly 1 operand") - } -} - -func __asm_proxy_VSCATTERPF1QPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VSCATTERPF1QPD(v[0]) - } else { - panic("instruction VSCATTERPF1QPD takes exactly 1 operand") - } -} - -func __asm_proxy_VSCATTERPF1QPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VSCATTERPF1QPS(v[0]) - } else { - panic("instruction VSCATTERPF1QPS takes exactly 1 operand") - } -} - -func __asm_proxy_VSCATTERQPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VSCATTERQPD(v[0], v[1]) - } else { - panic("instruction VSCATTERQPD takes exactly 2 operands") - } -} - -func __asm_proxy_VSCATTERQPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VSCATTERQPS(v[0], v[1]) - } else { - panic("instruction VSCATTERQPS takes exactly 2 operands") - } -} - -func __asm_proxy_VSHUFF32X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VSHUFF32X4(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VSHUFF32X4 takes exactly 4 operands") - } -} - -func __asm_proxy_VSHUFF64X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VSHUFF64X2(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VSHUFF64X2 takes exactly 4 operands") - } -} - -func __asm_proxy_VSHUFI32X4__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VSHUFI32X4(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VSHUFI32X4 takes exactly 4 operands") - } -} - -func __asm_proxy_VSHUFI64X2__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VSHUFI64X2(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VSHUFI64X2 takes exactly 4 operands") - } -} - -func __asm_proxy_VSHUFPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VSHUFPD(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VSHUFPD takes exactly 4 operands") - } -} - -func __asm_proxy_VSHUFPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 4 { - return p.VSHUFPS(v[0], v[1], v[2], v[3]) - } else { - panic("instruction VSHUFPS takes exactly 4 operands") - } -} - -func __asm_proxy_VSQRTPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VSQRTPD(v[0], v[1]) - case 3 : return p.VSQRTPD(v[0], v[1], v[2]) - default : panic("instruction VSQRTPD takes 2 or 3 operands") - } -} - -func __asm_proxy_VSQRTPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VSQRTPS(v[0], v[1]) - case 3 : return p.VSQRTPS(v[0], v[1], v[2]) - default : panic("instruction VSQRTPS takes 2 or 3 operands") - } -} - -func __asm_proxy_VSQRTSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSQRTSD(v[0], v[1], v[2]) - case 4 : return p.VSQRTSD(v[0], v[1], v[2], v[3]) - default : panic("instruction VSQRTSD takes 3 or 4 operands") - } -} - -func __asm_proxy_VSQRTSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSQRTSS(v[0], v[1], v[2]) - case 4 : return p.VSQRTSS(v[0], v[1], v[2], v[3]) - default : panic("instruction VSQRTSS takes 3 or 4 operands") - } -} - -func __asm_proxy_VSTMXCSR__(p *Program, v ...interface{}) *Instruction { - if len(v) == 1 { - return p.VSTMXCSR(v[0]) - } else { - panic("instruction VSTMXCSR takes exactly 1 operand") - } -} - -func __asm_proxy_VSUBPD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSUBPD(v[0], v[1], v[2]) - case 4 : return p.VSUBPD(v[0], v[1], v[2], v[3]) - default : panic("instruction VSUBPD takes 3 or 4 operands") - } -} - -func __asm_proxy_VSUBPS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSUBPS(v[0], v[1], v[2]) - case 4 : return p.VSUBPS(v[0], v[1], v[2], v[3]) - default : panic("instruction VSUBPS takes 3 or 4 operands") - } -} - -func __asm_proxy_VSUBSD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSUBSD(v[0], v[1], v[2]) - case 4 : return p.VSUBSD(v[0], v[1], v[2], v[3]) - default : panic("instruction VSUBSD takes 3 or 4 operands") - } -} - -func __asm_proxy_VSUBSS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 3 : return p.VSUBSS(v[0], v[1], v[2]) - case 4 : return p.VSUBSS(v[0], v[1], v[2], v[3]) - default : panic("instruction VSUBSS takes 3 or 4 operands") - } -} - -func __asm_proxy_VTESTPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VTESTPD(v[0], v[1]) - } else { - panic("instruction VTESTPD takes exactly 2 operands") - } -} - -func __asm_proxy_VTESTPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.VTESTPS(v[0], v[1]) - } else { - panic("instruction VTESTPS takes exactly 2 operands") - } -} - -func __asm_proxy_VUCOMISD__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VUCOMISD(v[0], v[1]) - case 3 : return p.VUCOMISD(v[0], v[1], v[2]) - default : panic("instruction VUCOMISD takes 2 or 3 operands") - } -} - -func __asm_proxy_VUCOMISS__(p *Program, v ...interface{}) *Instruction { - switch len(v) { - case 2 : return p.VUCOMISS(v[0], v[1]) - case 3 : return p.VUCOMISS(v[0], v[1], v[2]) - default : panic("instruction VUCOMISS takes 2 or 3 operands") - } -} - -func __asm_proxy_VUNPCKHPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VUNPCKHPD(v[0], v[1], v[2]) - } else { - panic("instruction VUNPCKHPD takes exactly 3 operands") - } -} - -func __asm_proxy_VUNPCKHPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VUNPCKHPS(v[0], v[1], v[2]) - } else { - panic("instruction VUNPCKHPS takes exactly 3 operands") - } -} - -func __asm_proxy_VUNPCKLPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VUNPCKLPD(v[0], v[1], v[2]) - } else { - panic("instruction VUNPCKLPD takes exactly 3 operands") - } -} - -func __asm_proxy_VUNPCKLPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VUNPCKLPS(v[0], v[1], v[2]) - } else { - panic("instruction VUNPCKLPS takes exactly 3 operands") - } -} - -func __asm_proxy_VXORPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VXORPD(v[0], v[1], v[2]) - } else { - panic("instruction VXORPD takes exactly 3 operands") - } -} - -func __asm_proxy_VXORPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 3 { - return p.VXORPS(v[0], v[1], v[2]) - } else { - panic("instruction VXORPS takes exactly 3 operands") - } -} - -func __asm_proxy_VZEROALL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.VZEROALL() - } else { - panic("instruction VZEROALL takes no operands") - } -} - -func __asm_proxy_VZEROUPPER__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.VZEROUPPER() - } else { - panic("instruction VZEROUPPER takes no operands") - } -} - -func __asm_proxy_XADDB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XADDB(v[0], v[1]) - } else { - panic("instruction XADDB takes exactly 2 operands") - } -} - -func __asm_proxy_XADDL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XADDL(v[0], v[1]) - } else { - panic("instruction XADDL takes exactly 2 operands") - } -} - -func __asm_proxy_XADDQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XADDQ(v[0], v[1]) - } else { - panic("instruction XADDQ takes exactly 2 operands") - } -} - -func __asm_proxy_XADDW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XADDW(v[0], v[1]) - } else { - panic("instruction XADDW takes exactly 2 operands") - } -} - -func __asm_proxy_XCHGB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XCHGB(v[0], v[1]) - } else { - panic("instruction XCHGB takes exactly 2 operands") - } -} - -func __asm_proxy_XCHGL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XCHGL(v[0], v[1]) - } else { - panic("instruction XCHGL takes exactly 2 operands") - } -} - -func __asm_proxy_XCHGQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XCHGQ(v[0], v[1]) - } else { - panic("instruction XCHGQ takes exactly 2 operands") - } -} - -func __asm_proxy_XCHGW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XCHGW(v[0], v[1]) - } else { - panic("instruction XCHGW takes exactly 2 operands") - } -} - -func __asm_proxy_XGETBV__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.XGETBV() - } else { - panic("instruction XGETBV takes no operands") - } -} - -func __asm_proxy_XLATB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 0 { - return p.XLATB() - } else { - panic("instruction XLATB takes no operands") - } -} - -func __asm_proxy_XORB__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XORB(v[0], v[1]) - } else { - panic("instruction XORB takes exactly 2 operands") - } -} - -func __asm_proxy_XORL__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XORL(v[0], v[1]) - } else { - panic("instruction XORL takes exactly 2 operands") - } -} - -func __asm_proxy_XORPD__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XORPD(v[0], v[1]) - } else { - panic("instruction XORPD takes exactly 2 operands") - } -} - -func __asm_proxy_XORPS__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XORPS(v[0], v[1]) - } else { - panic("instruction XORPS takes exactly 2 operands") - } -} - -func __asm_proxy_XORQ__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XORQ(v[0], v[1]) - } else { - panic("instruction XORQ takes exactly 2 operands") - } -} - -func __asm_proxy_XORW__(p *Program, v ...interface{}) *Instruction { - if len(v) == 2 { - return p.XORW(v[0], v[1]) - } else { - panic("instruction XORW takes exactly 2 operands") - } -} diff --git a/vendor/github.com/cloudwego/iasm/x86_64/registers.go b/vendor/github.com/cloudwego/iasm/x86_64/registers.go deleted file mode 100644 index 574c2ee96..000000000 --- a/vendor/github.com/cloudwego/iasm/x86_64/registers.go +++ /dev/null @@ -1,693 +0,0 @@ -// -// 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", -} diff --git a/vendor/github.com/cloudwego/iasm/x86_64/utils.go b/vendor/github.com/cloudwego/iasm/x86_64/utils.go deleted file mode 100644 index 56c107ff5..000000000 --- a/vendor/github.com/cloudwego/iasm/x86_64/utils.go +++ /dev/null @@ -1,147 +0,0 @@ -// -// 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) diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go index b59042c6f..068d00f79 100644 --- a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go +++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go @@ -52,10 +52,15 @@ func InstallShieldCab(raw []byte, _ uint32) bool { } // Zstd matches a Zstandard archive file. +// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md func Zstd(raw []byte, limit uint32) bool { - return len(raw) >= 4 && - (0x22 <= raw[0] && raw[0] <= 0x28 || raw[0] == 0x1E) && // Different Zstandard versions. - bytes.HasPrefix(raw[1:], []byte{0xB5, 0x2F, 0xFD}) + if len(raw) < 4 { + return false + } + sig := binary.LittleEndian.Uint32(raw) + // Check for Zstandard frames and skippable frames. + return (sig >= 0xFD2FB522 && sig <= 0xFD2FB528) || + (sig >= 0x184D2A50 && sig <= 0x184D2A5F) } // CRX matches a Chrome extension file: a zip archive prepended by a package header. diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go index f866113fd..f6c64829d 100644 --- a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go +++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go @@ -110,3 +110,22 @@ func zipContains(raw, sig []byte, msoCheck bool) bool { } return false } + +// APK matches an Android Package Archive. +// The source of signatures is https://github.com/file/file/blob/1778642b8ba3d947a779a36fcd81f8e807220a19/magic/Magdir/archive#L1820-L1887 +func APK(raw []byte, _ uint32) bool { + apkSignatures := [][]byte{ + []byte("AndroidManifest.xml"), + []byte("META-INF/com/android/build/gradle/app-metadata.properties"), + []byte("classes.dex"), + []byte("resources.arsc"), + []byte("res/drawable"), + } + for _, sig := range apkSignatures { + if zipContains(raw, sig, false) { + return true + } + } + + return false +} diff --git a/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md b/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md index a45a3021b..f9bf03cba 100644 --- a/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md +++ b/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md @@ -1,4 +1,4 @@ -## 177 Supported MIME types +## 178 Supported MIME types This file is automatically generated when running tests. Do not edit manually. Extension | MIME type | Aliases @@ -11,6 +11,7 @@ Extension | MIME type | Aliases **.docx** | application/vnd.openxmlformats-officedocument.wordprocessingml.document | - **.pptx** | application/vnd.openxmlformats-officedocument.presentationml.presentation | - **.epub** | application/epub+zip | - +**.apk** | application/vnd.android.package-archive | - **.jar** | application/jar | - **.odt** | application/vnd.oasis.opendocument.text | application/x-vnd.oasis.opendocument.text **.ott** | application/vnd.oasis.opendocument.text-template | application/x-vnd.oasis.opendocument.text-template diff --git a/vendor/github.com/gabriel-vasile/mimetype/tree.go b/vendor/github.com/gabriel-vasile/mimetype/tree.go index 771e302bc..b5f566227 100644 --- a/vendor/github.com/gabriel-vasile/mimetype/tree.go +++ b/vendor/github.com/gabriel-vasile/mimetype/tree.go @@ -44,7 +44,11 @@ func([]byte, uint32) bool { return true }, "application/gzip-compressed", "application/x-gzip-compressed", "gzip/document") sevenZ = newMIME("application/x-7z-compressed", ".7z", magic.SevenZ) - zip = newMIME("application/zip", ".zip", magic.Zip, xlsx, docx, pptx, epub, jar, odt, ods, odp, odg, odf, odc, sxc). + // APK must be checked before JAR because APK is a subset of JAR. + // This means APK should be a child of JAR detector, but in practice, + // the decisive signature for JAR might be located at the end of the file + // and not reachable because of library readLimit. + zip = newMIME("application/zip", ".zip", magic.Zip, xlsx, docx, pptx, epub, apk, jar, odt, ods, odp, odg, odf, odc, sxc). alias("application/x-zip", "application/x-zip-compressed") tar = newMIME("application/x-tar", ".tar", magic.Tar) xar = newMIME("application/x-xar", ".xar", magic.Xar) @@ -57,6 +61,7 @@ func([]byte, uint32) bool { return true }, pptx = newMIME("application/vnd.openxmlformats-officedocument.presentationml.presentation", ".pptx", magic.Pptx) epub = newMIME("application/epub+zip", ".epub", magic.Epub) jar = newMIME("application/jar", ".jar", magic.Jar) + apk = newMIME("application/vnd.android.package-archive", ".apk", magic.APK) ole = newMIME("application/x-ole-storage", "", magic.Ole, msi, aaf, msg, xls, pub, ppt, doc) msi = newMIME("application/x-ms-installer", ".msi", magic.Msi). alias("application/x-windows-installer", "application/x-msi") diff --git a/vendor/github.com/gin-contrib/gzip/README.md b/vendor/github.com/gin-contrib/gzip/README.md index 86469858f..bb651977c 100644 --- a/vendor/github.com/gin-contrib/gzip/README.md +++ b/vendor/github.com/gin-contrib/gzip/README.md @@ -49,7 +49,7 @@ func main() { } ``` -Customized Excluded Extensions +### Customized Excluded Extensions ```go package main @@ -77,7 +77,7 @@ func main() { } ``` -Customized Excluded Paths +### Customized Excluded Paths ```go package main @@ -105,7 +105,7 @@ func main() { } ``` -Customized Excluded Paths +### Customized Excluded Paths with Regex ```go package main @@ -132,3 +132,38 @@ func main() { } } ``` + +### Server Push + +```go +package main + +import ( + "fmt" + "log" + "net/http" + "time" + + "github.com/gin-contrib/gzip" + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + r.Use(gzip.Gzip(gzip.DefaultCompression)) + r.GET("/stream", func(c *gin.Context) { + c.Header("Content-Type", "text/event-stream") + c.Header("Connection", "keep-alive") + for i := 0; i < 10; i++ { + fmt.Fprintf(c.Writer, "id: %d\ndata: tick %d\n\n", i, time.Now().Unix()) + c.Writer.Flush() + time.Sleep(1 * time.Second) + } + }) + + // Listen and Server in 0.0.0.0:8080 + if err := r.Run(":8080"); err != nil { + log.Fatal(err) + } +} +``` diff --git a/vendor/github.com/gin-contrib/gzip/gzip.go b/vendor/github.com/gin-contrib/gzip/gzip.go index 529c62df6..931945a88 100644 --- a/vendor/github.com/gin-contrib/gzip/gzip.go +++ b/vendor/github.com/gin-contrib/gzip/gzip.go @@ -1,7 +1,11 @@ package gzip import ( + "bufio" "compress/gzip" + "errors" + "net" + "net/http" "github.com/gin-gonic/gin" ) @@ -11,6 +15,7 @@ BestSpeed = gzip.BestSpeed DefaultCompression = gzip.DefaultCompression NoCompression = gzip.NoCompression + HuffmanOnly = gzip.HuffmanOnly ) func Gzip(level int, options ...Option) gin.HandlerFunc { @@ -32,8 +37,31 @@ func (g *gzipWriter) Write(data []byte) (int, error) { return g.writer.Write(data) } +func (g *gzipWriter) Flush() { + _ = g.writer.Flush() + g.ResponseWriter.Flush() +} + // Fix: https://github.com/mholt/caddy/issues/38 func (g *gzipWriter) WriteHeader(code int) { g.Header().Del("Content-Length") g.ResponseWriter.WriteHeader(code) } + +// Ensure gzipWriter implements the http.Hijacker interface. +// This will cause a compile-time error if gzipWriter does not implement all methods of the http.Hijacker interface. +var _ http.Hijacker = (*gzipWriter)(nil) + +// Hijack allows the caller to take over the connection from the HTTP server. +// After a call to Hijack, the HTTP server library will not do anything else with the connection. +// It becomes the caller's responsibility to manage and close the connection. +// +// It returns the underlying net.Conn, a buffered reader/writer for the connection, and an error +// if the ResponseWriter does not support the Hijacker interface. +func (g *gzipWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + hijacker, ok := g.ResponseWriter.(http.Hijacker) + if !ok { + return nil, nil, errors.New("the ResponseWriter doesn't support the Hijacker interface") + } + return hijacker.Hijack() +} diff --git a/vendor/github.com/gin-contrib/gzip/handler.go b/vendor/github.com/gin-contrib/gzip/handler.go index ee9eb9f66..412c8386b 100644 --- a/vendor/github.com/gin-contrib/gzip/handler.go +++ b/vendor/github.com/gin-contrib/gzip/handler.go @@ -2,84 +2,114 @@ import ( "compress/gzip" - "fmt" "io" "net/http" "path/filepath" + "strconv" "strings" "sync" "github.com/gin-gonic/gin" ) +const ( + headerAcceptEncoding = "Accept-Encoding" + headerContentEncoding = "Content-Encoding" + headerVary = "Vary" +) + type gzipHandler struct { - *Options + *config gzPool sync.Pool } -func newGzipHandler(level int, options ...Option) *gzipHandler { +func isCompressionLevelValid(level int) bool { + return level == gzip.DefaultCompression || + level == gzip.NoCompression || + (level >= gzip.BestSpeed && level <= gzip.BestCompression) +} + +func newGzipHandler(level int, opts ...Option) *gzipHandler { + cfg := &config{ + excludedExtensions: DefaultExcludedExtentions, + } + + // Apply each option to the config + for _, o := range opts { + o.apply(cfg) + } + + if !isCompressionLevelValid(level) { + // For web content, level 4 seems to be a sweet spot. + level = 4 + } + handler := &gzipHandler{ - Options: DefaultOptions, + config: cfg, gzPool: sync.Pool{ New: func() interface{} { - gz, err := gzip.NewWriterLevel(io.Discard, level) - if err != nil { - panic(err) - } + gz, _ := gzip.NewWriterLevel(io.Discard, level) return gz }, }, } - for _, setter := range options { - setter(handler.Options) - } return handler } +// Handle is a middleware function for handling gzip compression in HTTP requests and responses. +// It first checks if the request has a "Content-Encoding" header set to "gzip" and if a decompression +// function is provided, it will call the decompression function. If the handler is set to decompress only, +// or if the custom compression decision function indicates not to compress, it will return early. +// Otherwise, it retrieves a gzip.Writer from the pool, sets the necessary response headers for gzip encoding, +// and wraps the response writer with a gzipWriter. After the request is processed, it ensures the gzip.Writer +// is properly closed and the "Content-Length" header is set based on the response size. func (g *gzipHandler) Handle(c *gin.Context) { - if fn := g.DecompressFn; fn != nil && c.Request.Header.Get("Content-Encoding") == "gzip" { + if fn := g.decompressFn; fn != nil && strings.Contains(c.Request.Header.Get("Content-Encoding"), "gzip") { fn(c) } - if !g.shouldCompress(c.Request) { + if g.decompressOnly || + (g.customShouldCompressFn != nil && !g.customShouldCompressFn(c)) || + (g.customShouldCompressFn == nil && !g.shouldCompress(c.Request)) { return } gz := g.gzPool.Get().(*gzip.Writer) - defer g.gzPool.Put(gz) - defer gz.Reset(io.Discard) gz.Reset(c.Writer) - c.Header("Content-Encoding", "gzip") - c.Header("Vary", "Accept-Encoding") + c.Header(headerContentEncoding, "gzip") + c.Writer.Header().Add(headerVary, headerAcceptEncoding) + // check ETag Header + originalEtag := c.GetHeader("ETag") + if originalEtag != "" && !strings.HasPrefix(originalEtag, "W/") { + c.Header("ETag", "W/"+originalEtag) + } c.Writer = &gzipWriter{c.Writer, gz} defer func() { if c.Writer.Size() < 0 { // do not write gzip footer when nothing is written to the response body gz.Reset(io.Discard) } - gz.Close() - c.Header("Content-Length", fmt.Sprint(c.Writer.Size())) + _ = gz.Close() + if c.Writer.Size() > -1 { + c.Header("Content-Length", strconv.Itoa(c.Writer.Size())) + } + g.gzPool.Put(gz) }() c.Next() } func (g *gzipHandler) shouldCompress(req *http.Request) bool { - if !strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") || - strings.Contains(req.Header.Get("Connection"), "Upgrade") || - strings.Contains(req.Header.Get("Accept"), "text/event-stream") { + if !strings.Contains(req.Header.Get(headerAcceptEncoding), "gzip") || + strings.Contains(req.Header.Get("Connection"), "Upgrade") { return false } + // Check if the request path is excluded from compression extension := filepath.Ext(req.URL.Path) - if g.ExcludedExtensions.Contains(extension) { - return false - } - - if g.ExcludedPaths.Contains(req.URL.Path) { - return false - } - if g.ExcludedPathesRegexs.Contains(req.URL.Path) { + if g.excludedExtensions.Contains(extension) || + g.excludedPaths.Contains(req.URL.Path) || + g.excludedPathesRegexs.Contains(req.URL.Path) { return false } diff --git a/vendor/github.com/gin-contrib/gzip/options.go b/vendor/github.com/gin-contrib/gzip/options.go index c0953e08a..67607f51b 100644 --- a/vendor/github.com/gin-contrib/gzip/options.go +++ b/vendor/github.com/gin-contrib/gzip/options.go @@ -2,6 +2,8 @@ import ( "compress/gzip" + "errors" + "io" "net/http" "regexp" "strings" @@ -10,58 +12,134 @@ ) var ( + // DefaultExcludedExtentions is a predefined list of file extensions that should be excluded from gzip compression. + // These extensions typically represent image files that are already compressed + // and do not benefit from additional compression. DefaultExcludedExtentions = NewExcludedExtensions([]string{ ".png", ".gif", ".jpeg", ".jpg", }) - DefaultOptions = &Options{ - ExcludedExtensions: DefaultExcludedExtentions, - } + // ErrUnsupportedContentEncoding is an error that indicates the content encoding + // is not supported by the application. + ErrUnsupportedContentEncoding = errors.New("unsupported content encoding") ) -type Options struct { - ExcludedExtensions ExcludedExtensions - ExcludedPaths ExcludedPaths - ExcludedPathesRegexs ExcludedPathesRegexs - DecompressFn func(c *gin.Context) +// Option is an interface that defines a method to apply a configuration +// to a given config instance. Implementations of this interface can be +// used to modify the configuration settings of the logger. +type Option interface { + apply(*config) } -type Option func(*Options) +// Ensures that optionFunc implements the Option interface at compile time. +// If optionFunc does not implement Option, a compile-time error will occur. +var _ Option = (*optionFunc)(nil) +type optionFunc func(*config) + +func (o optionFunc) apply(c *config) { + o(c) +} + +type config struct { + excludedExtensions ExcludedExtensions + excludedPaths ExcludedPaths + excludedPathesRegexs ExcludedPathesRegexs + decompressFn func(c *gin.Context) + decompressOnly bool + customShouldCompressFn func(c *gin.Context) bool +} + +// WithExcludedExtensions returns an Option that sets the ExcludedExtensions field of the Options struct. +// Parameters: +// - args: []string - A slice of file extensions to exclude from gzip compression. func WithExcludedExtensions(args []string) Option { - return func(o *Options) { - o.ExcludedExtensions = NewExcludedExtensions(args) - } + return optionFunc(func(o *config) { + o.excludedExtensions = NewExcludedExtensions(args) + }) } +// WithExcludedPaths returns an Option that sets the ExcludedPaths field of the Options struct. +// Parameters: +// - args: []string - A slice of paths to exclude from gzip compression. func WithExcludedPaths(args []string) Option { - return func(o *Options) { - o.ExcludedPaths = NewExcludedPaths(args) - } + return optionFunc(func(o *config) { + o.excludedPaths = NewExcludedPaths(args) + }) } +// WithExcludedPathsRegexs returns an Option that sets the ExcludedPathesRegexs field of the Options struct. +// Parameters: +// - args: []string - A slice of regex patterns to exclude paths from gzip compression. func WithExcludedPathsRegexs(args []string) Option { - return func(o *Options) { - o.ExcludedPathesRegexs = NewExcludedPathesRegexs(args) - } + return optionFunc(func(o *config) { + o.excludedPathesRegexs = NewExcludedPathesRegexs(args) + }) } +// WithDecompressFn returns an Option that sets the DecompressFn field of the Options struct. +// Parameters: +// - decompressFn: func(c *gin.Context) - A function to handle decompression of incoming requests. func WithDecompressFn(decompressFn func(c *gin.Context)) Option { - return func(o *Options) { - o.DecompressFn = decompressFn - } + return optionFunc(func(o *config) { + o.decompressFn = decompressFn + }) +} + +// WithDecompressOnly is an option that configures the gzip middleware to only +// decompress incoming requests without compressing the responses. When this +// option is enabled, the middleware will set the DecompressOnly field of the +// Options struct to true. +func WithDecompressOnly() Option { + return optionFunc(func(o *config) { + o.decompressOnly = true + }) +} + +// WithCustomShouldCompressFn returns an Option that sets the CustomShouldCompressFn field of the Options struct. +// Parameters: +// - fn: func(c *gin.Context) bool - A function to determine if a request should be compressed. +// The function should return true if the request should be compressed, false otherwise. +// If the function returns false, the middleware will not compress the response. +// If the function is nil, the middleware will use the default logic to determine +// if the response should be compressed. +// +// Returns: +// - Option - An option that sets the CustomShouldCompressFn field of the Options struct. +// +// Example: +// +// router.Use(gzip.Gzip(gzip.DefaultCompression, gzip.WithCustomShouldCompressFn(func(c *gin.Context) bool { +// return c.Request.URL.Path != "/no-compress" +// }))) +func WithCustomShouldCompressFn(fn func(c *gin.Context) bool) Option { + return optionFunc(func(o *config) { + o.customShouldCompressFn = fn + }) } // Using map for better lookup performance type ExcludedExtensions map[string]struct{} +// NewExcludedExtensions creates a new ExcludedExtensions map from a slice of file extensions. +// Parameters: +// - extensions: []string - A slice of file extensions to exclude from gzip compression. +// +// Returns: +// - ExcludedExtensions - A map of excluded file extensions. func NewExcludedExtensions(extensions []string) ExcludedExtensions { - res := make(ExcludedExtensions) + res := make(ExcludedExtensions, len(extensions)) for _, e := range extensions { res[e] = struct{}{} } return res } +// Contains checks if a given file extension is in the ExcludedExtensions map. +// Parameters: +// - target: string - The file extension to check. +// +// Returns: +// - bool - True if the extension is excluded, false otherwise. func (e ExcludedExtensions) Contains(target string) bool { _, ok := e[target] return ok @@ -69,10 +147,22 @@ func (e ExcludedExtensions) Contains(target string) bool { type ExcludedPaths []string +// NewExcludedPaths creates a new ExcludedPaths slice from a slice of paths. +// Parameters: +// - paths: []string - A slice of paths to exclude from gzip compression. +// +// Returns: +// - ExcludedPaths - A slice of excluded paths. func NewExcludedPaths(paths []string) ExcludedPaths { return ExcludedPaths(paths) } +// Contains checks if a given request URI starts with any of the excluded paths. +// Parameters: +// - requestURI: string - The request URI to check. +// +// Returns: +// - bool - True if the URI starts with an excluded path, false otherwise. func (e ExcludedPaths) Contains(requestURI string) bool { for _, path := range e { if strings.HasPrefix(requestURI, path) { @@ -84,14 +174,26 @@ func (e ExcludedPaths) Contains(requestURI string) bool { type ExcludedPathesRegexs []*regexp.Regexp +// NewExcludedPathesRegexs creates a new ExcludedPathesRegexs slice from a slice of regex patterns. +// Parameters: +// - regexs: []string - A slice of regex patterns to exclude paths from gzip compression. +// +// Returns: +// - ExcludedPathesRegexs - A slice of excluded path regex patterns. func NewExcludedPathesRegexs(regexs []string) ExcludedPathesRegexs { - result := make([]*regexp.Regexp, len(regexs)) + result := make(ExcludedPathesRegexs, len(regexs)) for i, reg := range regexs { result[i] = regexp.MustCompile(reg) } return result } +// Contains checks if a given request URI matches any of the excluded path regex patterns. +// Parameters: +// - requestURI: string - The request URI to check. +// +// Returns: +// - bool - True if the URI matches an excluded path regex pattern, false otherwise. func (e ExcludedPathesRegexs) Contains(requestURI string) bool { for _, reg := range e { if reg.MatchString(requestURI) { @@ -101,16 +203,68 @@ func (e ExcludedPathesRegexs) Contains(requestURI string) bool { return false } +// DefaultDecompressHandle is a middleware function for the Gin framework that +// decompresses the request body if it is gzip encoded. It checks if the request +// body is nil and returns immediately if it is. Otherwise, it attempts to create +// a new gzip reader from the request body. If an error occurs during this process, +// it aborts the request with a 400 Bad Request status and the error. If successful, +// it removes the "Content-Encoding" and "Content-Length" headers from the request +// and replaces the request body with the decompressed reader. +// +// Parameters: +// - c: *gin.Context - The Gin context for the current request. func DefaultDecompressHandle(c *gin.Context) { if c.Request.Body == nil { return } - r, err := gzip.NewReader(c.Request.Body) - if err != nil { - _ = c.AbortWithError(http.StatusBadRequest, err) + + contentEncodingField := strings.Split(strings.ToLower(c.GetHeader("Content-Encoding")), ",") + if len(contentEncodingField) == 0 { // nothing to decompress + c.Next() + return } + + toClose := make([]io.Closer, 0, len(contentEncodingField)) + defer func() { + for i := len(toClose); i > 0; i-- { + toClose[i-1].Close() + } + }() + + // parses multiply gzips like + // Content-Encoding: gzip, gzip, gzip + // allowed by RFC + for i := 0; i < len(contentEncodingField); i++ { + trimmedValue := strings.TrimSpace(contentEncodingField[i]) + + if trimmedValue == "" { + continue + } + + if trimmedValue != "gzip" { + // According to RFC 7231, Section 3.1.2.2: + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.2 + // An origin server MAY respond with a status code of 415 (Unsupported + // Media Type) if a representation in the request message has a content + // coding that is not acceptable. + _ = c.AbortWithError(http.StatusUnsupportedMediaType, ErrUnsupportedContentEncoding) + } + + r, err := gzip.NewReader(c.Request.Body) + if err != nil { + _ = c.AbortWithError(http.StatusBadRequest, err) + + return + } + + toClose = append(toClose, c.Request.Body) + + c.Request.Body = r + } + c.Request.Header.Del("Content-Encoding") c.Request.Header.Del("Content-Length") - c.Request.Body = r + + c.Next() } diff --git a/vendor/github.com/gin-contrib/sse/.golangci.yml b/vendor/github.com/gin-contrib/sse/.golangci.yml new file mode 100644 index 000000000..4c44c5fae --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/.golangci.yml @@ -0,0 +1,3 @@ +linters: + disable: + - errcheck diff --git a/vendor/github.com/gin-contrib/sse/.goreleaser.yaml b/vendor/github.com/gin-contrib/sse/.goreleaser.yaml new file mode 100644 index 000000000..4c910add4 --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/.goreleaser.yaml @@ -0,0 +1,29 @@ +builds: + - # If true, skip the build. + # Useful for library projects. + # Default is false + skip: true + +changelog: + use: github + groups: + - title: Features + regexp: "^.*feat[(\\w)]*:+.*$" + order: 0 + - title: "Bug fixes" + regexp: "^.*fix[(\\w)]*:+.*$" + order: 1 + - title: "Enhancements" + regexp: "^.*chore[(\\w)]*:+.*$" + order: 2 + - title: "Refactor" + regexp: "^.*refactor[(\\w)]*:+.*$" + order: 3 + - title: "Build process updates" + regexp: ^.*?(build|ci)(\(.+\))??!?:.+$ + order: 4 + - title: "Documentation updates" + regexp: ^.*?docs?(\(.+\))??!?:.+$ + order: 4 + - title: Others + order: 999 diff --git a/vendor/github.com/gin-contrib/sse/.travis.yml b/vendor/github.com/gin-contrib/sse/.travis.yml deleted file mode 100644 index d0e8fcf99..000000000 --- a/vendor/github.com/gin-contrib/sse/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: go -sudo: false -go: - - 1.8.x - - 1.9.x - - 1.10.x - - 1.11.x - - 1.12.x - - master - -git: - depth: 10 - -matrix: - fast_finish: true - include: - - go: 1.11.x - env: GO111MODULE=on - - go: 1.12.x - env: GO111MODULE=on - -script: - - go test -v -covermode=count -coverprofile=coverage.out - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/gin-contrib/sse/README.md b/vendor/github.com/gin-contrib/sse/README.md index c9c49cf94..cfe2c820b 100644 --- a/vendor/github.com/gin-contrib/sse/README.md +++ b/vendor/github.com/gin-contrib/sse/README.md @@ -1,7 +1,7 @@ # Server-Sent Events -[![GoDoc](https://godoc.org/github.com/gin-contrib/sse?status.svg)](https://godoc.org/github.com/gin-contrib/sse) -[![Build Status](https://travis-ci.org/gin-contrib/sse.svg)](https://travis-ci.org/gin-contrib/sse) +[![Go Reference](https://pkg.go.dev/badge/github.com/gin-contrib/sse.svg)](https://pkg.go.dev/github.com/gin-contrib/sse) +[![Run Tests](https://github.com/gin-contrib/sse/actions/workflows/go.yml/badge.svg)](https://github.com/gin-contrib/sse/actions/workflows/go.yml) [![codecov](https://codecov.io/gh/gin-contrib/sse/branch/master/graph/badge.svg)](https://codecov.io/gh/gin-contrib/sse) [![Go Report Card](https://goreportcard.com/badge/github.com/gin-contrib/sse)](https://goreportcard.com/report/github.com/gin-contrib/sse) @@ -16,32 +16,33 @@ Server-sent events (SSE) is a technology where a browser receives automatic upda import "github.com/gin-contrib/sse" func httpHandler(w http.ResponseWriter, req *http.Request) { - // data can be a primitive like a string, an integer or a float - sse.Encode(w, sse.Event{ - Event: "message", - Data: "some data\nmore data", - }) + // data can be a primitive like a string, an integer or a float + sse.Encode(w, sse.Event{ + Event: "message", + Data: "some data\nmore data", + }) - // also a complex type, like a map, a struct or a slice - sse.Encode(w, sse.Event{ - Id: "124", - Event: "message", - Data: map[string]interface{}{ - "user": "manu", - "date": time.Now().Unix(), - "content": "hi!", - }, - }) + // also a complex type, like a map, a struct or a slice + sse.Encode(w, sse.Event{ + Id: "124", + Event: "message", + Data: map[string]interface{}{ + "user": "manu", + "date": time.Now().Unix(), + "content": "hi!", + }, + }) } ``` -``` + +```sh event: message data: some data\\nmore data id: 124 event: message data: {"content":"hi!","date":1431540810,"user":"manu"} - + ``` ## Content-Type @@ -49,7 +50,8 @@ data: {"content":"hi!","date":1431540810,"user":"manu"} ```go fmt.Println(sse.ContentType) ``` -``` + +```sh text/event-stream ``` diff --git a/vendor/github.com/gin-contrib/sse/sse-encoder.go b/vendor/github.com/gin-contrib/sse/sse-encoder.go index f9c808750..0d26c82f0 100644 --- a/vendor/github.com/gin-contrib/sse/sse-encoder.go +++ b/vendor/github.com/gin-contrib/sse/sse-encoder.go @@ -18,7 +18,7 @@ // W3C Working Draft 29 October 2009 // http://www.w3.org/TR/2009/WD-eventsource-20091029/ -const ContentType = "text/event-stream" +const ContentType = "text/event-stream;charset=utf-8" var contentType = []string{ContentType} var noCache = []string{"no-cache"} @@ -72,6 +72,14 @@ func writeRetry(w stringWriter, retry uint) { func writeData(w stringWriter, data interface{}) error { w.WriteString("data:") + + bData, ok := data.([]byte) + if ok { + dataReplacer.WriteString(w, string(bData)) + w.WriteString("\n\n") + return nil + } + switch kindOfData(data) { case reflect.Struct, reflect.Slice, reflect.Map: err := json.NewEncoder(w).Encode(data) diff --git a/vendor/github.com/go-playground/validator/v10/README.md b/vendor/github.com/go-playground/validator/v10/README.md index b0ac30d8f..25eadf026 100644 --- a/vendor/github.com/go-playground/validator/v10/README.md +++ b/vendor/github.com/go-playground/validator/v10/README.md @@ -1,7 +1,7 @@ Package validator ================= [![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -![Project status](https://img.shields.io/badge/version-10.23.0-green.svg) +![Project status](https://img.shields.io/badge/version-10.24.0-green.svg) [![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator) [![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator) @@ -22,6 +22,11 @@ It has the following **unique** features: - Customizable i18n aware error messages. - Default validator for the [gin](https://github.com/gin-gonic/gin) web framework; upgrading from v8 to v9 in gin see [here](https://github.com/go-playground/validator/tree/master/_examples/gin-upgrading-overriding) +A Call for Maintainers +---------------------- + +Please read the discussiong started [here](https://github.com/go-playground/validator/discussions/1330) if you are interested in contributing/helping maintain this package. + Installation ------------ @@ -266,74 +271,75 @@ validate := validator.New(validator.WithRequiredStructEnabled()) Benchmarks ------ -###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64 +###### Run on MacBook Pro Max M3 ```go -go version go1.21.0 darwin/arm64 +go version go1.23.3 darwin/arm64 goos: darwin goarch: arm64 +cpu: Apple M3 Max pkg: github.com/go-playground/validator/v10 -BenchmarkFieldSuccess-8 33142266 35.94 ns/op 0 B/op 0 allocs/op -BenchmarkFieldSuccessParallel-8 200816191 6.568 ns/op 0 B/op 0 allocs/op -BenchmarkFieldFailure-8 6779707 175.1 ns/op 200 B/op 4 allocs/op -BenchmarkFieldFailureParallel-8 11044147 108.4 ns/op 200 B/op 4 allocs/op -BenchmarkFieldArrayDiveSuccess-8 6054232 194.4 ns/op 97 B/op 5 allocs/op -BenchmarkFieldArrayDiveSuccessParallel-8 12523388 94.07 ns/op 97 B/op 5 allocs/op -BenchmarkFieldArrayDiveFailure-8 3587043 334.3 ns/op 300 B/op 10 allocs/op -BenchmarkFieldArrayDiveFailureParallel-8 5816665 200.8 ns/op 300 B/op 10 allocs/op -BenchmarkFieldMapDiveSuccess-8 2217910 540.1 ns/op 288 B/op 14 allocs/op -BenchmarkFieldMapDiveSuccessParallel-8 4446698 258.7 ns/op 288 B/op 14 allocs/op -BenchmarkFieldMapDiveFailure-8 2392759 504.6 ns/op 376 B/op 13 allocs/op -BenchmarkFieldMapDiveFailureParallel-8 4244199 286.9 ns/op 376 B/op 13 allocs/op -BenchmarkFieldMapDiveWithKeysSuccess-8 2005857 592.1 ns/op 288 B/op 14 allocs/op -BenchmarkFieldMapDiveWithKeysSuccessParallel-8 4400850 296.9 ns/op 288 B/op 14 allocs/op -BenchmarkFieldMapDiveWithKeysFailure-8 1850227 643.8 ns/op 553 B/op 16 allocs/op -BenchmarkFieldMapDiveWithKeysFailureParallel-8 3293233 375.1 ns/op 553 B/op 16 allocs/op -BenchmarkFieldCustomTypeSuccess-8 12174412 98.25 ns/op 32 B/op 2 allocs/op -BenchmarkFieldCustomTypeSuccessParallel-8 34389907 35.49 ns/op 32 B/op 2 allocs/op -BenchmarkFieldCustomTypeFailure-8 7582524 156.6 ns/op 184 B/op 3 allocs/op -BenchmarkFieldCustomTypeFailureParallel-8 13019902 92.79 ns/op 184 B/op 3 allocs/op -BenchmarkFieldOrTagSuccess-8 3427260 349.4 ns/op 16 B/op 1 allocs/op -BenchmarkFieldOrTagSuccessParallel-8 15144128 81.25 ns/op 16 B/op 1 allocs/op -BenchmarkFieldOrTagFailure-8 5913546 201.9 ns/op 216 B/op 5 allocs/op -BenchmarkFieldOrTagFailureParallel-8 9810212 113.7 ns/op 216 B/op 5 allocs/op -BenchmarkStructLevelValidationSuccess-8 13456327 87.66 ns/op 16 B/op 1 allocs/op -BenchmarkStructLevelValidationSuccessParallel-8 41818888 27.77 ns/op 16 B/op 1 allocs/op -BenchmarkStructLevelValidationFailure-8 4166284 272.6 ns/op 264 B/op 7 allocs/op -BenchmarkStructLevelValidationFailureParallel-8 7594581 152.1 ns/op 264 B/op 7 allocs/op -BenchmarkStructSimpleCustomTypeSuccess-8 6508082 182.6 ns/op 32 B/op 2 allocs/op -BenchmarkStructSimpleCustomTypeSuccessParallel-8 23078605 54.78 ns/op 32 B/op 2 allocs/op -BenchmarkStructSimpleCustomTypeFailure-8 3118352 381.0 ns/op 416 B/op 9 allocs/op -BenchmarkStructSimpleCustomTypeFailureParallel-8 5300738 224.1 ns/op 432 B/op 10 allocs/op -BenchmarkStructFilteredSuccess-8 4761807 251.1 ns/op 216 B/op 5 allocs/op -BenchmarkStructFilteredSuccessParallel-8 8792598 128.6 ns/op 216 B/op 5 allocs/op -BenchmarkStructFilteredFailure-8 5202573 232.1 ns/op 216 B/op 5 allocs/op -BenchmarkStructFilteredFailureParallel-8 9591267 121.4 ns/op 216 B/op 5 allocs/op -BenchmarkStructPartialSuccess-8 5188512 231.6 ns/op 224 B/op 4 allocs/op -BenchmarkStructPartialSuccessParallel-8 9179776 123.1 ns/op 224 B/op 4 allocs/op -BenchmarkStructPartialFailure-8 3071212 392.5 ns/op 440 B/op 9 allocs/op -BenchmarkStructPartialFailureParallel-8 5344261 223.7 ns/op 440 B/op 9 allocs/op -BenchmarkStructExceptSuccess-8 3184230 375.0 ns/op 424 B/op 8 allocs/op -BenchmarkStructExceptSuccessParallel-8 10090130 108.9 ns/op 208 B/op 3 allocs/op -BenchmarkStructExceptFailure-8 3347226 357.7 ns/op 424 B/op 8 allocs/op -BenchmarkStructExceptFailureParallel-8 5654923 209.5 ns/op 424 B/op 8 allocs/op -BenchmarkStructSimpleCrossFieldSuccess-8 5232265 229.1 ns/op 56 B/op 3 allocs/op -BenchmarkStructSimpleCrossFieldSuccessParallel-8 17436674 64.75 ns/op 56 B/op 3 allocs/op -BenchmarkStructSimpleCrossFieldFailure-8 3128613 383.6 ns/op 272 B/op 8 allocs/op -BenchmarkStructSimpleCrossFieldFailureParallel-8 6994113 168.8 ns/op 272 B/op 8 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3506487 340.9 ns/op 64 B/op 4 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 13431300 91.77 ns/op 64 B/op 4 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2410566 500.9 ns/op 288 B/op 9 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 6344510 188.2 ns/op 288 B/op 9 allocs/op -BenchmarkStructSimpleSuccess-8 8922726 133.8 ns/op 0 B/op 0 allocs/op -BenchmarkStructSimpleSuccessParallel-8 55291153 23.63 ns/op 0 B/op 0 allocs/op -BenchmarkStructSimpleFailure-8 3171553 378.4 ns/op 416 B/op 9 allocs/op -BenchmarkStructSimpleFailureParallel-8 5571692 212.0 ns/op 416 B/op 9 allocs/op -BenchmarkStructComplexSuccess-8 1683750 714.5 ns/op 224 B/op 5 allocs/op -BenchmarkStructComplexSuccessParallel-8 4578046 257.0 ns/op 224 B/op 5 allocs/op -BenchmarkStructComplexFailure-8 481585 2547 ns/op 3041 B/op 48 allocs/op -BenchmarkStructComplexFailureParallel-8 965764 1577 ns/op 3040 B/op 48 allocs/op -BenchmarkOneof-8 17380881 68.50 ns/op 0 B/op 0 allocs/op -BenchmarkOneofParallel-8 8084733 153.5 ns/op 0 B/op 0 allocs/op +BenchmarkFieldSuccess-16 42461943 27.88 ns/op 0 B/op 0 allocs/op +BenchmarkFieldSuccessParallel-16 486632887 2.289 ns/op 0 B/op 0 allocs/op +BenchmarkFieldFailure-16 9566167 121.3 ns/op 200 B/op 4 allocs/op +BenchmarkFieldFailureParallel-16 17551471 83.68 ns/op 200 B/op 4 allocs/op +BenchmarkFieldArrayDiveSuccess-16 7602306 155.6 ns/op 97 B/op 5 allocs/op +BenchmarkFieldArrayDiveSuccessParallel-16 20664610 59.80 ns/op 97 B/op 5 allocs/op +BenchmarkFieldArrayDiveFailure-16 4659756 252.9 ns/op 301 B/op 10 allocs/op +BenchmarkFieldArrayDiveFailureParallel-16 8010116 152.9 ns/op 301 B/op 10 allocs/op +BenchmarkFieldMapDiveSuccess-16 2834575 421.2 ns/op 288 B/op 14 allocs/op +BenchmarkFieldMapDiveSuccessParallel-16 7179700 171.8 ns/op 288 B/op 14 allocs/op +BenchmarkFieldMapDiveFailure-16 3081728 384.4 ns/op 376 B/op 13 allocs/op +BenchmarkFieldMapDiveFailureParallel-16 6058137 204.0 ns/op 377 B/op 13 allocs/op +BenchmarkFieldMapDiveWithKeysSuccess-16 2544975 464.8 ns/op 288 B/op 14 allocs/op +BenchmarkFieldMapDiveWithKeysSuccessParallel-16 6661954 181.4 ns/op 288 B/op 14 allocs/op +BenchmarkFieldMapDiveWithKeysFailure-16 2435484 490.7 ns/op 553 B/op 16 allocs/op +BenchmarkFieldMapDiveWithKeysFailureParallel-16 4249617 282.0 ns/op 554 B/op 16 allocs/op +BenchmarkFieldCustomTypeSuccess-16 14943525 77.35 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeSuccessParallel-16 64051954 20.61 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeFailure-16 10721384 107.1 ns/op 184 B/op 3 allocs/op +BenchmarkFieldCustomTypeFailureParallel-16 18714495 69.77 ns/op 184 B/op 3 allocs/op +BenchmarkFieldOrTagSuccess-16 4063124 294.3 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagSuccessParallel-16 31903756 41.22 ns/op 18 B/op 1 allocs/op +BenchmarkFieldOrTagFailure-16 7748558 146.8 ns/op 216 B/op 5 allocs/op +BenchmarkFieldOrTagFailureParallel-16 13139854 92.05 ns/op 216 B/op 5 allocs/op +BenchmarkStructLevelValidationSuccess-16 16808389 70.25 ns/op 16 B/op 1 allocs/op +BenchmarkStructLevelValidationSuccessParallel-16 90686955 14.47 ns/op 16 B/op 1 allocs/op +BenchmarkStructLevelValidationFailure-16 5818791 200.2 ns/op 264 B/op 7 allocs/op +BenchmarkStructLevelValidationFailureParallel-16 11115874 107.5 ns/op 264 B/op 7 allocs/op +BenchmarkStructSimpleCustomTypeSuccess-16 7764956 151.9 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeSuccessParallel-16 52316265 30.37 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeFailure-16 4195429 277.2 ns/op 416 B/op 9 allocs/op +BenchmarkStructSimpleCustomTypeFailureParallel-16 7305661 164.6 ns/op 432 B/op 10 allocs/op +BenchmarkStructFilteredSuccess-16 6312625 186.1 ns/op 216 B/op 5 allocs/op +BenchmarkStructFilteredSuccessParallel-16 13684459 93.42 ns/op 216 B/op 5 allocs/op +BenchmarkStructFilteredFailure-16 6751482 171.2 ns/op 216 B/op 5 allocs/op +BenchmarkStructFilteredFailureParallel-16 14146070 86.93 ns/op 216 B/op 5 allocs/op +BenchmarkStructPartialSuccess-16 6544448 177.3 ns/op 224 B/op 4 allocs/op +BenchmarkStructPartialSuccessParallel-16 13951946 88.73 ns/op 224 B/op 4 allocs/op +BenchmarkStructPartialFailure-16 4075833 287.5 ns/op 440 B/op 9 allocs/op +BenchmarkStructPartialFailureParallel-16 7490805 161.3 ns/op 440 B/op 9 allocs/op +BenchmarkStructExceptSuccess-16 4107187 281.4 ns/op 424 B/op 8 allocs/op +BenchmarkStructExceptSuccessParallel-16 15979173 80.86 ns/op 208 B/op 3 allocs/op +BenchmarkStructExceptFailure-16 4434372 264.3 ns/op 424 B/op 8 allocs/op +BenchmarkStructExceptFailureParallel-16 8081367 154.1 ns/op 424 B/op 8 allocs/op +BenchmarkStructSimpleCrossFieldSuccess-16 6459542 183.4 ns/op 56 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldSuccessParallel-16 41013781 37.95 ns/op 56 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldFailure-16 4034998 292.1 ns/op 272 B/op 8 allocs/op +BenchmarkStructSimpleCrossFieldFailureParallel-16 11348446 115.3 ns/op 272 B/op 8 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccess-16 4448528 267.7 ns/op 64 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-16 26813619 48.33 ns/op 64 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailure-16 3090646 384.5 ns/op 288 B/op 9 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-16 9870906 129.5 ns/op 288 B/op 9 allocs/op +BenchmarkStructSimpleSuccess-16 10675562 109.5 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleSuccessParallel-16 131159784 8.932 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleFailure-16 4094979 286.6 ns/op 416 B/op 9 allocs/op +BenchmarkStructSimpleFailureParallel-16 7606663 157.9 ns/op 416 B/op 9 allocs/op +BenchmarkStructComplexSuccess-16 2073470 576.0 ns/op 224 B/op 5 allocs/op +BenchmarkStructComplexSuccessParallel-16 7821831 161.3 ns/op 224 B/op 5 allocs/op +BenchmarkStructComplexFailure-16 576358 2001 ns/op 3042 B/op 48 allocs/op +BenchmarkStructComplexFailureParallel-16 1000000 1171 ns/op 3041 B/op 48 allocs/op +BenchmarkOneof-16 22503973 52.82 ns/op 0 B/op 0 allocs/op +BenchmarkOneofParallel-16 8538474 140.4 ns/op 0 B/op 0 allocs/op ``` Complementary Software @@ -349,6 +355,20 @@ How to Contribute Make a pull request... +Maintenance and support for SDK major versions +---------------------------------------------- + +See prior discussion [here](https://github.com/go-playground/validator/discussions/1342) for more details. + +This package is aligned with the [Go release policy](https://go.dev/doc/devel/release) in that support is guaranteed for +the two most recent major versions. + +This does not mean the package will not work with older versions of Go, only that we reserve the right to increase the +MSGV(Minimum Supported Go Version) when the need arises to address Security issues/patches, OS issues & support or newly +introduced functionality that would greatly benefit the maintenance and/or usage of this package. + +If and when the MSGV is increased it will be done so in a minimum of a `Minor` release bump. + License ------- Distributed under MIT License, please see license file within the code for more details. diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go b/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go index d407dd791..d7ec53f07 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go @@ -88,9 +88,7 @@ func opaqueInitHook(mi *MessageInfo) bool { mi.oneofs = map[protoreflect.Name]*oneofInfo{} for i := 0; i < mi.Desc.Oneofs().Len(); i++ { od := mi.Desc.Oneofs().Get(i) - if !od.IsSynthetic() { - mi.oneofs[od.Name()] = makeOneofInfo(od, si.structInfo, mi.Exporter) - } + mi.oneofs[od.Name()] = makeOneofInfoOpaque(mi, od, si.structInfo, mi.Exporter) } mi.denseFields = make([]*fieldInfo, fds.Len()*2) @@ -119,6 +117,26 @@ func opaqueInitHook(mi *MessageInfo) bool { return true } +func makeOneofInfoOpaque(mi *MessageInfo, od protoreflect.OneofDescriptor, si structInfo, x exporter) *oneofInfo { + oi := &oneofInfo{oneofDesc: od} + if od.IsSynthetic() { + fd := od.Fields().Get(0) + index, _ := presenceIndex(mi.Desc, fd) + oi.which = func(p pointer) protoreflect.FieldNumber { + if p.IsNil() { + return 0 + } + if !mi.present(p, index) { + return 0 + } + return od.Fields().Get(0).Number() + } + return oi + } + // Dispatch to non-opaque oneof implementation for non-synthetic oneofs. + return makeOneofInfo(od, si, x) +} + func (mi *MessageInfo) fieldInfoForMapOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo { ft := fs.Type if ft.Kind() != reflect.Map { diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index 3018450df..386c823aa 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -52,7 +52,7 @@ const ( Major = 1 Minor = 36 - Patch = 1 + Patch = 2 PreRelease = "" ) diff --git a/vendor/modules.txt b/vendor/modules.txt index 030cc6f3a..7c54562f3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -101,7 +101,7 @@ github.com/beorn7/perks/quantile ## explicit; go 1.14 github.com/buckket/go-blurhash github.com/buckket/go-blurhash/base83 -# github.com/bytedance/sonic v1.12.6 +# github.com/bytedance/sonic v1.12.7 ## explicit; go 1.17 github.com/bytedance/sonic github.com/bytedance/sonic/ast @@ -135,10 +135,12 @@ github.com/bytedance/sonic/internal/utils github.com/bytedance/sonic/option github.com/bytedance/sonic/unquote github.com/bytedance/sonic/utf8 -# github.com/bytedance/sonic/loader v0.2.1 +# github.com/bytedance/sonic/loader v0.2.2 ## explicit; go 1.16 github.com/bytedance/sonic/loader github.com/bytedance/sonic/loader/internal/abi +github.com/bytedance/sonic/loader/internal/iasm/expr +github.com/bytedance/sonic/loader/internal/iasm/x86_64 github.com/bytedance/sonic/loader/internal/rt # github.com/cenkalti/backoff/v4 v4.3.0 ## explicit; go 1.18 @@ -158,10 +160,6 @@ github.com/cilium/ebpf/link # github.com/cloudwego/base64x v0.1.4 ## explicit; go 1.16 github.com/cloudwego/base64x -# github.com/cloudwego/iasm v0.2.0 -## explicit; go 1.16 -github.com/cloudwego/iasm/expr -github.com/cloudwego/iasm/x86_64 # github.com/containerd/cgroups/v3 v3.0.1 ## explicit; go 1.17 github.com/containerd/cgroups/v3 @@ -208,7 +206,7 @@ github.com/felixge/httpsnoop # github.com/fsnotify/fsnotify v1.7.0 ## explicit; go 1.17 github.com/fsnotify/fsnotify -# github.com/gabriel-vasile/mimetype v1.4.7 +# github.com/gabriel-vasile/mimetype v1.4.8 ## explicit; go 1.20 github.com/gabriel-vasile/mimetype github.com/gabriel-vasile/mimetype/internal/charset @@ -217,15 +215,15 @@ github.com/gabriel-vasile/mimetype/internal/magic # github.com/gin-contrib/cors v1.7.3 ## explicit; go 1.21.0 github.com/gin-contrib/cors -# github.com/gin-contrib/gzip v1.1.0 +# github.com/gin-contrib/gzip v1.2.2 ## explicit; go 1.21.0 github.com/gin-contrib/gzip # github.com/gin-contrib/sessions v1.0.2 ## explicit; go 1.20 github.com/gin-contrib/sessions github.com/gin-contrib/sessions/memstore -# github.com/gin-contrib/sse v0.1.0 -## explicit; go 1.12 +# github.com/gin-contrib/sse v1.0.0 +## explicit; go 1.13 github.com/gin-contrib/sse # github.com/gin-gonic/gin v1.10.0 ## explicit; go 1.20 @@ -312,8 +310,8 @@ github.com/go-playground/locales/currency # github.com/go-playground/universal-translator v0.18.1 ## explicit; go 1.18 github.com/go-playground/universal-translator -# github.com/go-playground/validator/v10 v10.23.0 -## explicit; go 1.18 +# github.com/go-playground/validator/v10 v10.24.0 +## explicit; go 1.20 github.com/go-playground/validator/v10 # github.com/go-swagger/go-swagger v0.31.0 => github.com/superseriousbusiness/go-swagger v0.31.0-gts-go1.23-fix ## explicit; go 1.21 @@ -1077,7 +1075,7 @@ go.uber.org/automaxprocs/maxprocs # go.uber.org/multierr v1.11.0 ## explicit; go 1.19 go.uber.org/multierr -# golang.org/x/arch v0.12.0 +# golang.org/x/arch v0.13.0 ## explicit; go 1.18 golang.org/x/arch/x86/x86asm # golang.org/x/crypto v0.32.0 @@ -1263,7 +1261,7 @@ google.golang.org/grpc/serviceconfig google.golang.org/grpc/stats google.golang.org/grpc/status google.golang.org/grpc/tap -# google.golang.org/protobuf v1.36.1 +# google.golang.org/protobuf v1.36.2 ## explicit; go 1.21 google.golang.org/protobuf/encoding/protodelim google.golang.org/protobuf/encoding/protojson From 3428bc96336ad666d61ce0e954a50af9e72a0fa8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:07:16 +0000 Subject: [PATCH 11/16] [chore]: Bump github.com/miekg/dns from 1.1.62 to 1.1.63 (#3695) Bumps [github.com/miekg/dns](https://github.com/miekg/dns) from 1.1.62 to 1.1.63. - [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release) - [Commits](https://github.com/miekg/dns/compare/v1.1.62...v1.1.63) --- updated-dependencies: - dependency-name: github.com/miekg/dns dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- vendor/github.com/miekg/dns/README.md | 1 + vendor/github.com/miekg/dns/dnssec.go | 42 +++++++++++++------ vendor/github.com/miekg/dns/edns.go | 36 +++++++--------- ...useport.go => listen_no_socket_options.go} | 22 ++++++++-- ..._reuseport.go => listen_socket_options.go} | 31 ++++++++++++++ vendor/github.com/miekg/dns/server.go | 1 + vendor/github.com/miekg/dns/sig0.go | 3 +- vendor/github.com/miekg/dns/version.go | 2 +- vendor/modules.txt | 2 +- 11 files changed, 102 insertions(+), 44 deletions(-) rename vendor/github.com/miekg/dns/{listen_no_reuseport.go => listen_no_socket_options.go} (61%) rename vendor/github.com/miekg/dns/{listen_reuseport.go => listen_socket_options.go} (66%) diff --git a/go.mod b/go.mod index 218e52273..d11d0c921 100644 --- a/go.mod +++ b/go.mod @@ -60,7 +60,7 @@ require ( github.com/jackc/pgx/v5 v5.7.2 github.com/k3a/html2text v1.2.1 github.com/microcosm-cc/bluemonday v1.0.27 - github.com/miekg/dns v1.1.62 + github.com/miekg/dns v1.1.63 github.com/minio/minio-go/v7 v7.0.81 github.com/mitchellh/mapstructure v1.5.0 github.com/ncruces/go-sqlite3 v0.22.0 diff --git a/go.sum b/go.sum index 769b0bee0..79747b403 100644 --- a/go.sum +++ b/go.sum @@ -407,8 +407,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= -github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= -github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= +github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= +github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v7 v7.0.81 h1:SzhMN0TQ6T/xSBu6Nvw3M5M8voM+Ht8RH3hE8S7zxaA= diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md index 8d5a2a478..9831c37ba 100644 --- a/vendor/github.com/miekg/dns/README.md +++ b/vendor/github.com/miekg/dns/README.md @@ -85,6 +85,7 @@ A not-so-up-to-date-list-that-may-be-actually-current: * https://github.com/wintbiit/NineDNS * https://linuxcontainers.org/incus/ * https://ifconfig.es +* https://github.com/zmap/zdns Send pull request if you want to be listed here. diff --git a/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/miekg/dns/dnssec.go index 1be87eae6..ffdafcebd 100644 --- a/vendor/github.com/miekg/dns/dnssec.go +++ b/vendor/github.com/miekg/dns/dnssec.go @@ -250,14 +250,6 @@ func (d *DS) ToCDS() *CDS { // zero, it is used as-is, otherwise the TTL of the RRset is used as the // OrigTTL. func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error { - if k == nil { - return ErrPrivKey - } - // s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set - if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { - return ErrKey - } - h0 := rrset[0].Header() rr.Hdr.Rrtype = TypeRRSIG rr.Hdr.Name = h0.Name @@ -272,6 +264,18 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error { rr.Labels-- // wildcard, remove from label count } + return rr.signAsIs(k, rrset) +} + +func (rr *RRSIG) signAsIs(k crypto.Signer, rrset []RR) error { + if k == nil { + return ErrPrivKey + } + // s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set + if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { + return ErrKey + } + sigwire := new(rrsigWireFmt) sigwire.TypeCovered = rr.TypeCovered sigwire.Algorithm = rr.Algorithm @@ -370,9 +374,12 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { if rr.Algorithm != k.Algorithm { return ErrKey } - if !strings.EqualFold(rr.SignerName, k.Hdr.Name) { + + signerName := CanonicalName(rr.SignerName) + if !equal(signerName, k.Hdr.Name) { return ErrKey } + if k.Protocol != 3 { return ErrKey } @@ -384,9 +391,18 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { } // IsRRset checked that we have at least one RR and that the RRs in - // the set have consistent type, class, and name. Also check that type and - // class matches the RRSIG record. - if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || h0.Rrtype != rr.TypeCovered { + // the set have consistent type, class, and name. Also check that type, + // class and name matches the RRSIG record. + // Also checks RFC 4035 5.3.1 the number of labels in the RRset owner + // name MUST be greater than or equal to the value in the RRSIG RR's Labels field. + // RFC 4035 5.3.1 Signer's Name MUST be the name of the zone that [contains the RRset]. + // Since we don't have SOA info, checking suffix may be the best we can do...? + if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || + h0.Rrtype != rr.TypeCovered || + uint8(CountLabel(h0.Name)) < rr.Labels || + !equal(h0.Name, rr.Hdr.Name) || + !strings.HasSuffix(CanonicalName(h0.Name), signerName) { + return ErrRRset } @@ -400,7 +416,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { sigwire.Expiration = rr.Expiration sigwire.Inception = rr.Inception sigwire.KeyTag = rr.KeyTag - sigwire.SignerName = CanonicalName(rr.SignerName) + sigwire.SignerName = signerName // Create the desired binary blob signeddata := make([]byte, DefaultMsgSize) n, err := packSigWire(sigwire, signeddata) diff --git a/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/miekg/dns/edns.go index c1bbdaae2..0447fd826 100644 --- a/vendor/github.com/miekg/dns/edns.go +++ b/vendor/github.com/miekg/dns/edns.go @@ -58,7 +58,7 @@ func makeDataOpt(code uint16) EDNS0 { case EDNS0EDE: return new(EDNS0_EDE) case EDNS0ESU: - return &EDNS0_ESU{Code: EDNS0ESU} + return new(EDNS0_ESU) default: e := new(EDNS0_LOCAL) e.Code = code @@ -66,8 +66,7 @@ func makeDataOpt(code uint16) EDNS0 { } } -// OPT is the EDNS0 RR appended to messages to convey extra (meta) information. -// See RFC 6891. +// OPT is the EDNS0 RR appended to messages to convey extra (meta) information. See RFC 6891. type OPT struct { Hdr RR_Header Option []EDNS0 `dns:"opt"` @@ -144,8 +143,6 @@ func (*OPT) parse(c *zlexer, origin string) *ParseError { func (rr *OPT) isDuplicate(r2 RR) bool { return false } -// return the old value -> delete SetVersion? - // Version returns the EDNS version used. Only zero is defined. func (rr *OPT) Version() uint8 { return uint8(rr.Hdr.Ttl & 0x00FF0000 >> 16) @@ -236,8 +233,8 @@ type EDNS0 interface { // e.Nsid = "AA" // o.Option = append(o.Option, e) type EDNS0_NSID struct { - Code uint16 // Always EDNS0NSID - Nsid string // This string needs to be hex encoded + Code uint16 // always EDNS0NSID + Nsid string // string needs to be hex encoded } func (e *EDNS0_NSID) pack() ([]byte, error) { @@ -275,7 +272,7 @@ func (e *EDNS0_NSID) copy() EDNS0 { return &EDNS0_NSID{e.Code, e.Nsid} // When packing it will apply SourceNetmask. If you need more advanced logic, // patches welcome and good luck. type EDNS0_SUBNET struct { - Code uint16 // Always EDNS0SUBNET + Code uint16 // always EDNS0SUBNET Family uint16 // 1 for IP, 2 for IP6 SourceNetmask uint8 SourceScope uint8 @@ -399,8 +396,8 @@ func (e *EDNS0_SUBNET) copy() EDNS0 { // // There is no guarantee that the Cookie string has a specific length. type EDNS0_COOKIE struct { - Code uint16 // Always EDNS0COOKIE - Cookie string // Hex-encoded cookie data + Code uint16 // always EDNS0COOKIE + Cookie string // hex encoded cookie data } func (e *EDNS0_COOKIE) pack() ([]byte, error) { @@ -430,7 +427,7 @@ func (e *EDNS0_COOKIE) copy() EDNS0 { return &EDNS0_COOKIE{e.Code, e.C // e.Lease = 120 // in seconds // o.Option = append(o.Option, e) type EDNS0_UL struct { - Code uint16 // Always EDNS0UL + Code uint16 // always EDNS0UL Lease uint32 KeyLease uint32 } @@ -469,7 +466,7 @@ func (e *EDNS0_UL) unpack(b []byte) error { // EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 // Implemented for completeness, as the EDNS0 type code is assigned. type EDNS0_LLQ struct { - Code uint16 // Always EDNS0LLQ + Code uint16 // always EDNS0LLQ Version uint16 Opcode uint16 Error uint16 @@ -515,7 +512,7 @@ func (e *EDNS0_LLQ) copy() EDNS0 { // EDNS0_DAU implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975. type EDNS0_DAU struct { - Code uint16 // Always EDNS0DAU + Code uint16 // always EDNS0DAU AlgCode []uint8 } @@ -539,7 +536,7 @@ func (e *EDNS0_DAU) copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} } // EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975. type EDNS0_DHU struct { - Code uint16 // Always EDNS0DHU + Code uint16 // always EDNS0DHU AlgCode []uint8 } @@ -563,7 +560,7 @@ func (e *EDNS0_DHU) copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} } // EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975. type EDNS0_N3U struct { - Code uint16 // Always EDNS0N3U + Code uint16 // always EDNS0N3U AlgCode []uint8 } @@ -588,7 +585,7 @@ func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} } // EDNS0_EXPIRE implements the EDNS0 option as described in RFC 7314. type EDNS0_EXPIRE struct { - Code uint16 // Always EDNS0EXPIRE + Code uint16 // always EDNS0EXPIRE Expire uint32 Empty bool // Empty is used to signal an empty Expire option in a backwards compatible way, it's not used on the wire. } @@ -668,7 +665,7 @@ func (e *EDNS0_LOCAL) unpack(b []byte) error { // EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep // the TCP connection alive. See RFC 7828. type EDNS0_TCP_KEEPALIVE struct { - Code uint16 // Always EDNSTCPKEEPALIVE + Code uint16 // always EDNSTCPKEEPALIVE // Timeout is an idle timeout value for the TCP connection, specified in // units of 100 milliseconds, encoded in network byte order. If set to 0, @@ -839,13 +836,12 @@ func (e *EDNS0_EDE) unpack(b []byte) error { return nil } -// The EDNS0_ESU option for ENUM Source-URI Extension +// The EDNS0_ESU option for ENUM Source-URI Extension. type EDNS0_ESU struct { - Code uint16 + Code uint16 // always EDNS0ESU Uri string } -// Option implements the EDNS0 interface. func (e *EDNS0_ESU) Option() uint16 { return EDNS0ESU } func (e *EDNS0_ESU) String() string { return e.Uri } func (e *EDNS0_ESU) copy() EDNS0 { return &EDNS0_ESU{e.Code, e.Uri} } diff --git a/vendor/github.com/miekg/dns/listen_no_reuseport.go b/vendor/github.com/miekg/dns/listen_no_socket_options.go similarity index 61% rename from vendor/github.com/miekg/dns/listen_no_reuseport.go rename to vendor/github.com/miekg/dns/listen_no_socket_options.go index 8cebb2f17..9e4010bdc 100644 --- a/vendor/github.com/miekg/dns/listen_no_reuseport.go +++ b/vendor/github.com/miekg/dns/listen_no_socket_options.go @@ -3,9 +3,15 @@ package dns -import "net" +import ( + "fmt" + "net" +) -const supportsReusePort = false +const ( + supportsReusePort = false + supportsReuseAddr = false +) func listenTCP(network, addr string, reuseport, reuseaddr bool) (net.Listener, error) { if reuseport || reuseaddr { @@ -15,8 +21,6 @@ func listenTCP(network, addr string, reuseport, reuseaddr bool) (net.Listener, e return net.Listen(network, addr) } -const supportsReuseAddr = false - func listenUDP(network, addr string, reuseport, reuseaddr bool) (net.PacketConn, error) { if reuseport || reuseaddr { // TODO(tmthrgd): return an error? @@ -24,3 +28,13 @@ func listenUDP(network, addr string, reuseport, reuseaddr bool) (net.PacketConn, return net.ListenPacket(network, addr) } + +// this is just for test compatibility +func checkReuseport(fd uintptr) (bool, error) { + return false, fmt.Errorf("not supported") +} + +// this is just for test compatibility +func checkReuseaddr(fd uintptr) (bool, error) { + return false, fmt.Errorf("not supported") +} diff --git a/vendor/github.com/miekg/dns/listen_reuseport.go b/vendor/github.com/miekg/dns/listen_socket_options.go similarity index 66% rename from vendor/github.com/miekg/dns/listen_reuseport.go rename to vendor/github.com/miekg/dns/listen_socket_options.go index 41326f20b..35dfc9498 100644 --- a/vendor/github.com/miekg/dns/listen_reuseport.go +++ b/vendor/github.com/miekg/dns/listen_socket_options.go @@ -39,10 +39,40 @@ func reuseaddrControl(network, address string, c syscall.RawConn) error { return opErr } +func reuseaddrandportControl(network, address string, c syscall.RawConn) error { + err := reuseaddrControl(network, address, c) + if err != nil { + return err + } + + return reuseportControl(network, address, c) +} + +// this is just for test compatibility +func checkReuseport(fd uintptr) (bool, error) { + v, err := unix.GetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT) + if err != nil { + return false, err + } + + return v == 1, nil +} + +// this is just for test compatibility +func checkReuseaddr(fd uintptr) (bool, error) { + v, err := unix.GetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR) + if err != nil { + return false, err + } + + return v == 1, nil +} + func listenTCP(network, addr string, reuseport, reuseaddr bool) (net.Listener, error) { var lc net.ListenConfig switch { case reuseaddr && reuseport: + lc.Control = reuseaddrandportControl case reuseport: lc.Control = reuseportControl case reuseaddr: @@ -56,6 +86,7 @@ func listenUDP(network, addr string, reuseport, reuseaddr bool) (net.PacketConn, var lc net.ListenConfig switch { case reuseaddr && reuseport: + lc.Control = reuseaddrandportControl case reuseport: lc.Control = reuseportControl case reuseaddr: diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go index 81580d1e5..b04d370f6 100644 --- a/vendor/github.com/miekg/dns/server.go +++ b/vendor/github.com/miekg/dns/server.go @@ -226,6 +226,7 @@ type Server struct { // If NotifyStartedFunc is set it is called once the server has started listening. NotifyStartedFunc func() // DecorateReader is optional, allows customization of the process that reads raw DNS messages. + // The decorated reader must not mutate the data read from the conn. DecorateReader DecorateReader // DecorateWriter is optional, allows customization of the process that writes raw DNS messages. DecorateWriter DecorateWriter diff --git a/vendor/github.com/miekg/dns/sig0.go b/vendor/github.com/miekg/dns/sig0.go index 2c4b10352..057bb5787 100644 --- a/vendor/github.com/miekg/dns/sig0.go +++ b/vendor/github.com/miekg/dns/sig0.go @@ -7,7 +7,6 @@ "crypto/rsa" "encoding/binary" "math/big" - "strings" "time" ) @@ -151,7 +150,7 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error { } // If key has come from the DNS name compression might // have mangled the case of the name - if !strings.EqualFold(signername, k.Header().Name) { + if !equal(signername, k.Header().Name) { return &Error{err: "signer name doesn't match key name"} } sigend := offset diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go index 00c8629f2..e290e3dff 100644 --- a/vendor/github.com/miekg/dns/version.go +++ b/vendor/github.com/miekg/dns/version.go @@ -3,7 +3,7 @@ import "fmt" // Version is current version of this library. -var Version = v{1, 1, 62} +var Version = v{1, 1, 63} // v holds the version of this library. type v struct { diff --git a/vendor/modules.txt b/vendor/modules.txt index 7c54562f3..b0a43b471 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -489,7 +489,7 @@ github.com/mattn/go-isatty ## explicit; go 1.19 github.com/microcosm-cc/bluemonday github.com/microcosm-cc/bluemonday/css -# github.com/miekg/dns v1.1.62 +# github.com/miekg/dns v1.1.63 ## explicit; go 1.19 github.com/miekg/dns # github.com/minio/md5-simd v1.1.2 From a7737687182dbf8803800f575e2083cecfd481f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:08:13 +0000 Subject: [PATCH 12/16] [chore]: Bump github.com/SherClockHolmes/webpush-go from 1.3.0 to 1.4.0 (#3694) Bumps [github.com/SherClockHolmes/webpush-go](https://github.com/SherClockHolmes/webpush-go) from 1.3.0 to 1.4.0. - [Release notes](https://github.com/SherClockHolmes/webpush-go/releases) - [Commits](https://github.com/SherClockHolmes/webpush-go/compare/v1.3.0...v1.4.0) --- updated-dependencies: - dependency-name: github.com/SherClockHolmes/webpush-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 3 +- go.sum | 34 +- .../SherClockHolmes/webpush-go/vapid.go | 21 +- .../SherClockHolmes/webpush-go/webpush.go | 1 - .../github.com/golang-jwt/jwt/v5/.gitignore | 4 + vendor/github.com/golang-jwt/jwt/v5/LICENSE | 9 + .../golang-jwt/jwt/v5/MIGRATION_GUIDE.md | 195 +++++++++++ vendor/github.com/golang-jwt/jwt/v5/README.md | 167 +++++++++ .../github.com/golang-jwt/jwt/v5/SECURITY.md | 19 ++ .../golang-jwt/jwt/v5/VERSION_HISTORY.md | 137 ++++++++ vendor/github.com/golang-jwt/jwt/v5/claims.go | 16 + vendor/github.com/golang-jwt/jwt/v5/doc.go | 4 + vendor/github.com/golang-jwt/jwt/v5/ecdsa.go | 134 ++++++++ .../golang-jwt/jwt/v5/ecdsa_utils.go | 69 ++++ .../github.com/golang-jwt/jwt/v5/ed25519.go | 79 +++++ .../golang-jwt/jwt/v5/ed25519_utils.go | 64 ++++ vendor/github.com/golang-jwt/jwt/v5/errors.go | 49 +++ .../golang-jwt/jwt/v5/errors_go1_20.go | 47 +++ .../golang-jwt/jwt/v5/errors_go_other.go | 78 +++++ vendor/github.com/golang-jwt/jwt/v5/hmac.go | 104 ++++++ .../golang-jwt/jwt/v5/map_claims.go | 109 ++++++ vendor/github.com/golang-jwt/jwt/v5/none.go | 50 +++ vendor/github.com/golang-jwt/jwt/v5/parser.go | 238 +++++++++++++ .../golang-jwt/jwt/v5/parser_option.go | 128 +++++++ .../golang-jwt/jwt/v5/registered_claims.go | 63 ++++ vendor/github.com/golang-jwt/jwt/v5/rsa.go | 93 ++++++ .../github.com/golang-jwt/jwt/v5/rsa_pss.go | 135 ++++++++ .../github.com/golang-jwt/jwt/v5/rsa_utils.go | 107 ++++++ .../golang-jwt/jwt/v5/signing_method.go | 49 +++ .../golang-jwt/jwt/v5/staticcheck.conf | 1 + vendor/github.com/golang-jwt/jwt/v5/token.go | 100 ++++++ .../golang-jwt/jwt/v5/token_option.go | 5 + vendor/github.com/golang-jwt/jwt/v5/types.go | 149 +++++++++ .../github.com/golang-jwt/jwt/v5/validator.go | 316 ++++++++++++++++++ vendor/modules.txt | 5 +- 35 files changed, 2766 insertions(+), 16 deletions(-) create mode 100644 vendor/github.com/golang-jwt/jwt/v5/.gitignore create mode 100644 vendor/github.com/golang-jwt/jwt/v5/LICENSE create mode 100644 vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md create mode 100644 vendor/github.com/golang-jwt/jwt/v5/README.md create mode 100644 vendor/github.com/golang-jwt/jwt/v5/SECURITY.md create mode 100644 vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md create mode 100644 vendor/github.com/golang-jwt/jwt/v5/claims.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/doc.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/ecdsa.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/ed25519.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/errors.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/hmac.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/map_claims.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/none.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/parser.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/parser_option.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/registered_claims.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/rsa.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/signing_method.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf create mode 100644 vendor/github.com/golang-jwt/jwt/v5/token.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/token_option.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/types.go create mode 100644 vendor/github.com/golang-jwt/jwt/v5/validator.go diff --git a/go.mod b/go.mod index d11d0c921..d0b6c8aa3 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( codeberg.org/superseriousbusiness/exif-terminator v0.9.1 github.com/DmitriyVTitov/size v1.5.0 github.com/KimMachineGun/automemlimit v0.6.1 - github.com/SherClockHolmes/webpush-go v1.3.0 + github.com/SherClockHolmes/webpush-go v1.4.0 github.com/buckket/go-blurhash v1.1.0 github.com/coreos/go-oidc/v3 v3.12.0 github.com/gin-contrib/cors v1.7.3 @@ -158,6 +158,7 @@ require ( github.com/goccy/go-json v0.10.4 // indirect github.com/godbus/dbus/v5 v5.0.4 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/geo v0.0.0-20200319012246-673a6f80352d // indirect github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/css v1.0.1 // indirect diff --git a/go.sum b/go.sum index 79747b403..9f976cfe8 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/SherClockHolmes/webpush-go v1.3.0 h1:CAu3FvEE9QS4drc3iKNgpBWFfGqNthKlZhp5QpYnu6k= -github.com/SherClockHolmes/webpush-go v1.3.0/go.mod h1:AxRHmJuYwKGG1PVgYzToik1lphQvDnqFYDqimHvwhIw= +github.com/SherClockHolmes/webpush-go v1.4.0 h1:ocnzNKWN23T9nvHi6IfyrQjkIc0oJWv1B1pULsf9i3s= +github.com/SherClockHolmes/webpush-go v1.4.0/go.mod h1:XSq8pKX11vNV8MJEMwjrlTkxhAj1zKfxmyhdV7Pd6UA= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= @@ -251,6 +251,8 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/geo v0.0.0-20200319012246-673a6f80352d h1:C/hKUcHT483btRbeGkrRjJz+Zbcj8audldIi9tRJDCc= github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= @@ -671,7 +673,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -710,6 +715,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -746,6 +754,9 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -766,6 +777,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -809,13 +823,22 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -827,6 +850,9 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -875,6 +901,8 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/github.com/SherClockHolmes/webpush-go/vapid.go b/vendor/github.com/SherClockHolmes/webpush-go/vapid.go index fe2c580a6..d1c2a9154 100644 --- a/vendor/github.com/SherClockHolmes/webpush-go/vapid.go +++ b/vendor/github.com/SherClockHolmes/webpush-go/vapid.go @@ -5,12 +5,12 @@ "crypto/elliptic" "crypto/rand" "encoding/base64" - "fmt" "math/big" "net/url" + "strings" "time" - "github.com/golang-jwt/jwt" + "github.com/golang-jwt/jwt/v5" ) // GenerateVAPIDKeys will create a private and public VAPID key pair @@ -72,10 +72,15 @@ func getVAPIDAuthorizationHeader( return "", err } + // Unless subscriber is an HTTPS URL, assume an e-mail address + if !strings.HasPrefix(subscriber, "https:") { + subscriber = "mailto:" + subscriber + } + token := jwt.NewWithClaims(jwt.SigningMethodES256, jwt.MapClaims{ - "aud": fmt.Sprintf("%s://%s", subURL.Scheme, subURL.Host), - "exp": expiration.Unix(), - "sub": fmt.Sprintf("mailto:%s", subscriber), + "aud": subURL.Scheme + "://" + subURL.Host, + "exp": time.Now().Add(time.Hour * 12).Unix(), + "sub": subscriber, }) // Decode the VAPID private key @@ -98,11 +103,7 @@ func getVAPIDAuthorizationHeader( return "", err } - return fmt.Sprintf( - "vapid t=%s, k=%s", - jwtString, - base64.RawURLEncoding.EncodeToString(pubKey), - ), nil + return "vapid t=" + jwtString + ", k=" + base64.RawURLEncoding.EncodeToString(pubKey), nil } // Need to decode the vapid private key in multiple base64 formats diff --git a/vendor/github.com/SherClockHolmes/webpush-go/webpush.go b/vendor/github.com/SherClockHolmes/webpush-go/webpush.go index 4c85ad638..a6ee7cd0c 100644 --- a/vendor/github.com/SherClockHolmes/webpush-go/webpush.go +++ b/vendor/github.com/SherClockHolmes/webpush-go/webpush.go @@ -201,7 +201,6 @@ func SendNotificationWithContext(ctx context.Context, message []byte, s *Subscri } req.Header.Set("Content-Encoding", "aes128gcm") - req.Header.Set("Content-Length", strconv.Itoa(len(ciphertext))) req.Header.Set("Content-Type", "application/octet-stream") req.Header.Set("TTL", strconv.Itoa(options.TTL)) diff --git a/vendor/github.com/golang-jwt/jwt/v5/.gitignore b/vendor/github.com/golang-jwt/jwt/v5/.gitignore new file mode 100644 index 000000000..09573e016 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +bin +.idea/ + diff --git a/vendor/github.com/golang-jwt/jwt/v5/LICENSE b/vendor/github.com/golang-jwt/jwt/v5/LICENSE new file mode 100644 index 000000000..35dbc2520 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) 2012 Dave Grijalva +Copyright (c) 2021 golang-jwt maintainers + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md b/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md new file mode 100644 index 000000000..ff9c57e1d --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md @@ -0,0 +1,195 @@ +# Migration Guide (v5.0.0) + +Version `v5` contains a major rework of core functionalities in the `jwt-go` +library. This includes support for several validation options as well as a +re-design of the `Claims` interface. Lastly, we reworked how errors work under +the hood, which should provide a better overall developer experience. + +Starting from [v5.0.0](https://github.com/golang-jwt/jwt/releases/tag/v5.0.0), +the import path will be: + + "github.com/golang-jwt/jwt/v5" + +For most users, changing the import path *should* suffice. However, since we +intentionally changed and cleaned some of the public API, existing programs +might need to be updated. The following sections describe significant changes +and corresponding updates for existing programs. + +## Parsing and Validation Options + +Under the hood, a new `Validator` struct takes care of validating the claims. A +long awaited feature has been the option to fine-tune the validation of tokens. +This is now possible with several `ParserOption` functions that can be appended +to most `Parse` functions, such as `ParseWithClaims`. The most important options +and changes are: + * Added `WithLeeway` to support specifying the leeway that is allowed when + validating time-based claims, such as `exp` or `nbf`. + * Changed default behavior to not check the `iat` claim. Usage of this claim + is OPTIONAL according to the JWT RFC. The claim itself is also purely + informational according to the RFC, so a strict validation failure is not + recommended. If you want to check for sensible values in these claims, + please use the `WithIssuedAt` parser option. + * Added `WithAudience`, `WithSubject` and `WithIssuer` to support checking for + expected `aud`, `sub` and `iss`. + * Added `WithStrictDecoding` and `WithPaddingAllowed` options to allow + previously global settings to enable base64 strict encoding and the parsing + of base64 strings with padding. The latter is strictly speaking against the + standard, but unfortunately some of the major identity providers issue some + of these incorrect tokens. Both options are disabled by default. + +## Changes to the `Claims` interface + +### Complete Restructuring + +Previously, the claims interface was satisfied with an implementation of a +`Valid() error` function. This had several issues: + * The different claim types (struct claims, map claims, etc.) then contained + similar (but not 100 % identical) code of how this validation was done. This + lead to a lot of (almost) duplicate code and was hard to maintain + * It was not really semantically close to what a "claim" (or a set of claims) + really is; which is a list of defined key/value pairs with a certain + semantic meaning. + +Since all the validation functionality is now extracted into the validator, all +`VerifyXXX` and `Valid` functions have been removed from the `Claims` interface. +Instead, the interface now represents a list of getters to retrieve values with +a specific meaning. This allows us to completely decouple the validation logic +with the underlying storage representation of the claim, which could be a +struct, a map or even something stored in a database. + +```go +type Claims interface { + GetExpirationTime() (*NumericDate, error) + GetIssuedAt() (*NumericDate, error) + GetNotBefore() (*NumericDate, error) + GetIssuer() (string, error) + GetSubject() (string, error) + GetAudience() (ClaimStrings, error) +} +``` + +Users that previously directly called the `Valid` function on their claims, +e.g., to perform validation independently of parsing/verifying a token, can now +use the `jwt.NewValidator` function to create a `Validator` independently of the +`Parser`. + +```go +var v = jwt.NewValidator(jwt.WithLeeway(5*time.Second)) +v.Validate(myClaims) +``` + +### Supported Claim Types and Removal of `StandardClaims` + +The two standard claim types supported by this library, `MapClaims` and +`RegisteredClaims` both implement the necessary functions of this interface. The +old `StandardClaims` struct, which has already been deprecated in `v4` is now +removed. + +Users using custom claims, in most cases, will not experience any changes in the +behavior as long as they embedded `RegisteredClaims`. If they created a new +claim type from scratch, they now need to implemented the proper getter +functions. + +### Migrating Application Specific Logic of the old `Valid` + +Previously, users could override the `Valid` method in a custom claim, for +example to extend the validation with application-specific claims. However, this +was always very dangerous, since once could easily disable the standard +validation and signature checking. + +In order to avoid that, while still supporting the use-case, a new +`ClaimsValidator` interface has been introduced. This interface consists of the +`Validate() error` function. If the validator sees, that a `Claims` struct +implements this interface, the errors returned to the `Validate` function will +be *appended* to the regular standard validation. It is not possible to disable +the standard validation anymore (even only by accident). + +Usage examples can be found in [example_test.go](./example_test.go), to build +claims structs like the following. + +```go +// MyCustomClaims includes all registered claims, plus Foo. +type MyCustomClaims struct { + Foo string `json:"foo"` + jwt.RegisteredClaims +} + +// Validate can be used to execute additional application-specific claims +// validation. +func (m MyCustomClaims) Validate() error { + if m.Foo != "bar" { + return errors.New("must be foobar") + } + + return nil +} +``` + +## Changes to the `Token` and `Parser` struct + +The previously global functions `DecodeSegment` and `EncodeSegment` were moved +to the `Parser` and `Token` struct respectively. This will allow us in the +future to configure the behavior of these two based on options supplied on the +parser or the token (creation). This also removes two previously global +variables and moves them to parser options `WithStrictDecoding` and +`WithPaddingAllowed`. + +In order to do that, we had to adjust the way signing methods work. Previously +they were given a base64 encoded signature in `Verify` and were expected to +return a base64 encoded version of the signature in `Sign`, both as a `string`. +However, this made it necessary to have `DecodeSegment` and `EncodeSegment` +global and was a less than perfect design because we were repeating +encoding/decoding steps for all signing methods. Now, `Sign` and `Verify` +operate on a decoded signature as a `[]byte`, which feels more natural for a +cryptographic operation anyway. Lastly, `Parse` and `SignedString` take care of +the final encoding/decoding part. + +In addition to that, we also changed the `Signature` field on `Token` from a +`string` to `[]byte` and this is also now populated with the decoded form. This +is also more consistent, because the other parts of the JWT, mainly `Header` and +`Claims` were already stored in decoded form in `Token`. Only the signature was +stored in base64 encoded form, which was redundant with the information in the +`Raw` field, which contains the complete token as base64. + +```go +type Token struct { + Raw string // Raw contains the raw token + Method SigningMethod // Method is the signing method used or to be used + Header map[string]interface{} // Header is the first segment of the token in decoded form + Claims Claims // Claims is the second segment of the token in decoded form + Signature []byte // Signature is the third segment of the token in decoded form + Valid bool // Valid specifies if the token is valid +} +``` + +Most (if not all) of these changes should not impact the normal usage of this +library. Only users directly accessing the `Signature` field as well as +developers of custom signing methods should be affected. + +# Migration Guide (v4.0.0) + +Starting from [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0), +the import path will be: + + "github.com/golang-jwt/jwt/v4" + +The `/v4` version will be backwards compatible with existing `v3.x.y` tags in +this repo, as well as `github.com/dgrijalva/jwt-go`. For most users this should +be a drop-in replacement, if you're having troubles migrating, please open an +issue. + +You can replace all occurrences of `github.com/dgrijalva/jwt-go` or +`github.com/golang-jwt/jwt` with `github.com/golang-jwt/jwt/v4`, either manually +or by using tools such as `sed` or `gofmt`. + +And then you'd typically run: + +``` +go get github.com/golang-jwt/jwt/v4 +go mod tidy +``` + +# Older releases (before v3.2.0) + +The original migration guide for older releases can be found at +https://github.com/dgrijalva/jwt-go/blob/master/MIGRATION_GUIDE.md. diff --git a/vendor/github.com/golang-jwt/jwt/v5/README.md b/vendor/github.com/golang-jwt/jwt/v5/README.md new file mode 100644 index 000000000..964598a31 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/README.md @@ -0,0 +1,167 @@ +# jwt-go + +[![build](https://github.com/golang-jwt/jwt/actions/workflows/build.yml/badge.svg)](https://github.com/golang-jwt/jwt/actions/workflows/build.yml) +[![Go +Reference](https://pkg.go.dev/badge/github.com/golang-jwt/jwt/v5.svg)](https://pkg.go.dev/github.com/golang-jwt/jwt/v5) +[![Coverage Status](https://coveralls.io/repos/github/golang-jwt/jwt/badge.svg?branch=main)](https://coveralls.io/github/golang-jwt/jwt?branch=main) + +A [go](http://www.golang.org) (or 'golang' for search engine friendliness) +implementation of [JSON Web +Tokens](https://datatracker.ietf.org/doc/html/rfc7519). + +Starting with [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0) +this project adds Go module support, but maintains backwards compatibility with +older `v3.x.y` tags and upstream `github.com/dgrijalva/jwt-go`. See the +[`MIGRATION_GUIDE.md`](./MIGRATION_GUIDE.md) for more information. Version +v5.0.0 introduces major improvements to the validation of tokens, but is not +entirely backwards compatible. + +> After the original author of the library suggested migrating the maintenance +> of `jwt-go`, a dedicated team of open source maintainers decided to clone the +> existing library into this repository. See +> [dgrijalva/jwt-go#462](https://github.com/dgrijalva/jwt-go/issues/462) for a +> detailed discussion on this topic. + + +**SECURITY NOTICE:** Some older versions of Go have a security issue in the +crypto/elliptic. Recommendation is to upgrade to at least 1.15 See issue +[dgrijalva/jwt-go#216](https://github.com/dgrijalva/jwt-go/issues/216) for more +detail. + +**SECURITY NOTICE:** It's important that you [validate the `alg` presented is +what you +expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). +This library attempts to make it easy to do the right thing by requiring key +types match the expected alg, but you should take the extra step to verify it in +your usage. See the examples provided. + +### Supported Go versions + +Our support of Go versions is aligned with Go's [version release +policy](https://golang.org/doc/devel/release#policy). So we will support a major +version of Go until there are two newer major releases. We no longer support +building jwt-go with unsupported Go versions, as these contain security +vulnerabilities which will not be fixed. + +## What the heck is a JWT? + +JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web +Tokens. + +In short, it's a signed JSON object that does something useful (for example, +authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is +made of three parts, separated by `.`'s. The first two parts are JSON objects, +that have been [base64url](https://datatracker.ietf.org/doc/html/rfc4648) +encoded. The last part is the signature, encoded the same way. + +The first part is called the header. It contains the necessary information for +verifying the last part, the signature. For example, which encryption method +was used for signing and what key was used. + +The part in the middle is the interesting bit. It's called the Claims and +contains the actual stuff you care about. Refer to [RFC +7519](https://datatracker.ietf.org/doc/html/rfc7519) for information about +reserved keys and the proper way to add your own. + +## What's in the box? + +This library supports the parsing and verification as well as the generation and +signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, +RSA-PSS, and ECDSA, though hooks are present for adding your own. + +## Installation Guidelines + +1. To install the jwt package, you first need to have + [Go](https://go.dev/doc/install) installed, then you can use the command + below to add `jwt-go` as a dependency in your Go program. + +```sh +go get -u github.com/golang-jwt/jwt/v5 +``` + +2. Import it in your code: + +```go +import "github.com/golang-jwt/jwt/v5" +``` + +## Usage + +A detailed usage guide, including how to sign and verify tokens can be found on +our [documentation website](https://golang-jwt.github.io/jwt/usage/create/). + +## Examples + +See [the project documentation](https://pkg.go.dev/github.com/golang-jwt/jwt/v5) +for examples of usage: + +* [Simple example of parsing and validating a + token](https://pkg.go.dev/github.com/golang-jwt/jwt/v5#example-Parse-Hmac) +* [Simple example of building and signing a + token](https://pkg.go.dev/github.com/golang-jwt/jwt/v5#example-New-Hmac) +* [Directory of + Examples](https://pkg.go.dev/github.com/golang-jwt/jwt/v5#pkg-examples) + +## Compliance + +This library was last reviewed to comply with [RFC +7519](https://datatracker.ietf.org/doc/html/rfc7519) dated May 2015 with a few +notable differences: + +* In order to protect against accidental use of [Unsecured + JWTs](https://datatracker.ietf.org/doc/html/rfc7519#section-6), tokens using + `alg=none` will only be accepted if the constant + `jwt.UnsafeAllowNoneSignatureType` is provided as the key. + +## Project Status & Versioning + +This library is considered production ready. Feedback and feature requests are +appreciated. The API should be considered stable. There should be very few +backwards-incompatible changes outside of major version updates (and only with +good reason). + +This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull +requests will land on `main`. Periodically, versions will be tagged from +`main`. You can find all the releases on [the project releases +page](https://github.com/golang-jwt/jwt/releases). + +**BREAKING CHANGES:*** A full list of breaking changes is available in +`VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating +your code. + +## Extensions + +This library publishes all the necessary components for adding your own signing +methods or key functions. Simply implement the `SigningMethod` interface and +register a factory method using `RegisterSigningMethod` or provide a +`jwt.Keyfunc`. + +A common use case would be integrating with different 3rd party signature +providers, like key management services from various cloud providers or Hardware +Security Modules (HSMs) or to implement additional standards. + +| Extension | Purpose | Repo | +| --------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| GCP | Integrates with multiple Google Cloud Platform signing tools (AppEngine, IAM API, Cloud KMS) | https://github.com/someone1/gcp-jwt-go | +| AWS | Integrates with AWS Key Management Service, KMS | https://github.com/matelang/jwt-go-aws-kms | +| JWKS | Provides support for JWKS ([RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517)) as a `jwt.Keyfunc` | https://github.com/MicahParks/keyfunc | + +*Disclaimer*: Unless otherwise specified, these integrations are maintained by +third parties and should not be considered as a primary offer by any of the +mentioned cloud providers + +## More + +Go package documentation can be found [on +pkg.go.dev](https://pkg.go.dev/github.com/golang-jwt/jwt/v5). Additional +documentation can be found on [our project +page](https://golang-jwt.github.io/jwt/). + +The command line utility included in this project (cmd/jwt) provides a +straightforward example of token creation and parsing as well as a useful tool +for debugging your own integration. You'll also find several implementation +examples in the documentation. + +[golang-jwt](https://github.com/orgs/golang-jwt) incorporates a modified version +of the JWT logo, which is distributed under the terms of the [MIT +License](https://github.com/jsonwebtoken/jsonwebtoken.github.io/blob/master/LICENSE.txt). diff --git a/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md b/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md new file mode 100644 index 000000000..b08402c34 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md @@ -0,0 +1,19 @@ +# Security Policy + +## Supported Versions + +As of February 2022 (and until this document is updated), the latest version `v4` is supported. + +## Reporting a Vulnerability + +If you think you found a vulnerability, and even if you are not sure, please report it to jwt-go-security@googlegroups.com or one of the other [golang-jwt maintainers](https://github.com/orgs/golang-jwt/people). Please try be explicit, describe steps to reproduce the security issue with code example(s). + +You will receive a response within a timely manner. If the issue is confirmed, we will do our best to release a patch as soon as possible given the complexity of the problem. + +## Public Discussions + +Please avoid publicly discussing a potential security vulnerability. + +Let's take this offline and find a solution first, this limits the potential impact as much as possible. + +We appreciate your help! diff --git a/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md b/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md new file mode 100644 index 000000000..b5039e49c --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md @@ -0,0 +1,137 @@ +# `jwt-go` Version History + +The following version history is kept for historic purposes. To retrieve the current changes of each version, please refer to the change-log of the specific release versions on https://github.com/golang-jwt/jwt/releases. + +## 4.0.0 + +* Introduces support for Go modules. The `v4` version will be backwards compatible with `v3.x.y`. + +## 3.2.2 + +* Starting from this release, we are adopting the policy to support the most 2 recent versions of Go currently available. By the time of this release, this is Go 1.15 and 1.16 ([#28](https://github.com/golang-jwt/jwt/pull/28)). +* Fixed a potential issue that could occur when the verification of `exp`, `iat` or `nbf` was not required and contained invalid contents, i.e. non-numeric/date. Thanks for @thaJeztah for making us aware of that and @giorgos-f3 for originally reporting it to the formtech fork ([#40](https://github.com/golang-jwt/jwt/pull/40)). +* Added support for EdDSA / ED25519 ([#36](https://github.com/golang-jwt/jwt/pull/36)). +* Optimized allocations ([#33](https://github.com/golang-jwt/jwt/pull/33)). + +## 3.2.1 + +* **Import Path Change**: See MIGRATION_GUIDE.md for tips on updating your code + * Changed the import path from `github.com/dgrijalva/jwt-go` to `github.com/golang-jwt/jwt` +* Fixed type confusing issue between `string` and `[]string` in `VerifyAudience` ([#12](https://github.com/golang-jwt/jwt/pull/12)). This fixes CVE-2020-26160 + +#### 3.2.0 + +* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation +* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate +* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before. +* Deprecated `ParseFromRequestWithClaims` to simplify API in the future. + +#### 3.1.0 + +* Improvements to `jwt` command line tool +* Added `SkipClaimsValidation` option to `Parser` +* Documentation updates + +#### 3.0.0 + +* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code + * Dropped support for `[]byte` keys when using RSA signing methods. This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods. + * `ParseFromRequest` has been moved to `request` subpackage and usage has changed + * The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`. The default value is type `MapClaims`, which is an alias to `map[string]interface{}`. This makes it possible to use a custom type when decoding claims. +* Other Additions and Changes + * Added `Claims` interface type to allow users to decode the claims into a custom type + * Added `ParseWithClaims`, which takes a third argument of type `Claims`. Use this function instead of `Parse` if you have a custom type you'd like to decode into. + * Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage + * Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims` + * Added new interface type `Extractor`, which is used for extracting JWT strings from http requests. Used with `ParseFromRequest` and `ParseFromRequestWithClaims`. + * Added several new, more specific, validation errors to error type bitmask + * Moved examples from README to executable example files + * Signing method registry is now thread safe + * Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser) + +#### 2.7.0 + +This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes. + +* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying +* Error text for expired tokens includes how long it's been expired +* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM` +* Documentation updates + +#### 2.6.0 + +* Exposed inner error within ValidationError +* Fixed validation errors when using UseJSONNumber flag +* Added several unit tests + +#### 2.5.0 + +* Added support for signing method none. You shouldn't use this. The API tries to make this clear. +* Updated/fixed some documentation +* Added more helpful error message when trying to parse tokens that begin with `BEARER ` + +#### 2.4.0 + +* Added new type, Parser, to allow for configuration of various parsing parameters + * You can now specify a list of valid signing methods. Anything outside this set will be rejected. + * You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON +* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go) +* Fixed some bugs with ECDSA parsing + +#### 2.3.0 + +* Added support for ECDSA signing methods +* Added support for RSA PSS signing methods (requires go v1.4) + +#### 2.2.0 + +* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`. Result will now be the parsed token and an error, instead of a panic. + +#### 2.1.0 + +Backwards compatible API change that was missed in 2.0.0. + +* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte` + +#### 2.0.0 + +There were two major reasons for breaking backwards compatibility with this update. The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations. There will likely be no required code changes to support this change. + +The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods. Not all keys used for all signing methods have a single standard on-disk representation. Requiring `[]byte` as the type for all keys proved too limiting. Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys. Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`. + +It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`. + +* **Compatibility Breaking Changes** + * `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct` + * `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct` + * `KeyFunc` now returns `interface{}` instead of `[]byte` + * `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key + * `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key +* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodHS256` + * Added public package global `SigningMethodHS384` + * Added public package global `SigningMethodHS512` +* Renamed type `SigningMethodRS256` to `SigningMethodRSA`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodRS256` + * Added public package global `SigningMethodRS384` + * Added public package global `SigningMethodRS512` +* Moved sample private key for HMAC tests from an inline value to a file on disk. Value is unchanged. +* Refactored the RSA implementation to be easier to read +* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM` + +## 1.0.2 + +* Fixed bug in parsing public keys from certificates +* Added more tests around the parsing of keys for RS256 +* Code refactoring in RS256 implementation. No functional changes + +## 1.0.1 + +* Fixed panic if RS256 signing method was passed an invalid key + +## 1.0.0 + +* First versioned release +* API stabilized +* Supports creating, signing, parsing, and validating JWT tokens +* Supports RS256 and HS256 signing methods diff --git a/vendor/github.com/golang-jwt/jwt/v5/claims.go b/vendor/github.com/golang-jwt/jwt/v5/claims.go new file mode 100644 index 000000000..d50ff3dad --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/claims.go @@ -0,0 +1,16 @@ +package jwt + +// Claims represent any form of a JWT Claims Set according to +// https://datatracker.ietf.org/doc/html/rfc7519#section-4. In order to have a +// common basis for validation, it is required that an implementation is able to +// supply at least the claim names provided in +// https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 namely `exp`, +// `iat`, `nbf`, `iss`, `sub` and `aud`. +type Claims interface { + GetExpirationTime() (*NumericDate, error) + GetIssuedAt() (*NumericDate, error) + GetNotBefore() (*NumericDate, error) + GetIssuer() (string, error) + GetSubject() (string, error) + GetAudience() (ClaimStrings, error) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/doc.go b/vendor/github.com/golang-jwt/jwt/v5/doc.go new file mode 100644 index 000000000..a86dc1a3b --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/doc.go @@ -0,0 +1,4 @@ +// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html +// +// See README.md for more info. +package jwt diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go new file mode 100644 index 000000000..c929e4a02 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go @@ -0,0 +1,134 @@ +package jwt + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rand" + "errors" + "math/big" +) + +var ( + // Sadly this is missing from crypto/ecdsa compared to crypto/rsa + ErrECDSAVerification = errors.New("crypto/ecdsa: verification error") +) + +// SigningMethodECDSA implements the ECDSA family of signing methods. +// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification +type SigningMethodECDSA struct { + Name string + Hash crypto.Hash + KeySize int + CurveBits int +} + +// Specific instances for EC256 and company +var ( + SigningMethodES256 *SigningMethodECDSA + SigningMethodES384 *SigningMethodECDSA + SigningMethodES512 *SigningMethodECDSA +) + +func init() { + // ES256 + SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256} + RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod { + return SigningMethodES256 + }) + + // ES384 + SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384} + RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod { + return SigningMethodES384 + }) + + // ES512 + SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521} + RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod { + return SigningMethodES512 + }) +} + +func (m *SigningMethodECDSA) Alg() string { + return m.Name +} + +// Verify implements token verification for the SigningMethod. +// For this verify method, key must be an ecdsa.PublicKey struct +func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key interface{}) error { + // Get the key + var ecdsaKey *ecdsa.PublicKey + switch k := key.(type) { + case *ecdsa.PublicKey: + ecdsaKey = k + default: + return newError("ECDSA verify expects *ecdsa.PublicKey", ErrInvalidKeyType) + } + + if len(sig) != 2*m.KeySize { + return ErrECDSAVerification + } + + r := big.NewInt(0).SetBytes(sig[:m.KeySize]) + s := big.NewInt(0).SetBytes(sig[m.KeySize:]) + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus { + return nil + } + + return ErrECDSAVerification +} + +// Sign implements token signing for the SigningMethod. +// For this signing method, key must be an ecdsa.PrivateKey struct +func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) ([]byte, error) { + // Get the key + var ecdsaKey *ecdsa.PrivateKey + switch k := key.(type) { + case *ecdsa.PrivateKey: + ecdsaKey = k + default: + return nil, newError("ECDSA sign expects *ecdsa.PrivateKey", ErrInvalidKeyType) + } + + // Create the hasher + if !m.Hash.Available() { + return nil, ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return r, s + if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil { + curveBits := ecdsaKey.Curve.Params().BitSize + + if m.CurveBits != curveBits { + return nil, ErrInvalidKey + } + + keyBytes := curveBits / 8 + if curveBits%8 > 0 { + keyBytes += 1 + } + + // We serialize the outputs (r and s) into big-endian byte arrays + // padded with zeros on the left to make sure the sizes work out. + // Output must be 2*keyBytes long. + out := make([]byte, 2*keyBytes) + r.FillBytes(out[0:keyBytes]) // r is assigned to the first half of output. + s.FillBytes(out[keyBytes:]) // s is assigned to the second half of output. + + return out, nil + } else { + return nil, err + } +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go new file mode 100644 index 000000000..5700636d3 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go @@ -0,0 +1,69 @@ +package jwt + +import ( + "crypto/ecdsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrNotECPublicKey = errors.New("key is not a valid ECDSA public key") + ErrNotECPrivateKey = errors.New("key is not a valid ECDSA private key") +) + +// ParseECPrivateKeyFromPEM parses a PEM encoded Elliptic Curve Private Key Structure +func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } + } + + var pkey *ecdsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok { + return nil, ErrNotECPrivateKey + } + + return pkey, nil +} + +// ParseECPublicKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 public key +func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + return nil, err + } + } + + var pkey *ecdsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok { + return nil, ErrNotECPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519.go new file mode 100644 index 000000000..c2138119e --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/ed25519.go @@ -0,0 +1,79 @@ +package jwt + +import ( + "crypto" + "crypto/ed25519" + "crypto/rand" + "errors" +) + +var ( + ErrEd25519Verification = errors.New("ed25519: verification error") +) + +// SigningMethodEd25519 implements the EdDSA family. +// Expects ed25519.PrivateKey for signing and ed25519.PublicKey for verification +type SigningMethodEd25519 struct{} + +// Specific instance for EdDSA +var ( + SigningMethodEdDSA *SigningMethodEd25519 +) + +func init() { + SigningMethodEdDSA = &SigningMethodEd25519{} + RegisterSigningMethod(SigningMethodEdDSA.Alg(), func() SigningMethod { + return SigningMethodEdDSA + }) +} + +func (m *SigningMethodEd25519) Alg() string { + return "EdDSA" +} + +// Verify implements token verification for the SigningMethod. +// For this verify method, key must be an ed25519.PublicKey +func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key interface{}) error { + var ed25519Key ed25519.PublicKey + var ok bool + + if ed25519Key, ok = key.(ed25519.PublicKey); !ok { + return newError("Ed25519 verify expects ed25519.PublicKey", ErrInvalidKeyType) + } + + if len(ed25519Key) != ed25519.PublicKeySize { + return ErrInvalidKey + } + + // Verify the signature + if !ed25519.Verify(ed25519Key, []byte(signingString), sig) { + return ErrEd25519Verification + } + + return nil +} + +// Sign implements token signing for the SigningMethod. +// For this signing method, key must be an ed25519.PrivateKey +func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) ([]byte, error) { + var ed25519Key crypto.Signer + var ok bool + + if ed25519Key, ok = key.(crypto.Signer); !ok { + return nil, newError("Ed25519 sign expects crypto.Signer", ErrInvalidKeyType) + } + + if _, ok := ed25519Key.Public().(ed25519.PublicKey); !ok { + return nil, ErrInvalidKey + } + + // Sign the string and return the result. ed25519 performs a two-pass hash + // as part of its algorithm. Therefore, we need to pass a non-prehashed + // message into the Sign function, as indicated by crypto.Hash(0) + sig, err := ed25519Key.Sign(rand.Reader, []byte(signingString), crypto.Hash(0)) + if err != nil { + return nil, err + } + + return sig, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go new file mode 100644 index 000000000..cdb5e68e8 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go @@ -0,0 +1,64 @@ +package jwt + +import ( + "crypto" + "crypto/ed25519" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrNotEdPrivateKey = errors.New("key is not a valid Ed25519 private key") + ErrNotEdPublicKey = errors.New("key is not a valid Ed25519 public key") +) + +// ParseEdPrivateKeyFromPEM parses a PEM-encoded Edwards curve private key +func ParseEdPrivateKeyFromPEM(key []byte) (crypto.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } + + var pkey ed25519.PrivateKey + var ok bool + if pkey, ok = parsedKey.(ed25519.PrivateKey); !ok { + return nil, ErrNotEdPrivateKey + } + + return pkey, nil +} + +// ParseEdPublicKeyFromPEM parses a PEM-encoded Edwards curve public key +func ParseEdPublicKeyFromPEM(key []byte) (crypto.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + return nil, err + } + + var pkey ed25519.PublicKey + var ok bool + if pkey, ok = parsedKey.(ed25519.PublicKey); !ok { + return nil, ErrNotEdPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors.go b/vendor/github.com/golang-jwt/jwt/v5/errors.go new file mode 100644 index 000000000..23bb616dd --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/errors.go @@ -0,0 +1,49 @@ +package jwt + +import ( + "errors" + "strings" +) + +var ( + ErrInvalidKey = errors.New("key is invalid") + ErrInvalidKeyType = errors.New("key is of invalid type") + ErrHashUnavailable = errors.New("the requested hash function is unavailable") + ErrTokenMalformed = errors.New("token is malformed") + ErrTokenUnverifiable = errors.New("token is unverifiable") + ErrTokenSignatureInvalid = errors.New("token signature is invalid") + ErrTokenRequiredClaimMissing = errors.New("token is missing required claim") + ErrTokenInvalidAudience = errors.New("token has invalid audience") + ErrTokenExpired = errors.New("token is expired") + ErrTokenUsedBeforeIssued = errors.New("token used before issued") + ErrTokenInvalidIssuer = errors.New("token has invalid issuer") + ErrTokenInvalidSubject = errors.New("token has invalid subject") + ErrTokenNotValidYet = errors.New("token is not valid yet") + ErrTokenInvalidId = errors.New("token has invalid id") + ErrTokenInvalidClaims = errors.New("token has invalid claims") + ErrInvalidType = errors.New("invalid type for claim") +) + +// joinedError is an error type that works similar to what [errors.Join] +// produces, with the exception that it has a nice error string; mainly its +// error messages are concatenated using a comma, rather than a newline. +type joinedError struct { + errs []error +} + +func (je joinedError) Error() string { + msg := []string{} + for _, err := range je.errs { + msg = append(msg, err.Error()) + } + + return strings.Join(msg, ", ") +} + +// joinErrors joins together multiple errors. Useful for scenarios where +// multiple errors next to each other occur, e.g., in claims validation. +func joinErrors(errs ...error) error { + return &joinedError{ + errs: errs, + } +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go b/vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go new file mode 100644 index 000000000..a893d355e --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go @@ -0,0 +1,47 @@ +//go:build go1.20 +// +build go1.20 + +package jwt + +import ( + "fmt" +) + +// Unwrap implements the multiple error unwrapping for this error type, which is +// possible in Go 1.20. +func (je joinedError) Unwrap() []error { + return je.errs +} + +// newError creates a new error message with a detailed error message. The +// message will be prefixed with the contents of the supplied error type. +// Additionally, more errors, that provide more context can be supplied which +// will be appended to the message. This makes use of Go 1.20's possibility to +// include more than one %w formatting directive in [fmt.Errorf]. +// +// For example, +// +// newError("no keyfunc was provided", ErrTokenUnverifiable) +// +// will produce the error string +// +// "token is unverifiable: no keyfunc was provided" +func newError(message string, err error, more ...error) error { + var format string + var args []any + if message != "" { + format = "%w: %s" + args = []any{err, message} + } else { + format = "%w" + args = []any{err} + } + + for _, e := range more { + format += ": %w" + args = append(args, e) + } + + err = fmt.Errorf(format, args...) + return err +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go b/vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go new file mode 100644 index 000000000..2ad542f00 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go @@ -0,0 +1,78 @@ +//go:build !go1.20 +// +build !go1.20 + +package jwt + +import ( + "errors" + "fmt" +) + +// Is implements checking for multiple errors using [errors.Is], since multiple +// error unwrapping is not possible in versions less than Go 1.20. +func (je joinedError) Is(err error) bool { + for _, e := range je.errs { + if errors.Is(e, err) { + return true + } + } + + return false +} + +// wrappedErrors is a workaround for wrapping multiple errors in environments +// where Go 1.20 is not available. It basically uses the already implemented +// functionality of joinedError to handle multiple errors with supplies a +// custom error message that is identical to the one we produce in Go 1.20 using +// multiple %w directives. +type wrappedErrors struct { + msg string + joinedError +} + +// Error returns the stored error string +func (we wrappedErrors) Error() string { + return we.msg +} + +// newError creates a new error message with a detailed error message. The +// message will be prefixed with the contents of the supplied error type. +// Additionally, more errors, that provide more context can be supplied which +// will be appended to the message. Since we cannot use of Go 1.20's possibility +// to include more than one %w formatting directive in [fmt.Errorf], we have to +// emulate that. +// +// For example, +// +// newError("no keyfunc was provided", ErrTokenUnverifiable) +// +// will produce the error string +// +// "token is unverifiable: no keyfunc was provided" +func newError(message string, err error, more ...error) error { + // We cannot wrap multiple errors here with %w, so we have to be a little + // bit creative. Basically, we are using %s instead of %w to produce the + // same error message and then throw the result into a custom error struct. + var format string + var args []any + if message != "" { + format = "%s: %s" + args = []any{err, message} + } else { + format = "%s" + args = []any{err} + } + errs := []error{err} + + for _, e := range more { + format += ": %s" + args = append(args, e) + errs = append(errs, e) + } + + err = &wrappedErrors{ + msg: fmt.Sprintf(format, args...), + joinedError: joinedError{errs: errs}, + } + return err +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/hmac.go b/vendor/github.com/golang-jwt/jwt/v5/hmac.go new file mode 100644 index 000000000..aca600ce1 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/hmac.go @@ -0,0 +1,104 @@ +package jwt + +import ( + "crypto" + "crypto/hmac" + "errors" +) + +// SigningMethodHMAC implements the HMAC-SHA family of signing methods. +// Expects key type of []byte for both signing and validation +type SigningMethodHMAC struct { + Name string + Hash crypto.Hash +} + +// Specific instances for HS256 and company +var ( + SigningMethodHS256 *SigningMethodHMAC + SigningMethodHS384 *SigningMethodHMAC + SigningMethodHS512 *SigningMethodHMAC + ErrSignatureInvalid = errors.New("signature is invalid") +) + +func init() { + // HS256 + SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod { + return SigningMethodHS256 + }) + + // HS384 + SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod { + return SigningMethodHS384 + }) + + // HS512 + SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod { + return SigningMethodHS512 + }) +} + +func (m *SigningMethodHMAC) Alg() string { + return m.Name +} + +// Verify implements token verification for the SigningMethod. Returns nil if +// the signature is valid. Key must be []byte. +// +// Note it is not advised to provide a []byte which was converted from a 'human +// readable' string using a subset of ASCII characters. To maximize entropy, you +// should ideally be providing a []byte key which was produced from a +// cryptographically random source, e.g. crypto/rand. Additional information +// about this, and why we intentionally are not supporting string as a key can +// be found on our usage guide +// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types. +func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interface{}) error { + // Verify the key is the right type + keyBytes, ok := key.([]byte) + if !ok { + return newError("HMAC verify expects []byte", ErrInvalidKeyType) + } + + // Can we use the specified hashing method? + if !m.Hash.Available() { + return ErrHashUnavailable + } + + // This signing method is symmetric, so we validate the signature + // by reproducing the signature from the signing string and key, then + // comparing that against the provided signature. + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + if !hmac.Equal(sig, hasher.Sum(nil)) { + return ErrSignatureInvalid + } + + // No validation errors. Signature is good. + return nil +} + +// Sign implements token signing for the SigningMethod. Key must be []byte. +// +// Note it is not advised to provide a []byte which was converted from a 'human +// readable' string using a subset of ASCII characters. To maximize entropy, you +// should ideally be providing a []byte key which was produced from a +// cryptographically random source, e.g. crypto/rand. Additional information +// about this, and why we intentionally are not supporting string as a key can +// be found on our usage guide https://golang-jwt.github.io/jwt/usage/signing_methods/. +func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte, error) { + if keyBytes, ok := key.([]byte); ok { + if !m.Hash.Available() { + return nil, ErrHashUnavailable + } + + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + + return hasher.Sum(nil), nil + } + + return nil, newError("HMAC sign expects []byte", ErrInvalidKeyType) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/map_claims.go b/vendor/github.com/golang-jwt/jwt/v5/map_claims.go new file mode 100644 index 000000000..b2b51a1f8 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/map_claims.go @@ -0,0 +1,109 @@ +package jwt + +import ( + "encoding/json" + "fmt" +) + +// MapClaims is a claims type that uses the map[string]interface{} for JSON +// decoding. This is the default claims type if you don't supply one +type MapClaims map[string]interface{} + +// GetExpirationTime implements the Claims interface. +func (m MapClaims) GetExpirationTime() (*NumericDate, error) { + return m.parseNumericDate("exp") +} + +// GetNotBefore implements the Claims interface. +func (m MapClaims) GetNotBefore() (*NumericDate, error) { + return m.parseNumericDate("nbf") +} + +// GetIssuedAt implements the Claims interface. +func (m MapClaims) GetIssuedAt() (*NumericDate, error) { + return m.parseNumericDate("iat") +} + +// GetAudience implements the Claims interface. +func (m MapClaims) GetAudience() (ClaimStrings, error) { + return m.parseClaimsString("aud") +} + +// GetIssuer implements the Claims interface. +func (m MapClaims) GetIssuer() (string, error) { + return m.parseString("iss") +} + +// GetSubject implements the Claims interface. +func (m MapClaims) GetSubject() (string, error) { + return m.parseString("sub") +} + +// parseNumericDate tries to parse a key in the map claims type as a number +// date. This will succeed, if the underlying type is either a [float64] or a +// [json.Number]. Otherwise, nil will be returned. +func (m MapClaims) parseNumericDate(key string) (*NumericDate, error) { + v, ok := m[key] + if !ok { + return nil, nil + } + + switch exp := v.(type) { + case float64: + if exp == 0 { + return nil, nil + } + + return newNumericDateFromSeconds(exp), nil + case json.Number: + v, _ := exp.Float64() + + return newNumericDateFromSeconds(v), nil + } + + return nil, newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType) +} + +// parseClaimsString tries to parse a key in the map claims type as a +// [ClaimsStrings] type, which can either be a string or an array of string. +func (m MapClaims) parseClaimsString(key string) (ClaimStrings, error) { + var cs []string + switch v := m[key].(type) { + case string: + cs = append(cs, v) + case []string: + cs = v + case []interface{}: + for _, a := range v { + vs, ok := a.(string) + if !ok { + return nil, newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType) + } + cs = append(cs, vs) + } + } + + return cs, nil +} + +// parseString tries to parse a key in the map claims type as a [string] type. +// If the key does not exist, an empty string is returned. If the key has the +// wrong type, an error is returned. +func (m MapClaims) parseString(key string) (string, error) { + var ( + ok bool + raw interface{} + iss string + ) + raw, ok = m[key] + if !ok { + return "", nil + } + + iss, ok = raw.(string) + if !ok { + return "", newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType) + } + + return iss, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/none.go b/vendor/github.com/golang-jwt/jwt/v5/none.go new file mode 100644 index 000000000..685c2ea30 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/none.go @@ -0,0 +1,50 @@ +package jwt + +// SigningMethodNone implements the none signing method. This is required by the spec +// but you probably should never use it. +var SigningMethodNone *signingMethodNone + +const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed" + +var NoneSignatureTypeDisallowedError error + +type signingMethodNone struct{} +type unsafeNoneMagicConstant string + +func init() { + SigningMethodNone = &signingMethodNone{} + NoneSignatureTypeDisallowedError = newError("'none' signature type is not allowed", ErrTokenUnverifiable) + + RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod { + return SigningMethodNone + }) +} + +func (m *signingMethodNone) Alg() string { + return "none" +} + +// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Verify(signingString string, sig []byte, key interface{}) (err error) { + // Key must be UnsafeAllowNoneSignatureType to prevent accidentally + // accepting 'none' signing method + if _, ok := key.(unsafeNoneMagicConstant); !ok { + return NoneSignatureTypeDisallowedError + } + // If signing method is none, signature must be an empty string + if len(sig) != 0 { + return newError("'none' signing method with non-empty signature", ErrTokenUnverifiable) + } + + // Accept 'none' signing method. + return nil +} + +// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Sign(signingString string, key interface{}) ([]byte, error) { + if _, ok := key.(unsafeNoneMagicConstant); ok { + return []byte{}, nil + } + + return nil, NoneSignatureTypeDisallowedError +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser.go b/vendor/github.com/golang-jwt/jwt/v5/parser.go new file mode 100644 index 000000000..ecf99af78 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/parser.go @@ -0,0 +1,238 @@ +package jwt + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "strings" +) + +type Parser struct { + // If populated, only these methods will be considered valid. + validMethods []string + + // Use JSON Number format in JSON decoder. + useJSONNumber bool + + // Skip claims validation during token parsing. + skipClaimsValidation bool + + validator *Validator + + decodeStrict bool + + decodePaddingAllowed bool +} + +// NewParser creates a new Parser with the specified options +func NewParser(options ...ParserOption) *Parser { + p := &Parser{ + validator: &Validator{}, + } + + // Loop through our parsing options and apply them + for _, option := range options { + option(p) + } + + return p +} + +// Parse parses, validates, verifies the signature and returns the parsed token. +// keyFunc will receive the parsed token and should return the key for validating. +func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { + return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) +} + +// ParseWithClaims parses, validates, and verifies like Parse, but supplies a default object implementing the Claims +// interface. This provides default values which can be overridden and allows a caller to use their own type, rather +// than the default MapClaims implementation of Claims. +// +// Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims), +// make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the +// proper memory for it before passing in the overall claims, otherwise you might run into a panic. +func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { + token, parts, err := p.ParseUnverified(tokenString, claims) + if err != nil { + return token, err + } + + // Verify signing method is in the required set + if p.validMethods != nil { + var signingMethodValid = false + var alg = token.Method.Alg() + for _, m := range p.validMethods { + if m == alg { + signingMethodValid = true + break + } + } + if !signingMethodValid { + // signing method is not in the listed set + return token, newError(fmt.Sprintf("signing method %v is invalid", alg), ErrTokenSignatureInvalid) + } + } + + // Decode signature + token.Signature, err = p.DecodeSegment(parts[2]) + if err != nil { + return token, newError("could not base64 decode signature", ErrTokenMalformed, err) + } + text := strings.Join(parts[0:2], ".") + + // Lookup key(s) + if keyFunc == nil { + // keyFunc was not provided. short circuiting validation + return token, newError("no keyfunc was provided", ErrTokenUnverifiable) + } + + got, err := keyFunc(token) + if err != nil { + return token, newError("error while executing keyfunc", ErrTokenUnverifiable, err) + } + + switch have := got.(type) { + case VerificationKeySet: + if len(have.Keys) == 0 { + return token, newError("keyfunc returned empty verification key set", ErrTokenUnverifiable) + } + // Iterate through keys and verify signature, skipping the rest when a match is found. + // Return the last error if no match is found. + for _, key := range have.Keys { + if err = token.Method.Verify(text, token.Signature, key); err == nil { + break + } + } + default: + err = token.Method.Verify(text, token.Signature, have) + } + if err != nil { + return token, newError("", ErrTokenSignatureInvalid, err) + } + + // Validate Claims + if !p.skipClaimsValidation { + // Make sure we have at least a default validator + if p.validator == nil { + p.validator = NewValidator() + } + + if err := p.validator.Validate(claims); err != nil { + return token, newError("", ErrTokenInvalidClaims, err) + } + } + + // No errors so far, token is valid. + token.Valid = true + + return token, nil +} + +// ParseUnverified parses the token but doesn't validate the signature. +// +// WARNING: Don't use this method unless you know what you're doing. +// +// It's only ever useful in cases where you know the signature is valid (since it has already +// been or will be checked elsewhere in the stack) and you want to extract values from it. +func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) { + parts = strings.Split(tokenString, ".") + if len(parts) != 3 { + return nil, parts, newError("token contains an invalid number of segments", ErrTokenMalformed) + } + + token = &Token{Raw: tokenString} + + // parse Header + var headerBytes []byte + if headerBytes, err = p.DecodeSegment(parts[0]); err != nil { + return token, parts, newError("could not base64 decode header", ErrTokenMalformed, err) + } + if err = json.Unmarshal(headerBytes, &token.Header); err != nil { + return token, parts, newError("could not JSON decode header", ErrTokenMalformed, err) + } + + // parse Claims + token.Claims = claims + + claimBytes, err := p.DecodeSegment(parts[1]) + if err != nil { + return token, parts, newError("could not base64 decode claim", ErrTokenMalformed, err) + } + + // If `useJSONNumber` is enabled then we must use *json.Decoder to decode + // the claims. However, this comes with a performance penalty so only use + // it if we must and, otherwise, simple use json.Unmarshal. + if !p.useJSONNumber { + // JSON Unmarshal. Special case for map type to avoid weird pointer behavior. + if c, ok := token.Claims.(MapClaims); ok { + err = json.Unmarshal(claimBytes, &c) + } else { + err = json.Unmarshal(claimBytes, &claims) + } + } else { + dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) + dec.UseNumber() + // JSON Decode. Special case for map type to avoid weird pointer behavior. + if c, ok := token.Claims.(MapClaims); ok { + err = dec.Decode(&c) + } else { + err = dec.Decode(&claims) + } + } + if err != nil { + return token, parts, newError("could not JSON decode claim", ErrTokenMalformed, err) + } + + // Lookup signature method + if method, ok := token.Header["alg"].(string); ok { + if token.Method = GetSigningMethod(method); token.Method == nil { + return token, parts, newError("signing method (alg) is unavailable", ErrTokenUnverifiable) + } + } else { + return token, parts, newError("signing method (alg) is unspecified", ErrTokenUnverifiable) + } + + return token, parts, nil +} + +// DecodeSegment decodes a JWT specific base64url encoding. This function will +// take into account whether the [Parser] is configured with additional options, +// such as [WithStrictDecoding] or [WithPaddingAllowed]. +func (p *Parser) DecodeSegment(seg string) ([]byte, error) { + encoding := base64.RawURLEncoding + + if p.decodePaddingAllowed { + if l := len(seg) % 4; l > 0 { + seg += strings.Repeat("=", 4-l) + } + encoding = base64.URLEncoding + } + + if p.decodeStrict { + encoding = encoding.Strict() + } + return encoding.DecodeString(seg) +} + +// Parse parses, validates, verifies the signature and returns the parsed token. +// keyFunc will receive the parsed token and should return the cryptographic key +// for verifying the signature. The caller is strongly encouraged to set the +// WithValidMethods option to validate the 'alg' claim in the token matches the +// expected algorithm. For more details about the importance of validating the +// 'alg' claim, see +// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ +func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { + return NewParser(options...).Parse(tokenString, keyFunc) +} + +// ParseWithClaims is a shortcut for NewParser().ParseWithClaims(). +// +// Note: If you provide a custom claim implementation that embeds one of the +// standard claims (such as RegisteredClaims), make sure that a) you either +// embed a non-pointer version of the claims or b) if you are using a pointer, +// allocate the proper memory for it before passing in the overall claims, +// otherwise you might run into a panic. +func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { + return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser_option.go b/vendor/github.com/golang-jwt/jwt/v5/parser_option.go new file mode 100644 index 000000000..88a780fbd --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/parser_option.go @@ -0,0 +1,128 @@ +package jwt + +import "time" + +// ParserOption is used to implement functional-style options that modify the +// behavior of the parser. To add new options, just create a function (ideally +// beginning with With or Without) that returns an anonymous function that takes +// a *Parser type as input and manipulates its configuration accordingly. +type ParserOption func(*Parser) + +// WithValidMethods is an option to supply algorithm methods that the parser +// will check. Only those methods will be considered valid. It is heavily +// encouraged to use this option in order to prevent attacks such as +// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/. +func WithValidMethods(methods []string) ParserOption { + return func(p *Parser) { + p.validMethods = methods + } +} + +// WithJSONNumber is an option to configure the underlying JSON parser with +// UseNumber. +func WithJSONNumber() ParserOption { + return func(p *Parser) { + p.useJSONNumber = true + } +} + +// WithoutClaimsValidation is an option to disable claims validation. This +// option should only be used if you exactly know what you are doing. +func WithoutClaimsValidation() ParserOption { + return func(p *Parser) { + p.skipClaimsValidation = true + } +} + +// WithLeeway returns the ParserOption for specifying the leeway window. +func WithLeeway(leeway time.Duration) ParserOption { + return func(p *Parser) { + p.validator.leeway = leeway + } +} + +// WithTimeFunc returns the ParserOption for specifying the time func. The +// primary use-case for this is testing. If you are looking for a way to account +// for clock-skew, WithLeeway should be used instead. +func WithTimeFunc(f func() time.Time) ParserOption { + return func(p *Parser) { + p.validator.timeFunc = f + } +} + +// WithIssuedAt returns the ParserOption to enable verification +// of issued-at. +func WithIssuedAt() ParserOption { + return func(p *Parser) { + p.validator.verifyIat = true + } +} + +// WithExpirationRequired returns the ParserOption to make exp claim required. +// By default exp claim is optional. +func WithExpirationRequired() ParserOption { + return func(p *Parser) { + p.validator.requireExp = true + } +} + +// WithAudience configures the validator to require the specified audience in +// the `aud` claim. Validation will fail if the audience is not listed in the +// token or the `aud` claim is missing. +// +// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is +// application-specific. Since this validation API is helping developers in +// writing secure application, we decided to REQUIRE the existence of the claim, +// if an audience is expected. +func WithAudience(aud string) ParserOption { + return func(p *Parser) { + p.validator.expectedAud = aud + } +} + +// WithIssuer configures the validator to require the specified issuer in the +// `iss` claim. Validation will fail if a different issuer is specified in the +// token or the `iss` claim is missing. +// +// NOTE: While the `iss` claim is OPTIONAL in a JWT, the handling of it is +// application-specific. Since this validation API is helping developers in +// writing secure application, we decided to REQUIRE the existence of the claim, +// if an issuer is expected. +func WithIssuer(iss string) ParserOption { + return func(p *Parser) { + p.validator.expectedIss = iss + } +} + +// WithSubject configures the validator to require the specified subject in the +// `sub` claim. Validation will fail if a different subject is specified in the +// token or the `sub` claim is missing. +// +// NOTE: While the `sub` claim is OPTIONAL in a JWT, the handling of it is +// application-specific. Since this validation API is helping developers in +// writing secure application, we decided to REQUIRE the existence of the claim, +// if a subject is expected. +func WithSubject(sub string) ParserOption { + return func(p *Parser) { + p.validator.expectedSub = sub + } +} + +// WithPaddingAllowed will enable the codec used for decoding JWTs to allow +// padding. Note that the JWS RFC7515 states that the tokens will utilize a +// Base64url encoding with no padding. Unfortunately, some implementations of +// JWT are producing non-standard tokens, and thus require support for decoding. +func WithPaddingAllowed() ParserOption { + return func(p *Parser) { + p.decodePaddingAllowed = true + } +} + +// WithStrictDecoding will switch the codec used for decoding JWTs into strict +// mode. In this mode, the decoder requires that trailing padding bits are zero, +// as described in RFC 4648 section 3.5. +func WithStrictDecoding() ParserOption { + return func(p *Parser) { + p.decodeStrict = true + } +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/registered_claims.go b/vendor/github.com/golang-jwt/jwt/v5/registered_claims.go new file mode 100644 index 000000000..77951a531 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/registered_claims.go @@ -0,0 +1,63 @@ +package jwt + +// RegisteredClaims are a structured version of the JWT Claims Set, +// restricted to Registered Claim Names, as referenced at +// https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 +// +// This type can be used on its own, but then additional private and +// public claims embedded in the JWT will not be parsed. The typical use-case +// therefore is to embedded this in a user-defined claim type. +// +// See examples for how to use this with your own claim types. +type RegisteredClaims struct { + // the `iss` (Issuer) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1 + Issuer string `json:"iss,omitempty"` + + // the `sub` (Subject) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2 + Subject string `json:"sub,omitempty"` + + // the `aud` (Audience) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3 + Audience ClaimStrings `json:"aud,omitempty"` + + // the `exp` (Expiration Time) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4 + ExpiresAt *NumericDate `json:"exp,omitempty"` + + // the `nbf` (Not Before) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5 + NotBefore *NumericDate `json:"nbf,omitempty"` + + // the `iat` (Issued At) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6 + IssuedAt *NumericDate `json:"iat,omitempty"` + + // the `jti` (JWT ID) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7 + ID string `json:"jti,omitempty"` +} + +// GetExpirationTime implements the Claims interface. +func (c RegisteredClaims) GetExpirationTime() (*NumericDate, error) { + return c.ExpiresAt, nil +} + +// GetNotBefore implements the Claims interface. +func (c RegisteredClaims) GetNotBefore() (*NumericDate, error) { + return c.NotBefore, nil +} + +// GetIssuedAt implements the Claims interface. +func (c RegisteredClaims) GetIssuedAt() (*NumericDate, error) { + return c.IssuedAt, nil +} + +// GetAudience implements the Claims interface. +func (c RegisteredClaims) GetAudience() (ClaimStrings, error) { + return c.Audience, nil +} + +// GetIssuer implements the Claims interface. +func (c RegisteredClaims) GetIssuer() (string, error) { + return c.Issuer, nil +} + +// GetSubject implements the Claims interface. +func (c RegisteredClaims) GetSubject() (string, error) { + return c.Subject, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa.go b/vendor/github.com/golang-jwt/jwt/v5/rsa.go new file mode 100644 index 000000000..83cbee6ae --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/rsa.go @@ -0,0 +1,93 @@ +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// SigningMethodRSA implements the RSA family of signing methods. +// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation +type SigningMethodRSA struct { + Name string + Hash crypto.Hash +} + +// Specific instances for RS256 and company +var ( + SigningMethodRS256 *SigningMethodRSA + SigningMethodRS384 *SigningMethodRSA + SigningMethodRS512 *SigningMethodRSA +) + +func init() { + // RS256 + SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod { + return SigningMethodRS256 + }) + + // RS384 + SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod { + return SigningMethodRS384 + }) + + // RS512 + SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod { + return SigningMethodRS512 + }) +} + +func (m *SigningMethodRSA) Alg() string { + return m.Name +} + +// Verify implements token verification for the SigningMethod +// For this signing method, must be an *rsa.PublicKey structure. +func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key interface{}) error { + var rsaKey *rsa.PublicKey + var ok bool + + if rsaKey, ok = key.(*rsa.PublicKey); !ok { + return newError("RSA verify expects *rsa.PublicKey", ErrInvalidKeyType) + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig) +} + +// Sign implements token signing for the SigningMethod +// For this signing method, must be an *rsa.PrivateKey structure. +func (m *SigningMethodRSA) Sign(signingString string, key interface{}) ([]byte, error) { + var rsaKey *rsa.PrivateKey + var ok bool + + // Validate type of key + if rsaKey, ok = key.(*rsa.PrivateKey); !ok { + return nil, newError("RSA sign expects *rsa.PrivateKey", ErrInvalidKeyType) + } + + // Create the hasher + if !m.Hash.Available() { + return nil, ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil { + return sigBytes, nil + } else { + return nil, err + } +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go new file mode 100644 index 000000000..28c386ec4 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go @@ -0,0 +1,135 @@ +//go:build go1.4 +// +build go1.4 + +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// SigningMethodRSAPSS implements the RSAPSS family of signing methods signing methods +type SigningMethodRSAPSS struct { + *SigningMethodRSA + Options *rsa.PSSOptions + // VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS. + // Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow + // https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously. + // See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details. + VerifyOptions *rsa.PSSOptions +} + +// Specific instances for RS/PS and company. +var ( + SigningMethodPS256 *SigningMethodRSAPSS + SigningMethodPS384 *SigningMethodRSAPSS + SigningMethodPS512 *SigningMethodRSAPSS +) + +func init() { + // PS256 + SigningMethodPS256 = &SigningMethodRSAPSS{ + SigningMethodRSA: &SigningMethodRSA{ + Name: "PS256", + Hash: crypto.SHA256, + }, + Options: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }, + VerifyOptions: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + }, + } + RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod { + return SigningMethodPS256 + }) + + // PS384 + SigningMethodPS384 = &SigningMethodRSAPSS{ + SigningMethodRSA: &SigningMethodRSA{ + Name: "PS384", + Hash: crypto.SHA384, + }, + Options: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }, + VerifyOptions: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + }, + } + RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod { + return SigningMethodPS384 + }) + + // PS512 + SigningMethodPS512 = &SigningMethodRSAPSS{ + SigningMethodRSA: &SigningMethodRSA{ + Name: "PS512", + Hash: crypto.SHA512, + }, + Options: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }, + VerifyOptions: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + }, + } + RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod { + return SigningMethodPS512 + }) +} + +// Verify implements token verification for the SigningMethod. +// For this verify method, key must be an rsa.PublicKey struct +func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key interface{}) error { + var rsaKey *rsa.PublicKey + switch k := key.(type) { + case *rsa.PublicKey: + rsaKey = k + default: + return newError("RSA-PSS verify expects *rsa.PublicKey", ErrInvalidKeyType) + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + opts := m.Options + if m.VerifyOptions != nil { + opts = m.VerifyOptions + } + + return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts) +} + +// Sign implements token signing for the SigningMethod. +// For this signing method, key must be an rsa.PrivateKey struct +func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) ([]byte, error) { + var rsaKey *rsa.PrivateKey + + switch k := key.(type) { + case *rsa.PrivateKey: + rsaKey = k + default: + return nil, newError("RSA-PSS sign expects *rsa.PrivateKey", ErrInvalidKeyType) + } + + // Create the hasher + if !m.Hash.Available() { + return nil, ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil { + return sigBytes, nil + } else { + return nil, err + } +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go new file mode 100644 index 000000000..b3aeebbe1 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go @@ -0,0 +1,107 @@ +package jwt + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrKeyMustBePEMEncoded = errors.New("invalid key: Key must be a PEM encoded PKCS1 or PKCS8 key") + ErrNotRSAPrivateKey = errors.New("key is not a valid RSA private key") + ErrNotRSAPublicKey = errors.New("key is not a valid RSA public key") +) + +// ParseRSAPrivateKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 private key +func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey interface{} + if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + +// ParseRSAPrivateKeyFromPEMWithPassword parses a PEM encoded PKCS1 or PKCS8 private key protected with password +// +// Deprecated: This function is deprecated and should not be used anymore. It uses the deprecated x509.DecryptPEMBlock +// function, which was deprecated since RFC 1423 is regarded insecure by design. Unfortunately, there is no alternative +// in the Go standard library for now. See https://github.com/golang/go/issues/8860. +func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey interface{} + + var blockDecrypted []byte + if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil { + return nil, err + } + + if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + +// ParseRSAPublicKeyFromPEM parses a certificate or a PEM encoded PKCS1 or PKIX public key +func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + if parsedKey, err = x509.ParsePKCS1PublicKey(block.Bytes); err != nil { + return nil, err + } + } + } + + var pkey *rsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PublicKey); !ok { + return nil, ErrNotRSAPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/signing_method.go b/vendor/github.com/golang-jwt/jwt/v5/signing_method.go new file mode 100644 index 000000000..0d73631c1 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/signing_method.go @@ -0,0 +1,49 @@ +package jwt + +import ( + "sync" +) + +var signingMethods = map[string]func() SigningMethod{} +var signingMethodLock = new(sync.RWMutex) + +// SigningMethod can be used add new methods for signing or verifying tokens. It +// takes a decoded signature as an input in the Verify function and produces a +// signature in Sign. The signature is then usually base64 encoded as part of a +// JWT. +type SigningMethod interface { + Verify(signingString string, sig []byte, key interface{}) error // Returns nil if signature is valid + Sign(signingString string, key interface{}) ([]byte, error) // Returns signature or error + Alg() string // returns the alg identifier for this method (example: 'HS256') +} + +// RegisterSigningMethod registers the "alg" name and a factory function for signing method. +// This is typically done during init() in the method's implementation +func RegisterSigningMethod(alg string, f func() SigningMethod) { + signingMethodLock.Lock() + defer signingMethodLock.Unlock() + + signingMethods[alg] = f +} + +// GetSigningMethod retrieves a signing method from an "alg" string +func GetSigningMethod(alg string) (method SigningMethod) { + signingMethodLock.RLock() + defer signingMethodLock.RUnlock() + + if methodF, ok := signingMethods[alg]; ok { + method = methodF() + } + return +} + +// GetAlgorithms returns a list of registered "alg" names +func GetAlgorithms() (algs []string) { + signingMethodLock.RLock() + defer signingMethodLock.RUnlock() + + for alg := range signingMethods { + algs = append(algs, alg) + } + return +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf b/vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf new file mode 100644 index 000000000..53745d51d --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf @@ -0,0 +1 @@ +checks = ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1023"] diff --git a/vendor/github.com/golang-jwt/jwt/v5/token.go b/vendor/github.com/golang-jwt/jwt/v5/token.go new file mode 100644 index 000000000..352873a2d --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/token.go @@ -0,0 +1,100 @@ +package jwt + +import ( + "crypto" + "encoding/base64" + "encoding/json" +) + +// Keyfunc will be used by the Parse methods as a callback function to supply +// the key for verification. The function receives the parsed, but unverified +// Token. This allows you to use properties in the Header of the token (such as +// `kid`) to identify which key to use. +// +// The returned interface{} may be a single key or a VerificationKeySet containing +// multiple keys. +type Keyfunc func(*Token) (interface{}, error) + +// VerificationKey represents a public or secret key for verifying a token's signature. +type VerificationKey interface { + crypto.PublicKey | []uint8 +} + +// VerificationKeySet is a set of public or secret keys. It is used by the parser to verify a token. +type VerificationKeySet struct { + Keys []VerificationKey +} + +// Token represents a JWT Token. Different fields will be used depending on +// whether you're creating or parsing/verifying a token. +type Token struct { + Raw string // Raw contains the raw token. Populated when you [Parse] a token + Method SigningMethod // Method is the signing method used or to be used + Header map[string]interface{} // Header is the first segment of the token in decoded form + Claims Claims // Claims is the second segment of the token in decoded form + Signature []byte // Signature is the third segment of the token in decoded form. Populated when you Parse a token + Valid bool // Valid specifies if the token is valid. Populated when you Parse/Verify a token +} + +// New creates a new [Token] with the specified signing method and an empty map +// of claims. Additional options can be specified, but are currently unused. +func New(method SigningMethod, opts ...TokenOption) *Token { + return NewWithClaims(method, MapClaims{}, opts...) +} + +// NewWithClaims creates a new [Token] with the specified signing method and +// claims. Additional options can be specified, but are currently unused. +func NewWithClaims(method SigningMethod, claims Claims, opts ...TokenOption) *Token { + return &Token{ + Header: map[string]interface{}{ + "typ": "JWT", + "alg": method.Alg(), + }, + Claims: claims, + Method: method, + } +} + +// SignedString creates and returns a complete, signed JWT. The token is signed +// using the SigningMethod specified in the token. Please refer to +// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types +// for an overview of the different signing methods and their respective key +// types. +func (t *Token) SignedString(key interface{}) (string, error) { + sstr, err := t.SigningString() + if err != nil { + return "", err + } + + sig, err := t.Method.Sign(sstr, key) + if err != nil { + return "", err + } + + return sstr + "." + t.EncodeSegment(sig), nil +} + +// SigningString generates the signing string. This is the most expensive part +// of the whole deal. Unless you need this for something special, just go +// straight for the SignedString. +func (t *Token) SigningString() (string, error) { + h, err := json.Marshal(t.Header) + if err != nil { + return "", err + } + + c, err := json.Marshal(t.Claims) + if err != nil { + return "", err + } + + return t.EncodeSegment(h) + "." + t.EncodeSegment(c), nil +} + +// EncodeSegment encodes a JWT specific base64url encoding with padding +// stripped. In the future, this function might take into account a +// [TokenOption]. Therefore, this function exists as a method of [Token], rather +// than a global function. +func (*Token) EncodeSegment(seg []byte) string { + return base64.RawURLEncoding.EncodeToString(seg) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/token_option.go b/vendor/github.com/golang-jwt/jwt/v5/token_option.go new file mode 100644 index 000000000..b4ae3badf --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/token_option.go @@ -0,0 +1,5 @@ +package jwt + +// TokenOption is a reserved type, which provides some forward compatibility, +// if we ever want to introduce token creation-related options. +type TokenOption func(*Token) diff --git a/vendor/github.com/golang-jwt/jwt/v5/types.go b/vendor/github.com/golang-jwt/jwt/v5/types.go new file mode 100644 index 000000000..b2655a9e6 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/types.go @@ -0,0 +1,149 @@ +package jwt + +import ( + "encoding/json" + "fmt" + "math" + "strconv" + "time" +) + +// TimePrecision sets the precision of times and dates within this library. This +// has an influence on the precision of times when comparing expiry or other +// related time fields. Furthermore, it is also the precision of times when +// serializing. +// +// For backwards compatibility the default precision is set to seconds, so that +// no fractional timestamps are generated. +var TimePrecision = time.Second + +// MarshalSingleStringAsArray modifies the behavior of the ClaimStrings type, +// especially its MarshalJSON function. +// +// If it is set to true (the default), it will always serialize the type as an +// array of strings, even if it just contains one element, defaulting to the +// behavior of the underlying []string. If it is set to false, it will serialize +// to a single string, if it contains one element. Otherwise, it will serialize +// to an array of strings. +var MarshalSingleStringAsArray = true + +// NumericDate represents a JSON numeric date value, as referenced at +// https://datatracker.ietf.org/doc/html/rfc7519#section-2. +type NumericDate struct { + time.Time +} + +// NewNumericDate constructs a new *NumericDate from a standard library time.Time struct. +// It will truncate the timestamp according to the precision specified in TimePrecision. +func NewNumericDate(t time.Time) *NumericDate { + return &NumericDate{t.Truncate(TimePrecision)} +} + +// newNumericDateFromSeconds creates a new *NumericDate out of a float64 representing a +// UNIX epoch with the float fraction representing non-integer seconds. +func newNumericDateFromSeconds(f float64) *NumericDate { + round, frac := math.Modf(f) + return NewNumericDate(time.Unix(int64(round), int64(frac*1e9))) +} + +// MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch +// represented in NumericDate to a byte array, using the precision specified in TimePrecision. +func (date NumericDate) MarshalJSON() (b []byte, err error) { + var prec int + if TimePrecision < time.Second { + prec = int(math.Log10(float64(time.Second) / float64(TimePrecision))) + } + truncatedDate := date.Truncate(TimePrecision) + + // For very large timestamps, UnixNano would overflow an int64, but this + // function requires nanosecond level precision, so we have to use the + // following technique to get round the issue: + // + // 1. Take the normal unix timestamp to form the whole number part of the + // output, + // 2. Take the result of the Nanosecond function, which returns the offset + // within the second of the particular unix time instance, to form the + // decimal part of the output + // 3. Concatenate them to produce the final result + seconds := strconv.FormatInt(truncatedDate.Unix(), 10) + nanosecondsOffset := strconv.FormatFloat(float64(truncatedDate.Nanosecond())/float64(time.Second), 'f', prec, 64) + + output := append([]byte(seconds), []byte(nanosecondsOffset)[1:]...) + + return output, nil +} + +// UnmarshalJSON is an implementation of the json.RawMessage interface and +// deserializes a [NumericDate] from a JSON representation, i.e. a +// [json.Number]. This number represents an UNIX epoch with either integer or +// non-integer seconds. +func (date *NumericDate) UnmarshalJSON(b []byte) (err error) { + var ( + number json.Number + f float64 + ) + + if err = json.Unmarshal(b, &number); err != nil { + return fmt.Errorf("could not parse NumericData: %w", err) + } + + if f, err = number.Float64(); err != nil { + return fmt.Errorf("could not convert json number value to float: %w", err) + } + + n := newNumericDateFromSeconds(f) + *date = *n + + return nil +} + +// ClaimStrings is basically just a slice of strings, but it can be either +// serialized from a string array or just a string. This type is necessary, +// since the "aud" claim can either be a single string or an array. +type ClaimStrings []string + +func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) { + var value interface{} + + if err = json.Unmarshal(data, &value); err != nil { + return err + } + + var aud []string + + switch v := value.(type) { + case string: + aud = append(aud, v) + case []string: + aud = ClaimStrings(v) + case []interface{}: + for _, vv := range v { + vs, ok := vv.(string) + if !ok { + return ErrInvalidType + } + aud = append(aud, vs) + } + case nil: + return nil + default: + return ErrInvalidType + } + + *s = aud + + return +} + +func (s ClaimStrings) MarshalJSON() (b []byte, err error) { + // This handles a special case in the JWT RFC. If the string array, e.g. + // used by the "aud" field, only contains one element, it MAY be serialized + // as a single string. This may or may not be desired based on the ecosystem + // of other JWT library used, so we make it configurable by the variable + // MarshalSingleStringAsArray. + if len(s) == 1 && !MarshalSingleStringAsArray { + return json.Marshal(s[0]) + } + + return json.Marshal([]string(s)) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/validator.go b/vendor/github.com/golang-jwt/jwt/v5/validator.go new file mode 100644 index 000000000..008ecd871 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/validator.go @@ -0,0 +1,316 @@ +package jwt + +import ( + "crypto/subtle" + "fmt" + "time" +) + +// ClaimsValidator is an interface that can be implemented by custom claims who +// wish to execute any additional claims validation based on +// application-specific logic. The Validate function is then executed in +// addition to the regular claims validation and any error returned is appended +// to the final validation result. +// +// type MyCustomClaims struct { +// Foo string `json:"foo"` +// jwt.RegisteredClaims +// } +// +// func (m MyCustomClaims) Validate() error { +// if m.Foo != "bar" { +// return errors.New("must be foobar") +// } +// return nil +// } +type ClaimsValidator interface { + Claims + Validate() error +} + +// Validator is the core of the new Validation API. It is automatically used by +// a [Parser] during parsing and can be modified with various parser options. +// +// The [NewValidator] function should be used to create an instance of this +// struct. +type Validator struct { + // leeway is an optional leeway that can be provided to account for clock skew. + leeway time.Duration + + // timeFunc is used to supply the current time that is needed for + // validation. If unspecified, this defaults to time.Now. + timeFunc func() time.Time + + // requireExp specifies whether the exp claim is required + requireExp bool + + // verifyIat specifies whether the iat (Issued At) claim will be verified. + // According to https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 this + // only specifies the age of the token, but no validation check is + // necessary. However, if wanted, it can be checked if the iat is + // unrealistic, i.e., in the future. + verifyIat bool + + // expectedAud contains the audience this token expects. Supplying an empty + // string will disable aud checking. + expectedAud string + + // expectedIss contains the issuer this token expects. Supplying an empty + // string will disable iss checking. + expectedIss string + + // expectedSub contains the subject this token expects. Supplying an empty + // string will disable sub checking. + expectedSub string +} + +// NewValidator can be used to create a stand-alone validator with the supplied +// options. This validator can then be used to validate already parsed claims. +// +// Note: Under normal circumstances, explicitly creating a validator is not +// needed and can potentially be dangerous; instead functions of the [Parser] +// class should be used. +// +// The [Validator] is only checking the *validity* of the claims, such as its +// expiration time, but it does NOT perform *signature verification* of the +// token. +func NewValidator(opts ...ParserOption) *Validator { + p := NewParser(opts...) + return p.validator +} + +// Validate validates the given claims. It will also perform any custom +// validation if claims implements the [ClaimsValidator] interface. +// +// Note: It will NOT perform any *signature verification* on the token that +// contains the claims and expects that the [Claim] was already successfully +// verified. +func (v *Validator) Validate(claims Claims) error { + var ( + now time.Time + errs []error = make([]error, 0, 6) + err error + ) + + // Check, if we have a time func + if v.timeFunc != nil { + now = v.timeFunc() + } else { + now = time.Now() + } + + // We always need to check the expiration time, but usage of the claim + // itself is OPTIONAL by default. requireExp overrides this behavior + // and makes the exp claim mandatory. + if err = v.verifyExpiresAt(claims, now, v.requireExp); err != nil { + errs = append(errs, err) + } + + // We always need to check not-before, but usage of the claim itself is + // OPTIONAL. + if err = v.verifyNotBefore(claims, now, false); err != nil { + errs = append(errs, err) + } + + // Check issued-at if the option is enabled + if v.verifyIat { + if err = v.verifyIssuedAt(claims, now, false); err != nil { + errs = append(errs, err) + } + } + + // If we have an expected audience, we also require the audience claim + if v.expectedAud != "" { + if err = v.verifyAudience(claims, v.expectedAud, true); err != nil { + errs = append(errs, err) + } + } + + // If we have an expected issuer, we also require the issuer claim + if v.expectedIss != "" { + if err = v.verifyIssuer(claims, v.expectedIss, true); err != nil { + errs = append(errs, err) + } + } + + // If we have an expected subject, we also require the subject claim + if v.expectedSub != "" { + if err = v.verifySubject(claims, v.expectedSub, true); err != nil { + errs = append(errs, err) + } + } + + // Finally, we want to give the claim itself some possibility to do some + // additional custom validation based on a custom Validate function. + cvt, ok := claims.(ClaimsValidator) + if ok { + if err := cvt.Validate(); err != nil { + errs = append(errs, err) + } + } + + if len(errs) == 0 { + return nil + } + + return joinErrors(errs...) +} + +// verifyExpiresAt compares the exp claim in claims against cmp. This function +// will succeed if cmp < exp. Additional leeway is taken into account. +// +// If exp is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// Additionally, if any error occurs while retrieving the claim, e.g., when its +// the wrong type, an ErrTokenUnverifiable error will be returned. +func (v *Validator) verifyExpiresAt(claims Claims, cmp time.Time, required bool) error { + exp, err := claims.GetExpirationTime() + if err != nil { + return err + } + + if exp == nil { + return errorIfRequired(required, "exp") + } + + return errorIfFalse(cmp.Before((exp.Time).Add(+v.leeway)), ErrTokenExpired) +} + +// verifyIssuedAt compares the iat claim in claims against cmp. This function +// will succeed if cmp >= iat. Additional leeway is taken into account. +// +// If iat is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// Additionally, if any error occurs while retrieving the claim, e.g., when its +// the wrong type, an ErrTokenUnverifiable error will be returned. +func (v *Validator) verifyIssuedAt(claims Claims, cmp time.Time, required bool) error { + iat, err := claims.GetIssuedAt() + if err != nil { + return err + } + + if iat == nil { + return errorIfRequired(required, "iat") + } + + return errorIfFalse(!cmp.Before(iat.Add(-v.leeway)), ErrTokenUsedBeforeIssued) +} + +// verifyNotBefore compares the nbf claim in claims against cmp. This function +// will return true if cmp >= nbf. Additional leeway is taken into account. +// +// If nbf is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// Additionally, if any error occurs while retrieving the claim, e.g., when its +// the wrong type, an ErrTokenUnverifiable error will be returned. +func (v *Validator) verifyNotBefore(claims Claims, cmp time.Time, required bool) error { + nbf, err := claims.GetNotBefore() + if err != nil { + return err + } + + if nbf == nil { + return errorIfRequired(required, "nbf") + } + + return errorIfFalse(!cmp.Before(nbf.Add(-v.leeway)), ErrTokenNotValidYet) +} + +// verifyAudience compares the aud claim against cmp. +// +// If aud is not set or an empty list, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// Additionally, if any error occurs while retrieving the claim, e.g., when its +// the wrong type, an ErrTokenUnverifiable error will be returned. +func (v *Validator) verifyAudience(claims Claims, cmp string, required bool) error { + aud, err := claims.GetAudience() + if err != nil { + return err + } + + if len(aud) == 0 { + return errorIfRequired(required, "aud") + } + + // use a var here to keep constant time compare when looping over a number of claims + result := false + + var stringClaims string + for _, a := range aud { + if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 { + result = true + } + stringClaims = stringClaims + a + } + + // case where "" is sent in one or many aud claims + if stringClaims == "" { + return errorIfRequired(required, "aud") + } + + return errorIfFalse(result, ErrTokenInvalidAudience) +} + +// verifyIssuer compares the iss claim in claims against cmp. +// +// If iss is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// Additionally, if any error occurs while retrieving the claim, e.g., when its +// the wrong type, an ErrTokenUnverifiable error will be returned. +func (v *Validator) verifyIssuer(claims Claims, cmp string, required bool) error { + iss, err := claims.GetIssuer() + if err != nil { + return err + } + + if iss == "" { + return errorIfRequired(required, "iss") + } + + return errorIfFalse(iss == cmp, ErrTokenInvalidIssuer) +} + +// verifySubject compares the sub claim against cmp. +// +// If sub is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// Additionally, if any error occurs while retrieving the claim, e.g., when its +// the wrong type, an ErrTokenUnverifiable error will be returned. +func (v *Validator) verifySubject(claims Claims, cmp string, required bool) error { + sub, err := claims.GetSubject() + if err != nil { + return err + } + + if sub == "" { + return errorIfRequired(required, "sub") + } + + return errorIfFalse(sub == cmp, ErrTokenInvalidSubject) +} + +// errorIfFalse returns the error specified in err, if the value is true. +// Otherwise, nil is returned. +func errorIfFalse(value bool, err error) error { + if value { + return nil + } else { + return err + } +} + +// errorIfRequired returns an ErrTokenRequiredClaimMissing error if required is +// true. Otherwise, nil is returned. +func errorIfRequired(required bool, claim string) error { + if required { + return newError(fmt.Sprintf("%s claim is required", claim), ErrTokenRequiredClaimMissing) + } else { + return nil + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index b0a43b471..8bb41745e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -84,7 +84,7 @@ github.com/Masterminds/semver/v3 # github.com/Masterminds/sprig/v3 v3.2.3 ## explicit; go 1.13 github.com/Masterminds/sprig/v3 -# github.com/SherClockHolmes/webpush-go v1.3.0 +# github.com/SherClockHolmes/webpush-go v1.4.0 ## explicit; go 1.13 github.com/SherClockHolmes/webpush-go # github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 @@ -342,6 +342,9 @@ github.com/godbus/dbus/v5 # github.com/golang-jwt/jwt v3.2.2+incompatible ## explicit github.com/golang-jwt/jwt +# github.com/golang-jwt/jwt/v5 v5.2.1 +## explicit; go 1.18 +github.com/golang-jwt/jwt/v5 # github.com/golang/geo v0.0.0-20200319012246-673a6f80352d ## explicit; go 1.12 github.com/golang/geo/r1 From 702d49207fd50f08adfc7411af68ceaa5be82cfb Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Mon, 27 Jan 2025 12:10:18 +0100 Subject: [PATCH 13/16] [bugfix] Fix top-level posts with a mention being counted as replies when doing `exclude_replies` (#3689) * [bugfix] Fix top-level posts with a mention being counted as replies * add index for new reply exclusion query --- internal/db/bundb/account.go | 18 ++-- ...126162825_top_level_mention_replies_fix.go | 89 +++++++++++++++++++ 2 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 internal/db/bundb/migrations/20250126162825_top_level_mention_replies_fix.go diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go index 3d85df381..c5f9148a9 100644 --- a/internal/db/bundb/account.go +++ b/internal/db/bundb/account.go @@ -899,15 +899,19 @@ func (a *accountDB) GetAccountStatuses(ctx context.Context, accountID string, li if excludeReplies { q = q.WhereGroup(" AND ", func(q *bun.SelectQuery) *bun.SelectQuery { + // We're excluding replies so + // only include posts if they: return q. - // Do include self replies (threads), but - // don't include replies to other people. - Where("? = ?", bun.Ident("status.in_reply_to_account_id"), accountID). - WhereOr("? IS NULL", bun.Ident("status.in_reply_to_uri")) + // Don't reply to anything OR + Where("? IS NULL", bun.Ident("status.in_reply_to_uri")). + // reply to self AND don't mention + // anyone (ie., self-reply threads). + WhereGroup(" OR ", func(q *bun.SelectQuery) *bun.SelectQuery { + q = q.Where("? = ?", bun.Ident("status.in_reply_to_account_id"), accountID) + q = whereArrayIsNullOrEmpty(q, bun.Ident("status.mentions")) + return q + }) }) - // Don't include replies that mention other people: - // for example, an account's reply to its own reply to someone else. - q = whereArrayIsNullOrEmpty(q, bun.Ident("status.mentions")) } if excludeReblogs { diff --git a/internal/db/bundb/migrations/20250126162825_top_level_mention_replies_fix.go b/internal/db/bundb/migrations/20250126162825_top_level_mention_replies_fix.go new file mode 100644 index 000000000..0b198f17b --- /dev/null +++ b/internal/db/bundb/migrations/20250126162825_top_level_mention_replies_fix.go @@ -0,0 +1,89 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package migrations + +import ( + "context" + + gtsmodel "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/uptrace/bun" + "github.com/uptrace/bun/dialect" +) + +func init() { + up := func(ctx context.Context, db *bun.DB) error { + var expression string + switch db.Dialect().Name() { + case dialect.PG: + expression = "(mentions IS NULL OR CARDINALITY(mentions) = 0)" + case dialect.SQLite: + expression = "(mentions IS NULL OR json_array_length(mentions) = 0)" + default: + panic("db conn was neither pg not sqlite") + } + + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + log.Info(ctx, + "removing previous statuses_account_view_idx and reindexing statuses; "+ + "this may take a few minutes, please don't interrupt this migration", + ) + + // Remove old index with columns + // in really awkward order. + if _, err := tx. + NewDropIndex(). + Model((*gtsmodel.Status)(nil)). + Index("statuses_account_view_idx"). + IfExists(). + Exec(ctx); err != nil { + return err + } + + // Create new index with + // columns in desired order. + if _, err := tx. + NewCreateIndex(). + Model((*gtsmodel.Status)(nil)). + Index("statuses_account_view_idx"). + Column( + "account_id", + "in_reply_to_uri", + "in_reply_to_account_id", + ). + ColumnExpr(expression). + ColumnExpr("id DESC"). + IfNotExists(). + Exec(ctx); err != nil { + return err + } + + return nil + }) + } + + down := func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + return nil + }) + } + + if err := Migrations.Register(up, down); err != nil { + panic(err) + } +} From 7b7fc528f14588b2a7b9dffd0ef75c1c466accd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vivian=20Lim=20=E2=AD=90?= <1565930+vivlim@users.noreply.github.com> Date: Mon, 27 Jan 2025 05:24:31 -0800 Subject: [PATCH 14/16] [feature/frontend] Add login button to index page which reiterates info about clients (#3377) * Add login button to index page which reiterates info about clients * bit of CSS fiddling, move apps from front page to login info * fix indentation --------- Co-authored-by: tobi --- internal/web/index.go | 9 +- internal/web/login-info.go | 60 +++++++++++++ internal/web/web.go | 18 ++-- web/assets/ellipsis.svg | 5 ++ web/source/css/index.css | 50 ----------- web/source/css/login-info.css | 114 ++++++++++++++++++++++++ web/source/css/page.css | 6 ++ web/template/index.tmpl | 1 - web/template/index_apps.tmpl | 118 ------------------------- web/template/login_button.tmpl | 22 +++++ web/template/login_info.tmpl | 157 +++++++++++++++++++++++++++++++++ web/template/page.tmpl | 5 +- 12 files changed, 386 insertions(+), 179 deletions(-) create mode 100644 internal/web/login-info.go create mode 100644 web/assets/ellipsis.svg create mode 100644 web/source/css/login-info.css delete mode 100644 web/template/index_apps.tmpl create mode 100644 web/template/login_button.tmpl create mode 100644 web/template/login_info.tmpl diff --git a/internal/web/index.go b/internal/web/index.go index 25960cf7f..02ce30138 100644 --- a/internal/web/index.go +++ b/internal/web/index.go @@ -60,7 +60,14 @@ func (m *Module) indexHandler(c *gin.Context) { Instance: instance, OGMeta: apiutil.OGBase(instance), Stylesheets: []string{cssAbout, cssIndex}, - Extra: map[string]any{"showStrap": true}, + Extra: map[string]any{ + // Render "home to x + // users [etc]" strap. + "showStrap": true, + // Show "log in" button + // in top-right corner. + "showLoginButton": true, + }, } apiutil.TemplateWebPage(c, page) diff --git a/internal/web/login-info.go b/internal/web/login-info.go new file mode 100644 index 000000000..bd52f72ef --- /dev/null +++ b/internal/web/login-info.go @@ -0,0 +1,60 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package web + +import ( + "context" + + "github.com/gin-gonic/gin" + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" +) + +const ( + loginPath = "/login" +) + +func (m *Module) loginGETHandler(c *gin.Context) { + instance, errWithCode := m.processor.InstanceGetV1(c.Request.Context()) + if errWithCode != nil { + apiutil.WebErrorHandler(c, errWithCode, m.processor.InstanceGetV1) + return + } + + // Return instance we already got from the db, + // don't try to fetch it again when erroring. + instanceGet := func(ctx context.Context) (*apimodel.InstanceV1, gtserror.WithCode) { + return instance, nil + } + + // We only serve text/html at this endpoint. + if _, err := apiutil.NegotiateAccept(c, apiutil.TextHTML); err != nil { + apiutil.WebErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), instanceGet) + return + } + + page := apiutil.WebPage{ + Template: "login_info.tmpl", + Instance: instance, + OGMeta: apiutil.OGBase(instance), + Stylesheets: []string{cssAbout, cssLoginInfo}, + } + + apiutil.TemplateWebPage(c, page) +} diff --git a/internal/web/web.go b/internal/web/web.go index 35f8f21b0..ddf7d53ea 100644 --- a/internal/web/web.go +++ b/internal/web/web.go @@ -59,14 +59,15 @@ eTagHeader = "ETag" // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag lastModifiedHeader = "Last-Modified" // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified - cssFA = assetsPathPrefix + "/Fork-Awesome/css/fork-awesome.min.css" - cssAbout = distPathPrefix + "/about.css" - cssIndex = distPathPrefix + "/index.css" - cssStatus = distPathPrefix + "/status.css" - cssThread = distPathPrefix + "/thread.css" - cssProfile = distPathPrefix + "/profile.css" - cssSettings = distPathPrefix + "/settings-style.css" - cssTag = distPathPrefix + "/tag.css" + cssFA = assetsPathPrefix + "/Fork-Awesome/css/fork-awesome.min.css" + cssAbout = distPathPrefix + "/about.css" + cssIndex = distPathPrefix + "/index.css" + cssLoginInfo = distPathPrefix + "/login-info.css" + cssStatus = distPathPrefix + "/status.css" + cssThread = distPathPrefix + "/thread.css" + cssProfile = distPathPrefix + "/profile.css" + cssSettings = distPathPrefix + "/settings-style.css" + cssTag = distPathPrefix + "/tag.css" jsFrontend = distPathPrefix + "/frontend.js" // Progressive enhancement frontend JS. jsSettings = distPathPrefix + "/settings.js" // Settings panel React application. @@ -121,6 +122,7 @@ func (m *Module) Route(r *router.Router, mi ...gin.HandlerFunc) { r.AttachHandler(http.MethodPost, confirmEmailPath, m.confirmEmailPOSTHandler) r.AttachHandler(http.MethodGet, robotsPath, m.robotsGETHandler) r.AttachHandler(http.MethodGet, aboutPath, m.aboutGETHandler) + r.AttachHandler(http.MethodGet, loginPath, m.loginGETHandler) r.AttachHandler(http.MethodGet, domainBlockListPath, m.domainBlockListGETHandler) r.AttachHandler(http.MethodGet, tagsPath, m.tagGETHandler) r.AttachHandler(http.MethodGet, signupPath, m.signupGETHandler) diff --git a/web/assets/ellipsis.svg b/web/assets/ellipsis.svg new file mode 100644 index 000000000..e1b114020 --- /dev/null +++ b/web/assets/ellipsis.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/source/css/index.css b/web/source/css/index.css index 382cd68c6..9f8e662d4 100644 --- a/web/source/css/index.css +++ b/web/source/css/index.css @@ -75,53 +75,3 @@ max-width: 100%; } } - -.apps { - align-self: start; - - .applist { - margin: 0; - padding: 0; - - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: 0.5rem; - align-content: start; - - .applist-entry { - display: grid; - grid-template-columns: 25% 1fr; - grid-template-areas: "logo text"; - gap: 1.5rem; - padding: 0.5rem; - - .applist-logo { - grid-area: logo; - align-self: center; - justify-self: center; - width: 100%; - object-fit: contain; - flex: 1 1 auto; - } - - .applist-logo.redraw { - fill: $fg; - stroke: $fg; - } - - .applist-text { - grid-area: text; - - a { - font-weight: bold; - } - } - } - } -} - -@media screen and (max-width: 600px) { - .apps .applist { - grid-template-columns: 1fr; - } -} diff --git a/web/source/css/login-info.css b/web/source/css/login-info.css new file mode 100644 index 000000000..6605b46be --- /dev/null +++ b/web/source/css/login-info.css @@ -0,0 +1,114 @@ +/* + GoToSocial + Copyright (C) GoToSocial Authors admin@gotosocial.org + SPDX-License-Identifier: AGPL-3.0-or-later + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +/* + Reuse about styling, but rework it + to separate sections a bit more. +*/ +.about { + padding: 0; + + background: initial; + box-shadow: initial; + border: initial; + border-radius: initial; + + .about-section { + padding: 2rem; + background: $bg-accent; + box-shadow: $boxshadow; + border: $boxshadow-border; + border-radius: $br; + + h3 { + margin-top: 0px; + } + } + + & > .about-section.settings { + display: flex; + flex-direction: row; + gap: 1rem; + align-items: center; + justify-content: center; + + padding-top: 1rem; + padding-bottom: 1rem; + + p.settings-text { + margin-top: auto; + margin-bottom: auto; + flex: auto; + } + + .settings-button { + flex: auto; + } + } + + & > .about-section.apps { + align-self: start; + + .applist { + margin: 0; + padding: 0; + + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 0.5rem; + align-content: start; + + .applist-entry { + display: grid; + grid-template-columns: 25% 1fr; + grid-template-areas: "logo text"; + gap: 1.5rem; + padding: 0.5rem; + + .applist-logo { + grid-area: logo; + align-self: center; + justify-self: center; + width: 100%; + object-fit: contain; + flex: 1 1 auto; + } + + .applist-logo.redraw { + fill: $fg; + stroke: $fg; + } + + .applist-text { + grid-area: text; + + a { + font-weight: bold; + } + } + } + } + + @media screen and (max-width: 600px) { + .applist { + grid-template-columns: 1fr; + } + } + } +} diff --git a/web/source/css/page.css b/web/source/css/page.css index 752b264ee..822d095c4 100644 --- a/web/source/css/page.css +++ b/web/source/css/page.css @@ -135,3 +135,9 @@ text-align: center; } } + +.login { + position: absolute; + top: 2vh; + right: 2vh; +} diff --git a/web/template/index.tmpl b/web/template/index.tmpl index 358bc081e..0adba1741 100644 --- a/web/template/index.tmpl +++ b/web/template/index.tmpl @@ -36,6 +36,5 @@ {{- include "index_what_is_this.tmpl" . | indent 1 }} {{- include "index_register.tmpl" . | indent 1 }} - {{- include "index_apps.tmpl" . | indent 1 }} {{- end }} \ No newline at end of file diff --git a/web/template/index_apps.tmpl b/web/template/index_apps.tmpl deleted file mode 100644 index 480a12f0b..000000000 --- a/web/template/index_apps.tmpl +++ /dev/null @@ -1,118 +0,0 @@ -{{- /* -// GoToSocial -// Copyright (C) GoToSocial Authors admin@gotosocial.org -// SPDX-License-Identifier: AGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -*/ -}} - -{{- with . }} -
-

Client applications

-
-
-{{- end }} diff --git a/web/template/login_button.tmpl b/web/template/login_button.tmpl new file mode 100644 index 000000000..5c961545b --- /dev/null +++ b/web/template/login_button.tmpl @@ -0,0 +1,22 @@ +{{- /* +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ -}} + +{{- if .showLoginButton }} + +{{- end }} \ No newline at end of file diff --git a/web/template/login_info.tmpl b/web/template/login_info.tmpl new file mode 100644 index 000000000..238e3e9d2 --- /dev/null +++ b/web/template/login_info.tmpl @@ -0,0 +1,157 @@ +{{- /* +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ -}} + +{{- with . }} +
+
+

+ Looking to configure your profile and other settings? +

+ + Settings + +
+
+

Client applications

+
+

+ Want to log in and start posting? + Unlike other ActivityPub softwares, GoToSocial does not provide its own + webclient. Instead it implements the Mastodon client API, so you can use + a variety of third-party clients to log in to your account here: +

+
    +
  • +
    +

    Pinafore is a web client designed for speed and simplicity.

    + + Use Pinafore + +
    + +
  • +
  • +
    +

    Tusky is a lightweight mobile client for Android.

    + + Get Tusky + +
    + +
  • +
  • +
    +

    Feditext (beta) is a beautiful client for iOS, iPadOS and macOS.

    + + Get Feditext + +
    + +
  • +
  • +
    +

    + Masto-FE (🦥 flavour) is an (experimental!) client based on + the Mastodon Glitch web frontend, with some small changes specific to GoToSocial. +

    + + Try Masto-FE (🦥 flavour) + +
    + +
  • +
  • +
    +

    Or try one of the Mastodon clients listed on the official Mastodon page.

    + + Browse Mastodon apps + +
    + +
  • +
+
+
+
+{{- end }} \ No newline at end of file diff --git a/web/template/page.tmpl b/web/template/page.tmpl index d2edc5277..52599a531 100644 --- a/web/template/page.tmpl +++ b/web/template/page.tmpl @@ -71,7 +71,9 @@ image/webp {{- end }} {{- template "instanceTitle" . -}} - + + {{- include "login_button.tmpl" . | indent 3 }} +
@@ -81,5 +83,6 @@ image/webp
{{- include "page_footer.tmpl" . | indent 3 }}
+
\ No newline at end of file From 3617e27afa181392763258240bc276f3da4b44e2 Mon Sep 17 00:00:00 2001 From: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:54:51 +0000 Subject: [PATCH 15/16] bumps uptrace/bun deps to v1.2.8 (#3698) --- go.mod | 16 +- go.sum | 20 +-- .../github.com/puzpuzpuz/xsync/v3/README.md | 43 ++++- vendor/github.com/puzpuzpuz/xsync/v3/map.go | 53 +++++- vendor/github.com/puzpuzpuz/xsync/v3/mapof.go | 53 +++++- .../puzpuzpuz/xsync/v3/mpmcqueue.go | 56 +++--- .../puzpuzpuz/xsync/v3/mpmcqueueof.go | 64 +++---- .../puzpuzpuz/xsync/v3/spscqueue.go | 92 ++++++++++ .../puzpuzpuz/xsync/v3/spscqueueof.go | 96 ++++++++++ vendor/github.com/uptrace/bun/CHANGELOG.md | 23 +++ vendor/github.com/uptrace/bun/db.go | 170 +++++++++++++++++- .../uptrace/bun/dialect/feature/feature.go | 58 +++++- .../uptrace/bun/dialect/pgdialect/dialect.go | 29 ++- .../uptrace/bun/dialect/pgdialect/version.go | 2 +- .../bun/dialect/sqlitedialect/version.go | 2 +- .../uptrace/bun/model_table_has_many.go | 18 +- .../github.com/uptrace/bun/model_table_m2m.go | 2 +- vendor/github.com/uptrace/bun/package.json | 2 +- vendor/github.com/uptrace/bun/query_base.go | 47 +++-- .../uptrace/bun/query_column_add.go | 8 +- .../uptrace/bun/query_column_drop.go | 3 +- vendor/github.com/uptrace/bun/query_delete.go | 15 +- .../uptrace/bun/query_index_create.go | 3 +- .../uptrace/bun/query_index_drop.go | 3 +- vendor/github.com/uptrace/bun/query_insert.go | 7 +- vendor/github.com/uptrace/bun/query_merge.go | 7 +- vendor/github.com/uptrace/bun/query_raw.go | 15 +- vendor/github.com/uptrace/bun/query_select.go | 30 ++-- .../uptrace/bun/query_table_create.go | 3 +- .../uptrace/bun/query_table_drop.go | 3 +- .../uptrace/bun/query_table_truncate.go | 3 +- vendor/github.com/uptrace/bun/query_update.go | 13 +- vendor/github.com/uptrace/bun/query_values.go | 3 +- vendor/github.com/uptrace/bun/version.go | 2 +- vendor/modules.txt | 16 +- 35 files changed, 760 insertions(+), 220 deletions(-) create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/spscqueue.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/spscqueueof.go diff --git a/go.mod b/go.mod index d0b6c8aa3..f7abc31e1 100644 --- a/go.mod +++ b/go.mod @@ -78,20 +78,20 @@ require ( github.com/tetratelabs/wazero v1.8.2 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 github.com/ulule/limiter/v3 v3.11.2 - github.com/uptrace/bun v1.2.8 - github.com/uptrace/bun/dialect/pgdialect v1.2.8 - github.com/uptrace/bun/dialect/sqlitedialect v1.2.8 - github.com/uptrace/bun/extra/bunotel v1.2.8 + github.com/uptrace/bun v1.2.9 + github.com/uptrace/bun/dialect/pgdialect v1.2.9 + github.com/uptrace/bun/dialect/sqlitedialect v1.2.9 + github.com/uptrace/bun/extra/bunotel v1.2.9 github.com/wagslane/go-password-validator v0.3.0 github.com/yuin/goldmark v1.7.8 - go.opentelemetry.io/otel v1.33.0 + go.opentelemetry.io/otel v1.34.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 go.opentelemetry.io/otel/exporters/prometheus v0.51.0 - go.opentelemetry.io/otel/metric v1.33.0 + go.opentelemetry.io/otel/metric v1.34.0 go.opentelemetry.io/otel/sdk v1.32.0 go.opentelemetry.io/otel/sdk/metric v1.32.0 - go.opentelemetry.io/otel/trace v1.33.0 + go.opentelemetry.io/otel/trace v1.34.0 go.uber.org/automaxprocs v1.6.0 golang.org/x/crypto v0.32.0 golang.org/x/image v0.23.0 @@ -202,7 +202,7 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.59.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/puzpuzpuz/xsync/v3 v3.5.0 // indirect github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a // indirect diff --git a/go.sum b/go.sum index 9f976cfe8..1771e1654 100644 --- a/go.sum +++ b/go.sum @@ -471,8 +471,8 @@ github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJ github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= -github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/puzpuzpuz/xsync/v3 v3.5.0 h1:i+cMcpEDY1BkNm7lPDkCtE4oElsYLn+EKF8kAu2vXT4= +github.com/puzpuzpuz/xsync/v3 v3.5.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b h1:aUNXCGgukb4gtY99imuIeoh8Vr0GSwAlYxPAhqZrpFc= github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b/go.mod h1:wTPjTepVu7uJBYgZ0SdWHQlIas582j6cn2jgk4DDdlg= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= @@ -586,14 +586,14 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= -github.com/uptrace/bun v1.2.8 h1:HEiLvy9wc7ehU5S02+O6NdV5BLz48lL4REPhTkMX3Dg= -github.com/uptrace/bun v1.2.8/go.mod h1:JBq0uBKsKqNT0Ccce1IAFZY337Wkf08c6F6qlmfOHE8= -github.com/uptrace/bun/dialect/pgdialect v1.2.8 h1:9n3qVh6yc+u7F3lpXzsWrAFJG1yLHUC2thjCCVEDpM8= -github.com/uptrace/bun/dialect/pgdialect v1.2.8/go.mod h1:plksD43MjAlPGYLD9/SzsLUpGH5poXE9IB1+ka/sEzE= -github.com/uptrace/bun/dialect/sqlitedialect v1.2.8 h1:Huqw7YhLFTbocbSv8NETYYXqKtwLa6XsciCWtjzWSWU= -github.com/uptrace/bun/dialect/sqlitedialect v1.2.8/go.mod h1:ni7h2uwIc5zPhxgmCMTEbefONc4XsVr/ATfz1Q7d3CE= -github.com/uptrace/bun/extra/bunotel v1.2.8 h1:mu98xQ2EcmkeNGT+YjVtMludtZNHfhfHqhrS77mk4YM= -github.com/uptrace/bun/extra/bunotel v1.2.8/go.mod h1:NSjzSfYdDg0WSiY54pFp4ykGoGUmbc/xYQ7AsdyslHQ= +github.com/uptrace/bun v1.2.9 h1:OOt2DlIcRUMSZPr6iXDFg/LaQd59kOxbAjpIVHddKRs= +github.com/uptrace/bun v1.2.9/go.mod h1:r2ZaaGs9Ru5bpGTr8GQfp8jp+TlCav9grYCPOu2CJSg= +github.com/uptrace/bun/dialect/pgdialect v1.2.9 h1:caf5uFbOGiXvadV6pA5gn87k0awFFxL1kuuY3SpxnWk= +github.com/uptrace/bun/dialect/pgdialect v1.2.9/go.mod h1:m7L9JtOp/Lt8HccET70ULxplMweE/u0S9lNUSxz2duo= +github.com/uptrace/bun/dialect/sqlitedialect v1.2.9 h1:HLzGWXBh07sT8zhVPy6veYbbGrAtYq0KzyRHXBj+GjA= +github.com/uptrace/bun/dialect/sqlitedialect v1.2.9/go.mod h1:dUR+ecoCWA0FIa9vhQVRnGtYYPpuCLJoEEtX9E1aiBU= +github.com/uptrace/bun/extra/bunotel v1.2.9 h1:BGGrBga+iVL78SGiMpLt2N9MAKvrG3f8wLk8zCLwFJg= +github.com/uptrace/bun/extra/bunotel v1.2.9/go.mod h1:6dVl5Ko6xOhuoqUPWHpfFrntBDwmOnq0OMiR/SGwAC8= github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2 h1:ZjUj9BLYf9PEqBn8W/OapxhPjVRdC6CsXTdULHsyk5c= github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2/go.mod h1:O8bHQfyinKwTXKkiKNGmLQS7vRsqRxIQTFZpYpHK3IQ= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= diff --git a/vendor/github.com/puzpuzpuz/xsync/v3/README.md b/vendor/github.com/puzpuzpuz/xsync/v3/README.md index 6fe04976f..3971553ae 100644 --- a/vendor/github.com/puzpuzpuz/xsync/v3/README.md +++ b/vendor/github.com/puzpuzpuz/xsync/v3/README.md @@ -80,7 +80,14 @@ m.Store(Point{42, 42}, 42) v, ok := m.Load(point{42, 42}) ``` -Both maps use the built-in Golang's hash function which has DDOS protection. This means that each map instance gets its own seed number and the hash function uses that seed for hash code calculation. However, for smaller keys this hash function has some overhead. So, if you don't need DDOS protection, you may provide a custom hash function when creating a `MapOf`. For instance, Murmur3 finalizer does a decent job when it comes to integers: +Apart from `Range` method available for map iteration, there are also `ToPlainMap`/`ToPlainMapOf` utility functions to convert a `Map`/`MapOf` to a built-in Go's `map`: +```go +m := xsync.NewMapOf[int, int]() +m.Store(42, 42) +pm := xsync.ToPlainMapOf(m) +``` + +Both `Map` and `MapOf` use the built-in Golang's hash function which has DDOS protection. This means that each map instance gets its own seed number and the hash function uses that seed for hash code calculation. However, for smaller keys this hash function has some overhead. So, if you don't need DDOS protection, you may provide a custom hash function when creating a `MapOf`. For instance, Murmur3 finalizer does a decent job when it comes to integers: ```go m := NewMapOfWithHasher[int, int](func(i int, _ uint64) uint64 { @@ -93,28 +100,50 @@ m := NewMapOfWithHasher[int, int](func(i int, _ uint64) uint64 { When benchmarking concurrent maps, make sure to configure all of the competitors with the same hash function or, at least, take hash function performance into the consideration. +### SPSCQueue + +A `SPSCQueue` is a bounded single-producer single-consumer concurrent queue. This means that not more than a single goroutine must be publishing items to the queue while not more than a single goroutine must be consuming those items. + +```go +q := xsync.NewSPSCQueue(1024) +// producer inserts an item into the queue +// optimistic insertion attempt; doesn't block +inserted := q.TryEnqueue("bar") +// consumer obtains an item from the queue +// optimistic obtain attempt; doesn't block +item, ok := q.TryDequeue() // interface{} pointing to a string +``` + +`SPSCQueueOf[I]` is an implementation with parametrized item type. It is available for Go 1.19 or later. + +```go +q := xsync.NewSPSCQueueOf[string](1024) +inserted := q.TryEnqueue("foo") +item, ok := q.TryDequeue() // string +``` + +The queue is based on the data structure from this [article](https://rigtorp.se/ringbuffer). The idea is to reduce the CPU cache coherency traffic by keeping cached copies of read and write indexes used by producer and consumer respectively. + ### MPMCQueue A `MPMCQueue` is a bounded multi-producer multi-consumer concurrent queue. ```go q := xsync.NewMPMCQueue(1024) -// producer inserts an item into the queue -q.Enqueue("foo") +// producer optimistically inserts an item into the queue // optimistic insertion attempt; doesn't block inserted := q.TryEnqueue("bar") // consumer obtains an item from the queue -item := q.Dequeue() // interface{} pointing to a string // optimistic obtain attempt; doesn't block -item, ok := q.TryDequeue() +item, ok := q.TryDequeue() // interface{} pointing to a string ``` `MPMCQueueOf[I]` is an implementation with parametrized item type. It is available for Go 1.19 or later. ```go q := xsync.NewMPMCQueueOf[string](1024) -q.Enqueue("foo") -item := q.Dequeue() // string +inserted := q.TryEnqueue("foo") +item, ok := q.TryDequeue() // string ``` The queue is based on the algorithm from the [MPMCQueue](https://github.com/rigtorp/MPMCQueue) C++ library which in its turn references D.Vyukov's [MPMC queue](https://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue). According to the following [classification](https://www.1024cores.net/home/lock-free-algorithms/queues), the queue is array-based, fails on overflow, provides causal FIFO, has blocking producers and consumers. diff --git a/vendor/github.com/puzpuzpuz/xsync/v3/map.go b/vendor/github.com/puzpuzpuz/xsync/v3/map.go index 6c5b6ebd6..a2730c3f1 100644 --- a/vendor/github.com/puzpuzpuz/xsync/v3/map.go +++ b/vendor/github.com/puzpuzpuz/xsync/v3/map.go @@ -200,6 +200,21 @@ func newMapTable(minTableLen int) *mapTable { return t } +// ToPlainMap returns a native map with a copy of xsync Map's +// contents. The copied xsync Map should not be modified while +// this call is made. If the copied Map is modified, the copying +// behavior is the same as in the Range method. +func ToPlainMap(m *Map) map[string]interface{} { + pm := make(map[string]interface{}) + if m != nil { + m.Range(func(key string, value interface{}) bool { + pm[key] = value + return true + }) + } + return pm +} + // Load returns the value stored in the map for a key, or nil if no // value is present. // The ok result indicates whether value was found in the map. @@ -279,6 +294,34 @@ func(interface{}, bool) (interface{}, bool) { ) } +// LoadOrTryCompute returns the existing value for the key if present. +// Otherwise, it tries to compute the value using the provided function +// and, if success, returns the computed value. The loaded result is true +// if the value was loaded, false if stored. If the compute attempt was +// cancelled, a nil will be returned. +// +// This call locks a hash table bucket while the compute function +// is executed. It means that modifications on other entries in +// the bucket will be blocked until the valueFn executes. Consider +// this when the function includes long-running operations. +func (m *Map) LoadOrTryCompute( + key string, + valueFn func() (newValue interface{}, cancel bool), +) (value interface{}, loaded bool) { + return m.doCompute( + key, + func(interface{}, bool) (interface{}, bool) { + nv, c := valueFn() + if !c { + return nv, false + } + return nil, true + }, + true, + false, + ) +} + // LoadOrCompute returns the existing value for the key if present. // Otherwise, it computes the value using the provided function and // returns the computed value. The loaded result is true if the value @@ -447,11 +490,11 @@ func (m *Map) doCompute( if b.next == nil { if emptyb != nil { // Insertion into an existing bucket. - var zeroedV interface{} - newValue, del := valueFn(zeroedV, false) + var zeroV interface{} + newValue, del := valueFn(zeroV, false) if del { unlockBucket(&rootb.topHashMutex) - return zeroedV, false + return zeroV, false } // First we update the value, then the key. // This is important for atomic snapshot states. @@ -471,8 +514,8 @@ func (m *Map) doCompute( goto compute_attempt } // Insertion into a new bucket. - var zeroedV interface{} - newValue, del := valueFn(zeroedV, false) + var zeroV interface{} + newValue, del := valueFn(zeroV, false) if del { unlockBucket(&rootb.topHashMutex) return newValue, false diff --git a/vendor/github.com/puzpuzpuz/xsync/v3/mapof.go b/vendor/github.com/puzpuzpuz/xsync/v3/mapof.go index 4c4ad0867..cbf9cac91 100644 --- a/vendor/github.com/puzpuzpuz/xsync/v3/mapof.go +++ b/vendor/github.com/puzpuzpuz/xsync/v3/mapof.go @@ -149,6 +149,21 @@ func newMapOfTable[K comparable, V any](minTableLen int) *mapOfTable[K, V] { return t } +// ToPlainMapOf returns a native map with a copy of xsync Map's +// contents. The copied xsync Map should not be modified while +// this call is made. If the copied Map is modified, the copying +// behavior is the same as in the Range method. +func ToPlainMapOf[K comparable, V any](m *MapOf[K, V]) map[K]V { + pm := make(map[K]V) + if m != nil { + m.Range(func(key K, value V) bool { + pm[key] = value + return true + }) + } + return pm +} + // Load returns the value stored in the map for a key, or zero value // of type V if no value is present. // The ok result indicates whether value was found in the map. @@ -243,6 +258,34 @@ func(V, bool) (V, bool) { ) } +// LoadOrTryCompute returns the existing value for the key if present. +// Otherwise, it tries to compute the value using the provided function +// and, if success, returns the computed value. The loaded result is true +// if the value was loaded, false if stored. If the compute attempt was +// cancelled, a zero value of type V will be returned. +// +// This call locks a hash table bucket while the compute function +// is executed. It means that modifications on other entries in +// the bucket will be blocked until the valueFn executes. Consider +// this when the function includes long-running operations. +func (m *MapOf[K, V]) LoadOrTryCompute( + key K, + valueFn func() (newValue V, cancel bool), +) (value V, loaded bool) { + return m.doCompute( + key, + func(V, bool) (V, bool) { + nv, c := valueFn() + if !c { + return nv, false + } + return nv, true // nv is ignored + }, + true, + false, + ) +} + // Compute either sets the computed new value for the key or deletes // the value for the key. When the delete result of the valueFn function // is set to true, the value will be deleted, if it exists. When delete @@ -390,11 +433,11 @@ func (m *MapOf[K, V]) doCompute( if b.next == nil { if emptyb != nil { // Insertion into an existing bucket. - var zeroedV V - newValue, del := valueFn(zeroedV, false) + var zeroV V + newValue, del := valueFn(zeroV, false) if del { rootb.mu.Unlock() - return zeroedV, false + return zeroV, false } newe := new(entryOf[K, V]) newe.key = key @@ -414,8 +457,8 @@ func (m *MapOf[K, V]) doCompute( goto compute_attempt } // Insertion into a new bucket. - var zeroedV V - newValue, del := valueFn(zeroedV, false) + var zeroV V + newValue, del := valueFn(zeroV, false) if del { rootb.mu.Unlock() return newValue, false diff --git a/vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueue.go b/vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueue.go index 96584e698..c5fd26237 100644 --- a/vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueue.go +++ b/vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueue.go @@ -50,6 +50,8 @@ func NewMPMCQueue(capacity int) *MPMCQueue { // Enqueue inserts the given item into the queue. // Blocks, if the queue is full. +// +// Deprecated: use TryEnqueue in combination with runtime.Gosched(). func (q *MPMCQueue) Enqueue(item interface{}) { head := atomic.AddUint64(&q.head, 1) - 1 slot := &q.slots[q.idx(head)] @@ -63,6 +65,8 @@ func (q *MPMCQueue) Enqueue(item interface{}) { // Dequeue retrieves and removes the item from the head of the queue. // Blocks, if the queue is empty. +// +// Deprecated: use TryDequeue in combination with runtime.Gosched(). func (q *MPMCQueue) Dequeue() interface{} { tail := atomic.AddUint64(&q.tail, 1) - 1 slot := &q.slots[q.idx(tail)] @@ -81,24 +85,16 @@ func (q *MPMCQueue) Dequeue() interface{} { // full and the item was inserted. func (q *MPMCQueue) TryEnqueue(item interface{}) bool { head := atomic.LoadUint64(&q.head) - for { - slot := &q.slots[q.idx(head)] - turn := q.turn(head) * 2 - if atomic.LoadUint64(&slot.turn) == turn { - if atomic.CompareAndSwapUint64(&q.head, head, head+1) { - slot.item = item - atomic.StoreUint64(&slot.turn, turn+1) - return true - } - } else { - prevHead := head - head = atomic.LoadUint64(&q.head) - if head == prevHead { - return false - } + slot := &q.slots[q.idx(head)] + turn := q.turn(head) * 2 + if atomic.LoadUint64(&slot.turn) == turn { + if atomic.CompareAndSwapUint64(&q.head, head, head+1) { + slot.item = item + atomic.StoreUint64(&slot.turn, turn+1) + return true } - runtime.Gosched() } + return false } // TryDequeue retrieves and removes the item from the head of the @@ -106,26 +102,18 @@ func (q *MPMCQueue) TryEnqueue(item interface{}) bool { // indicates that the queue isn't empty and an item was retrieved. func (q *MPMCQueue) TryDequeue() (item interface{}, ok bool) { tail := atomic.LoadUint64(&q.tail) - for { - slot := &q.slots[q.idx(tail)] - turn := q.turn(tail)*2 + 1 - if atomic.LoadUint64(&slot.turn) == turn { - if atomic.CompareAndSwapUint64(&q.tail, tail, tail+1) { - item = slot.item - ok = true - slot.item = nil - atomic.StoreUint64(&slot.turn, turn+1) - return - } - } else { - prevTail := tail - tail = atomic.LoadUint64(&q.tail) - if tail == prevTail { - return - } + slot := &q.slots[q.idx(tail)] + turn := q.turn(tail)*2 + 1 + if atomic.LoadUint64(&slot.turn) == turn { + if atomic.CompareAndSwapUint64(&q.tail, tail, tail+1) { + item = slot.item + ok = true + slot.item = nil + atomic.StoreUint64(&slot.turn, turn+1) + return } - runtime.Gosched() } + return } func (q *MPMCQueue) idx(i uint64) uint64 { diff --git a/vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueueof.go b/vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueueof.go index 38a8fa3c6..3f7e4ccc1 100644 --- a/vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueueof.go +++ b/vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueueof.go @@ -12,7 +12,7 @@ // A MPMCQueueOf is a bounded multi-producer multi-consumer concurrent // queue. It's a generic version of MPMCQueue. // -// MPMCQueue instances must be created with NewMPMCQueueOf function. +// MPMCQueueOf instances must be created with NewMPMCQueueOf function. // A MPMCQueueOf must not be copied after first use. // // Based on the data structure from the following C++ library: @@ -61,6 +61,8 @@ func NewMPMCQueueOf[I any](capacity int) *MPMCQueueOf[I] { // Enqueue inserts the given item into the queue. // Blocks, if the queue is full. +// +// Deprecated: use TryEnqueue in combination with runtime.Gosched(). func (q *MPMCQueueOf[I]) Enqueue(item I) { head := atomic.AddUint64(&q.head, 1) - 1 slot := &q.slots[q.idx(head)] @@ -74,8 +76,10 @@ func (q *MPMCQueueOf[I]) Enqueue(item I) { // Dequeue retrieves and removes the item from the head of the queue. // Blocks, if the queue is empty. +// +// Deprecated: use TryDequeue in combination with runtime.Gosched(). func (q *MPMCQueueOf[I]) Dequeue() I { - var zeroedI I + var zeroI I tail := atomic.AddUint64(&q.tail, 1) - 1 slot := &q.slots[q.idx(tail)] turn := q.turn(tail)*2 + 1 @@ -83,7 +87,7 @@ func (q *MPMCQueueOf[I]) Dequeue() I { runtime.Gosched() } item := slot.item - slot.item = zeroedI + slot.item = zeroI slot.turn.Store(turn + 1) return item } @@ -93,24 +97,16 @@ func (q *MPMCQueueOf[I]) Dequeue() I { // full and the item was inserted. func (q *MPMCQueueOf[I]) TryEnqueue(item I) bool { head := atomic.LoadUint64(&q.head) - for { - slot := &q.slots[q.idx(head)] - turn := q.turn(head) * 2 - if slot.turn.Load() == turn { - if atomic.CompareAndSwapUint64(&q.head, head, head+1) { - slot.item = item - slot.turn.Store(turn + 1) - return true - } - } else { - prevHead := head - head = atomic.LoadUint64(&q.head) - if head == prevHead { - return false - } + slot := &q.slots[q.idx(head)] + turn := q.turn(head) * 2 + if slot.turn.Load() == turn { + if atomic.CompareAndSwapUint64(&q.head, head, head+1) { + slot.item = item + slot.turn.Store(turn + 1) + return true } - runtime.Gosched() } + return false } // TryDequeue retrieves and removes the item from the head of the @@ -118,27 +114,19 @@ func (q *MPMCQueueOf[I]) TryEnqueue(item I) bool { // indicates that the queue isn't empty and an item was retrieved. func (q *MPMCQueueOf[I]) TryDequeue() (item I, ok bool) { tail := atomic.LoadUint64(&q.tail) - for { - slot := &q.slots[q.idx(tail)] - turn := q.turn(tail)*2 + 1 - if slot.turn.Load() == turn { - if atomic.CompareAndSwapUint64(&q.tail, tail, tail+1) { - var zeroedI I - item = slot.item - ok = true - slot.item = zeroedI - slot.turn.Store(turn + 1) - return - } - } else { - prevTail := tail - tail = atomic.LoadUint64(&q.tail) - if tail == prevTail { - return - } + slot := &q.slots[q.idx(tail)] + turn := q.turn(tail)*2 + 1 + if slot.turn.Load() == turn { + if atomic.CompareAndSwapUint64(&q.tail, tail, tail+1) { + var zeroI I + item = slot.item + ok = true + slot.item = zeroI + slot.turn.Store(turn + 1) + return } - runtime.Gosched() } + return } func (q *MPMCQueueOf[I]) idx(i uint64) uint64 { diff --git a/vendor/github.com/puzpuzpuz/xsync/v3/spscqueue.go b/vendor/github.com/puzpuzpuz/xsync/v3/spscqueue.go new file mode 100644 index 000000000..6e4f84bc0 --- /dev/null +++ b/vendor/github.com/puzpuzpuz/xsync/v3/spscqueue.go @@ -0,0 +1,92 @@ +package xsync + +import ( + "sync/atomic" +) + +// A SPSCQueue is a bounded single-producer single-consumer concurrent +// queue. This means that not more than a single goroutine must be +// publishing items to the queue while not more than a single goroutine +// must be consuming those items. +// +// SPSCQueue instances must be created with NewSPSCQueue function. +// A SPSCQueue must not be copied after first use. +// +// Based on the data structure from the following article: +// https://rigtorp.se/ringbuffer/ +type SPSCQueue struct { + cap uint64 + pidx uint64 + //lint:ignore U1000 prevents false sharing + pad0 [cacheLineSize - 8]byte + pcachedIdx uint64 + //lint:ignore U1000 prevents false sharing + pad1 [cacheLineSize - 8]byte + cidx uint64 + //lint:ignore U1000 prevents false sharing + pad2 [cacheLineSize - 8]byte + ccachedIdx uint64 + //lint:ignore U1000 prevents false sharing + pad3 [cacheLineSize - 8]byte + items []interface{} +} + +// NewSPSCQueue creates a new SPSCQueue instance with the given +// capacity. +func NewSPSCQueue(capacity int) *SPSCQueue { + if capacity < 1 { + panic("capacity must be positive number") + } + return &SPSCQueue{ + cap: uint64(capacity + 1), + items: make([]interface{}, capacity+1), + } +} + +// TryEnqueue inserts the given item into the queue. Does not block +// and returns immediately. The result indicates that the queue isn't +// full and the item was inserted. +func (q *SPSCQueue) TryEnqueue(item interface{}) bool { + // relaxed memory order would be enough here + idx := atomic.LoadUint64(&q.pidx) + nextIdx := idx + 1 + if nextIdx == q.cap { + nextIdx = 0 + } + cachedIdx := q.ccachedIdx + if nextIdx == cachedIdx { + cachedIdx = atomic.LoadUint64(&q.cidx) + q.ccachedIdx = cachedIdx + if nextIdx == cachedIdx { + return false + } + } + q.items[idx] = item + atomic.StoreUint64(&q.pidx, nextIdx) + return true +} + +// TryDequeue retrieves and removes the item from the head of the +// queue. Does not block and returns immediately. The ok result +// indicates that the queue isn't empty and an item was retrieved. +func (q *SPSCQueue) TryDequeue() (item interface{}, ok bool) { + // relaxed memory order would be enough here + idx := atomic.LoadUint64(&q.cidx) + cachedIdx := q.pcachedIdx + if idx == cachedIdx { + cachedIdx = atomic.LoadUint64(&q.pidx) + q.pcachedIdx = cachedIdx + if idx == cachedIdx { + return + } + } + item = q.items[idx] + q.items[idx] = nil + ok = true + nextIdx := idx + 1 + if nextIdx == q.cap { + nextIdx = 0 + } + atomic.StoreUint64(&q.cidx, nextIdx) + return +} diff --git a/vendor/github.com/puzpuzpuz/xsync/v3/spscqueueof.go b/vendor/github.com/puzpuzpuz/xsync/v3/spscqueueof.go new file mode 100644 index 000000000..3ae132e50 --- /dev/null +++ b/vendor/github.com/puzpuzpuz/xsync/v3/spscqueueof.go @@ -0,0 +1,96 @@ +//go:build go1.19 +// +build go1.19 + +package xsync + +import ( + "sync/atomic" +) + +// A SPSCQueueOf is a bounded single-producer single-consumer concurrent +// queue. This means that not more than a single goroutine must be +// publishing items to the queue while not more than a single goroutine +// must be consuming those items. +// +// SPSCQueueOf instances must be created with NewSPSCQueueOf function. +// A SPSCQueueOf must not be copied after first use. +// +// Based on the data structure from the following article: +// https://rigtorp.se/ringbuffer/ +type SPSCQueueOf[I any] struct { + cap uint64 + pidx uint64 + //lint:ignore U1000 prevents false sharing + pad0 [cacheLineSize - 8]byte + pcachedIdx uint64 + //lint:ignore U1000 prevents false sharing + pad1 [cacheLineSize - 8]byte + cidx uint64 + //lint:ignore U1000 prevents false sharing + pad2 [cacheLineSize - 8]byte + ccachedIdx uint64 + //lint:ignore U1000 prevents false sharing + pad3 [cacheLineSize - 8]byte + items []I +} + +// NewSPSCQueueOf creates a new SPSCQueueOf instance with the given +// capacity. +func NewSPSCQueueOf[I any](capacity int) *SPSCQueueOf[I] { + if capacity < 1 { + panic("capacity must be positive number") + } + return &SPSCQueueOf[I]{ + cap: uint64(capacity + 1), + items: make([]I, capacity+1), + } +} + +// TryEnqueue inserts the given item into the queue. Does not block +// and returns immediately. The result indicates that the queue isn't +// full and the item was inserted. +func (q *SPSCQueueOf[I]) TryEnqueue(item I) bool { + // relaxed memory order would be enough here + idx := atomic.LoadUint64(&q.pidx) + next_idx := idx + 1 + if next_idx == q.cap { + next_idx = 0 + } + cached_idx := q.ccachedIdx + if next_idx == cached_idx { + cached_idx = atomic.LoadUint64(&q.cidx) + q.ccachedIdx = cached_idx + if next_idx == cached_idx { + return false + } + } + q.items[idx] = item + atomic.StoreUint64(&q.pidx, next_idx) + return true +} + +// TryDequeue retrieves and removes the item from the head of the +// queue. Does not block and returns immediately. The ok result +// indicates that the queue isn't empty and an item was retrieved. +func (q *SPSCQueueOf[I]) TryDequeue() (item I, ok bool) { + // relaxed memory order would be enough here + idx := atomic.LoadUint64(&q.cidx) + cached_idx := q.pcachedIdx + if idx == cached_idx { + cached_idx = atomic.LoadUint64(&q.pidx) + q.pcachedIdx = cached_idx + if idx == cached_idx { + return + } + } + var zeroI I + item = q.items[idx] + q.items[idx] = zeroI + ok = true + next_idx := idx + 1 + if next_idx == q.cap { + next_idx = 0 + } + atomic.StoreUint64(&q.cidx, next_idx) + return +} diff --git a/vendor/github.com/uptrace/bun/CHANGELOG.md b/vendor/github.com/uptrace/bun/CHANGELOG.md index e4cdc5ebd..9baa78316 100644 --- a/vendor/github.com/uptrace/bun/CHANGELOG.md +++ b/vendor/github.com/uptrace/bun/CHANGELOG.md @@ -1,3 +1,26 @@ +## [1.2.9](https://github.com/uptrace/bun/compare/v1.2.8...v1.2.9) (2025-01-26) + + +### Bug Fixes + +* apply join condition to select with count ([e77b9e7](https://github.com/uptrace/bun/commit/e77b9e72fa5ae8e173d506a4e154ba64214c4aff)), closes [#597](https://github.com/uptrace/bun/issues/597) +* build ([702e525](https://github.com/uptrace/bun/commit/702e525e30ec93b6d4611359518e1008b67744af)) +* individual replica timeout ([9f5e8b1](https://github.com/uptrace/bun/commit/9f5e8b1c46673bd1779bd4309a28db33dcd695bf)) +* test ([dfc4059](https://github.com/uptrace/bun/commit/dfc405901907419d043bb6ced3ad20c131c1b972)) + + +### Features + +* add feature flag AlterColumnExists ([fc35e12](https://github.com/uptrace/bun/commit/fc35e1222242b3d581f0b7496a9021aadfc50b07)), closes [#704](https://github.com/uptrace/bun/issues/704) +* add Options ([815e11a](https://github.com/uptrace/bun/commit/815e11a023d2babf65d528a20ddffc7628636e7e)) +* allow to specify read-only replica for SELECTs ([cbbe1e9](https://github.com/uptrace/bun/commit/cbbe1e94fd0c72d1870395a663c8053d7e8c6ace)) +* downgrade to use the field in has-many-relation ([91e0d27](https://github.com/uptrace/bun/commit/91e0d2719a5a20b3208cea0232e2dbcb452d6c23)), closes [#1107](https://github.com/uptrace/bun/issues/1107) +* make WithReadOnlyReplica variadic ([4cbb15a](https://github.com/uptrace/bun/commit/4cbb15a53e566e03284253aa46be372338968954)) +* **pgdialect:** allow to convert uint to int ([7d22ddd](https://github.com/uptrace/bun/commit/7d22ddd263b28b9fd6e172e0208c124b7c56f111)) +* **pgdriver:** improve otel instrumentation ([c40e4f3](https://github.com/uptrace/bun/commit/c40e4f3c50c710903236dc89b56a843a0351a21a)) + + + ## [1.2.8](https://github.com/uptrace/bun/compare/v1.2.7...v1.2.8) (2025-01-06) diff --git a/vendor/github.com/uptrace/bun/db.go b/vendor/github.com/uptrace/bun/db.go index c283f56bd..067996d1c 100644 --- a/vendor/github.com/uptrace/bun/db.go +++ b/vendor/github.com/uptrace/bun/db.go @@ -9,6 +9,7 @@ "reflect" "strings" "sync/atomic" + "time" "github.com/uptrace/bun/dialect/feature" "github.com/uptrace/bun/internal" @@ -26,32 +27,56 @@ type DBStats struct { type DBOption func(db *DB) +func WithOptions(opts ...DBOption) DBOption { + return func(db *DB) { + for _, opt := range opts { + opt(db) + } + } +} + func WithDiscardUnknownColumns() DBOption { return func(db *DB) { db.flags = db.flags.Set(discardUnknownColumns) } } -type DB struct { - *sql.DB +func WithConnResolver(resolver ConnResolver) DBOption { + return func(db *DB) { + db.resolver = resolver + } +} - dialect schema.Dialect +type DB struct { + // Must be a pointer so we copy the whole state, not individual fields. + *noCopyState queryHooks []QueryHook fmter schema.Formatter - flags internal.Flag - stats DBStats } +// noCopyState contains DB fields that must not be copied on clone(), +// for example, it is forbidden to copy atomic.Pointer. +type noCopyState struct { + *sql.DB + dialect schema.Dialect + resolver ConnResolver + + flags internal.Flag + closed atomic.Bool +} + func NewDB(sqldb *sql.DB, dialect schema.Dialect, opts ...DBOption) *DB { dialect.Init(sqldb) db := &DB{ - DB: sqldb, - dialect: dialect, - fmter: schema.NewFormatter(dialect), + noCopyState: &noCopyState{ + DB: sqldb, + dialect: dialect, + }, + fmter: schema.NewFormatter(dialect), } for _, opt := range opts { @@ -69,6 +94,22 @@ func (db *DB) String() string { return b.String() } +func (db *DB) Close() error { + if db.closed.Swap(true) { + return nil + } + + firstErr := db.DB.Close() + + if db.resolver != nil { + if err := db.resolver.Close(); err != nil && firstErr == nil { + firstErr = err + } + } + + return firstErr +} + func (db *DB) DBStats() DBStats { return DBStats{ Queries: atomic.LoadUint32(&db.stats.Queries), @@ -703,3 +744,116 @@ func (tx Tx) NewDropColumn() *DropColumnQuery { func (db *DB) makeQueryBytes() []byte { return internal.MakeQueryBytes() } + +//------------------------------------------------------------------------------ + +// ConnResolver enables routing queries to multiple databases. +type ConnResolver interface { + ResolveConn(query Query) IConn + Close() error +} + +// TODO: +// - make monitoring interval configurable +// - make ping timeout configutable +// - allow adding read/write replicas for multi-master replication +type ReadWriteConnResolver struct { + replicas []*sql.DB // read-only replicas + healthyReplicas atomic.Pointer[[]*sql.DB] + nextReplica atomic.Int64 + closed atomic.Bool +} + +func NewReadWriteConnResolver(opts ...ReadWriteConnResolverOption) *ReadWriteConnResolver { + r := new(ReadWriteConnResolver) + + for _, opt := range opts { + opt(r) + } + + if len(r.replicas) > 0 { + r.healthyReplicas.Store(&r.replicas) + go r.monitor() + } + + return r +} + +type ReadWriteConnResolverOption func(r *ReadWriteConnResolver) + +func WithReadOnlyReplica(dbs ...*sql.DB) ReadWriteConnResolverOption { + return func(r *ReadWriteConnResolver) { + r.replicas = append(r.replicas, dbs...) + } +} + +func (r *ReadWriteConnResolver) Close() error { + if r.closed.Swap(true) { + return nil + } + + var firstErr error + for _, db := range r.replicas { + if err := db.Close(); err != nil && firstErr == nil { + firstErr = err + } + } + return firstErr +} + +// healthyReplica returns a random healthy replica. +func (r *ReadWriteConnResolver) ResolveConn(query Query) IConn { + if len(r.replicas) == 0 || !isReadOnlyQuery(query) { + return nil + } + + replicas := r.loadHealthyReplicas() + if len(replicas) == 0 { + return nil + } + if len(replicas) == 1 { + return replicas[0] + } + i := r.nextReplica.Add(1) + return replicas[int(i)%len(replicas)] +} + +func isReadOnlyQuery(query Query) bool { + sel, ok := query.(*SelectQuery) + if !ok { + return false + } + for _, el := range sel.with { + if !isReadOnlyQuery(el.query) { + return false + } + } + return true +} + +func (r *ReadWriteConnResolver) loadHealthyReplicas() []*sql.DB { + if ptr := r.healthyReplicas.Load(); ptr != nil { + return *ptr + } + return nil +} + +func (r *ReadWriteConnResolver) monitor() { + const interval = 5 * time.Second + for !r.closed.Load() { + healthy := make([]*sql.DB, 0, len(r.replicas)) + + for _, replica := range r.replicas { + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + err := replica.PingContext(ctx) + cancel() + + if err == nil { + healthy = append(healthy, replica) + } + } + + r.healthyReplicas.Store(&healthy) + time.Sleep(interval) + } +} diff --git a/vendor/github.com/uptrace/bun/dialect/feature/feature.go b/vendor/github.com/uptrace/bun/dialect/feature/feature.go index 0707c6f88..89693fc21 100644 --- a/vendor/github.com/uptrace/bun/dialect/feature/feature.go +++ b/vendor/github.com/uptrace/bun/dialect/feature/feature.go @@ -1,6 +1,11 @@ package feature -import "github.com/uptrace/bun/internal" +import ( + "fmt" + "strconv" + + "github.com/uptrace/bun/internal" +) type Feature = internal.Flag @@ -35,4 +40,55 @@ UpdateOrderLimit // UPDATE ... ORDER BY ... LIMIT ... DeleteOrderLimit // DELETE ... ORDER BY ... LIMIT ... DeleteReturning + AlterColumnExists // ADD/DROP COLUMN IF NOT EXISTS/IF EXISTS ) + +type NotSupportError struct { + Flag Feature +} + +func (err *NotSupportError) Error() string { + name, ok := flag2str[err.Flag] + if !ok { + name = strconv.FormatInt(int64(err.Flag), 10) + } + return fmt.Sprintf("bun: feature %s is not supported by current dialect", name) +} + +func NewNotSupportError(flag Feature) *NotSupportError { + return &NotSupportError{Flag: flag} +} + +var flag2str = map[Feature]string{ + CTE: "CTE", + WithValues: "WithValues", + Returning: "Returning", + InsertReturning: "InsertReturning", + Output: "Output", + DefaultPlaceholder: "DefaultPlaceholder", + DoubleColonCast: "DoubleColonCast", + ValuesRow: "ValuesRow", + UpdateMultiTable: "UpdateMultiTable", + InsertTableAlias: "InsertTableAlias", + UpdateTableAlias: "UpdateTableAlias", + DeleteTableAlias: "DeleteTableAlias", + AutoIncrement: "AutoIncrement", + Identity: "Identity", + TableCascade: "TableCascade", + TableIdentity: "TableIdentity", + TableTruncate: "TableTruncate", + InsertOnConflict: "InsertOnConflict", + InsertOnDuplicateKey: "InsertOnDuplicateKey", + InsertIgnore: "InsertIgnore", + TableNotExists: "TableNotExists", + OffsetFetch: "OffsetFetch", + SelectExists: "SelectExists", + UpdateFromTable: "UpdateFromTable", + MSSavepoint: "MSSavepoint", + GeneratedIdentity: "GeneratedIdentity", + CompositeIn: "CompositeIn", + UpdateOrderLimit: "UpdateOrderLimit", + DeleteOrderLimit: "DeleteOrderLimit", + DeleteReturning: "DeleteReturning", + AlterColumnExists: "AlterColumnExists", +} diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go index 2180e6ab7..05c4e371f 100644 --- a/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go +++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go @@ -3,6 +3,7 @@ import ( "database/sql" "fmt" + "strconv" "strings" "github.com/uptrace/bun" @@ -25,8 +26,9 @@ func init() { type Dialect struct { schema.BaseDialect - tables *schema.Tables - features feature.Feature + tables *schema.Tables + features feature.Feature + uintAsInt bool } var _ schema.Dialect = (*Dialect)(nil) @@ -53,7 +55,8 @@ func New(opts ...DialectOption) *Dialect { feature.SelectExists | feature.GeneratedIdentity | feature.CompositeIn | - feature.DeleteReturning + feature.DeleteReturning | + feature.AlterColumnExists for _, opt := range opts { opt(d) @@ -70,6 +73,12 @@ func WithoutFeature(other feature.Feature) DialectOption { } } +func WithAppendUintAsInt(on bool) DialectOption { + return func(d *Dialect) { + d.uintAsInt = on + } +} + func (d *Dialect) Init(*sql.DB) {} func (d *Dialect) Name() dialect.Name { @@ -127,6 +136,20 @@ func (d *Dialect) IdentQuote() byte { return '"' } +func (d *Dialect) AppendUint32(b []byte, n uint32) []byte { + if d.uintAsInt { + return strconv.AppendInt(b, int64(int32(n)), 10) + } + return strconv.AppendUint(b, uint64(n), 10) +} + +func (d *Dialect) AppendUint64(b []byte, n uint64) []byte { + if d.uintAsInt { + return strconv.AppendInt(b, int64(n), 10) + } + return strconv.AppendUint(b, n, 10) +} + func (d *Dialect) AppendSequence(b []byte, _ *schema.Table, _ *schema.Field) []byte { return appendGeneratedAsIdentity(b) } diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/version.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/version.go index 161a14b69..4e0c5ef36 100644 --- a/vendor/github.com/uptrace/bun/dialect/pgdialect/version.go +++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/version.go @@ -2,5 +2,5 @@ // Version is the current release version. func Version() string { - return "1.2.8" + return "1.2.9" } diff --git a/vendor/github.com/uptrace/bun/dialect/sqlitedialect/version.go b/vendor/github.com/uptrace/bun/dialect/sqlitedialect/version.go index b80d9ac06..e42267b8a 100644 --- a/vendor/github.com/uptrace/bun/dialect/sqlitedialect/version.go +++ b/vendor/github.com/uptrace/bun/dialect/sqlitedialect/version.go @@ -2,5 +2,5 @@ // Version is the current release version. func Version() string { - return "1.2.8" + return "1.2.9" } diff --git a/vendor/github.com/uptrace/bun/model_table_has_many.go b/vendor/github.com/uptrace/bun/model_table_has_many.go index f7ace5740..c7bdee98a 100644 --- a/vendor/github.com/uptrace/bun/model_table_has_many.go +++ b/vendor/github.com/uptrace/bun/model_table_has_many.go @@ -94,7 +94,7 @@ func (m *hasManyModel) Scan(src interface{}) error { for i, f := range m.rel.JoinPKs { if f.Name == column { - m.structKey[i] = indirectFieldValue(field.Value(m.strct)) + m.structKey[i] = indirectAsKey(field.Value(m.strct)) break } } @@ -144,19 +144,27 @@ func baseValues(model TableModel, fields []*schema.Field) map[internal.MapKey][] func modelKey(key []interface{}, strct reflect.Value, fields []*schema.Field) []interface{} { for _, f := range fields { - key = append(key, indirectFieldValue(f.Value(strct))) + key = append(key, indirectAsKey(f.Value(strct))) } return key } -// indirectFieldValue return the field value dereferencing the pointer if necessary. +// indirectAsKey return the field value dereferencing the pointer if necessary. // The value is then used as a map key. -func indirectFieldValue(field reflect.Value) interface{} { +func indirectAsKey(field reflect.Value) interface{} { if field.Kind() != reflect.Ptr { i := field.Interface() if valuer, ok := i.(driver.Valuer); ok { if v, err := valuer.Value(); err == nil { - return v + switch reflect.TypeOf(v).Kind() { + case reflect.Array, reflect.Chan, reflect.Func, + reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: + // NOTE #1107, these types cannot be used as map key, + // let us use original logic. + return i + default: + return v + } } } return i diff --git a/vendor/github.com/uptrace/bun/model_table_m2m.go b/vendor/github.com/uptrace/bun/model_table_m2m.go index df072fbdf..1a6b1b46a 100644 --- a/vendor/github.com/uptrace/bun/model_table_m2m.go +++ b/vendor/github.com/uptrace/bun/model_table_m2m.go @@ -103,7 +103,7 @@ func (m *m2mModel) scanM2MColumn(column string, src interface{}) error { if err := field.Scan(dest, src); err != nil { return err } - m.structKey = append(m.structKey, indirectFieldValue(dest)) + m.structKey = append(m.structKey, indirectAsKey(dest)) break } } diff --git a/vendor/github.com/uptrace/bun/package.json b/vendor/github.com/uptrace/bun/package.json index 9408f194e..bedb0ba29 100644 --- a/vendor/github.com/uptrace/bun/package.json +++ b/vendor/github.com/uptrace/bun/package.json @@ -1,6 +1,6 @@ { "name": "gobun", - "version": "1.2.8", + "version": "1.2.9", "main": "index.js", "repository": "git@github.com:uptrace/bun.git", "author": "Vladimir Mihailenco ", diff --git a/vendor/github.com/uptrace/bun/query_base.go b/vendor/github.com/uptrace/bun/query_base.go index 08ff8e5d9..b17498742 100644 --- a/vendor/github.com/uptrace/bun/query_base.go +++ b/vendor/github.com/uptrace/bun/query_base.go @@ -24,7 +24,7 @@ type withQuery struct { name string - query schema.QueryAppender + query Query recursive bool } @@ -114,8 +114,16 @@ func (q *baseQuery) DB() *DB { return q.db } -func (q *baseQuery) GetConn() IConn { - return q.conn +func (q *baseQuery) resolveConn(query Query) IConn { + if q.conn != nil { + return q.conn + } + if q.db.resolver != nil { + if conn := q.db.resolver.ResolveConn(query); conn != nil { + return conn + } + } + return q.db.DB } func (q *baseQuery) GetModel() Model { @@ -128,10 +136,8 @@ func (q *baseQuery) GetTableName() string { } for _, wq := range q.with { - if v, ok := wq.query.(Query); ok { - if model := v.GetModel(); model != nil { - return v.GetTableName() - } + if model := wq.query.GetModel(); model != nil { + return wq.query.GetTableName() } } @@ -249,7 +255,7 @@ func (q *baseQuery) isSoftDelete() bool { //------------------------------------------------------------------------------ -func (q *baseQuery) addWith(name string, query schema.QueryAppender, recursive bool) { +func (q *baseQuery) addWith(name string, query Query, recursive bool) { q.with = append(q.with, withQuery{ name: name, query: query, @@ -565,28 +571,33 @@ func (q *baseQuery) scan( hasDest bool, ) (sql.Result, error) { ctx, event := q.db.beforeQuery(ctx, iquery, query, nil, query, q.model) + res, err := q._scan(ctx, iquery, query, model, hasDest) + q.db.afterQuery(ctx, event, res, err) + return res, err +} - rows, err := q.conn.QueryContext(ctx, query) +func (q *baseQuery) _scan( + ctx context.Context, + iquery Query, + query string, + model Model, + hasDest bool, +) (sql.Result, error) { + rows, err := q.resolveConn(iquery).QueryContext(ctx, query) if err != nil { - q.db.afterQuery(ctx, event, nil, err) return nil, err } defer rows.Close() numRow, err := model.ScanRows(ctx, rows) if err != nil { - q.db.afterQuery(ctx, event, nil, err) return nil, err } if numRow == 0 && hasDest && isSingleRowModel(model) { - err = sql.ErrNoRows + return nil, sql.ErrNoRows } - - res := driver.RowsAffected(numRow) - q.db.afterQuery(ctx, event, res, err) - - return res, err + return driver.RowsAffected(numRow), nil } func (q *baseQuery) exec( @@ -595,7 +606,7 @@ func (q *baseQuery) exec( query string, ) (sql.Result, error) { ctx, event := q.db.beforeQuery(ctx, iquery, query, nil, query, q.model) - res, err := q.conn.ExecContext(ctx, query) + res, err := q.resolveConn(iquery).ExecContext(ctx, query) q.db.afterQuery(ctx, event, res, err) return res, err } diff --git a/vendor/github.com/uptrace/bun/query_column_add.go b/vendor/github.com/uptrace/bun/query_column_add.go index 48cb2542a..c3c781a1d 100644 --- a/vendor/github.com/uptrace/bun/query_column_add.go +++ b/vendor/github.com/uptrace/bun/query_column_add.go @@ -5,6 +5,7 @@ "database/sql" "fmt" + "github.com/uptrace/bun/dialect/feature" "github.com/uptrace/bun/internal" "github.com/uptrace/bun/schema" ) @@ -21,8 +22,7 @@ type AddColumnQuery struct { func NewAddColumnQuery(db *DB) *AddColumnQuery { q := &AddColumnQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, } return q @@ -133,6 +133,10 @@ func (q *AddColumnQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte //------------------------------------------------------------------------------ func (q *AddColumnQuery) Exec(ctx context.Context, dest ...interface{}) (sql.Result, error) { + if q.ifNotExists && !q.hasFeature(feature.AlterColumnExists) { + return nil, feature.NewNotSupportError(feature.AlterColumnExists) + } + queryBytes, err := q.AppendQuery(q.db.fmter, q.db.makeQueryBytes()) if err != nil { return nil, err diff --git a/vendor/github.com/uptrace/bun/query_column_drop.go b/vendor/github.com/uptrace/bun/query_column_drop.go index 986bffed3..e66e35b9a 100644 --- a/vendor/github.com/uptrace/bun/query_column_drop.go +++ b/vendor/github.com/uptrace/bun/query_column_drop.go @@ -20,8 +20,7 @@ type DropColumnQuery struct { func NewDropColumnQuery(db *DB) *DropColumnQuery { q := &DropColumnQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, } return q diff --git a/vendor/github.com/uptrace/bun/query_delete.go b/vendor/github.com/uptrace/bun/query_delete.go index d2cf34bd5..99ec37bb7 100644 --- a/vendor/github.com/uptrace/bun/query_delete.go +++ b/vendor/github.com/uptrace/bun/query_delete.go @@ -25,8 +25,7 @@ func NewDeleteQuery(db *DB) *DeleteQuery { q := &DeleteQuery{ whereBaseQuery: whereBaseQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, }, } @@ -58,12 +57,12 @@ func (q *DeleteQuery) Apply(fns ...func(*DeleteQuery) *DeleteQuery) *DeleteQuery return q } -func (q *DeleteQuery) With(name string, query schema.QueryAppender) *DeleteQuery { +func (q *DeleteQuery) With(name string, query Query) *DeleteQuery { q.addWith(name, query, false) return q } -func (q *DeleteQuery) WithRecursive(name string, query schema.QueryAppender) *DeleteQuery { +func (q *DeleteQuery) WithRecursive(name string, query Query) *DeleteQuery { q.addWith(name, query, true) return q } @@ -128,7 +127,7 @@ func (q *DeleteQuery) WhereAllWithDeleted() *DeleteQuery { func (q *DeleteQuery) Order(orders ...string) *DeleteQuery { if !q.hasFeature(feature.DeleteOrderLimit) { - q.err = errors.New("bun: order is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.DeleteOrderLimit) return q } q.addOrder(orders...) @@ -137,7 +136,7 @@ func (q *DeleteQuery) Order(orders ...string) *DeleteQuery { func (q *DeleteQuery) OrderExpr(query string, args ...interface{}) *DeleteQuery { if !q.hasFeature(feature.DeleteOrderLimit) { - q.err = errors.New("bun: order is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.DeleteOrderLimit) return q } q.addOrderExpr(query, args...) @@ -152,7 +151,7 @@ func (q *DeleteQuery) ForceDelete() *DeleteQuery { // ------------------------------------------------------------------------------ func (q *DeleteQuery) Limit(n int) *DeleteQuery { if !q.hasFeature(feature.DeleteOrderLimit) { - q.err = errors.New("bun: limit is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.DeleteOrderLimit) return q } q.setLimit(n) @@ -166,7 +165,7 @@ func (q *DeleteQuery) Limit(n int) *DeleteQuery { // To suppress the auto-generated RETURNING clause, use `Returning("NULL")`. func (q *DeleteQuery) Returning(query string, args ...interface{}) *DeleteQuery { if !q.hasFeature(feature.DeleteReturning) { - q.err = errors.New("bun: returning is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.DeleteOrderLimit) return q } diff --git a/vendor/github.com/uptrace/bun/query_index_create.go b/vendor/github.com/uptrace/bun/query_index_create.go index ad1905cc3..4ac4ffd10 100644 --- a/vendor/github.com/uptrace/bun/query_index_create.go +++ b/vendor/github.com/uptrace/bun/query_index_create.go @@ -29,8 +29,7 @@ func NewCreateIndexQuery(db *DB) *CreateIndexQuery { q := &CreateIndexQuery{ whereBaseQuery: whereBaseQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, }, } diff --git a/vendor/github.com/uptrace/bun/query_index_drop.go b/vendor/github.com/uptrace/bun/query_index_drop.go index a2a23fb8a..27c6e7f67 100644 --- a/vendor/github.com/uptrace/bun/query_index_drop.go +++ b/vendor/github.com/uptrace/bun/query_index_drop.go @@ -24,8 +24,7 @@ type DropIndexQuery struct { func NewDropIndexQuery(db *DB) *DropIndexQuery { q := &DropIndexQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, } return q diff --git a/vendor/github.com/uptrace/bun/query_insert.go b/vendor/github.com/uptrace/bun/query_insert.go index 63e84545a..d2e158d77 100644 --- a/vendor/github.com/uptrace/bun/query_insert.go +++ b/vendor/github.com/uptrace/bun/query_insert.go @@ -31,8 +31,7 @@ func NewInsertQuery(db *DB) *InsertQuery { q := &InsertQuery{ whereBaseQuery: whereBaseQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, }, } @@ -64,12 +63,12 @@ func (q *InsertQuery) Apply(fns ...func(*InsertQuery) *InsertQuery) *InsertQuery return q } -func (q *InsertQuery) With(name string, query schema.QueryAppender) *InsertQuery { +func (q *InsertQuery) With(name string, query Query) *InsertQuery { q.addWith(name, query, false) return q } -func (q *InsertQuery) WithRecursive(name string, query schema.QueryAppender) *InsertQuery { +func (q *InsertQuery) WithRecursive(name string, query Query) *InsertQuery { q.addWith(name, query, true) return q } diff --git a/vendor/github.com/uptrace/bun/query_merge.go b/vendor/github.com/uptrace/bun/query_merge.go index 7dee02002..0c172f180 100644 --- a/vendor/github.com/uptrace/bun/query_merge.go +++ b/vendor/github.com/uptrace/bun/query_merge.go @@ -26,8 +26,7 @@ type MergeQuery struct { func NewMergeQuery(db *DB) *MergeQuery { q := &MergeQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, } if q.db.dialect.Name() != dialect.MSSQL && q.db.dialect.Name() != dialect.PG { @@ -61,12 +60,12 @@ func (q *MergeQuery) Apply(fns ...func(*MergeQuery) *MergeQuery) *MergeQuery { return q } -func (q *MergeQuery) With(name string, query schema.QueryAppender) *MergeQuery { +func (q *MergeQuery) With(name string, query Query) *MergeQuery { q.addWith(name, query, false) return q } -func (q *MergeQuery) WithRecursive(name string, query schema.QueryAppender) *MergeQuery { +func (q *MergeQuery) WithRecursive(name string, query Query) *MergeQuery { q.addWith(name, query, true) return q } diff --git a/vendor/github.com/uptrace/bun/query_raw.go b/vendor/github.com/uptrace/bun/query_raw.go index 8c3a6a7f8..308329567 100644 --- a/vendor/github.com/uptrace/bun/query_raw.go +++ b/vendor/github.com/uptrace/bun/query_raw.go @@ -15,23 +15,10 @@ type RawQuery struct { comment string } -// Deprecated: Use NewRaw instead. When add it to IDB, it conflicts with the sql.Conn#Raw -func (db *DB) Raw(query string, args ...interface{}) *RawQuery { - return &RawQuery{ - baseQuery: baseQuery{ - db: db, - conn: db.DB, - }, - query: query, - args: args, - } -} - func NewRawQuery(db *DB, query string, args ...interface{}) *RawQuery { return &RawQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, query: query, args: args, diff --git a/vendor/github.com/uptrace/bun/query_select.go b/vendor/github.com/uptrace/bun/query_select.go index 11761bb96..1ef7e3bb1 100644 --- a/vendor/github.com/uptrace/bun/query_select.go +++ b/vendor/github.com/uptrace/bun/query_select.go @@ -41,8 +41,7 @@ func NewSelectQuery(db *DB) *SelectQuery { return &SelectQuery{ whereBaseQuery: whereBaseQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, }, } @@ -73,12 +72,12 @@ func (q *SelectQuery) Apply(fns ...func(*SelectQuery) *SelectQuery) *SelectQuery return q } -func (q *SelectQuery) With(name string, query schema.QueryAppender) *SelectQuery { +func (q *SelectQuery) With(name string, query Query) *SelectQuery { q.addWith(name, query, false) return q } -func (q *SelectQuery) WithRecursive(name string, query schema.QueryAppender) *SelectQuery { +func (q *SelectQuery) WithRecursive(name string, query Query) *SelectQuery { q.addWith(name, query, true) return q } @@ -537,6 +536,13 @@ func (q *SelectQuery) appendQuery( return nil, err } + if err := q.forEachInlineRelJoin(func(j *relationJoin) error { + j.applyTo(q) + return nil + }); err != nil { + return nil, err + } + b = append(b, "SELECT "...) if len(q.distinctOn) > 0 { @@ -730,8 +736,6 @@ func (q *SelectQuery) appendColumns(fmter schema.Formatter, b []byte) (_ []byte, func (q *SelectQuery) appendInlineRelColumns( fmter schema.Formatter, b []byte, join *relationJoin, ) (_ []byte, err error) { - join.applyTo(q) - if join.columns != nil { table := join.JoinModel.Table() for i, col := range join.columns { @@ -795,7 +799,7 @@ func (q *SelectQuery) Rows(ctx context.Context) (*sql.Rows, error) { query := internal.String(queryBytes) ctx, event := q.db.beforeQuery(ctx, q, query, nil, query, q.model) - rows, err := q.conn.QueryContext(ctx, query) + rows, err := q.resolveConn(q).QueryContext(ctx, query) q.db.afterQuery(ctx, event, nil, err) return rows, err } @@ -931,7 +935,7 @@ func (q *SelectQuery) Count(ctx context.Context) (int, error) { ctx, event := q.db.beforeQuery(ctx, qq, query, nil, query, q.model) var num int - err = q.conn.QueryRowContext(ctx, query).Scan(&num) + err = q.resolveConn(q).QueryRowContext(ctx, query).Scan(&num) q.db.afterQuery(ctx, event, nil, err) @@ -949,13 +953,15 @@ func (q *SelectQuery) ScanAndCount(ctx context.Context, dest ...interface{}) (in return int(n), nil } } - if _, ok := q.conn.(*DB); ok { - return q.scanAndCountConc(ctx, dest...) + if q.conn == nil { + return q.scanAndCountConcurrently(ctx, dest...) } return q.scanAndCountSeq(ctx, dest...) } -func (q *SelectQuery) scanAndCountConc(ctx context.Context, dest ...interface{}) (int, error) { +func (q *SelectQuery) scanAndCountConcurrently( + ctx context.Context, dest ...interface{}, +) (int, error) { var count int var wg sync.WaitGroup var mu sync.Mutex @@ -1033,7 +1039,7 @@ func (q *SelectQuery) selectExists(ctx context.Context) (bool, error) { ctx, event := q.db.beforeQuery(ctx, qq, query, nil, query, q.model) var exists bool - err = q.conn.QueryRowContext(ctx, query).Scan(&exists) + err = q.resolveConn(q).QueryRowContext(ctx, query).Scan(&exists) q.db.afterQuery(ctx, event, nil, err) diff --git a/vendor/github.com/uptrace/bun/query_table_create.go b/vendor/github.com/uptrace/bun/query_table_create.go index 2c7855e7a..d8c4566cb 100644 --- a/vendor/github.com/uptrace/bun/query_table_create.go +++ b/vendor/github.com/uptrace/bun/query_table_create.go @@ -40,8 +40,7 @@ type CreateTableQuery struct { func NewCreateTableQuery(db *DB) *CreateTableQuery { q := &CreateTableQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, varchar: db.Dialect().DefaultVarcharLen(), } diff --git a/vendor/github.com/uptrace/bun/query_table_drop.go b/vendor/github.com/uptrace/bun/query_table_drop.go index 01f000293..4e7d305a9 100644 --- a/vendor/github.com/uptrace/bun/query_table_drop.go +++ b/vendor/github.com/uptrace/bun/query_table_drop.go @@ -21,8 +21,7 @@ type DropTableQuery struct { func NewDropTableQuery(db *DB) *DropTableQuery { q := &DropTableQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, } return q diff --git a/vendor/github.com/uptrace/bun/query_table_truncate.go b/vendor/github.com/uptrace/bun/query_table_truncate.go index 7ee5d2a8d..0f30a1d04 100644 --- a/vendor/github.com/uptrace/bun/query_table_truncate.go +++ b/vendor/github.com/uptrace/bun/query_table_truncate.go @@ -22,8 +22,7 @@ type TruncateTableQuery struct { func NewTruncateTableQuery(db *DB) *TruncateTableQuery { q := &TruncateTableQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, } return q diff --git a/vendor/github.com/uptrace/bun/query_update.go b/vendor/github.com/uptrace/bun/query_update.go index 24a90d512..b700f2180 100644 --- a/vendor/github.com/uptrace/bun/query_update.go +++ b/vendor/github.com/uptrace/bun/query_update.go @@ -32,8 +32,7 @@ func NewUpdateQuery(db *DB) *UpdateQuery { q := &UpdateQuery{ whereBaseQuery: whereBaseQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, }, } @@ -65,12 +64,12 @@ func (q *UpdateQuery) Apply(fns ...func(*UpdateQuery) *UpdateQuery) *UpdateQuery return q } -func (q *UpdateQuery) With(name string, query schema.QueryAppender) *UpdateQuery { +func (q *UpdateQuery) With(name string, query Query) *UpdateQuery { q.addWith(name, query, false) return q } -func (q *UpdateQuery) WithRecursive(name string, query schema.QueryAppender) *UpdateQuery { +func (q *UpdateQuery) WithRecursive(name string, query Query) *UpdateQuery { q.addWith(name, query, true) return q } @@ -207,7 +206,7 @@ func (q *UpdateQuery) WhereAllWithDeleted() *UpdateQuery { // ------------------------------------------------------------------------------ func (q *UpdateQuery) Order(orders ...string) *UpdateQuery { if !q.hasFeature(feature.UpdateOrderLimit) { - q.err = errors.New("bun: order is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.UpdateOrderLimit) return q } q.addOrder(orders...) @@ -216,7 +215,7 @@ func (q *UpdateQuery) Order(orders ...string) *UpdateQuery { func (q *UpdateQuery) OrderExpr(query string, args ...interface{}) *UpdateQuery { if !q.hasFeature(feature.UpdateOrderLimit) { - q.err = errors.New("bun: order is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.UpdateOrderLimit) return q } q.addOrderExpr(query, args...) @@ -225,7 +224,7 @@ func (q *UpdateQuery) OrderExpr(query string, args ...interface{}) *UpdateQuery func (q *UpdateQuery) Limit(n int) *UpdateQuery { if !q.hasFeature(feature.UpdateOrderLimit) { - q.err = errors.New("bun: limit is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.UpdateOrderLimit) return q } q.setLimit(n) diff --git a/vendor/github.com/uptrace/bun/query_values.go b/vendor/github.com/uptrace/bun/query_values.go index 97fbc65fa..db6c852c3 100644 --- a/vendor/github.com/uptrace/bun/query_values.go +++ b/vendor/github.com/uptrace/bun/query_values.go @@ -25,8 +25,7 @@ type ValuesQuery struct { func NewValuesQuery(db *DB, model interface{}) *ValuesQuery { q := &ValuesQuery{ baseQuery: baseQuery{ - db: db, - conn: db.DB, + db: db, }, } q.setModel(model) diff --git a/vendor/github.com/uptrace/bun/version.go b/vendor/github.com/uptrace/bun/version.go index 0da3dc05d..e74eba8d4 100644 --- a/vendor/github.com/uptrace/bun/version.go +++ b/vendor/github.com/uptrace/bun/version.go @@ -2,5 +2,5 @@ // Version is the current release version. func Version() string { - return "1.2.8" + return "1.2.9" } diff --git a/vendor/modules.txt b/vendor/modules.txt index 8bb41745e..edebc0503 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -589,7 +589,7 @@ github.com/prometheus/common/model github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util -# github.com/puzpuzpuz/xsync/v3 v3.4.0 +# github.com/puzpuzpuz/xsync/v3 v3.5.0 ## explicit; go 1.18 github.com/puzpuzpuz/xsync/v3 # github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b @@ -939,7 +939,7 @@ github.com/ugorji/go/codec github.com/ulule/limiter/v3 github.com/ulule/limiter/v3/drivers/store/common github.com/ulule/limiter/v3/drivers/store/memory -# github.com/uptrace/bun v1.2.8 +# github.com/uptrace/bun v1.2.9 ## explicit; go 1.22.0 github.com/uptrace/bun github.com/uptrace/bun/dialect @@ -953,13 +953,13 @@ github.com/uptrace/bun/internal/tagparser github.com/uptrace/bun/migrate github.com/uptrace/bun/migrate/sqlschema github.com/uptrace/bun/schema -# github.com/uptrace/bun/dialect/pgdialect v1.2.8 +# github.com/uptrace/bun/dialect/pgdialect v1.2.9 ## explicit; go 1.22.0 github.com/uptrace/bun/dialect/pgdialect -# github.com/uptrace/bun/dialect/sqlitedialect v1.2.8 +# github.com/uptrace/bun/dialect/sqlitedialect v1.2.9 ## explicit; go 1.22.0 github.com/uptrace/bun/dialect/sqlitedialect -# github.com/uptrace/bun/extra/bunotel v1.2.8 +# github.com/uptrace/bun/extra/bunotel v1.2.9 ## explicit; go 1.22.0 github.com/uptrace/bun/extra/bunotel # github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2 @@ -997,7 +997,7 @@ go.mongodb.org/mongo-driver/bson/bsonrw go.mongodb.org/mongo-driver/bson/bsontype go.mongodb.org/mongo-driver/bson/primitive go.mongodb.org/mongo-driver/x/bsonx/bsoncore -# go.opentelemetry.io/otel v1.33.0 => go.opentelemetry.io/otel v1.29.0 +# go.opentelemetry.io/otel v1.34.0 => go.opentelemetry.io/otel v1.29.0 ## explicit; go 1.21 go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute @@ -1038,7 +1038,7 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/retry # go.opentelemetry.io/otel/exporters/prometheus v0.51.0 ## explicit; go 1.21 go.opentelemetry.io/otel/exporters/prometheus -# go.opentelemetry.io/otel/metric v1.33.0 => go.opentelemetry.io/otel/metric v1.29.0 +# go.opentelemetry.io/otel/metric v1.34.0 => go.opentelemetry.io/otel/metric v1.29.0 ## explicit; go 1.21 go.opentelemetry.io/otel/metric go.opentelemetry.io/otel/metric/embedded @@ -1059,7 +1059,7 @@ go.opentelemetry.io/otel/sdk/metric/internal/aggregate go.opentelemetry.io/otel/sdk/metric/internal/exemplar go.opentelemetry.io/otel/sdk/metric/internal/x go.opentelemetry.io/otel/sdk/metric/metricdata -# go.opentelemetry.io/otel/trace v1.33.0 => go.opentelemetry.io/otel/trace v1.29.0 +# go.opentelemetry.io/otel/trace v1.34.0 => go.opentelemetry.io/otel/trace v1.29.0 ## explicit; go 1.21 go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded From 726d2ba483b58402fa5e8d5a99d5cbd290bdeb67 Mon Sep 17 00:00:00 2001 From: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:54:59 +0000 Subject: [PATCH 16/16] [chore] some tidy ups (#3677) * small formatting changes (no logic) * improve code comments * fix import cycle * shutup stinky linter --- internal/db/application.go | 26 +++++++++++----------- internal/gtsmodel/token.go | 3 ++- internal/httpclient/client.go | 3 +++ internal/webpush/realsender.go | 24 ++------------------ internal/webpush/realsender_test.go | 8 ++++++- internal/webpush/sender.go | 34 ++++++++++++++++++++--------- 6 files changed, 51 insertions(+), 47 deletions(-) diff --git a/internal/db/application.go b/internal/db/application.go index 5a4068431..1011698bf 100644 --- a/internal/db/application.go +++ b/internal/db/application.go @@ -36,42 +36,42 @@ type Application interface { // DeleteApplicationByClientID deletes the application with corresponding client_id value from the database. DeleteApplicationByClientID(ctx context.Context, clientID string) error - // GetClientByID ... + // GetClientByID fetches the application client from database with ID. GetClientByID(ctx context.Context, id string) (*gtsmodel.Client, error) - // PutClient ... + // PutClient puts the given application client in the database. PutClient(ctx context.Context, client *gtsmodel.Client) error - // DeleteClientByID ... + // DeleteClientByID deletes the application client from database with ID. DeleteClientByID(ctx context.Context, id string) error - // GetAllTokens ... + // GetAllTokens fetches all client oauth tokens from database. GetAllTokens(ctx context.Context) ([]*gtsmodel.Token, error) - // GetTokenByID ... + // GetTokenByID fetches the client oauth token from database with ID. GetTokenByID(ctx context.Context, id string) (*gtsmodel.Token, error) - // GetTokenByCode ... + // GetTokenByCode fetches the client oauth token from database with code. GetTokenByCode(ctx context.Context, code string) (*gtsmodel.Token, error) - // GetTokenByAccess ... + // GetTokenByAccess fetches the client oauth token from database with access code. GetTokenByAccess(ctx context.Context, access string) (*gtsmodel.Token, error) - // GetTokenByRefresh ... + // GetTokenByRefresh fetches the client oauth token from database with refresh code. GetTokenByRefresh(ctx context.Context, refresh string) (*gtsmodel.Token, error) - // PutToken ... + // PutToken puts given client oauth token in the database. PutToken(ctx context.Context, token *gtsmodel.Token) error - // DeleteTokenByID ... + // DeleteTokenByID deletes client oauth token from database with ID. DeleteTokenByID(ctx context.Context, id string) error - // DeleteTokenByCode ... + // DeleteTokenByCode deletes client oauth token from database with code. DeleteTokenByCode(ctx context.Context, code string) error - // DeleteTokenByAccess ... + // DeleteTokenByAccess deletes client oauth token from database with access code. DeleteTokenByAccess(ctx context.Context, access string) error - // DeleteTokenByRefresh ... + // DeleteTokenByRefresh deletes client oauth token from database with refresh code. DeleteTokenByRefresh(ctx context.Context, refresh string) error } diff --git a/internal/gtsmodel/token.go b/internal/gtsmodel/token.go index fd640abde..0586ae68a 100644 --- a/internal/gtsmodel/token.go +++ b/internal/gtsmodel/token.go @@ -19,7 +19,8 @@ import "time" -// Token is a translation of the gotosocial token with the ExpiresIn fields replaced with ExpiresAt. +// Token is a translation of the gotosocial token +// with the ExpiresIn fields replaced with ExpiresAt. type Token struct { ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created diff --git a/internal/httpclient/client.go b/internal/httpclient/client.go index 10fba5d42..445c6a9e5 100644 --- a/internal/httpclient/client.go +++ b/internal/httpclient/client.go @@ -178,6 +178,9 @@ func New(cfg Config) *Client { return &c } +// RoundTrip allows httpclient.Client{} to be used as an http.Transport{}, just calling Client{}.Do(). +func (c *Client) RoundTrip(r *http.Request) (rsp *http.Response, err error) { return c.Do(r) } + // Do will essentially perform http.Client{}.Do() with retry-backoff functionality. func (c *Client) Do(r *http.Request) (rsp *http.Response, err error) { diff --git a/internal/webpush/realsender.go b/internal/webpush/realsender.go index 8b3a1bd66..4c4657957 100644 --- a/internal/webpush/realsender.go +++ b/internal/webpush/realsender.go @@ -33,30 +33,20 @@ "github.com/superseriousbusiness/gotosocial/internal/filter/usermute" "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" - "github.com/superseriousbusiness/gotosocial/internal/httpclient" "github.com/superseriousbusiness/gotosocial/internal/log" "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/superseriousbusiness/gotosocial/internal/text" "github.com/superseriousbusiness/gotosocial/internal/typeutils" ) -// realSender is the production Web Push sender, backed by an HTTP client, DB, and worker pool. +// realSender is the production Web Push sender, +// backed by an HTTP client, DB, and worker pool. type realSender struct { httpClient *http.Client state *state.State converter *typeutils.Converter } -// NewRealSender creates a Sender from an http.Client instead of an httpclient.Client. -// This should only be used by NewSender and in tests. -func NewRealSender(httpClient *http.Client, state *state.State, converter *typeutils.Converter) Sender { - return &realSender{ - httpClient: httpClient, - state: state, - converter: converter, - } -} - func (r *realSender) Send( ctx context.Context, notification *gtsmodel.Notification, @@ -329,13 +319,3 @@ func formatNotificationBody(apiNotification *apimodel.Notification) string { func firstNBytesTrimSpace(s string, n int) string { return strings.TrimSpace(text.FirstNBytesByWords(strings.TrimSpace(s), n)) } - -// gtsHTTPClientRoundTripper helps wrap a GtS HTTP client back into a regular HTTP client, -// so that webpush-go can use our IP filters, bad hosts list, and retries. -type gtsHTTPClientRoundTripper struct { - httpClient *httpclient.Client -} - -func (r *gtsHTTPClientRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) { - return r.httpClient.Do(request) -} diff --git a/internal/webpush/realsender_test.go b/internal/webpush/realsender_test.go index c94bbbb8e..8446fc47d 100644 --- a/internal/webpush/realsender_test.go +++ b/internal/webpush/realsender_test.go @@ -24,6 +24,9 @@ "testing" "time" + // for go:linkname + _ "unsafe" + "github.com/stretchr/testify/suite" "github.com/superseriousbusiness/gotosocial/internal/cleaner" "github.com/superseriousbusiness/gotosocial/internal/db" @@ -120,7 +123,7 @@ func (suite *RealSenderStandardTestSuite) SetupTest() { suite.oauthServer = testrig.NewTestOauthServer(suite.db) suite.emailSender = testrig.NewEmailSender("../../web/template/", nil) - suite.webPushSender = webpush.NewRealSender( + suite.webPushSender = newSenderWith( &http.Client{ Transport: suite, }, @@ -261,3 +264,6 @@ func (suite *RealSenderStandardTestSuite) TestServerError() { func TestRealSenderStandardTestSuite(t *testing.T) { suite.Run(t, &RealSenderStandardTestSuite{}) } + +//go:linkname newSenderWith github.com/superseriousbusiness/gotosocial/internal/webpush.newSenderWith +func newSenderWith(*http.Client, *state.State, *typeutils.Converter) webpush.Sender diff --git a/internal/webpush/sender.go b/internal/webpush/sender.go index 5331f049a..060118019 100644 --- a/internal/webpush/sender.go +++ b/internal/webpush/sender.go @@ -30,7 +30,9 @@ // Sender can send Web Push notifications. type Sender interface { - // Send queues up a notification for delivery to all of an account's Web Push subscriptions. + + // Send queues up a notification for delivery to + // all of an account's Web Push subscriptions. Send( ctx context.Context, notification *gtsmodel.Notification, @@ -41,14 +43,26 @@ type Sender interface { // NewSender creates a new sender from an HTTP client, DB, and worker pool. func NewSender(httpClient *httpclient.Client, state *state.State, converter *typeutils.Converter) Sender { - return NewRealSender( - &http.Client{ - Transport: >sHTTPClientRoundTripper{ - httpClient: httpClient, - }, - // Other fields are already set on the http.Client inside the httpclient.Client. + return &realSender{ + httpClient: &http.Client{ + // Pass in our wrapped httpclient.Client{} + // type as http.Transport{} in order to take + // advantage of retries, SSF protection etc. + Transport: httpClient, + + // Other http.Client{} fields are already + // set in embedded httpclient.Client{}. }, - state, - converter, - ) + state: state, + converter: converter, + } +} + +// an internal function purely existing for the webpush test package to link to and use a custom http.Client{}. +func newSenderWith(client *http.Client, state *state.State, converter *typeutils.Converter) Sender { //nolint:unused + return &realSender{ + httpClient: client, + state: state, + converter: converter, + } }