cjson
fuzzing
inputs
test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9library_config
cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmaketests
inputs
test1 test1.expected test10 test10.expected test11 test11.expected test2 test2.expected test3 test3.expected test4 test4.expected test5 test5.expected test6 test7 test7.expected test8 test8.expected test9 test9.expectedjson-patch-tests
.editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.jsonunity
auto
colour_prompt.rb colour_reporter.rb generate_config.yml generate_module.rb generate_test_runner.rb parse_output.rb stylize_as_junit.rb test_file_filter.rb type_sanitizer.rb unity_test_summary.py unity_test_summary.rb unity_to_junit.pydocs
ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txtexamples
unity_config.hcurl
.github
scripts
cleancmd.pl cmp-config.pl cmp-pkg-config.sh codespell-ignore.words codespell.sh distfiles.sh pyspelling.words pyspelling.yaml randcurl.pl requirements-docs.txt requirements-proselint.txt requirements.txt shellcheck-ci.sh shellcheck.sh spellcheck.curl trimmarkdownheader.pl typos.sh typos.toml verify-examples.pl verify-synopsis.pl yamlcheck.sh yamlcheck.yamlworkflows
appveyor-status.yml checkdocs.yml checksrc.yml checkurls.yml codeql.yml configure-vs-cmake.yml curl-for-win.yml distcheck.yml fuzz.yml http3-linux.yml label.yml linux-old.yml linux.yml macos.yml non-native.yml windows.ymlCMake
CurlSymbolHiding.cmake CurlTests.c FindBrotli.cmake FindCares.cmake FindGSS.cmake FindGnuTLS.cmake FindLDAP.cmake FindLibbacktrace.cmake FindLibgsasl.cmake FindLibidn2.cmake FindLibpsl.cmake FindLibssh.cmake FindLibssh2.cmake FindLibuv.cmake FindMbedTLS.cmake FindNGHTTP2.cmake FindNGHTTP3.cmake FindNGTCP2.cmake FindNettle.cmake FindQuiche.cmake FindRustls.cmake FindWolfSSL.cmake FindZstd.cmake Macros.cmake OtherTests.cmake PickyWarnings.cmake Utilities.cmake cmake_uninstall.in.cmake curl-config.in.cmake unix-cache.cmake win32-cache.cmakedocs
cmdline-opts
.gitignore CMakeLists.txt MANPAGE.md Makefile.am Makefile.inc _AUTHORS.md _BUGS.md _DESCRIPTION.md _ENVIRONMENT.md _EXITCODES.md _FILES.md _GLOBBING.md _NAME.md _OPTIONS.md _OUTPUT.md _PROGRESS.md _PROTOCOLS.md _PROXYPREFIX.md _SEEALSO.md _SYNOPSIS.md _URL.md _VARIABLES.md _VERSION.md _WWW.md abstract-unix-socket.md alt-svc.md anyauth.md append.md aws-sigv4.md basic.md ca-native.md cacert.md capath.md cert-status.md cert-type.md cert.md ciphers.md compressed-ssh.md compressed.md config.md connect-timeout.md connect-to.md continue-at.md cookie-jar.md cookie.md create-dirs.md create-file-mode.md crlf.md crlfile.md curves.md data-ascii.md data-binary.md data-raw.md data-urlencode.md data.md delegation.md digest.md disable-eprt.md disable-epsv.md disable.md disallow-username-in-url.md dns-interface.md dns-ipv4-addr.md dns-ipv6-addr.md dns-servers.md doh-cert-status.md doh-insecure.md doh-url.md dump-ca-embed.md dump-header.md ech.md egd-file.md engine.md etag-compare.md etag-save.md expect100-timeout.md fail-early.md fail-with-body.md fail.md false-start.md follow.md form-escape.md form-string.md form.md ftp-account.md ftp-alternative-to-user.md ftp-create-dirs.md ftp-method.md ftp-pasv.md ftp-port.md ftp-pret.md ftp-skip-pasv-ip.md ftp-ssl-ccc-mode.md ftp-ssl-ccc.md ftp-ssl-control.md get.md globoff.md happy-eyeballs-timeout-ms.md haproxy-clientip.md haproxy-protocol.md head.md header.md help.md hostpubmd5.md hostpubsha256.md hsts.md http0.9.md http1.0.md http1.1.md http2-prior-knowledge.md http2.md http3-only.md http3.md ignore-content-length.md insecure.md interface.md ip-tos.md ipfs-gateway.md ipv4.md ipv6.md json.md junk-session-cookies.md keepalive-cnt.md keepalive-time.md key-type.md key.md knownhosts.md krb.md libcurl.md limit-rate.md list-only.md local-port.md location-trusted.md location.md login-options.md mail-auth.md mail-from.md mail-rcpt-allowfails.md mail-rcpt.md mainpage.idx manual.md max-filesize.md max-redirs.md max-time.md metalink.md mptcp.md negotiate.md netrc-file.md netrc-optional.md netrc.md next.md no-alpn.md no-buffer.md no-clobber.md no-keepalive.md no-npn.md no-progress-meter.md no-sessionid.md noproxy.md ntlm-wb.md ntlm.md oauth2-bearer.md out-null.md output-dir.md output.md parallel-immediate.md parallel-max-host.md parallel-max.md parallel.md pass.md path-as-is.md pinnedpubkey.md post301.md post302.md post303.md preproxy.md progress-bar.md proto-default.md proto-redir.md proto.md proxy-anyauth.md proxy-basic.md proxy-ca-native.md proxy-cacert.md proxy-capath.md proxy-cert-type.md proxy-cert.md proxy-ciphers.md proxy-crlfile.md proxy-digest.md proxy-header.md proxy-http2.md proxy-insecure.md proxy-key-type.md proxy-key.md proxy-negotiate.md proxy-ntlm.md proxy-pass.md proxy-pinnedpubkey.md proxy-service-name.md proxy-ssl-allow-beast.md proxy-ssl-auto-client-cert.md proxy-tls13-ciphers.md proxy-tlsauthtype.md proxy-tlspassword.md proxy-tlsuser.md proxy-tlsv1.md proxy-user.md proxy.md proxy1.0.md proxytunnel.md pubkey.md quote.md random-file.md range.md rate.md raw.md referer.md remote-header-name.md remote-name-all.md remote-name.md remote-time.md remove-on-error.md request-target.md request.md resolve.md retry-all-errors.md retry-connrefused.md retry-delay.md retry-max-time.md retry.md sasl-authzid.md sasl-ir.md service-name.md show-error.md show-headers.md sigalgs.md silent.md skip-existing.md socks4.md socks4a.md socks5-basic.md socks5-gssapi-nec.md socks5-gssapi-service.md socks5-gssapi.md socks5-hostname.md socks5.md speed-limit.md speed-time.md ssl-allow-beast.md ssl-auto-client-cert.md ssl-no-revoke.md ssl-reqd.md ssl-revoke-best-effort.md ssl-sessions.md ssl.md sslv2.md sslv3.md stderr.md styled-output.md suppress-connect-headers.md tcp-fastopen.md tcp-nodelay.md telnet-option.md tftp-blksize.md tftp-no-options.md time-cond.md tls-earlydata.md tls-max.md tls13-ciphers.md tlsauthtype.md tlspassword.md tlsuser.md tlsv1.0.md tlsv1.1.md tlsv1.2.md tlsv1.3.md tlsv1.md tr-encoding.md trace-ascii.md trace-config.md trace-ids.md trace-time.md trace.md unix-socket.md upload-file.md upload-flags.md url-query.md url.md use-ascii.md user-agent.md user.md variable.md verbose.md version.md vlan-priority.md write-out.md xattr.mdexamples
.checksrc .gitignore 10-at-a-time.c CMakeLists.txt Makefile.am Makefile.example Makefile.inc README.md adddocsref.pl address-scope.c altsvc.c anyauthput.c block_ip.c cacertinmem.c certinfo.c chkspeed.c connect-to.c cookie_interface.c crawler.c debug.c default-scheme.c ephiperfifo.c evhiperfifo.c externalsocket.c fileupload.c ftp-delete.c ftp-wildcard.c ftpget.c ftpgetinfo.c ftpgetresp.c ftpsget.c ftpupload.c ftpuploadfrommem.c ftpuploadresume.c getinfo.c getinmemory.c getredirect.c getreferrer.c ghiper.c headerapi.c hiperfifo.c hsts-preload.c htmltidy.c htmltitle.cpp http-options.c http-post.c http2-download.c http2-pushinmemory.c http2-serverpush.c http2-upload.c http3-present.c http3.c httpcustomheader.c httpput-postfields.c httpput.c https.c imap-append.c imap-authzid.c imap-copy.c imap-create.c imap-delete.c imap-examine.c imap-fetch.c imap-list.c imap-lsub.c imap-multi.c imap-noop.c imap-search.c imap-ssl.c imap-store.c imap-tls.c interface.c ipv6.c keepalive.c localport.c log_failed_transfers.c maxconnects.c multi-app.c multi-debugcallback.c multi-double.c multi-event.c multi-formadd.c multi-legacy.c multi-post.c multi-single.c multi-uv.c netrc.c parseurl.c persistent.c pop3-authzid.c pop3-dele.c pop3-list.c pop3-multi.c pop3-noop.c pop3-retr.c pop3-ssl.c pop3-stat.c pop3-tls.c pop3-top.c pop3-uidl.c post-callback.c postinmemory.c postit2-formadd.c postit2.c progressfunc.c protofeats.c range.c resolve.c rtsp-options.c sendrecv.c sepheaders.c sessioninfo.c sftpget.c sftpuploadresume.c shared-connection-cache.c simple.c simplepost.c simplessl.c smooth-gtk-thread.c smtp-authzid.c smtp-expn.c smtp-mail.c smtp-mime.c smtp-multi.c smtp-ssl.c smtp-tls.c smtp-vrfy.c sslbackend.c synctime.c threaded.c unixsocket.c url2file.c urlapi.c usercertinmem.c version-check.pl websocket-cb.c websocket-updown.c websocket.c xmlstream.cinternals
BUFQ.md BUFREF.md CHECKSRC.md CLIENT-READERS.md CLIENT-WRITERS.md CODE_STYLE.md CONNECTION-FILTERS.md CREDENTIALS.md CURLX.md DYNBUF.md HASH.md LLIST.md MID.md MQTT.md MULTI-EV.md NEW-PROTOCOL.md PEERS.md PORTING.md RATELIMITS.md README.md SCORECARD.md SPLAY.md STRPARSE.md THRDPOOL-AND-QUEUE.md TIME-KEEPING.md TLS-SESSIONS.md UINT_SETS.md WEBSOCKET.mdlibcurl
opts
CMakeLists.txt CURLINFO_ACTIVESOCKET.md CURLINFO_APPCONNECT_TIME.md CURLINFO_APPCONNECT_TIME_T.md CURLINFO_CAINFO.md CURLINFO_CAPATH.md CURLINFO_CERTINFO.md CURLINFO_CONDITION_UNMET.md CURLINFO_CONNECT_TIME.md CURLINFO_CONNECT_TIME_T.md CURLINFO_CONN_ID.md CURLINFO_CONTENT_LENGTH_DOWNLOAD.md CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md CURLINFO_CONTENT_LENGTH_UPLOAD.md CURLINFO_CONTENT_LENGTH_UPLOAD_T.md CURLINFO_CONTENT_TYPE.md CURLINFO_COOKIELIST.md CURLINFO_EARLYDATA_SENT_T.md CURLINFO_EFFECTIVE_METHOD.md CURLINFO_EFFECTIVE_URL.md CURLINFO_FILETIME.md CURLINFO_FILETIME_T.md CURLINFO_FTP_ENTRY_PATH.md CURLINFO_HEADER_SIZE.md CURLINFO_HTTPAUTH_AVAIL.md CURLINFO_HTTPAUTH_USED.md CURLINFO_HTTP_CONNECTCODE.md CURLINFO_HTTP_VERSION.md CURLINFO_LASTSOCKET.md CURLINFO_LOCAL_IP.md CURLINFO_LOCAL_PORT.md CURLINFO_NAMELOOKUP_TIME.md CURLINFO_NAMELOOKUP_TIME_T.md CURLINFO_NUM_CONNECTS.md CURLINFO_OS_ERRNO.md CURLINFO_POSTTRANSFER_TIME_T.md CURLINFO_PRETRANSFER_TIME.md CURLINFO_PRETRANSFER_TIME_T.md CURLINFO_PRIMARY_IP.md CURLINFO_PRIMARY_PORT.md CURLINFO_PRIVATE.md CURLINFO_PROTOCOL.md CURLINFO_PROXYAUTH_AVAIL.md CURLINFO_PROXYAUTH_USED.md CURLINFO_PROXY_ERROR.md CURLINFO_PROXY_SSL_VERIFYRESULT.md CURLINFO_QUEUE_TIME_T.md CURLINFO_REDIRECT_COUNT.md CURLINFO_REDIRECT_TIME.md CURLINFO_REDIRECT_TIME_T.md CURLINFO_REDIRECT_URL.md CURLINFO_REFERER.md CURLINFO_REQUEST_SIZE.md CURLINFO_RESPONSE_CODE.md CURLINFO_RETRY_AFTER.md CURLINFO_RTSP_CLIENT_CSEQ.md CURLINFO_RTSP_CSEQ_RECV.md CURLINFO_RTSP_SERVER_CSEQ.md CURLINFO_RTSP_SESSION_ID.md CURLINFO_SCHEME.md CURLINFO_SIZE_DELIVERED.md CURLINFO_SIZE_DOWNLOAD.md CURLINFO_SIZE_DOWNLOAD_T.md CURLINFO_SIZE_UPLOAD.md CURLINFO_SIZE_UPLOAD_T.md CURLINFO_SPEED_DOWNLOAD.md CURLINFO_SPEED_DOWNLOAD_T.md CURLINFO_SPEED_UPLOAD.md CURLINFO_SPEED_UPLOAD_T.md CURLINFO_SSL_ENGINES.md CURLINFO_SSL_VERIFYRESULT.md CURLINFO_STARTTRANSFER_TIME.md CURLINFO_STARTTRANSFER_TIME_T.md CURLINFO_TLS_SESSION.md CURLINFO_TLS_SSL_PTR.md CURLINFO_TOTAL_TIME.md CURLINFO_TOTAL_TIME_T.md CURLINFO_USED_PROXY.md CURLINFO_XFER_ID.md CURLMINFO_XFERS_ADDED.md CURLMINFO_XFERS_CURRENT.md CURLMINFO_XFERS_DONE.md CURLMINFO_XFERS_PENDING.md CURLMINFO_XFERS_RUNNING.md CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.md CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.md CURLMOPT_MAXCONNECTS.md CURLMOPT_MAX_CONCURRENT_STREAMS.md CURLMOPT_MAX_HOST_CONNECTIONS.md CURLMOPT_MAX_PIPELINE_LENGTH.md CURLMOPT_MAX_TOTAL_CONNECTIONS.md CURLMOPT_NETWORK_CHANGED.md CURLMOPT_NOTIFYDATA.md CURLMOPT_NOTIFYFUNCTION.md CURLMOPT_PIPELINING.md CURLMOPT_PIPELINING_SERVER_BL.md CURLMOPT_PIPELINING_SITE_BL.md CURLMOPT_PUSHDATA.md CURLMOPT_PUSHFUNCTION.md CURLMOPT_QUICK_EXIT.md CURLMOPT_RESOLVE_THREADS_MAX.md CURLMOPT_SOCKETDATA.md CURLMOPT_SOCKETFUNCTION.md CURLMOPT_TIMERDATA.md CURLMOPT_TIMERFUNCTION.md CURLOPT_ABSTRACT_UNIX_SOCKET.md CURLOPT_ACCEPTTIMEOUT_MS.md CURLOPT_ACCEPT_ENCODING.md CURLOPT_ADDRESS_SCOPE.md CURLOPT_ALTSVC.md CURLOPT_ALTSVC_CTRL.md CURLOPT_APPEND.md CURLOPT_AUTOREFERER.md CURLOPT_AWS_SIGV4.md CURLOPT_BUFFERSIZE.md CURLOPT_CAINFO.md CURLOPT_CAINFO_BLOB.md CURLOPT_CAPATH.md CURLOPT_CA_CACHE_TIMEOUT.md CURLOPT_CERTINFO.md CURLOPT_CHUNK_BGN_FUNCTION.md CURLOPT_CHUNK_DATA.md CURLOPT_CHUNK_END_FUNCTION.md CURLOPT_CLOSESOCKETDATA.md CURLOPT_CLOSESOCKETFUNCTION.md CURLOPT_CONNECTTIMEOUT.md CURLOPT_CONNECTTIMEOUT_MS.md CURLOPT_CONNECT_ONLY.md CURLOPT_CONNECT_TO.md CURLOPT_CONV_FROM_NETWORK_FUNCTION.md CURLOPT_CONV_FROM_UTF8_FUNCTION.md CURLOPT_CONV_TO_NETWORK_FUNCTION.md CURLOPT_COOKIE.md CURLOPT_COOKIEFILE.md CURLOPT_COOKIEJAR.md CURLOPT_COOKIELIST.md CURLOPT_COOKIESESSION.md CURLOPT_COPYPOSTFIELDS.md CURLOPT_CRLF.md CURLOPT_CRLFILE.md CURLOPT_CURLU.md CURLOPT_CUSTOMREQUEST.md CURLOPT_DEBUGDATA.md CURLOPT_DEBUGFUNCTION.md CURLOPT_DEFAULT_PROTOCOL.md CURLOPT_DIRLISTONLY.md CURLOPT_DISALLOW_USERNAME_IN_URL.md CURLOPT_DNS_CACHE_TIMEOUT.md CURLOPT_DNS_INTERFACE.md CURLOPT_DNS_LOCAL_IP4.md CURLOPT_DNS_LOCAL_IP6.md CURLOPT_DNS_SERVERS.md CURLOPT_DNS_SHUFFLE_ADDRESSES.md CURLOPT_DNS_USE_GLOBAL_CACHE.md CURLOPT_DOH_SSL_VERIFYHOST.md CURLOPT_DOH_SSL_VERIFYPEER.md CURLOPT_DOH_SSL_VERIFYSTATUS.md CURLOPT_DOH_URL.md CURLOPT_ECH.md CURLOPT_EGDSOCKET.md CURLOPT_ERRORBUFFER.md CURLOPT_EXPECT_100_TIMEOUT_MS.md CURLOPT_FAILONERROR.md CURLOPT_FILETIME.md CURLOPT_FNMATCH_DATA.md CURLOPT_FNMATCH_FUNCTION.md CURLOPT_FOLLOWLOCATION.md CURLOPT_FORBID_REUSE.md CURLOPT_FRESH_CONNECT.md CURLOPT_FTPPORT.md CURLOPT_FTPSSLAUTH.md CURLOPT_FTP_ACCOUNT.md CURLOPT_FTP_ALTERNATIVE_TO_USER.md CURLOPT_FTP_CREATE_MISSING_DIRS.md CURLOPT_FTP_FILEMETHOD.md CURLOPT_FTP_SKIP_PASV_IP.md CURLOPT_FTP_SSL_CCC.md CURLOPT_FTP_USE_EPRT.md CURLOPT_FTP_USE_EPSV.md CURLOPT_FTP_USE_PRET.md CURLOPT_GSSAPI_DELEGATION.md CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.md CURLOPT_HAPROXYPROTOCOL.md CURLOPT_HAPROXY_CLIENT_IP.md CURLOPT_HEADER.md CURLOPT_HEADERDATA.md CURLOPT_HEADERFUNCTION.md CURLOPT_HEADEROPT.md CURLOPT_HSTS.md CURLOPT_HSTSREADDATA.md CURLOPT_HSTSREADFUNCTION.md CURLOPT_HSTSWRITEDATA.md CURLOPT_HSTSWRITEFUNCTION.md CURLOPT_HSTS_CTRL.md CURLOPT_HTTP09_ALLOWED.md CURLOPT_HTTP200ALIASES.md CURLOPT_HTTPAUTH.md CURLOPT_HTTPGET.md CURLOPT_HTTPHEADER.md CURLOPT_HTTPPOST.md CURLOPT_HTTPPROXYTUNNEL.md CURLOPT_HTTP_CONTENT_DECODING.md CURLOPT_HTTP_TRANSFER_DECODING.md CURLOPT_HTTP_VERSION.md CURLOPT_IGNORE_CONTENT_LENGTH.md CURLOPT_INFILESIZE.md CURLOPT_INFILESIZE_LARGE.md CURLOPT_INTERFACE.md CURLOPT_INTERLEAVEDATA.md CURLOPT_INTERLEAVEFUNCTION.md CURLOPT_IOCTLDATA.md CURLOPT_IOCTLFUNCTION.md CURLOPT_IPRESOLVE.md CURLOPT_ISSUERCERT.md CURLOPT_ISSUERCERT_BLOB.md CURLOPT_KEEP_SENDING_ON_ERROR.md CURLOPT_KEYPASSWD.md CURLOPT_KRBLEVEL.md CURLOPT_LOCALPORT.md CURLOPT_LOCALPORTRANGE.md CURLOPT_LOGIN_OPTIONS.md CURLOPT_LOW_SPEED_LIMIT.md CURLOPT_LOW_SPEED_TIME.md CURLOPT_MAIL_AUTH.md CURLOPT_MAIL_FROM.md CURLOPT_MAIL_RCPT.md CURLOPT_MAIL_RCPT_ALLOWFAILS.md CURLOPT_MAXAGE_CONN.md CURLOPT_MAXCONNECTS.md CURLOPT_MAXFILESIZE.md CURLOPT_MAXFILESIZE_LARGE.md CURLOPT_MAXLIFETIME_CONN.md CURLOPT_MAXREDIRS.md CURLOPT_MAX_RECV_SPEED_LARGE.md CURLOPT_MAX_SEND_SPEED_LARGE.md CURLOPT_MIMEPOST.md CURLOPT_MIME_OPTIONS.md CURLOPT_NETRC.md CURLOPT_NETRC_FILE.md CURLOPT_NEW_DIRECTORY_PERMS.md CURLOPT_NEW_FILE_PERMS.md CURLOPT_NOBODY.md CURLOPT_NOPROGRESS.md CURLOPT_NOPROXY.md CURLOPT_NOSIGNAL.md CURLOPT_OPENSOCKETDATA.md CURLOPT_OPENSOCKETFUNCTION.md CURLOPT_PASSWORD.md CURLOPT_PATH_AS_IS.md CURLOPT_PINNEDPUBLICKEY.md CURLOPT_PIPEWAIT.md CURLOPT_PORT.md CURLOPT_POST.md CURLOPT_POSTFIELDS.md CURLOPT_POSTFIELDSIZE.md CURLOPT_POSTFIELDSIZE_LARGE.md CURLOPT_POSTQUOTE.md CURLOPT_POSTREDIR.md CURLOPT_PREQUOTE.md CURLOPT_PREREQDATA.md CURLOPT_PREREQFUNCTION.md CURLOPT_PRE_PROXY.md CURLOPT_PRIVATE.md CURLOPT_PROGRESSDATA.md CURLOPT_PROGRESSFUNCTION.md CURLOPT_PROTOCOLS.md CURLOPT_PROTOCOLS_STR.md CURLOPT_PROXY.md CURLOPT_PROXYAUTH.md CURLOPT_PROXYHEADER.md CURLOPT_PROXYPASSWORD.md CURLOPT_PROXYPORT.md CURLOPT_PROXYTYPE.md CURLOPT_PROXYUSERNAME.md CURLOPT_PROXYUSERPWD.md CURLOPT_PROXY_CAINFO.md CURLOPT_PROXY_CAINFO_BLOB.md CURLOPT_PROXY_CAPATH.md CURLOPT_PROXY_CRLFILE.md CURLOPT_PROXY_ISSUERCERT.md CURLOPT_PROXY_ISSUERCERT_BLOB.md CURLOPT_PROXY_KEYPASSWD.md CURLOPT_PROXY_PINNEDPUBLICKEY.md CURLOPT_PROXY_SERVICE_NAME.md CURLOPT_PROXY_SSLCERT.md CURLOPT_PROXY_SSLCERTTYPE.md CURLOPT_PROXY_SSLCERT_BLOB.md CURLOPT_PROXY_SSLKEY.md CURLOPT_PROXY_SSLKEYTYPE.md CURLOPT_PROXY_SSLKEY_BLOB.md CURLOPT_PROXY_SSLVERSION.md CURLOPT_PROXY_SSL_CIPHER_LIST.md CURLOPT_PROXY_SSL_OPTIONS.md CURLOPT_PROXY_SSL_VERIFYHOST.md CURLOPT_PROXY_SSL_VERIFYPEER.md CURLOPT_PROXY_TLS13_CIPHERS.md CURLOPT_PROXY_TLSAUTH_PASSWORD.md CURLOPT_PROXY_TLSAUTH_TYPE.md CURLOPT_PROXY_TLSAUTH_USERNAME.md CURLOPT_PROXY_TRANSFER_MODE.md CURLOPT_PUT.md CURLOPT_QUICK_EXIT.md CURLOPT_QUOTE.md CURLOPT_RANDOM_FILE.md CURLOPT_RANGE.md CURLOPT_READDATA.md CURLOPT_READFUNCTION.md CURLOPT_REDIR_PROTOCOLS.md CURLOPT_REDIR_PROTOCOLS_STR.md CURLOPT_REFERER.md CURLOPT_REQUEST_TARGET.md CURLOPT_RESOLVE.md CURLOPT_RESOLVER_START_DATA.md CURLOPT_RESOLVER_START_FUNCTION.md CURLOPT_RESUME_FROM.md CURLOPT_RESUME_FROM_LARGE.md CURLOPT_RTSP_CLIENT_CSEQ.md CURLOPT_RTSP_REQUEST.md CURLOPT_RTSP_SERVER_CSEQ.md CURLOPT_RTSP_SESSION_ID.md CURLOPT_RTSP_STREAM_URI.md CURLOPT_RTSP_TRANSPORT.md CURLOPT_SASL_AUTHZID.md CURLOPT_SASL_IR.md CURLOPT_SEEKDATA.md CURLOPT_SEEKFUNCTION.md CURLOPT_SERVER_RESPONSE_TIMEOUT.md CURLOPT_SERVER_RESPONSE_TIMEOUT_MS.md CURLOPT_SERVICE_NAME.md CURLOPT_SHARE.md CURLOPT_SOCKOPTDATA.md CURLOPT_SOCKOPTFUNCTION.md CURLOPT_SOCKS5_AUTH.md CURLOPT_SOCKS5_GSSAPI_NEC.md CURLOPT_SOCKS5_GSSAPI_SERVICE.md CURLOPT_SSH_AUTH_TYPES.md CURLOPT_SSH_COMPRESSION.md CURLOPT_SSH_HOSTKEYDATA.md CURLOPT_SSH_HOSTKEYFUNCTION.md CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md CURLOPT_SSH_KEYDATA.md CURLOPT_SSH_KEYFUNCTION.md CURLOPT_SSH_KNOWNHOSTS.md CURLOPT_SSH_PRIVATE_KEYFILE.md CURLOPT_SSH_PUBLIC_KEYFILE.md CURLOPT_SSLCERT.md CURLOPT_SSLCERTTYPE.md CURLOPT_SSLCERT_BLOB.md CURLOPT_SSLENGINE.md CURLOPT_SSLENGINE_DEFAULT.md CURLOPT_SSLKEY.md CURLOPT_SSLKEYTYPE.md CURLOPT_SSLKEY_BLOB.md CURLOPT_SSLVERSION.md CURLOPT_SSL_CIPHER_LIST.md CURLOPT_SSL_CTX_DATA.md CURLOPT_SSL_CTX_FUNCTION.md CURLOPT_SSL_EC_CURVES.md CURLOPT_SSL_ENABLE_ALPN.md CURLOPT_SSL_ENABLE_NPN.md CURLOPT_SSL_FALSESTART.md CURLOPT_SSL_OPTIONS.md CURLOPT_SSL_SESSIONID_CACHE.md CURLOPT_SSL_SIGNATURE_ALGORITHMS.md CURLOPT_SSL_VERIFYHOST.md CURLOPT_SSL_VERIFYPEER.md CURLOPT_SSL_VERIFYSTATUS.md CURLOPT_STDERR.md CURLOPT_STREAM_DEPENDS.md CURLOPT_STREAM_DEPENDS_E.md CURLOPT_STREAM_WEIGHT.md CURLOPT_SUPPRESS_CONNECT_HEADERS.md CURLOPT_TCP_FASTOPEN.md CURLOPT_TCP_KEEPALIVE.md CURLOPT_TCP_KEEPCNT.md CURLOPT_TCP_KEEPIDLE.md CURLOPT_TCP_KEEPINTVL.md CURLOPT_TCP_NODELAY.md CURLOPT_TELNETOPTIONS.md CURLOPT_TFTP_BLKSIZE.md CURLOPT_TFTP_NO_OPTIONS.md CURLOPT_TIMECONDITION.md CURLOPT_TIMEOUT.md CURLOPT_TIMEOUT_MS.md CURLOPT_TIMEVALUE.md CURLOPT_TIMEVALUE_LARGE.md CURLOPT_TLS13_CIPHERS.md CURLOPT_TLSAUTH_PASSWORD.md CURLOPT_TLSAUTH_TYPE.md CURLOPT_TLSAUTH_USERNAME.md CURLOPT_TRAILERDATA.md CURLOPT_TRAILERFUNCTION.md CURLOPT_TRANSFERTEXT.md CURLOPT_TRANSFER_ENCODING.md CURLOPT_UNIX_SOCKET_PATH.md CURLOPT_UNRESTRICTED_AUTH.md CURLOPT_UPKEEP_INTERVAL_MS.md CURLOPT_UPLOAD.md CURLOPT_UPLOAD_BUFFERSIZE.md CURLOPT_UPLOAD_FLAGS.md CURLOPT_URL.md CURLOPT_USERAGENT.md CURLOPT_USERNAME.md CURLOPT_USERPWD.md CURLOPT_USE_SSL.md CURLOPT_VERBOSE.md CURLOPT_WILDCARDMATCH.md CURLOPT_WRITEDATA.md CURLOPT_WRITEFUNCTION.md CURLOPT_WS_OPTIONS.md CURLOPT_XFERINFODATA.md CURLOPT_XFERINFOFUNCTION.md CURLOPT_XOAUTH2_BEARER.md CURLSHOPT_LOCKFUNC.md CURLSHOPT_SHARE.md CURLSHOPT_UNLOCKFUNC.md CURLSHOPT_UNSHARE.md CURLSHOPT_USERDATA.md Makefile.am Makefile.incinclude
curl
Makefile.am curl.h curlver.h easy.h header.h mprintf.h multi.h options.h stdcheaders.h system.h typecheck-gcc.h urlapi.h websockets.hlib
curlx
base64.c base64.h basename.c basename.h dynbuf.c dynbuf.h fopen.c fopen.h inet_ntop.c inet_ntop.h inet_pton.c inet_pton.h multibyte.c multibyte.h nonblock.c nonblock.h snprintf.c snprintf.h strcopy.c strcopy.h strdup.c strdup.h strerr.c strerr.h strparse.c strparse.h timediff.c timediff.h timeval.c timeval.h version_win32.c version_win32.h wait.c wait.h warnless.c warnless.h winapi.c winapi.hvauth
cleartext.c cram.c digest.c digest.h digest_sspi.c gsasl.c krb5_gssapi.c krb5_sspi.c ntlm.c ntlm_sspi.c oauth2.c spnego_gssapi.c spnego_sspi.c vauth.c vauth.hvquic
curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.hvtls
apple.c apple.h cipher_suite.c cipher_suite.h gtls.c gtls.h hostcheck.c hostcheck.h keylog.c keylog.h mbedtls.c mbedtls.h openssl.c openssl.h rustls.c rustls.h schannel.c schannel.h schannel_int.h schannel_verify.c vtls.c vtls.h vtls_int.h vtls_scache.c vtls_scache.h vtls_spack.c vtls_spack.h wolfssl.c wolfssl.h x509asn1.c x509asn1.hm4
.gitignore curl-amissl.m4 curl-apple-sectrust.m4 curl-compilers.m4 curl-confopts.m4 curl-functions.m4 curl-gnutls.m4 curl-mbedtls.m4 curl-openssl.m4 curl-override.m4 curl-reentrant.m4 curl-rustls.m4 curl-schannel.m4 curl-sysconfig.m4 curl-wolfssl.m4 xc-am-iface.m4 xc-cc-check.m4 xc-lt-iface.m4 xc-val-flgs.m4 zz40-xc-ovr.m4 zz50-xc-ovr.m4projects
OS400
.checksrc README.OS400 ccsidcurl.c ccsidcurl.h config400.default curl.cmd curl.inc.in curlcl.c curlmain.c initscript.sh make-docs.sh make-include.sh make-lib.sh make-src.sh make-tests.sh makefile.sh os400sys.c os400sys.hWindows
tmpl
.gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filtersvms
Makefile.am backup_gnv_curl_src.com build_curl-config_script.com build_gnv_curl.com build_gnv_curl_pcsi_desc.com build_gnv_curl_pcsi_text.com build_gnv_curl_release_notes.com build_libcurl_pc.com build_vms.com clean_gnv_curl.com compare_curl_source.com config_h.com curl_crtl_init.c curl_gnv_build_steps.txt curl_release_note_start.txt curl_startup.com curlmsg.h curlmsg.msg curlmsg.sdl curlmsg_vms.h generate_config_vms_h_curl.com generate_vax_transfer.com gnv_conftest.c_first gnv_curl_configure.sh gnv_libcurl_symbols.opt gnv_link_curl.com macro32_exactcase.patch make_gnv_curl_install.sh make_pcsi_curl_kit_name.com pcsi_gnv_curl_file_list.txt pcsi_product_gnv_curl.com readme report_openssl_version.c setup_gnv_curl_build.com stage_curl_install.com vms_eco_level.hscripts
.checksrc CMakeLists.txt Makefile.am badwords badwords-all badwords.txt cd2cd cd2nroff cdall checksrc-all.pl checksrc.pl cmakelint.sh completion.pl contributors.sh contrithanks.sh coverage.sh delta dmaketgz extract-unit-protos firefox-db2pem.sh installcheck.sh maketgz managen mdlinkcheck mk-ca-bundle.pl mk-unity.pl nroff2cd perlcheck.sh pythonlint.sh randdisable release-notes.pl release-tools.sh schemetable.c singleuse.pl spacecheck.pl top-complexity top-length verify-release wcurlsrc
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc config2setopts.c config2setopts.h curl.rc curlinfo.c mk-file-embed.pl mkhelp.pl slist_wc.c slist_wc.h terminal.c terminal.h tool_cb_dbg.c tool_cb_dbg.h tool_cb_hdr.c tool_cb_hdr.h tool_cb_prg.c tool_cb_prg.h tool_cb_rea.c tool_cb_rea.h tool_cb_see.c tool_cb_see.h tool_cb_soc.c tool_cb_soc.h tool_cb_wrt.c tool_cb_wrt.h tool_cfgable.c tool_cfgable.h tool_dirhie.c tool_dirhie.h tool_doswin.c tool_doswin.h tool_easysrc.c tool_easysrc.h tool_filetime.c tool_filetime.h tool_findfile.c tool_findfile.h tool_formparse.c tool_formparse.h tool_getparam.c tool_getparam.h tool_getpass.c tool_getpass.h tool_help.c tool_help.h tool_helpers.c tool_helpers.h tool_hugehelp.h tool_ipfs.c tool_ipfs.h tool_libinfo.c tool_libinfo.h tool_listhelp.c tool_main.c tool_main.h tool_msgs.c tool_msgs.h tool_operate.c tool_operate.h tool_operhlp.c tool_operhlp.h tool_paramhlp.c tool_paramhlp.h tool_parsecfg.c tool_parsecfg.h tool_progress.c tool_progress.h tool_sdecls.h tool_setopt.c tool_setopt.h tool_setup.h tool_ssls.c tool_ssls.h tool_stderr.c tool_stderr.h tool_urlglob.c tool_urlglob.h tool_util.c tool_util.h tool_version.h tool_vms.c tool_vms.h tool_writeout.c tool_writeout.h tool_writeout_json.c tool_writeout_json.h tool_xattr.c tool_xattr.h var.c var.htests
certs
.gitignore CMakeLists.txt Makefile.am Makefile.inc genserv.pl srp-verifier-conf srp-verifier-db test-ca.cnf test-ca.prm test-client-cert.prm test-client-eku-only.prm test-localhost-san-first.prm test-localhost-san-last.prm test-localhost.nn.prm test-localhost.prm test-localhost0h.prmdata
.gitignore DISABLED Makefile.am data-xml1 data1400.c data1401.c data1402.c data1403.c data1404.c data1405.c data1406.c data1407.c data1420.c data1461.txt data1463.txt data1465.c data1481.c data1705-1.md data1705-2.md data1705-3.md data1705-4.md data1705-stdout.1 data1706-1.md data1706-2.md data1706-3.md data1706-4.md data1706-stdout.txt data320.html test1 test10 test100 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 test1008 test1009 test101 test1010 test1011 test1012 test1013 test1014 test1015 test1016 test1017 test1018 test1019 test102 test1020 test1021 test1022 test1023 test1024 test1025 test1026 test1027 test1028 test1029 test103 test1030 test1031 test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 test104 test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 test1048 test1049 test105 test1050 test1051 test1052 test1053 test1054 test1055 test1056 test1057 test1058 test1059 test106 test1060 test1061 test1062 test1063 test1064 test1065 test1066 test1067 test1068 test1069 test107 test1070 test1071 test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 test108 test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 test1088 test1089 test109 test1090 test1091 test1092 test1093 test1094 test1095 test1096 test1097 test1098 test1099 test11 test110 test1100 test1101 test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 test111 test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 test112 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 test1128 test1129 test113 test1130 test1131 test1132 test1133 test1134 test1135 test1136 test1137 test1138 test1139 test114 test1140 test1141 test1142 test1143 test1144 test1145 test1146 test1147 test1148 test1149 test115 test1150 test1151 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 test116 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 test1168 test1169 test117 test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 test1178 test1179 test118 test1180 test1181 test1182 test1183 test1184 test1185 test1186 test1187 test1188 test1189 test119 test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 test1199 test12 test120 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 test1208 test1209 test121 test1210 test1211 test1212 test1213 test1214 test1215 test1216 test1217 test1218 test1219 test122 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 test1228 test1229 test123 test1230 test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 test124 test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 test1248 test1249 test125 test1250 test1251 test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 test126 test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 test1268 test1269 test127 test1270 test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 test1279 test128 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 test1288 test1289 test129 test1290 test1291 test1292 test1293 test1294 test1295 test1296 test1297 test1298 test1299 test13 test130 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 test1309 test131 test1310 test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 test132 test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 test133 test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 test134 test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 test1348 test1349 test135 test1350 test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 test136 test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 test137 test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 test138 test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 test1388 test1389 test139 test1390 test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 test14 test140 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 test141 test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 test1418 test1419 test142 test1420 test1421 test1422 test1423 test1424 test1425 test1426 test1427 test1428 test1429 test143 test1430 test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 test144 test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 test145 test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 test146 test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 test1468 test1469 test147 test1470 test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 test1479 test148 test1480 test1481 test1482 test1483 test1484 test1485 test1486 test1487 test1488 test1489 test149 test1490 test1491 test1492 test1493 test1494 test1495 test1496 test1497 test1498 test1499 test15 test150 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 test1508 test1509 test151 test1510 test1511 test1512 test1513 test1514 test1515 test1516 test1517 test1518 test1519 test152 test1520 test1521 test1522 test1523 test1524 test1525 test1526 test1527 test1528 test1529 test153 test1530 test1531 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 test154 test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 test1548 test1549 test155 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 test1558 test1559 test156 test1560 test1561 test1562 test1563 test1564 test1565 test1566 test1567 test1568 test1569 test157 test1570 test1571 test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 test158 test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 test1589 test159 test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 test1598 test1599 test16 test160 test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 test1608 test1609 test161 test1610 test1611 test1612 test1613 test1614 test1615 test1616 test1617 test1618 test1619 test162 test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 test163 test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 test1638 test1639 test164 test1640 test1641 test1642 test1643 test1644 test1645 test165 test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 test1658 test1659 test166 test1660 test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 test1669 test167 test1670 test1671 test1672 test1673 test1674 test1675 test1676 test168 test1680 test1681 test1682 test1683 test1684 test1685 test169 test17 test170 test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 test1708 test1709 test171 test1710 test1711 test1712 test1713 test1714 test1715 test172 test1720 test1721 test173 test174 test175 test176 test177 test178 test179 test18 test180 test1800 test1801 test1802 test181 test182 test183 test184 test1847 test1848 test1849 test185 test1850 test1851 test186 test187 test188 test189 test19 test190 test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 test1908 test1909 test191 test1910 test1911 test1912 test1913 test1914 test1915 test1916 test1917 test1918 test1919 test192 test1920 test1921 test193 test1933 test1934 test1935 test1936 test1937 test1938 test1939 test194 test1940 test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 test195 test1955 test1956 test1957 test1958 test1959 test196 test1960 test1964 test1965 test1966 test197 test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 test1978 test1979 test198 test1980 test1981 test1982 test1983 test1984 test199 test2 test20 test200 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 test2008 test2009 test201 test2010 test2011 test2012 test2013 test2014 test202 test2023 test2024 test2025 test2026 test2027 test2028 test2029 test203 test2030 test2031 test2032 test2033 test2034 test2035 test2037 test2038 test2039 test204 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 test2048 test2049 test205 test2050 test2051 test2052 test2053 test2054 test2055 test2056 test2057 test2058 test2059 test206 test2060 test2061 test2062 test2063 test2064 test2065 test2066 test2067 test2068 test2069 test207 test2070 test2071 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 test208 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 test2088 test2089 test209 test2090 test2091 test2092 test21 test210 test2100 test2101 test2102 test2103 test2104 test211 test212 test213 test214 test215 test216 test217 test218 test219 test22 test220 test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 test221 test222 test223 test224 test225 test226 test227 test228 test229 test23 test230 test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 test2309 test231 test232 test233 test234 test235 test236 test237 test238 test239 test24 test240 test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 test2408 test2409 test241 test2410 test2411 test242 test243 test244 test245 test246 test247 test248 test249 test25 test250 test2500 test2501 test2502 test2503 test2504 test2505 test2506 test251 test252 test253 test254 test255 test256 test257 test258 test259 test26 test260 test2600 test2601 test2602 test2603 test2604 test2605 test261 test262 test263 test264 test265 test266 test267 test268 test269 test27 test270 test2700 test2701 test2702 test2703 test2704 test2705 test2706 test2707 test2708 test2709 test271 test2710 test2711 test2712 test2713 test2714 test2715 test2716 test2717 test2718 test2719 test272 test2720 test2721 test2722 test2723 test273 test274 test275 test276 test277 test278 test279 test28 test280 test281 test282 test283 test284 test285 test286 test287 test288 test289 test29 test290 test291 test292 test293 test294 test295 test296 test297 test298 test299 test3 test30 test300 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 test3008 test3009 test301 test3010 test3011 test3012 test3013 test3014 test3015 test3016 test3017 test3018 test3019 test302 test3020 test3021 test3022 test3023 test3024 test3025 test3026 test3027 test3028 test3029 test303 test3030 test3031 test3032 test3033 test3034 test3035 test3036 test304 test305 test306 test307 test308 test309 test31 test310 test3100 test3101 test3102 test3103 test3104 test3105 test3106 test311 test312 test313 test314 test315 test316 test317 test318 test319 test32 test320 test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 test3209 test321 test3210 test3211 test3212 test3213 test3214 test3215 test3216 test3217 test3218 test3219 test322 test3220 test323 test324 test325 test326 test327 test328 test329 test33 test330 test3300 test3301 test3302 test331 test332 test333 test334 test335 test336 test337 test338 test339 test34 test340 test341 test342 test343 test344 test345 test346 test347 test348 test349 test35 test350 test351 test352 test353 test354 test355 test356 test357 test358 test359 test36 test360 test361 test362 test363 test364 test365 test366 test367 test368 test369 test37 test370 test371 test372 test373 test374 test375 test376 test378 test379 test38 test380 test381 test383 test384 test385 test386 test387 test388 test389 test39 test390 test391 test392 test393 test394 test395 test396 test397 test398 test399 test4 test40 test400 test4000 test4001 test401 test402 test403 test404 test405 test406 test407 test408 test409 test41 test410 test411 test412 test413 test414 test415 test416 test417 test418 test419 test42 test420 test421 test422 test423 test424 test425 test426 test427 test428 test429 test43 test430 test431 test432 test433 test434 test435 test436 test437 test438 test439 test44 test440 test441 test442 test443 test444 test445 test446 test447 test448 test449 test45 test450 test451 test452 test453 test454 test455 test456 test457 test458 test459 test46 test460 test461 test462 test463 test467 test468 test469 test47 test470 test471 test472 test473 test474 test475 test476 test477 test478 test479 test48 test480 test481 test482 test483 test484 test485 test486 test487 test488 test489 test49 test490 test491 test492 test493 test494 test495 test496 test497 test498 test499 test5 test50 test500 test501 test502 test503 test504 test505 test506 test507 test508 test509 test51 test510 test511 test512 test513 test514 test515 test516 test517 test518 test519 test52 test520 test521 test522 test523 test524 test525 test526 test527 test528 test529 test53 test530 test531 test532 test533 test534 test535 test536 test537 test538 test539 test54 test540 test541 test542 test543 test544 test545 test546 test547 test548 test549 test55 test550 test551 test552 test553 test554 test555 test556 test557 test558 test559 test56 test560 test561 test562 test563 test564 test565 test566 test567 test568 test569 test57 test570 test571 test572 test573 test574 test575 test576 test577 test578 test579 test58 test580 test581 test582 test583 test584 test585 test586 test587 test588 test589 test59 test590 test591 test592 test593 test594 test595 test596 test597 test598 test599 test6 test60 test600 test601 test602 test603 test604 test605 test606 test607 test608 test609 test61 test610 test611 test612 test613 test614 test615 test616 test617 test618 test619 test62 test620 test621 test622 test623 test624 test625 test626 test627 test628 test629 test63 test630 test631 test632 test633 test634 test635 test636 test637 test638 test639 test64 test640 test641 test642 test643 test644 test645 test646 test647 test648 test649 test65 test650 test651 test652 test653 test654 test655 test656 test658 test659 test66 test660 test661 test662 test663 test664 test665 test666 test667 test668 test669 test67 test670 test671 test672 test673 test674 test675 test676 test677 test678 test679 test68 test680 test681 test682 test683 test684 test685 test686 test687 test688 test689 test69 test690 test691 test692 test693 test694 test695 test696 test697 test698 test699 test7 test70 test700 test701 test702 test703 test704 test705 test706 test707 test708 test709 test71 test710 test711 test712 test713 test714 test715 test716 test717 test718 test719 test72 test720 test721 test722 test723 test724 test725 test726 test727 test728 test729 test73 test730 test731 test732 test733 test734 test735 test736 test737 test738 test739 test74 test740 test741 test742 test743 test744 test745 test746 test747 test748 test749 test75 test750 test751 test752 test753 test754 test755 test756 test757 test758 test759 test76 test760 test761 test762 test763 test764 test765 test766 test767 test768 test769 test77 test770 test771 test772 test773 test774 test775 test776 test777 test778 test779 test78 test780 test781 test782 test783 test784 test785 test786 test787 test788 test789 test79 test790 test791 test792 test793 test794 test795 test796 test797 test798 test799 test8 test80 test800 test801 test802 test803 test804 test805 test806 test807 test808 test809 test81 test810 test811 test812 test813 test814 test815 test816 test817 test818 test819 test82 test820 test821 test822 test823 test824 test825 test826 test827 test828 test829 test83 test830 test831 test832 test833 test834 test835 test836 test837 test838 test839 test84 test840 test841 test842 test843 test844 test845 test846 test847 test848 test849 test85 test850 test851 test852 test853 test854 test855 test856 test857 test858 test859 test86 test860 test861 test862 test863 test864 test865 test866 test867 test868 test869 test87 test870 test871 test872 test873 test874 test875 test876 test877 test878 test879 test88 test880 test881 test882 test883 test884 test885 test886 test887 test888 test889 test89 test890 test891 test892 test893 test894 test895 test896 test897 test898 test899 test9 test90 test900 test901 test902 test903 test904 test905 test906 test907 test908 test909 test91 test910 test911 test912 test913 test914 test915 test916 test917 test918 test919 test92 test920 test921 test922 test923 test924 test925 test926 test927 test928 test929 test93 test930 test931 test932 test933 test934 test935 test936 test937 test938 test939 test94 test940 test941 test942 test943 test944 test945 test946 test947 test948 test949 test95 test950 test951 test952 test953 test954 test955 test956 test957 test958 test959 test96 test960 test961 test962 test963 test964 test965 test966 test967 test968 test969 test97 test970 test971 test972 test973 test974 test975 test976 test977 test978 test979 test98 test980 test981 test982 test983 test984 test985 test986 test987 test988 test989 test99 test990 test991 test992 test993 test994 test995 test996 test997 test998 test999http
testenv
__init__.py caddy.py certs.py client.py curl.py dante.py dnsd.py env.py httpd.py nghttpx.py ports.py sshd.py vsftpd.py ws_echo_server.pylibtest
.gitignore CMakeLists.txt Makefile.am Makefile.inc cli_ftp_upload.c cli_h2_pausing.c cli_h2_serverpush.c cli_h2_upgrade_extreme.c cli_hx_download.c cli_hx_upload.c cli_tls_session_reuse.c cli_upload_pausing.c cli_ws_data.c cli_ws_pingpong.c first.c first.h lib1156.c lib1301.c lib1308.c lib1485.c lib1500.c lib1501.c lib1502.c lib1506.c lib1507.c lib1508.c lib1509.c lib1510.c lib1511.c lib1512.c lib1513.c lib1514.c lib1515.c lib1517.c lib1518.c lib1520.c lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c lib1545.c lib1549.c lib1550.c lib1551.c lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c lib1559.c lib1560.c lib1564.c lib1565.c lib1567.c lib1568.c lib1569.c lib1571.c lib1576.c lib1582.c lib1587.c lib1588.c lib1589.c lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c lib1598.c lib1599.c lib1662.c lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c lib1933.c lib1934.c lib1935.c lib1936.c lib1937.c lib1938.c lib1939.c lib1940.c lib1945.c lib1947.c lib1948.c lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c lib1964.c lib1965.c lib1970.c lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c lib2023.c lib2032.c lib2082.c lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c lib2402.c lib2404.c lib2405.c lib2502.c lib2504.c lib2505.c lib2506.c lib2700.c lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c lib3207.c lib3208.c lib500.c lib501.c lib502.c lib503.c lib504.c lib505.c lib506.c lib507.c lib508.c lib509.c lib510.c lib511.c lib512.c lib513.c lib514.c lib515.c lib516.c lib517.c lib518.c lib519.c lib520.c lib521.c lib523.c lib524.c lib525.c lib526.c lib530.c lib533.c lib536.c lib537.c lib539.c lib540.c lib541.c lib542.c lib543.c lib544.c lib547.c lib549.c lib552.c lib553.c lib554.c lib555.c lib556.c lib557.c lib558.c lib559.c lib560.c lib562.c lib564.c lib566.c lib567.c lib568.c lib569.c lib570.c lib571.c lib572.c lib573.c lib574.c lib575.c lib576.c lib578.c lib579.c lib582.c lib583.c lib586.c lib589.c lib590.c lib591.c lib597.c lib598.c lib599.c lib643.c lib650.c lib651.c lib652.c lib653.c lib654.c lib655.c lib658.c lib659.c lib661.c lib666.c lib667.c lib668.c lib670.c lib674.c lib676.c lib677.c lib678.c lib694.c lib695.c lib751.c lib753.c lib757.c lib758.c lib766.c memptr.c mk-lib1521.pl test1013.pl test1022.pl test307.pl test610.pl test613.pl testtrace.c testtrace.h testutil.c testutil.h unitcheck.hserver
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc dnsd.c first.c first.h getpart.c mqttd.c resolve.c rtspd.c sockfilt.c socksd.c sws.c tftpd.c util.ctunit
.gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.cunit
.gitignore CMakeLists.txt Makefile.am Makefile.inc README.md unit1300.c unit1302.c unit1303.c unit1304.c unit1305.c unit1307.c unit1309.c unit1323.c unit1330.c unit1395.c unit1396.c unit1397.c unit1398.c unit1399.c unit1600.c unit1601.c unit1602.c unit1603.c unit1605.c unit1606.c unit1607.c unit1608.c unit1609.c unit1610.c unit1611.c unit1612.c unit1614.c unit1615.c unit1616.c unit1620.c unit1625.c unit1626.c unit1627.c unit1636.c unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c unit1666.c unit1667.c unit1668.c unit1669.c unit1674.c unit1675.c unit1676.c unit1979.c unit1980.c unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c unit3200.c unit3205.c unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c unit3219.c unit3300.c unit3301.c unit3302.cexamples
.env config.ini crypto_test.lua env_test.lua fs_example.lua http_server.lua https_test.lua ini_example.lua json.lua log.lua path_fs_example.lua process_example.lua request_download.lua request_test.lua run_all.lua sqlite_example.lua sqlite_http_template.lua stash_test.lua template_test.lua timer.lua websocket.luainiparser
example
iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.initest
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.hjinjac
libjinjac
src
CMakeLists.txt ast.c ast.h block_statement.c block_statement.h buffer.c buffer.h buildin.c buildin.h common.h convert.c convert.h flex_decl.h jfunction.c jfunction.h jinja_expression.l jinja_expression.y jinjac_parse.c jinjac_parse.h jinjac_stream.c jinjac_stream.h jlist.c jlist.h jobject.c jobject.h parameter.c parameter.h str_obj.c str_obj.h trace.c trace.htest
.gitignore CMakeLists.txt autotest.rb test_01.expected test_01.jinja test_01b.expected test_01b.jinja test_01c.expected test_01c.jinja test_01d.expected test_01d.jinja test_02.expected test_02.jinja test_03.expected test_03.jinja test_04.expected test_04.jinja test_05.expected test_05.jinja test_06.expected test_06.jinja test_07.expected test_07.jinja test_08.expected test_08.jinja test_08b.expected test_08b.jinja test_09.expected test_09.jinja test_10.expected test_10.jinja test_11.expected test_11.jinja test_12.expected test_12.jinja test_13.expected test_13.jinja test_14.expected test_14.jinja test_15.expected test_15.jinja test_16.expected test_16.jinja test_17.expected test_17.jinja test_18.expected test_18.jinja test_18b.expected test_18b.jinja test_18c.expected test_18c.jinja test_19.expected test_19.jinja test_19b.expected test_19b.jinja test_19c.expected test_19c.jinja test_19d.expected test_19d.jinja test_19e.expected test_19e.jinja test_19f.expected test_19f.jinja test_20.expected test_20.jinja test_21.expected test_21.jinja test_22.expected test_22.jinja test_22a.expected test_22a.jinja test_22b.expected test_22b.jinja test_23.expected test_23.jinja test_24.expected test_24.jinjalibev
Changes LICENSE Makefile Makefile.am Makefile.in README Symbols.ev Symbols.event aclocal.m4 autogen.sh compile config.guess config.h config.h.in config.status config.sub configure configure.ac depcomp ev++.h ev.3 ev.c ev.h ev.pod ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_vars.h ev_win32.c ev_wrap.h event.c event.h install-sh libev.m4 libtool ltmain.sh missing mkinstalldirs stamp-h1luajit
doc
bluequad-print.css bluequad.css contact.html ext_buffer.html ext_c_api.html ext_ffi.html ext_ffi_api.html ext_ffi_semantics.html ext_ffi_tutorial.html ext_jit.html ext_profiler.html extensions.html install.html luajit.html running.htmldynasm
dasm_arm.h dasm_arm.lua dasm_arm64.h dasm_arm64.lua dasm_mips.h dasm_mips.lua dasm_mips64.lua dasm_ppc.h dasm_ppc.lua dasm_proto.h dasm_x64.lua dasm_x86.h dasm_x86.lua dynasm.luasrc
host
.gitignore README buildvm.c buildvm.h buildvm_asm.c buildvm_fold.c buildvm_lib.c buildvm_libbc.h buildvm_peobj.c genlibbc.lua genminilua.lua genversion.lua minilua.cjit
.gitignore bc.lua bcsave.lua dis_arm.lua dis_arm64.lua dis_arm64be.lua dis_mips.lua dis_mips64.lua dis_mips64el.lua dis_mips64r6.lua dis_mips64r6el.lua dis_mipsel.lua dis_ppc.lua dis_x64.lua dis_x86.lua dump.lua p.lua v.lua zone.luawolfssl
.github
workflows
ada.yml arduino.yml async-examples.yml async.yml atecc608-sim.yml bind.yml cmake-autoconf.yml cmake.yml codespell.yml coverity-scan-fixes.yml cryptocb-only.yml curl.yml cyrus-sasl.yml disable-pk-algs.yml docker-Espressif.yml docker-OpenWrt.yml emnet-nonblock.yml fil-c.yml freertos-mem-track.yml gencertbuf.yml grpc.yml haproxy.yml hostap-vm.yml intelasm-c-fallback.yml ipmitool.yml jwt-cpp.yml krb5.yml libspdm.yml libssh2.yml libvncserver.yml linuxkm.yml macos-apple-native-cert-validation.yml mbedtls.sh mbedtls.yml membrowse-comment.yml membrowse-onboard.yml membrowse-report.yml memcached.sh memcached.yml mono.yml mosquitto.yml msmtp.yml msys2.yml multi-arch.yml multi-compiler.yml net-snmp.yml nginx.yml no-malloc.yml no-tls.yml nss.sh nss.yml ntp.yml ocsp.yml openldap.yml openssh.yml openssl-ech.yml opensslcoexist.yml openvpn.yml os-check.yml packaging.yml pam-ipmi.yml pq-all.yml pr-commit-check.yml psk.yml puf.yml python.yml rng-tools.yml rust-wrapper.yml se050-sim.yml smallStackSize.yml socat.yml softhsm.yml sssd.yml stm32-sim.yml stsafe-a120-sim.yml stunnel.yml symbol-prefixes.yml threadx.yml tls-anvil.yml trackmemory.yml watcomc.yml win-csharp-test.yml wolfCrypt-Wconversion.yml wolfboot-integration.yml wolfsm.yml xcode.yml zephyr-4.x.yml zephyr.ymlIDE
ARDUINO
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.hECLIPSE
Espressif
ESP-IDF
examples
template
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266wolfssl_benchmark
VisualGDB
wolfssl_benchmark_IDF_v4.4_ESP32.sln wolfssl_benchmark_IDF_v4.4_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32.sln wolfssl_benchmark_IDF_v5_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32C3.sln wolfssl_benchmark_IDF_v5_ESP32C3.vgdbproj wolfssl_benchmark_IDF_v5_ESP32S3.sln wolfssl_benchmark_IDF_v5_ESP32S3.vgdbprojwolfssl_client
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbprojwolfssl_server
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbprojwolfssl_test
VisualGDB
wolfssl_test-IDF_v5_ESP32.sln wolfssl_test-IDF_v5_ESP32.vgdbproj wolfssl_test-IDF_v5_ESP32C3.sln wolfssl_test-IDF_v5_ESP32C3.vgdbproj wolfssl_test-IDF_v5_ESP32C6.sln wolfssl_test-IDF_v5_ESP32C6.vgdbproj wolfssl_test_IDF_v5_ESP32S3.sln wolfssl_test_IDF_v5_ESP32S3.vgdbprojGCC-ARM
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ldIAR-EWARM
embOS
SAMV71_XULT
embOS_SAMV71_XULT_user_settings
user_settings.h user_settings_simple_example.h user_settings_verbose_example.hembOS_wolfcrypt_benchmark_SAMV71_XULT
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewpINTIME-RTOS
Makefile README.md include.am libwolfssl.c libwolfssl.vcxproj user_settings.h wolfExamples.c wolfExamples.h wolfExamples.sln wolfExamples.vcxproj wolfssl-lib.sln wolfssl-lib.vcxprojMQX
Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.hMSVS-2019-AZSPHERE
wolfssl_new_azsphere
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.cNETOS
Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.cPlatformIO
examples
wolfssl_benchmark
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspaceROWLEY-CROSSWORKS-ARM
Kinetis_FlashPlacement.xml README.md arm_startup.c benchmark_main.c hw.h include.am kinetis_hw.c retarget.c test_main.c user_settings.h wolfssl.hzp wolfssl_ltc.hzpRenesas
e2studio
RA6M3
README.md README_APRA6M_en.md README_APRA6M_jp.md include.amRX72N
EnvisionKit
Simple
README_EN.md README_JP.mdwolfssl_demo
key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.cSTM32Cube
README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.hWIN
README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxprojWIN-SRTP-KDF-140-3
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojWIN10
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojXCODE
Benchmark
include.amXilinxSDK
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.capple-universal
wolfssl-multiplatform
iotsafe
Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.hmynewt
README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.shcerts
1024
ca-cert.der ca-cert.pem ca-key.der ca-key.pem client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der dh1024.der dh1024.pem dsa-pub-1024.pem dsa1024.der dsa1024.pem include.am rsa1024.der server-cert.der server-cert.pem server-key.der server-key.pemcrl
extra-crls
ca-int-cert-revoked.pem claim-root.pem crl_critical_entry.pem crlnum_57oct.pem crlnum_64oct.pem general-server-crl.pem large_crlnum.pem large_crlnum2.pemdilithium
bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.amecc
bp256r1-key.der bp256r1-key.pem ca-secp256k1-cert.pem ca-secp256k1-key.pem client-bp256r1-cert.der client-bp256r1-cert.pem client-secp256k1-cert.der client-secp256k1-cert.pem genecc.sh include.am secp256k1-key.der secp256k1-key.pem secp256k1-param.pem secp256k1-privkey.der secp256k1-privkey.pem server-bp256r1-cert.der server-bp256r1-cert.pem server-secp256k1-cert.der server-secp256k1-cert.pem server2-secp256k1-cert.der server2-secp256k1-cert.pem wolfssl.cnf wolfssl_384.cnfed25519
ca-ed25519-key.der ca-ed25519-key.pem ca-ed25519-priv.der ca-ed25519-priv.pem ca-ed25519.der ca-ed25519.pem client-ed25519-key.der client-ed25519-key.pem client-ed25519-priv.der client-ed25519-priv.pem client-ed25519.der client-ed25519.pem eddsa-ed25519.der eddsa-ed25519.pem gen-ed25519-certs.sh gen-ed25519-keys.sh gen-ed25519.sh include.am root-ed25519-key.der root-ed25519-key.pem root-ed25519-priv.der root-ed25519-priv.pem root-ed25519.der root-ed25519.pem server-ed25519-cert.pem server-ed25519-key.der server-ed25519-key.pem server-ed25519-priv.der server-ed25519-priv.pem server-ed25519.der server-ed25519.pemed448
ca-ed448-key.der ca-ed448-key.pem ca-ed448-priv.der ca-ed448-priv.pem ca-ed448.der ca-ed448.pem client-ed448-key.der client-ed448-key.pem client-ed448-priv.der client-ed448-priv.pem client-ed448.der client-ed448.pem gen-ed448-certs.sh gen-ed448-keys.sh include.am root-ed448-key.der root-ed448-key.pem root-ed448-priv.der root-ed448-priv.pem root-ed448.der root-ed448.pem server-ed448-cert.pem server-ed448-key.der server-ed448-key.pem server-ed448-priv.der server-ed448-priv.pem server-ed448.der server-ed448.pemexternal
DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.amintermediate
ca_false_intermediate
gentestcert.sh int_ca.key server.key test_ca.key test_ca.pem test_int_not_cacert.pem test_sign_bynoca_srv.pem wolfssl_base.conf wolfssl_srv.conflms
bc_hss_L2_H5_W8_root.der bc_hss_L3_H5_W4_root.der bc_lms_chain_ca.der bc_lms_chain_leaf.der bc_lms_native_bc_root.der bc_lms_sha256_h10_w8_root.der bc_lms_sha256_h5_w4_root.der include.ammldsa
README.txt include.am mldsa44-cert.der mldsa44-cert.pem mldsa44-key.pem mldsa44_bare-priv.der mldsa44_bare-seed.der mldsa44_oqskeypair.der mldsa44_priv-only.der mldsa44_pub-spki.der mldsa44_seed-only.der mldsa44_seed-priv.der mldsa65-cert.der mldsa65-cert.pem mldsa65-key.pem mldsa65_bare-priv.der mldsa65_bare-seed.der mldsa65_oqskeypair.der mldsa65_priv-only.der mldsa65_pub-spki.der mldsa65_seed-only.der mldsa65_seed-priv.der mldsa87-cert.der mldsa87-cert.pem mldsa87-key.pem mldsa87_bare-priv.der mldsa87_bare-seed.der mldsa87_oqskeypair.der mldsa87_priv-only.der mldsa87_pub-spki.der mldsa87_seed-only.der mldsa87_seed-priv.derocsp
imposter-root-ca-cert.der imposter-root-ca-cert.pem imposter-root-ca-key.der imposter-root-ca-key.pem include.am index-ca-and-intermediate-cas.txt index-ca-and-intermediate-cas.txt.attr index-intermediate1-ca-issued-certs.txt index-intermediate1-ca-issued-certs.txt.attr index-intermediate2-ca-issued-certs.txt index-intermediate2-ca-issued-certs.txt.attr index-intermediate3-ca-issued-certs.txt index-intermediate3-ca-issued-certs.txt.attr intermediate1-ca-cert.der intermediate1-ca-cert.pem intermediate1-ca-key.der intermediate1-ca-key.pem intermediate2-ca-cert.der intermediate2-ca-cert.pem intermediate2-ca-key.der intermediate2-ca-key.pem intermediate3-ca-cert.der intermediate3-ca-cert.pem intermediate3-ca-key.der intermediate3-ca-key.pem ocsp-responder-cert.der ocsp-responder-cert.pem ocsp-responder-key.der ocsp-responder-key.pem openssl.cnf renewcerts-for-test.sh renewcerts.sh root-ca-cert.der root-ca-cert.pem root-ca-crl.pem root-ca-key.der root-ca-key.pem server1-cert.der server1-cert.pem server1-chain-noroot.pem server1-key.der server1-key.pem server2-cert.der server2-cert.pem server2-key.der server2-key.pem server3-cert.der server3-cert.pem server3-key.der server3-key.pem server4-cert.der server4-cert.pem server4-key.der server4-key.pem server5-cert.der server5-cert.pem server5-key.der server5-key.pem test-leaf-response.der test-multi-response.der test-response-nointern.der test-response-rsapss.der test-response.derp521
ca-p521-key.der ca-p521-key.pem ca-p521-priv.der ca-p521-priv.pem ca-p521.der ca-p521.pem client-p521-key.der client-p521-key.pem client-p521-priv.der client-p521-priv.pem client-p521.der client-p521.pem gen-p521-certs.sh gen-p521-keys.sh include.am root-p521-key.der root-p521-key.pem root-p521-priv.der root-p521-priv.pem root-p521.der root-p521.pem server-p521-cert.pem server-p521-key.der server-p521-key.pem server-p521-priv.der server-p521-priv.pem server-p521.der server-p521.pemrpk
client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.derrsapss
ca-3072-rsapss-key.der ca-3072-rsapss-key.pem ca-3072-rsapss-priv.der ca-3072-rsapss-priv.pem ca-3072-rsapss.der ca-3072-rsapss.pem ca-rsapss-key.der ca-rsapss-key.pem ca-rsapss-priv.der ca-rsapss-priv.pem ca-rsapss.der ca-rsapss.pem client-3072-rsapss-key.der client-3072-rsapss-key.pem client-3072-rsapss-priv.der client-3072-rsapss-priv.pem client-3072-rsapss.der client-3072-rsapss.pem client-rsapss-key.der client-rsapss-key.pem client-rsapss-priv.der client-rsapss-priv.pem client-rsapss.der client-rsapss.pem gen-rsapss-keys.sh include.am renew-rsapss-certs.sh root-3072-rsapss-key.der root-3072-rsapss-key.pem root-3072-rsapss-priv.der root-3072-rsapss-priv.pem root-3072-rsapss.der root-3072-rsapss.pem root-rsapss-key.der root-rsapss-key.pem root-rsapss-priv.der root-rsapss-priv.pem root-rsapss.der root-rsapss.pem server-3072-rsapss-cert.pem server-3072-rsapss-key.der server-3072-rsapss-key.pem server-3072-rsapss-priv.der server-3072-rsapss-priv.pem server-3072-rsapss.der server-3072-rsapss.pem server-mix-rsapss-cert.pem server-rsapss-cert.pem server-rsapss-key.der server-rsapss-key.pem server-rsapss-priv.der server-rsapss-priv.pem server-rsapss.der server-rsapss.pemslhdsa
bench_slhdsa_sha2_128f_key.der bench_slhdsa_sha2_128s_key.der bench_slhdsa_sha2_192f_key.der bench_slhdsa_sha2_192s_key.der bench_slhdsa_sha2_256f_key.der bench_slhdsa_sha2_256s_key.der bench_slhdsa_shake128f_key.der bench_slhdsa_shake128s_key.der bench_slhdsa_shake192f_key.der bench_slhdsa_shake192s_key.der bench_slhdsa_shake256f_key.der bench_slhdsa_shake256s_key.der client-mldsa44-priv.pem client-mldsa44-sha2.der client-mldsa44-sha2.pem client-mldsa44-shake.der client-mldsa44-shake.pem gen-slhdsa-mldsa-certs.sh include.am root-slhdsa-sha2-128s-priv.der root-slhdsa-sha2-128s-priv.pem root-slhdsa-sha2-128s.der root-slhdsa-sha2-128s.pem root-slhdsa-shake-128s-priv.der root-slhdsa-shake-128s-priv.pem root-slhdsa-shake-128s.der root-slhdsa-shake-128s.pem server-mldsa44-priv.pem server-mldsa44-sha2.der server-mldsa44-sha2.pem server-mldsa44-shake.der server-mldsa44-shake.pemsm2
ca-sm2-key.der ca-sm2-key.pem ca-sm2-priv.der ca-sm2-priv.pem ca-sm2.der ca-sm2.pem client-sm2-key.der client-sm2-key.pem client-sm2-priv.der client-sm2-priv.pem client-sm2.der client-sm2.pem fix_sm2_spki.py gen-sm2-certs.sh gen-sm2-keys.sh include.am root-sm2-key.der root-sm2-key.pem root-sm2-priv.der root-sm2-priv.pem root-sm2.der root-sm2.pem self-sm2-cert.pem self-sm2-key.pem self-sm2-priv.pem server-sm2-cert.der server-sm2-cert.pem server-sm2-key.der server-sm2-key.pem server-sm2-priv.der server-sm2-priv.pem server-sm2.der server-sm2.pemstatickeys
dh-ffdhe2048-params.pem dh-ffdhe2048-pub.der dh-ffdhe2048-pub.pem dh-ffdhe2048.der dh-ffdhe2048.pem ecc-secp256r1.der ecc-secp256r1.pem gen-static.sh include.am x25519-pub.der x25519-pub.pem x25519.der x25519.pemtest
catalog.txt cert-bad-neg-int.der cert-bad-oid.der cert-bad-utf8.der cert-ext-ia.cfg cert-ext-ia.der cert-ext-ia.pem cert-ext-joi.cfg cert-ext-joi.der cert-ext-joi.pem cert-ext-mnc.der cert-ext-multiple.cfg cert-ext-multiple.der cert-ext-multiple.pem cert-ext-nc-combined.der cert-ext-nc-combined.pem cert-ext-nc.cfg cert-ext-nc.der cert-ext-nc.pem cert-ext-ncdns.der cert-ext-ncdns.pem cert-ext-ncip.der cert-ext-ncip.pem cert-ext-ncmixed.der cert-ext-ncmulti.der cert-ext-ncmulti.pem cert-ext-ncrid.der cert-ext-ncrid.pem cert-ext-nct.cfg cert-ext-nct.der cert-ext-nct.pem cert-ext-ndir-exc.cfg cert-ext-ndir-exc.der cert-ext-ndir-exc.pem cert-ext-ndir.cfg cert-ext-ndir.der cert-ext-ndir.pem cert-ext-ns.der cert-over-max-altnames.cfg cert-over-max-altnames.der cert-over-max-altnames.pem cert-over-max-nc.cfg cert-over-max-nc.der cert-over-max-nc.pem client-ecc-cert-ski.hex cn-ip-literal.der cn-ip-wildcard.der crit-cert.pem crit-key.pem dh1024.der dh1024.pem dh512.der dh512.pem digsigku.pem encrypteddata.msg gen-badsig.sh gen-ext-certs.sh gen-testcerts.sh include.am kari-keyid-cms.msg ktri-keyid-cms.msg ossl-trusted-cert.pem server-badaltname.der server-badaltname.pem server-badaltnull.der server-badaltnull.pem server-badcn.der server-badcn.pem server-badcnnull.der server-badcnnull.pem server-cert-ecc-badsig.der server-cert-ecc-badsig.pem server-cert-rsa-badsig.der server-cert-rsa-badsig.pem server-duplicate-policy.pem server-garbage.der server-garbage.pem server-goodalt.der server-goodalt.pem server-goodaltwild.der server-goodaltwild.pem server-goodcn.der server-goodcn.pem server-goodcnwild.der server-goodcnwild.pem server-localhost.der server-localhost.pem smime-test-canon.p7s smime-test-multipart-badsig.p7s smime-test-multipart.p7s smime-test.p7stest-pathlen
assemble-chains.sh chainA-ICA1-key.pem chainA-ICA1-pathlen0.pem chainA-assembled.pem chainA-entity-key.pem chainA-entity.pem chainB-ICA1-key.pem chainB-ICA1-pathlen0.pem chainB-ICA2-key.pem chainB-ICA2-pathlen1.pem chainB-assembled.pem chainB-entity-key.pem chainB-entity.pem chainC-ICA1-key.pem chainC-ICA1-pathlen1.pem chainC-assembled.pem chainC-entity-key.pem chainC-entity.pem chainD-ICA1-key.pem chainD-ICA1-pathlen127.pem chainD-assembled.pem chainD-entity-key.pem chainD-entity.pem chainE-ICA1-key.pem chainE-ICA1-pathlen128.pem chainE-assembled.pem chainE-entity-key.pem chainE-entity.pem chainF-ICA1-key.pem chainF-ICA1-pathlen1.pem chainF-ICA2-key.pem chainF-ICA2-pathlen0.pem chainF-assembled.pem chainF-entity-key.pem chainF-entity.pem chainG-ICA1-key.pem chainG-ICA1-pathlen0.pem chainG-ICA2-key.pem chainG-ICA2-pathlen1.pem chainG-ICA3-key.pem chainG-ICA3-pathlen99.pem chainG-ICA4-key.pem chainG-ICA4-pathlen5.pem chainG-ICA5-key.pem chainG-ICA5-pathlen20.pem chainG-ICA6-key.pem chainG-ICA6-pathlen10.pem chainG-ICA7-key.pem chainG-ICA7-pathlen100.pem chainG-assembled.pem chainG-entity-key.pem chainG-entity.pem chainH-ICA1-key.pem chainH-ICA1-pathlen0.pem chainH-ICA2-key.pem chainH-ICA2-pathlen2.pem chainH-ICA3-key.pem chainH-ICA3-pathlen2.pem chainH-ICA4-key.pem chainH-ICA4-pathlen2.pem chainH-assembled.pem chainH-entity-key.pem chainH-entity.pem chainI-ICA1-key.pem chainI-ICA1-no_pathlen.pem chainI-ICA2-key.pem chainI-ICA2-no_pathlen.pem chainI-ICA3-key.pem chainI-ICA3-pathlen2.pem chainI-assembled.pem chainI-entity-key.pem chainI-entity.pem chainJ-ICA1-key.pem chainJ-ICA1-no_pathlen.pem chainJ-ICA2-key.pem chainJ-ICA2-no_pathlen.pem chainJ-ICA3-key.pem chainJ-ICA3-no_pathlen.pem chainJ-ICA4-key.pem chainJ-ICA4-pathlen2.pem chainJ-assembled.pem chainJ-entity-key.pem chainJ-entity.pem include.am refreshkeys.shtest-serial0
ee_normal.pem ee_serial0.pem generate_certs.sh include.am intermediate_serial0.pem root_serial0.pem root_serial0_key.pem selfsigned_nonca_serial0.pemxmss
bc_xmss_chain_ca.der bc_xmss_chain_leaf.der bc_xmss_sha2_10_256_root.der bc_xmss_sha2_16_256_root.der bc_xmssmt_sha2_20_2_256_root.der bc_xmssmt_sha2_20_4_256_root.der bc_xmssmt_sha2_40_8_256_root.der include.amcmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.indebian
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.indoc
dox_comments
header_files
aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h puf.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wc_she.h wc_slhdsa.h wolfio.hheader_files-ja
aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wolfio.hexamples
async
Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.hconfigs
README.md include.am user_settings_EBSnet.h user_settings_all.h user_settings_arduino.h user_settings_baremetal.h user_settings_ca.h user_settings_curve25519nonblock.h user_settings_dtls13.h user_settings_eccnonblock.h user_settings_espressif.h user_settings_fipsv2.h user_settings_fipsv5.h user_settings_min_ecc.h user_settings_openssl_compat.h user_settings_pkcs7.h user_settings_platformio.h user_settings_pq.h user_settings_rsa_only.h user_settings_stm32.h user_settings_template.h user_settings_tls12.h user_settings_tls13.h user_settings_wolfboot_keytools.h user_settings_wolfssh.h user_settings_wolftpm.hechoclient
echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quitlinuxkm
Kbuild Makefile README.md get_thread_size.c include.am linuxkm-fips-hash-wrapper.sh linuxkm-fips-hash.c linuxkm_memory.c linuxkm_memory.h linuxkm_wc_port.h lkcapi_aes_glue.c lkcapi_dh_glue.c lkcapi_ecdh_glue.c lkcapi_ecdsa_glue.c lkcapi_glue.c lkcapi_rsa_glue.c lkcapi_sha_glue.c module_exports.c.template module_hooks.c pie_redirect_table.c wolfcrypt.lds x86_vector_register_glue.cm4
ax_add_am_macro.m4 ax_am_jobserver.m4 ax_am_macros.m4 ax_append_compile_flags.m4 ax_append_flag.m4 ax_append_link_flags.m4 ax_append_to_file.m4 ax_atomic.m4 ax_bsdkm.m4 ax_check_compile_flag.m4 ax_check_link_flag.m4 ax_compiler_version.m4 ax_count_cpus.m4 ax_create_generic_config.m4 ax_debug.m4 ax_file_escapes.m4 ax_harden_compiler_flags.m4 ax_linuxkm.m4 ax_print_to_file.m4 ax_pthread.m4 ax_require_defined.m4 ax_tls.m4 ax_vcs_checkout.m4 hexversion.m4 lib_socket_nsl.m4 visibility.m4mqx
wolfcrypt_benchmark
ReferencedRSESystems.xml wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchwolfcrypt_test
ReferencedRSESystems.xml wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchwolfssl_client
ReferencedRSESystems.xml wolfssl_client_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchscripts
aria-cmake-build-test.sh asn1_oid_sum.pl benchmark.test benchmark_compare.sh cleanup_testfiles.sh crl-gen-openssl.test crl-revoked.test dertoc.pl dtls.test dtlscid.test external.test google.test include.am makedistsmall.sh memtest.sh ocsp-responder-openssl-interop.test ocsp-stapling-with-ca-as-responder.test ocsp-stapling-with-wolfssl-responder.test ocsp-stapling.test ocsp-stapling2.test ocsp-stapling_tls13multi.test ocsp.test openssl.test openssl_srtp.test pem.test ping.test pkcallbacks.test psk.test resume.test rsapss.test sniffer-gen.sh sniffer-ipv6.pcap sniffer-static-rsa.pcap sniffer-testsuite.test sniffer-tls12-keylog.out sniffer-tls12-keylog.pcap sniffer-tls12-keylog.sslkeylog sniffer-tls13-dh-resume.pcap sniffer-tls13-dh.pcap sniffer-tls13-ecc-resume.pcap sniffer-tls13-ecc.pcap sniffer-tls13-hrr.pcap sniffer-tls13-keylog.out sniffer-tls13-keylog.pcap sniffer-tls13-keylog.sslkeylog sniffer-tls13-x25519-resume.pcap sniffer-tls13-x25519.pcap stm32l4-v4_0_1_build.sh tls13.test trusted_peer.test unit.test.in user_settings_asm.shsrc
bio.c conf.c crl.c dtls.c dtls13.c include.am internal.c keys.c ocsp.c pk.c pk_ec.c pk_rsa.c quic.c sniffer.c ssl.c ssl_api_cert.c ssl_api_crl_ocsp.c ssl_api_pk.c ssl_asn1.c ssl_bn.c ssl_certman.c ssl_crypto.c ssl_ech.c ssl_load.c ssl_misc.c ssl_p7p12.c ssl_sess.c ssl_sk.c tls.c tls13.c wolfio.c x509.c x509_str.ctests
api
api.h api_decl.h create_ocsp_test_blobs.py include.am test_aes.c test_aes.h test_arc4.c test_arc4.h test_ascon.c test_ascon.h test_ascon_kats.h test_asn.c test_asn.h test_blake2.c test_blake2.h test_camellia.c test_camellia.h test_certman.c test_certman.h test_chacha.c test_chacha.h test_chacha20_poly1305.c test_chacha20_poly1305.h test_cmac.c test_cmac.h test_curve25519.c test_curve25519.h test_curve448.c test_curve448.h test_des3.c test_des3.h test_dh.c test_dh.h test_digest.h test_dsa.c test_dsa.h test_dtls.c test_dtls.h test_ecc.c test_ecc.h test_ed25519.c test_ed25519.h test_ed448.c test_ed448.h test_evp.c test_evp.h test_evp_cipher.c test_evp_cipher.h test_evp_digest.c test_evp_digest.h test_evp_pkey.c test_evp_pkey.h test_hash.c test_hash.h test_hmac.c test_hmac.h test_md2.c test_md2.h test_md4.c test_md4.h test_md5.c test_md5.h test_mldsa.c test_mldsa.h test_mlkem.c test_mlkem.h test_ocsp.c test_ocsp.h test_ocsp_test_blobs.h test_ossl_asn1.c test_ossl_asn1.h test_ossl_bio.c test_ossl_bio.h test_ossl_bn.c test_ossl_bn.h test_ossl_cipher.c test_ossl_cipher.h test_ossl_dgst.c test_ossl_dgst.h test_ossl_dh.c test_ossl_dh.h test_ossl_dsa.c test_ossl_dsa.h test_ossl_ec.c test_ossl_ec.h test_ossl_ecx.c test_ossl_ecx.h test_ossl_mac.c test_ossl_mac.h test_ossl_obj.c test_ossl_obj.h test_ossl_p7p12.c test_ossl_p7p12.h test_ossl_pem.c test_ossl_pem.h test_ossl_rand.c test_ossl_rand.h test_ossl_rsa.c test_ossl_rsa.h test_ossl_sk.c test_ossl_sk.h test_ossl_x509.c test_ossl_x509.h test_ossl_x509_acert.c test_ossl_x509_acert.h test_ossl_x509_crypto.c test_ossl_x509_crypto.h test_ossl_x509_ext.c test_ossl_x509_ext.h test_ossl_x509_info.c test_ossl_x509_info.h test_ossl_x509_io.c test_ossl_x509_io.h test_ossl_x509_lu.c test_ossl_x509_lu.h test_ossl_x509_name.c test_ossl_x509_name.h test_ossl_x509_pk.c test_ossl_x509_pk.h test_ossl_x509_str.c test_ossl_x509_str.h test_ossl_x509_vp.c test_ossl_x509_vp.h test_pkcs12.c test_pkcs12.h test_pkcs7.c test_pkcs7.h test_poly1305.c test_poly1305.h test_random.c test_random.h test_rc2.c test_rc2.h test_ripemd.c test_ripemd.h test_rsa.c test_rsa.h test_sha.c test_sha.h test_sha256.c test_sha256.h test_sha3.c test_sha3.h test_sha512.c test_sha512.h test_she.c test_she.h test_signature.c test_signature.h test_slhdsa.c test_slhdsa.h test_sm2.c test_sm2.h test_sm3.c test_sm3.h test_sm4.c test_sm4.h test_tls.c test_tls.h test_tls13.c test_tls13.h test_tls_ext.c test_tls_ext.h test_wc_encrypt.c test_wc_encrypt.h test_wolfmath.c test_wolfmath.h test_x509.c test_x509.hwolfcrypt
benchmark
README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.amsrc
port
Espressif
esp_crt_bundle
README.md cacrt_all.pem cacrt_deprecated.pem cacrt_local.pem esp_crt_bundle.c gen_crt_bundle.py pio_install_cryptography.pyRenesas
README.md renesas_common.c renesas_fspsm_aes.c renesas_fspsm_rsa.c renesas_fspsm_sha.c renesas_fspsm_util.c renesas_rx64_hw_sha.c renesas_rx64_hw_util.c renesas_tsip_aes.c renesas_tsip_rsa.c renesas_tsip_sha.c renesas_tsip_util.carm
armv8-32-aes-asm.S armv8-32-aes-asm_c.c armv8-32-chacha-asm.S armv8-32-chacha-asm_c.c armv8-32-curve25519.S armv8-32-curve25519_c.c armv8-32-mlkem-asm.S armv8-32-mlkem-asm_c.c armv8-32-poly1305-asm.S armv8-32-poly1305-asm_c.c armv8-32-sha256-asm.S armv8-32-sha256-asm_c.c armv8-32-sha3-asm.S armv8-32-sha3-asm_c.c armv8-32-sha512-asm.S armv8-32-sha512-asm_c.c armv8-aes-asm.S armv8-aes-asm_c.c armv8-aes.c armv8-chacha-asm.S armv8-chacha-asm_c.c armv8-curve25519.S armv8-curve25519_c.c armv8-mlkem-asm.S armv8-mlkem-asm_c.c armv8-poly1305-asm.S armv8-poly1305-asm_c.c armv8-sha256-asm.S armv8-sha256-asm_c.c armv8-sha256.c armv8-sha3-asm.S armv8-sha3-asm_c.c armv8-sha512-asm.S armv8-sha512-asm_c.c armv8-sha512.c cryptoCell.c cryptoCellHash.c thumb2-aes-asm.S thumb2-aes-asm_c.c thumb2-chacha-asm.S thumb2-chacha-asm_c.c thumb2-curve25519.S thumb2-curve25519_c.c thumb2-mlkem-asm.S thumb2-mlkem-asm_c.c thumb2-poly1305-asm.S thumb2-poly1305-asm_c.c thumb2-sha256-asm.S thumb2-sha256-asm_c.c thumb2-sha3-asm.S thumb2-sha3-asm_c.c thumb2-sha512-asm.S thumb2-sha512-asm_c.ccaam
README.md caam_aes.c caam_doc.pdf caam_driver.c caam_error.c caam_integrity.c caam_qnx.c caam_sha.c wolfcaam_aes.c wolfcaam_cmac.c wolfcaam_ecdsa.c wolfcaam_fsl_nxp.c wolfcaam_hash.c wolfcaam_hmac.c wolfcaam_init.c wolfcaam_qnx.c wolfcaam_rsa.c wolfcaam_seco.c wolfcaam_x25519.cdevcrypto
README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.criscv
riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.cwolfssl
openssl
aes.h asn1.h asn1t.h bio.h bn.h buffer.h camellia.h cmac.h cms.h compat_types.h conf.h crypto.h des.h dh.h dsa.h ec.h ec25519.h ec448.h ecdh.h ecdsa.h ed25519.h ed448.h engine.h err.h evp.h fips_rand.h hmac.h include.am kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pkcs12.h pkcs7.h rand.h rc4.h ripemd.h rsa.h safestack.h sha.h sha3.h srp.h ssl.h ssl23.h stack.h tls1.h txt_db.h ui.h x509.h x509_vfy.h x509v3.hwolfcrypt
port
Renesas
renesas-fspsm-crypt.h renesas-fspsm-types.h renesas-rx64-hw-crypt.h renesas-tsip-crypt.h renesas_cmn.h renesas_fspsm_internal.h renesas_sync.h renesas_tsip_internal.h renesas_tsip_types.hcaam
caam_driver.h caam_error.h caam_qnx.h wolfcaam.h wolfcaam_aes.h wolfcaam_cmac.h wolfcaam_ecdsa.h wolfcaam_fsl_nxp.h wolfcaam_hash.h wolfcaam_qnx.h wolfcaam_rsa.h wolfcaam_seco.h wolfcaam_sha.h wolfcaam_x25519.hwrapper
Ada
examples
src
aes_verify_main.adb rsa_verify_main.adb sha256_main.adb spark_sockets.adb spark_sockets.ads spark_terminal.adb spark_terminal.ads tls_client.adb tls_client.ads tls_client_main.adb tls_server.adb tls_server.ads tls_server_main.adbtests
src
aes_bindings_tests.adb aes_bindings_tests.ads rsa_verify_bindings_tests.adb rsa_verify_bindings_tests.ads sha256_bindings_tests.adb sha256_bindings_tests.ads tests.adbCSharp
wolfSSL-Example-IOCallbacks
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csprojwolfSSL-TLS-ServerThreaded
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csprojrust
wolfssl-wolfcrypt
src
aes.rs blake2.rs chacha20_poly1305.rs cmac.rs cmac_mac.rs curve25519.rs dh.rs dilithium.rs ecc.rs ecdsa.rs ed25519.rs ed448.rs fips.rs hkdf.rs hmac.rs hmac_mac.rs kdf.rs lib.rs lms.rs mlkem.rs mlkem_kem.rs pbkdf2_password_hash.rs prf.rs random.rs rsa.rs rsa_pkcs1v15.rs sha.rs sha_digest.rs sys.rstests
test_aes.rs test_blake2.rs test_chacha20_poly1305.rs test_cmac.rs test_cmac_mac.rs test_curve25519.rs test_dh.rs test_dilithium.rs test_ecc.rs test_ecdsa.rs test_ed25519.rs test_ed448.rs test_hkdf.rs test_hmac.rs test_hmac_mac.rs test_kdf.rs test_lms.rs test_mlkem.rs test_mlkem_kem.rs test_pbkdf2_password_hash.rs test_prf.rs test_random.rs test_rsa.rs test_rsa_pkcs1v15.rs test_sha.rs test_sha_digest.rs test_wolfcrypt.rszephyr
samples
wolfssl_benchmark
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.confwolfssl_test
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
luajit/src/vm_x86.dasc
raw
1|// Low-level VM code for x86 CPUs.
2|// Bytecode interpreter, fast functions and helper functions.
3|// Copyright (C) 2005-2026 Mike Pall. See Copyright Notice in luajit.h
4|
5|.if P64
6|.arch x64
7|.else
8|.arch x86
9|.endif
10|.section code_op, code_sub
11|
12|.actionlist build_actionlist
13|.globals GLOB_
14|.globalnames globnames
15|.externnames extnames
16|
17|//-----------------------------------------------------------------------
18|
19|.if P64
20|.define X64, 1
21|.if WIN
22|.define X64WIN, 1
23|.endif
24|.endif
25|
26|// Fixed register assignments for the interpreter.
27|// This is very fragile and has many dependencies. Caveat emptor.
28|.define BASE, edx // Not C callee-save, refetched anyway.
29|.if not X64
30|.define KBASE, edi // Must be C callee-save.
31|.define KBASEa, KBASE
32|.define PC, esi // Must be C callee-save.
33|.define PCa, PC
34|.define DISPATCH, ebx // Must be C callee-save.
35|.elif X64WIN
36|.define KBASE, edi // Must be C callee-save.
37|.define KBASEa, rdi
38|.define PC, esi // Must be C callee-save.
39|.define PCa, rsi
40|.define DISPATCH, ebx // Must be C callee-save.
41|.else
42|.define KBASE, r15d // Must be C callee-save.
43|.define KBASEa, r15
44|.define PC, ebx // Must be C callee-save.
45|.define PCa, rbx
46|.define DISPATCH, r14d // Must be C callee-save.
47|.endif
48|
49|.define RA, ecx
50|.define RAH, ch
51|.define RAL, cl
52|.define RB, ebp // Must be ebp (C callee-save).
53|.define RC, eax // Must be eax.
54|.define RCW, ax
55|.define RCH, ah
56|.define RCL, al
57|.define OP, RB
58|.define RD, RC
59|.define RDW, RCW
60|.define RDL, RCL
61|.if X64
62|.define RAa, rcx
63|.define RBa, rbp
64|.define RCa, rax
65|.define RDa, rax
66|.else
67|.define RAa, RA
68|.define RBa, RB
69|.define RCa, RC
70|.define RDa, RD
71|.endif
72|
73|.if not X64
74|.define FCARG1, ecx // x86 fastcall arguments.
75|.define FCARG2, edx
76|.elif X64WIN
77|.define CARG1, rcx // x64/WIN64 C call arguments.
78|.define CARG2, rdx
79|.define CARG3, r8
80|.define CARG4, r9
81|.define CARG1d, ecx
82|.define CARG2d, edx
83|.define CARG3d, r8d
84|.define CARG4d, r9d
85|.define FCARG1, CARG1d // Upwards compatible to x86 fastcall.
86|.define FCARG2, CARG2d
87|.else
88|.define CARG1, rdi // x64/POSIX C call arguments.
89|.define CARG2, rsi
90|.define CARG3, rdx
91|.define CARG4, rcx
92|.define CARG5, r8
93|.define CARG6, r9
94|.define CARG1d, edi
95|.define CARG2d, esi
96|.define CARG3d, edx
97|.define CARG4d, ecx
98|.define CARG5d, r8d
99|.define CARG6d, r9d
100|.define FCARG1, CARG1d // Simulate x86 fastcall.
101|.define FCARG2, CARG2d
102|.endif
103|
104|// Type definitions. Some of these are only used for documentation.
105|.type L, lua_State
106|.type GL, global_State
107|.type TVALUE, TValue
108|.type GCOBJ, GCobj
109|.type STR, GCstr
110|.type TAB, GCtab
111|.type LFUNC, GCfuncL
112|.type CFUNC, GCfuncC
113|.type PROTO, GCproto
114|.type UPVAL, GCupval
115|.type NODE, Node
116|.type NARGS, int
117|.type TRACE, GCtrace
118|.type SBUF, SBuf
119|
120|// Stack layout while in interpreter. Must match with lj_frame.h.
121|//-----------------------------------------------------------------------
122|.if not X64 // x86 stack layout.
123|
124|.if WIN
125|
126|.define CFRAME_SPACE, aword*9 // Delta for esp (see <--).
127|.macro saveregs_
128| push edi; push esi; push ebx
129| push extern lj_err_unwind_win
130| fs; push dword [0]
131| fs; mov [0], esp
132| sub esp, CFRAME_SPACE
133|.endmacro
134|.macro restoreregs
135| add esp, CFRAME_SPACE
136| fs; pop dword [0]
137| pop edi // Short for esp += 4.
138| pop ebx; pop esi; pop edi; pop ebp
139|.endmacro
140|
141|.else
142|
143|.define CFRAME_SPACE, aword*7 // Delta for esp (see <--).
144|.macro saveregs_
145| push edi; push esi; push ebx
146| sub esp, CFRAME_SPACE
147|.endmacro
148|.macro restoreregs
149| add esp, CFRAME_SPACE
150| pop ebx; pop esi; pop edi; pop ebp
151|.endmacro
152|
153|.endif
154|
155|.macro saveregs
156| push ebp; saveregs_
157|.endmacro
158|
159|.if WIN
160|.define SAVE_ERRF, aword [esp+aword*19] // vm_pcall/vm_cpcall only.
161|.define SAVE_NRES, aword [esp+aword*18]
162|.define SAVE_CFRAME, aword [esp+aword*17]
163|.define SAVE_L, aword [esp+aword*16]
164|//----- 16 byte aligned, ^^^ arguments from C caller
165|.define SAVE_RET, aword [esp+aword*15] //<-- esp entering interpreter.
166|.define SAVE_R4, aword [esp+aword*14]
167|.define SAVE_R3, aword [esp+aword*13]
168|.define SAVE_R2, aword [esp+aword*12]
169|//----- 16 byte aligned
170|.define SAVE_R1, aword [esp+aword*11]
171|.define SEH_FUNC, aword [esp+aword*10]
172|.define SEH_NEXT, aword [esp+aword*9] //<-- esp after register saves.
173|.define UNUSED2, aword [esp+aword*8]
174|//----- 16 byte aligned
175|.define UNUSED1, aword [esp+aword*7]
176|.define SAVE_PC, aword [esp+aword*6]
177|.define TMP2, aword [esp+aword*5]
178|.define TMP1, aword [esp+aword*4]
179|//----- 16 byte aligned
180|.define ARG4, aword [esp+aword*3]
181|.define ARG3, aword [esp+aword*2]
182|.define ARG2, aword [esp+aword*1]
183|.define ARG1, aword [esp] //<-- esp while in interpreter.
184|//----- 16 byte aligned, ^^^ arguments for C callee
185|.else
186|.define SAVE_ERRF, aword [esp+aword*15] // vm_pcall/vm_cpcall only.
187|.define SAVE_NRES, aword [esp+aword*14]
188|.define SAVE_CFRAME, aword [esp+aword*13]
189|.define SAVE_L, aword [esp+aword*12]
190|//----- 16 byte aligned, ^^^ arguments from C caller
191|.define SAVE_RET, aword [esp+aword*11] //<-- esp entering interpreter.
192|.define SAVE_R4, aword [esp+aword*10]
193|.define SAVE_R3, aword [esp+aword*9]
194|.define SAVE_R2, aword [esp+aword*8]
195|//----- 16 byte aligned
196|.define SAVE_R1, aword [esp+aword*7] //<-- esp after register saves.
197|.define SAVE_PC, aword [esp+aword*6]
198|.define TMP2, aword [esp+aword*5]
199|.define TMP1, aword [esp+aword*4]
200|//----- 16 byte aligned
201|.define ARG4, aword [esp+aword*3]
202|.define ARG3, aword [esp+aword*2]
203|.define ARG2, aword [esp+aword*1]
204|.define ARG1, aword [esp] //<-- esp while in interpreter.
205|//----- 16 byte aligned, ^^^ arguments for C callee
206|.endif
207|
208|// FPARGx overlaps ARGx and ARG(x+1) on x86.
209|.define FPARG3, qword [esp+qword*1]
210|.define FPARG1, qword [esp]
211|// TMPQ overlaps TMP1/TMP2. ARG5/MULTRES overlap TMP1/TMP2 (and TMPQ).
212|.define TMPQ, qword [esp+aword*4]
213|.define TMP3, ARG4
214|.define ARG5, TMP1
215|.define TMPa, TMP1
216|.define MULTRES, TMP2
217|
218|// Arguments for vm_call and vm_pcall.
219|.define INARG_BASE, SAVE_CFRAME // Overwritten by SAVE_CFRAME!
220|
221|// Arguments for vm_cpcall.
222|.define INARG_CP_CALL, SAVE_ERRF
223|.define INARG_CP_UD, SAVE_NRES
224|.define INARG_CP_FUNC, SAVE_CFRAME
225|
226|//-----------------------------------------------------------------------
227|.elif X64WIN // x64/Windows stack layout
228|
229|.define CFRAME_SPACE, aword*5 // Delta for rsp (see <--).
230|.macro saveregs_
231| push rdi; push rsi; push rbx
232| sub rsp, CFRAME_SPACE
233|.endmacro
234|.macro saveregs
235| push rbp; saveregs_
236|.endmacro
237|.macro restoreregs
238| add rsp, CFRAME_SPACE
239| pop rbx; pop rsi; pop rdi; pop rbp
240|.endmacro
241|
242|.define SAVE_CFRAME, aword [rsp+aword*13]
243|.define SAVE_PC, dword [rsp+dword*25]
244|.define SAVE_L, dword [rsp+dword*24]
245|.define SAVE_ERRF, dword [rsp+dword*23]
246|.define SAVE_NRES, dword [rsp+dword*22]
247|.define TMP2, dword [rsp+dword*21]
248|.define TMP1, dword [rsp+dword*20]
249|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by interpreter
250|.define SAVE_RET, aword [rsp+aword*9] //<-- rsp entering interpreter.
251|.define SAVE_R4, aword [rsp+aword*8]
252|.define SAVE_R3, aword [rsp+aword*7]
253|.define SAVE_R2, aword [rsp+aword*6]
254|.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves.
255|.define ARG5, aword [rsp+aword*4]
256|.define CSAVE_4, aword [rsp+aword*3]
257|.define CSAVE_3, aword [rsp+aword*2]
258|.define CSAVE_2, aword [rsp+aword*1]
259|.define CSAVE_1, aword [rsp] //<-- rsp while in interpreter.
260|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by callee
261|
262|// TMPQ overlaps TMP1/TMP2. MULTRES overlaps TMP2 (and TMPQ).
263|.define TMPQ, qword [rsp+aword*10]
264|.define MULTRES, TMP2
265|.define TMPa, ARG5
266|.define ARG5d, dword [rsp+aword*4]
267|.define TMP3, ARG5d
268|
269|//-----------------------------------------------------------------------
270|.else // x64/POSIX stack layout
271|
272|.define CFRAME_SPACE, aword*5 // Delta for rsp (see <--).
273|.macro saveregs_
274| push rbx; push r15; push r14
275|.if NO_UNWIND
276| push r13; push r12
277|.endif
278| sub rsp, CFRAME_SPACE
279|.endmacro
280|.macro saveregs
281| push rbp; saveregs_
282|.endmacro
283|.macro restoreregs
284| add rsp, CFRAME_SPACE
285|.if NO_UNWIND
286| pop r12; pop r13
287|.endif
288| pop r14; pop r15; pop rbx; pop rbp
289|.endmacro
290|
291|//----- 16 byte aligned,
292|.if NO_UNWIND
293|.define SAVE_RET, aword [rsp+aword*11] //<-- rsp entering interpreter.
294|.define SAVE_R4, aword [rsp+aword*10]
295|.define SAVE_R3, aword [rsp+aword*9]
296|.define SAVE_R2, aword [rsp+aword*8]
297|.define SAVE_R1, aword [rsp+aword*7]
298|.define SAVE_RU2, aword [rsp+aword*6]
299|.define SAVE_RU1, aword [rsp+aword*5] //<-- rsp after register saves.
300|.else
301|.define SAVE_RET, aword [rsp+aword*9] //<-- rsp entering interpreter.
302|.define SAVE_R4, aword [rsp+aword*8]
303|.define SAVE_R3, aword [rsp+aword*7]
304|.define SAVE_R2, aword [rsp+aword*6]
305|.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves.
306|.endif
307|.define SAVE_CFRAME, aword [rsp+aword*4]
308|.define SAVE_PC, dword [rsp+dword*7]
309|.define SAVE_L, dword [rsp+dword*6]
310|.define SAVE_ERRF, dword [rsp+dword*5]
311|.define SAVE_NRES, dword [rsp+dword*4]
312|.define TMPa, aword [rsp+aword*1]
313|.define TMP2, dword [rsp+dword*1]
314|.define TMP1, dword [rsp] //<-- rsp while in interpreter.
315|//----- 16 byte aligned
316|
317|// TMPQ overlaps TMP1/TMP2. MULTRES overlaps TMP2 (and TMPQ).
318|.define TMPQ, qword [rsp]
319|.define TMP3, dword [rsp+aword*1]
320|.define MULTRES, TMP2
321|
322|.endif
323|
324|//-----------------------------------------------------------------------
325|
326|// Instruction headers.
327|.macro ins_A; .endmacro
328|.macro ins_AD; .endmacro
329|.macro ins_AJ; .endmacro
330|.macro ins_ABC; movzx RB, RCH; movzx RC, RCL; .endmacro
331|.macro ins_AB_; movzx RB, RCH; .endmacro
332|.macro ins_A_C; movzx RC, RCL; .endmacro
333|.macro ins_AND; not RDa; .endmacro
334|
335|// Instruction decode+dispatch. Carefully tuned (nope, lodsd is not faster).
336|.macro ins_NEXT
337| mov RC, [PC]
338| movzx RA, RCH
339| movzx OP, RCL
340| add PC, 4
341| shr RC, 16
342|.if X64
343| jmp aword [DISPATCH+OP*8]
344|.else
345| jmp aword [DISPATCH+OP*4]
346|.endif
347|.endmacro
348|
349|// Instruction footer.
350|.if 1
351| // Replicated dispatch. Less unpredictable branches, but higher I-Cache use.
352| .define ins_next, ins_NEXT
353| .define ins_next_, ins_NEXT
354|.else
355| // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch.
356| // Affects only certain kinds of benchmarks (and only with -j off).
357| // Around 10%-30% slower on Core2, a lot more slower on P4.
358| .macro ins_next
359| jmp ->ins_next
360| .endmacro
361| .macro ins_next_
362| ->ins_next:
363| ins_NEXT
364| .endmacro
365|.endif
366|
367|// Call decode and dispatch.
368|.macro ins_callt
369| // BASE = new base, RB = LFUNC, RD = nargs+1, [BASE-4] = PC
370| mov PC, LFUNC:RB->pc
371| mov RA, [PC]
372| movzx OP, RAL
373| movzx RA, RAH
374| add PC, 4
375|.if X64
376| jmp aword [DISPATCH+OP*8]
377|.else
378| jmp aword [DISPATCH+OP*4]
379|.endif
380|.endmacro
381|
382|.macro ins_call
383| // BASE = new base, RB = LFUNC, RD = nargs+1
384| mov [BASE-4], PC
385| ins_callt
386|.endmacro
387|
388|//-----------------------------------------------------------------------
389|
390|// Macros to test operand types.
391|.macro checktp, reg, tp; cmp dword [BASE+reg*8+4], tp; .endmacro
392|.macro checknum, reg, target; checktp reg, LJ_TISNUM; jae target; .endmacro
393|.macro checkint, reg, target; checktp reg, LJ_TISNUM; jne target; .endmacro
394|.macro checkstr, reg, target; checktp reg, LJ_TSTR; jne target; .endmacro
395|.macro checktab, reg, target; checktp reg, LJ_TTAB; jne target; .endmacro
396|
397|// These operands must be used with movzx.
398|.define PC_OP, byte [PC-4]
399|.define PC_RA, byte [PC-3]
400|.define PC_RB, byte [PC-1]
401|.define PC_RC, byte [PC-2]
402|.define PC_RD, word [PC-2]
403|
404|.macro branchPC, reg
405| lea PC, [PC+reg*4-BCBIAS_J*4]
406|.endmacro
407|
408|// Assumes DISPATCH is relative to GL.
409#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
410#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
411|
412#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
413|
414|// Decrement hashed hotcount and trigger trace recorder if zero.
415|.macro hotloop, reg
416| mov reg, PC
417| shr reg, 1
418| and reg, HOTCOUNT_PCMASK
419| sub word [DISPATCH+reg+GG_DISP2HOT], HOTCOUNT_LOOP
420| jb ->vm_hotloop
421|.endmacro
422|
423|.macro hotcall, reg
424| mov reg, PC
425| shr reg, 1
426| and reg, HOTCOUNT_PCMASK
427| sub word [DISPATCH+reg+GG_DISP2HOT], HOTCOUNT_CALL
428| jb ->vm_hotcall
429|.endmacro
430|
431|// Set current VM state.
432|.macro set_vmstate, st
433| mov dword [DISPATCH+DISPATCH_GL(vmstate)], ~LJ_VMST_..st
434|.endmacro
435|
436|// x87 compares.
437|.macro fcomparepp // Compare and pop st0 >< st1.
438| fucomip st1
439| fpop
440|.endmacro
441|
442|.macro fpop1; fstp st1; .endmacro
443|
444|// Synthesize SSE FP constants.
445|.macro sseconst_abs, reg, tmp // Synthesize abs mask.
446|.if X64
447| mov64 tmp, U64x(7fffffff,ffffffff); movd reg, tmp
448|.else
449| pxor reg, reg; pcmpeqd reg, reg; psrlq reg, 1
450|.endif
451|.endmacro
452|
453|.macro sseconst_hi, reg, tmp, val // Synthesize hi-32 bit const.
454|.if X64
455| mov64 tmp, U64x(val,00000000); movd reg, tmp
456|.else
457| mov tmp, 0x .. val; movd reg, tmp; pshufd reg, reg, 0x51
458|.endif
459|.endmacro
460|
461|.macro sseconst_sign, reg, tmp // Synthesize sign mask.
462| sseconst_hi reg, tmp, 80000000
463|.endmacro
464|.macro sseconst_1, reg, tmp // Synthesize 1.0.
465| sseconst_hi reg, tmp, 3ff00000
466|.endmacro
467|.macro sseconst_2p52, reg, tmp // Synthesize 2^52.
468| sseconst_hi reg, tmp, 43300000
469|.endmacro
470|.macro sseconst_tobit, reg, tmp // Synthesize 2^52 + 2^51.
471| sseconst_hi reg, tmp, 43380000
472|.endmacro
473|
474|// Move table write barrier back. Overwrites reg.
475|.macro barrierback, tab, reg
476| and byte tab->marked, (uint8_t)~LJ_GC_BLACK // black2gray(tab)
477| mov reg, [DISPATCH+DISPATCH_GL(gc.grayagain)]
478| mov [DISPATCH+DISPATCH_GL(gc.grayagain)], tab
479| mov tab->gclist, reg
480|.endmacro
481|
482|//-----------------------------------------------------------------------
483
484/* Generate subroutines used by opcodes and other parts of the VM. */
485/* The .code_sub section should be last to help static branch prediction. */
486static void build_subroutines(BuildCtx *ctx)
487{
488 |.code_sub
489 |
490 |//-----------------------------------------------------------------------
491 |//-- Return handling ----------------------------------------------------
492 |//-----------------------------------------------------------------------
493 |
494 |->vm_returnp:
495 | test PC, FRAME_P
496 | jz ->cont_dispatch
497 |
498 | // Return from pcall or xpcall fast func.
499 | and PC, -8
500 | sub BASE, PC // Restore caller base.
501 | lea RAa, [RA+PC-8] // Rebase RA and prepend one result.
502 | mov PC, [BASE-4] // Fetch PC of previous frame.
503 | // Prepending may overwrite the pcall frame, so do it at the end.
504 | mov dword [BASE+RA+4], LJ_TTRUE // Prepend true to results.
505 |
506 |->vm_returnc:
507 | add RD, 1 // RD = nresults+1
508 | jz ->vm_unwind_yield
509 | mov MULTRES, RD
510 | test PC, FRAME_TYPE
511 | jz ->BC_RET_Z // Handle regular return to Lua.
512 |
513 |->vm_return:
514 | // BASE = base, RA = resultofs, RD = nresults+1 (= MULTRES), PC = return
515 | xor PC, FRAME_C
516 | test PC, FRAME_TYPE
517 | jnz ->vm_returnp
518 |
519 | // Return to C.
520 | set_vmstate C
521 | and PC, -8
522 | sub PC, BASE
523 | neg PC // Previous base = BASE - delta.
524 |
525 | sub RD, 1
526 | jz >2
527 |1: // Move results down.
528 |.if X64
529 | mov RBa, [BASE+RA]
530 | mov [BASE-8], RBa
531 |.else
532 | mov RB, [BASE+RA]
533 | mov [BASE-8], RB
534 | mov RB, [BASE+RA+4]
535 | mov [BASE-4], RB
536 |.endif
537 | add BASE, 8
538 | sub RD, 1
539 | jnz <1
540 |2:
541 | mov L:RB, SAVE_L
542 | mov L:RB->base, PC
543 |3:
544 | mov RD, MULTRES
545 | mov RA, SAVE_NRES // RA = wanted nresults+1
546 |4:
547 | cmp RA, RD
548 | jne >6 // More/less results wanted?
549 |5:
550 | sub BASE, 8
551 | mov L:RB->top, BASE
552 |
553 |->vm_leave_cp:
554 | mov RAa, SAVE_CFRAME // Restore previous C frame.
555 | mov L:RB->cframe, RAa
556 | xor eax, eax // Ok return status for vm_pcall.
557 |
558 |->vm_leave_unw:
559 | restoreregs
560 | ret
561 |
562 |6:
563 | jb >7 // Less results wanted?
564 | // More results wanted. Check stack size and fill up results with nil.
565 | cmp BASE, L:RB->maxstack
566 | ja >8
567 | mov dword [BASE-4], LJ_TNIL
568 | add BASE, 8
569 | add RD, 1
570 | jmp <4
571 |
572 |7: // Less results wanted.
573 | test RA, RA
574 | jz <5 // But check for LUA_MULTRET+1.
575 | sub RA, RD // Negative result!
576 | lea BASE, [BASE+RA*8] // Correct top.
577 | jmp <5
578 |
579 |8: // Corner case: need to grow stack for filling up results.
580 | // This can happen if:
581 | // - A C function grows the stack (a lot).
582 | // - The GC shrinks the stack in between.
583 | // - A return back from a lua_call() with (high) nresults adjustment.
584 | mov L:RB->top, BASE // Save current top held in BASE (yes).
585 | mov MULTRES, RD // Need to fill only remainder with nil.
586 | mov FCARG2, RA
587 | mov FCARG1, L:RB
588 | call extern lj_state_growstack@8 // (lua_State *L, int n)
589 | mov BASE, L:RB->top // Need the (realloced) L->top in BASE.
590 | jmp <3
591 |
592 |->vm_unwind_yield:
593 | mov al, LUA_YIELD
594 | jmp ->vm_unwind_c_eh
595 |
596 |->vm_unwind_c@8: // Unwind C stack, return from vm_pcall.
597 | // (void *cframe, int errcode)
598 |.if X64
599 | mov eax, CARG2d // Error return status for vm_pcall.
600 | mov rsp, CARG1
601 |.else
602 | mov eax, FCARG2 // Error return status for vm_pcall.
603 | mov esp, FCARG1
604 |.if WIN
605 | lea FCARG1, SEH_NEXT
606 | fs; mov [0], FCARG1
607 |.endif
608 |.endif
609 |->vm_unwind_c_eh: // Landing pad for external unwinder.
610 | mov L:RB, SAVE_L
611 | mov GL:RB, L:RB->glref
612 | mov dword GL:RB->vmstate, ~LJ_VMST_C
613 | jmp ->vm_leave_unw
614 |
615 |->vm_unwind_rethrow:
616 |.if X64 and not X64WIN
617 | mov FCARG1, SAVE_L
618 | mov FCARG2, eax
619 | restoreregs
620 | jmp extern lj_err_throw@8 // (lua_State *L, int errcode)
621 |.endif
622 |
623 |->vm_unwind_ff@4: // Unwind C stack, return from ff pcall.
624 | // (void *cframe)
625 |.if X64
626 | and CARG1, CFRAME_RAWMASK
627 | mov rsp, CARG1
628 |.else
629 | and FCARG1, CFRAME_RAWMASK
630 | mov esp, FCARG1
631 |.if WIN
632 | lea FCARG1, SEH_NEXT
633 | fs; mov [0], FCARG1
634 |.endif
635 |.endif
636 |->vm_unwind_ff_eh: // Landing pad for external unwinder.
637 | mov L:RB, SAVE_L
638 | mov RAa, -8 // Results start at BASE+RA = BASE-8.
639 | mov RD, 1+1 // Really 1+2 results, incr. later.
640 | mov BASE, L:RB->base
641 | mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
642 | add DISPATCH, GG_G2DISP
643 | mov PC, [BASE-4] // Fetch PC of previous frame.
644 | mov dword [BASE-4], LJ_TFALSE // Prepend false to error message.
645 | set_vmstate INTERP
646 | jmp ->vm_returnc // Increments RD/MULTRES and returns.
647 |
648 |.if WIN and not X64
649 |->vm_rtlunwind@16: // Thin layer around RtlUnwind.
650 | // (void *cframe, void *excptrec, void *unwinder, int errcode)
651 | mov [esp], FCARG1 // Return value for RtlUnwind.
652 | push FCARG2 // Exception record for RtlUnwind.
653 | push 0 // Ignored by RtlUnwind.
654 | push dword [FCARG1+CFRAME_OFS_SEH]
655 | call extern RtlUnwind@16 // Violates ABI (clobbers too much).
656 | mov FCARG1, eax
657 | mov FCARG2, [esp+4] // errcode (for vm_unwind_c).
658 | ret // Jump to unwinder.
659 |.endif
660 |
661 |//-----------------------------------------------------------------------
662 |//-- Grow stack for calls -----------------------------------------------
663 |//-----------------------------------------------------------------------
664 |
665 |->vm_growstack_c: // Grow stack for C function.
666 | mov FCARG2, LUA_MINSTACK
667 | jmp >2
668 |
669 |->vm_growstack_v: // Grow stack for vararg Lua function.
670 | sub RD, 8
671 | jmp >1
672 |
673 |->vm_growstack_f: // Grow stack for fixarg Lua function.
674 | // BASE = new base, RD = nargs+1, RB = L, PC = first PC
675 | lea RD, [BASE+NARGS:RD*8-8]
676 |1:
677 | movzx RA, byte [PC-4+PC2PROTO(framesize)]
678 | add PC, 4 // Must point after first instruction.
679 | mov L:RB->base, BASE
680 | mov L:RB->top, RD
681 | mov SAVE_PC, PC
682 | mov FCARG2, RA
683 |2:
684 | // RB = L, L->base = new base, L->top = top
685 | mov FCARG1, L:RB
686 | call extern lj_state_growstack@8 // (lua_State *L, int n)
687 | mov BASE, L:RB->base
688 | mov RD, L:RB->top
689 | mov LFUNC:RB, [BASE-8]
690 | sub RD, BASE
691 | shr RD, 3
692 | add NARGS:RD, 1
693 | // BASE = new base, RB = LFUNC, RD = nargs+1
694 | ins_callt // Just retry the call.
695 |
696 |//-----------------------------------------------------------------------
697 |//-- Entry points into the assembler VM ---------------------------------
698 |//-----------------------------------------------------------------------
699 |
700 |->vm_resume: // Setup C frame and resume thread.
701 | // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0)
702 | saveregs
703 |.if X64
704 | mov L:RB, CARG1d // Caveat: CARG1d may be RA.
705 | mov SAVE_L, CARG1d
706 | mov RA, CARG2d
707 |.else
708 | mov L:RB, SAVE_L
709 | mov RA, INARG_BASE // Caveat: overlaps SAVE_CFRAME!
710 |.endif
711 | mov PC, FRAME_CP
712 | xor RD, RD
713 | lea KBASEa, [esp+CFRAME_RESUME]
714 | mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
715 | add DISPATCH, GG_G2DISP
716 | mov SAVE_PC, RD // Any value outside of bytecode is ok.
717 | mov SAVE_CFRAME, RDa
718 |.if X64
719 | mov SAVE_NRES, RD
720 | mov SAVE_ERRF, RD
721 |.endif
722 | mov L:RB->cframe, KBASEa
723 | cmp byte L:RB->status, RDL
724 | je >2 // Initial resume (like a call).
725 |
726 | // Resume after yield (like a return).
727 | mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
728 | set_vmstate INTERP
729 | mov byte L:RB->status, RDL
730 | mov BASE, L:RB->base
731 | mov RD, L:RB->top
732 | sub RD, RA
733 | shr RD, 3
734 | add RD, 1 // RD = nresults+1
735 | sub RA, BASE // RA = resultofs
736 | mov PC, [BASE-4]
737 | mov MULTRES, RD
738 | test PC, FRAME_TYPE
739 | jz ->BC_RET_Z
740 | jmp ->vm_return
741 |
742 |->vm_pcall: // Setup protected C frame and enter VM.
743 | // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef)
744 | saveregs
745 | mov PC, FRAME_CP
746 |.if X64
747 | mov SAVE_ERRF, CARG4d
748 |.endif
749 | jmp >1
750 |
751 |->vm_call: // Setup C frame and enter VM.
752 | // (lua_State *L, TValue *base, int nres1)
753 | saveregs
754 | mov PC, FRAME_C
755 |
756 |1: // Entry point for vm_pcall above (PC = ftype).
757 |.if X64
758 | mov SAVE_NRES, CARG3d
759 | mov L:RB, CARG1d // Caveat: CARG1d may be RA.
760 | mov SAVE_L, CARG1d
761 | mov RA, CARG2d
762 |.else
763 | mov L:RB, SAVE_L
764 | mov RA, INARG_BASE // Caveat: overlaps SAVE_CFRAME!
765 |.endif
766 |
767 | mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
768 | mov KBASEa, L:RB->cframe // Add our C frame to cframe chain.
769 | mov SAVE_CFRAME, KBASEa
770 | mov SAVE_PC, L:RB // Any value outside of bytecode is ok.
771 | add DISPATCH, GG_G2DISP
772 |.if X64
773 | mov L:RB->cframe, rsp
774 |.else
775 | mov L:RB->cframe, esp
776 |.endif
777 |
778 |2: // Entry point for vm_resume/vm_cpcall (RA = base, RB = L, PC = ftype).
779 | mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
780 | set_vmstate INTERP
781 | mov BASE, L:RB->base // BASE = old base (used in vmeta_call).
782 | add PC, RA
783 | sub PC, BASE // PC = frame delta + frame type
784 |
785 | mov RD, L:RB->top
786 | sub RD, RA
787 | shr NARGS:RD, 3
788 | add NARGS:RD, 1 // RD = nargs+1
789 |
790 |->vm_call_dispatch:
791 | mov LFUNC:RB, [RA-8]
792 | cmp dword [RA-4], LJ_TFUNC
793 | jne ->vmeta_call // Ensure KBASE defined and != BASE.
794 |
795 |->vm_call_dispatch_f:
796 | mov BASE, RA
797 | ins_call
798 | // BASE = new base, RB = func, RD = nargs+1, PC = caller PC
799 |
800 |->vm_cpcall: // Setup protected C frame, call C.
801 | // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp)
802 | saveregs
803 |.if X64
804 | mov L:RB, CARG1d // Caveat: CARG1d may be RA.
805 | mov SAVE_L, CARG1d
806 |.else
807 | mov L:RB, SAVE_L
808 | // Caveat: INARG_CP_* and SAVE_CFRAME/SAVE_NRES/SAVE_ERRF overlap!
809 | mov RC, INARG_CP_UD // Get args before they are overwritten.
810 | mov RA, INARG_CP_FUNC
811 | mov BASE, INARG_CP_CALL
812 |.endif
813 | mov SAVE_PC, L:RB // Any value outside of bytecode is ok.
814 |
815 | mov KBASE, L:RB->stack // Compute -savestack(L, L->top).
816 | sub KBASE, L:RB->top
817 | mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
818 | mov SAVE_ERRF, 0 // No error function.
819 | mov SAVE_NRES, KBASE // Neg. delta means cframe w/o frame.
820 | add DISPATCH, GG_G2DISP
821 | // Handler may change cframe_nres(L->cframe) or cframe_errfunc(L->cframe).
822 |
823 |.if X64
824 | mov KBASEa, L:RB->cframe // Add our C frame to cframe chain.
825 | mov SAVE_CFRAME, KBASEa
826 | mov L:RB->cframe, rsp
827 | mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
828 |
829 | call CARG4 // (lua_State *L, lua_CFunction func, void *ud)
830 |.else
831 | mov ARG3, RC // Have to copy args downwards.
832 | mov ARG2, RA
833 | mov ARG1, L:RB
834 |
835 | mov KBASE, L:RB->cframe // Add our C frame to cframe chain.
836 | mov SAVE_CFRAME, KBASE
837 | mov L:RB->cframe, esp
838 | mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
839 |
840 | call BASE // (lua_State *L, lua_CFunction func, void *ud)
841 |.endif
842 | // TValue * (new base) or NULL returned in eax (RC).
843 | test RC, RC
844 | jz ->vm_leave_cp // No base? Just remove C frame.
845 | mov RA, RC
846 | mov PC, FRAME_CP
847 | jmp <2 // Else continue with the call.
848 |
849 |//-----------------------------------------------------------------------
850 |//-- Metamethod handling ------------------------------------------------
851 |//-----------------------------------------------------------------------
852 |
853 |//-- Continuation dispatch ----------------------------------------------
854 |
855 |->cont_dispatch:
856 | // BASE = meta base, RA = resultofs, RD = nresults+1 (also in MULTRES)
857 | add RA, BASE
858 | and PC, -8
859 | mov RB, BASE
860 | sub BASE, PC // Restore caller BASE.
861 | mov dword [RA+RD*8-4], LJ_TNIL // Ensure one valid arg.
862 | mov RC, RA // ... in [RC]
863 | mov PC, [RB-12] // Restore PC from [cont|PC].
864 |.if X64
865 | movsxd RAa, dword [RB-16] // May be negative on WIN64 with debug.
866 |.if FFI
867 | cmp RA, 1
868 | jbe >1
869 |.endif
870 | lea KBASEa, qword [=>0]
871 | add RAa, KBASEa
872 |.else
873 | mov RA, dword [RB-16]
874 |.if FFI
875 | cmp RA, 1
876 | jbe >1
877 |.endif
878 |.endif
879 | mov LFUNC:KBASE, [BASE-8]
880 | mov KBASE, LFUNC:KBASE->pc
881 | mov KBASE, [KBASE+PC2PROTO(k)]
882 | // BASE = base, RC = result, RB = meta base
883 | jmp RAa // Jump to continuation.
884 |
885 |.if FFI
886 |1:
887 | je ->cont_ffi_callback // cont = 1: return from FFI callback.
888 | // cont = 0: Tail call from C function.
889 | sub RB, BASE
890 | shr RB, 3
891 | lea RD, [RB-1]
892 | jmp ->vm_call_tail
893 |.endif
894 |
895 |->cont_cat: // BASE = base, RC = result, RB = mbase
896 | movzx RA, PC_RB
897 | sub RB, 16
898 | lea RA, [BASE+RA*8]
899 | sub RA, RB
900 | je ->cont_ra
901 | neg RA
902 | shr RA, 3
903 |.if X64WIN
904 | mov CARG3d, RA
905 | mov L:CARG1d, SAVE_L
906 | mov L:CARG1d->base, BASE
907 | mov RCa, [RC]
908 | mov [RB], RCa
909 | mov CARG2d, RB
910 |.elif X64
911 | mov L:CARG1d, SAVE_L
912 | mov L:CARG1d->base, BASE
913 | mov CARG3d, RA
914 | mov RAa, [RC]
915 | mov [RB], RAa
916 | mov CARG2d, RB
917 |.else
918 | mov ARG3, RA
919 | mov RA, [RC+4]
920 | mov RC, [RC]
921 | mov [RB+4], RA
922 | mov [RB], RC
923 | mov ARG2, RB
924 |.endif
925 | jmp ->BC_CAT_Z
926 |
927 |//-- Table indexing metamethods -----------------------------------------
928 |
929 |->vmeta_tgets:
930 | mov TMP1, RC // RC = GCstr *
931 | mov TMP2, LJ_TSTR
932 | lea RCa, TMP1 // Store temp. TValue in TMP1/TMP2.
933 | cmp PC_OP, BC_GGET
934 | jne >1
935 | lea RA, [DISPATCH+DISPATCH_GL(tmptv)] // Store fn->l.env in g->tmptv.
936 | mov [RA], TAB:RB // RB = GCtab *
937 | mov dword [RA+4], LJ_TTAB
938 | mov RB, RA
939 | jmp >2
940 |
941 |->vmeta_tgetb:
942 | movzx RC, PC_RC
943 |.if DUALNUM
944 | mov TMP2, LJ_TISNUM
945 | mov TMP1, RC
946 |.else
947 | cvtsi2sd xmm0, RC
948 | movsd TMPQ, xmm0
949 |.endif
950 | lea RCa, TMPQ // Store temp. TValue in TMPQ.
951 | jmp >1
952 |
953 |->vmeta_tgetv:
954 | movzx RC, PC_RC // Reload TValue *k from RC.
955 | lea RC, [BASE+RC*8]
956 |1:
957 | movzx RB, PC_RB // Reload TValue *t from RB.
958 | lea RB, [BASE+RB*8]
959 |2:
960 |.if X64
961 | mov L:CARG1d, SAVE_L
962 | mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
963 | mov CARG2d, RB
964 | mov CARG3, RCa // May be 64 bit ptr to stack.
965 | mov L:RB, L:CARG1d
966 |.else
967 | mov ARG2, RB
968 | mov L:RB, SAVE_L
969 | mov ARG3, RC
970 | mov ARG1, L:RB
971 | mov L:RB->base, BASE
972 |.endif
973 | mov SAVE_PC, PC
974 | call extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k)
975 | // TValue * (finished) or NULL (metamethod) returned in eax (RC).
976 | mov BASE, L:RB->base
977 | test RC, RC
978 | jz >3
979 |->cont_ra: // BASE = base, RC = result
980 | movzx RA, PC_RA
981 |.if X64
982 | mov RBa, [RC]
983 | mov [BASE+RA*8], RBa
984 |.else
985 | mov RB, [RC+4]
986 | mov RC, [RC]
987 | mov [BASE+RA*8+4], RB
988 | mov [BASE+RA*8], RC
989 |.endif
990 | ins_next
991 |
992 |3: // Call __index metamethod.
993 | // BASE = base, L->top = new base, stack = cont/func/t/k
994 | mov RA, L:RB->top
995 | mov [RA-12], PC // [cont|PC]
996 | lea PC, [RA+FRAME_CONT]
997 | sub PC, BASE
998 | mov LFUNC:RB, [RA-8] // Guaranteed to be a function here.
999 | mov NARGS:RD, 2+1 // 2 args for func(t, k).
1000 | jmp ->vm_call_dispatch_f
1001 |
1002 |->vmeta_tgetr:
1003 | mov FCARG1, TAB:RB
1004 | mov RB, BASE // Save BASE.
1005 | mov FCARG2, RC // Caveat: FCARG2 == BASE
1006 | call extern lj_tab_getinth@8 // (GCtab *t, int32_t key)
1007 | // cTValue * or NULL returned in eax (RC).
1008 | movzx RA, PC_RA
1009 | mov BASE, RB // Restore BASE.
1010 | test RC, RC
1011 | jnz ->BC_TGETR_Z
1012 | mov dword [BASE+RA*8+4], LJ_TNIL
1013 | jmp ->BC_TGETR2_Z
1014 |
1015 |//-----------------------------------------------------------------------
1016 |
1017 |->vmeta_tsets:
1018 | mov TMP1, RC // RC = GCstr *
1019 | mov TMP2, LJ_TSTR
1020 | lea RCa, TMP1 // Store temp. TValue in TMP1/TMP2.
1021 | cmp PC_OP, BC_GSET
1022 | jne >1
1023 | lea RA, [DISPATCH+DISPATCH_GL(tmptv)] // Store fn->l.env in g->tmptv.
1024 | mov [RA], TAB:RB // RB = GCtab *
1025 | mov dword [RA+4], LJ_TTAB
1026 | mov RB, RA
1027 | jmp >2
1028 |
1029 |->vmeta_tsetb:
1030 | movzx RC, PC_RC
1031 |.if DUALNUM
1032 | mov TMP2, LJ_TISNUM
1033 | mov TMP1, RC
1034 |.else
1035 | cvtsi2sd xmm0, RC
1036 | movsd TMPQ, xmm0
1037 |.endif
1038 | lea RCa, TMPQ // Store temp. TValue in TMPQ.
1039 | jmp >1
1040 |
1041 |->vmeta_tsetv:
1042 | movzx RC, PC_RC // Reload TValue *k from RC.
1043 | lea RC, [BASE+RC*8]
1044 |1:
1045 | movzx RB, PC_RB // Reload TValue *t from RB.
1046 | lea RB, [BASE+RB*8]
1047 |2:
1048 |.if X64
1049 | mov L:CARG1d, SAVE_L
1050 | mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
1051 | mov CARG2d, RB
1052 | mov CARG3, RCa // May be 64 bit ptr to stack.
1053 | mov L:RB, L:CARG1d
1054 |.else
1055 | mov ARG2, RB
1056 | mov L:RB, SAVE_L
1057 | mov ARG3, RC
1058 | mov ARG1, L:RB
1059 | mov L:RB->base, BASE
1060 |.endif
1061 | mov SAVE_PC, PC
1062 | call extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k)
1063 | // TValue * (finished) or NULL (metamethod) returned in eax (RC).
1064 | mov BASE, L:RB->base
1065 | test RC, RC
1066 | jz >3
1067 | // NOBARRIER: lj_meta_tset ensures the table is not black.
1068 | movzx RA, PC_RA
1069 |.if X64
1070 | mov RBa, [BASE+RA*8]
1071 | mov [RC], RBa
1072 |.else
1073 | mov RB, [BASE+RA*8+4]
1074 | mov RA, [BASE+RA*8]
1075 | mov [RC+4], RB
1076 | mov [RC], RA
1077 |.endif
1078 |->cont_nop: // BASE = base, (RC = result)
1079 | ins_next
1080 |
1081 |3: // Call __newindex metamethod.
1082 | // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
1083 | mov RA, L:RB->top
1084 | mov [RA-12], PC // [cont|PC]
1085 | movzx RC, PC_RA
1086 | // Copy value to third argument.
1087 |.if X64
1088 | mov RBa, [BASE+RC*8]
1089 | mov [RA+16], RBa
1090 |.else
1091 | mov RB, [BASE+RC*8+4]
1092 | mov RC, [BASE+RC*8]
1093 | mov [RA+20], RB
1094 | mov [RA+16], RC
1095 |.endif
1096 | lea PC, [RA+FRAME_CONT]
1097 | sub PC, BASE
1098 | mov LFUNC:RB, [RA-8] // Guaranteed to be a function here.
1099 | mov NARGS:RD, 3+1 // 3 args for func(t, k, v).
1100 | jmp ->vm_call_dispatch_f
1101 |
1102 |->vmeta_tsetr:
1103 |.if X64WIN
1104 | mov L:CARG1d, SAVE_L
1105 | mov CARG3d, RC
1106 | mov L:CARG1d->base, BASE
1107 | xchg CARG2d, TAB:RB // Caveat: CARG2d == BASE.
1108 |.elif X64
1109 | mov L:CARG1d, SAVE_L
1110 | mov CARG2d, TAB:RB
1111 | mov L:CARG1d->base, BASE
1112 | mov RB, BASE // Save BASE.
1113 | mov CARG3d, RC // Caveat: CARG3d == BASE.
1114 |.else
1115 | mov L:RA, SAVE_L
1116 | mov ARG2, TAB:RB
1117 | mov RB, BASE // Save BASE.
1118 | mov ARG3, RC
1119 | mov ARG1, L:RA
1120 | mov L:RA->base, BASE
1121 |.endif
1122 | mov SAVE_PC, PC
1123 | call extern lj_tab_setinth // (lua_State *L, GCtab *t, int32_t key)
1124 | // TValue * returned in eax (RC).
1125 | movzx RA, PC_RA
1126 | mov BASE, RB // Restore BASE.
1127 | jmp ->BC_TSETR_Z
1128 |
1129 |//-- Comparison metamethods ---------------------------------------------
1130 |
1131 |->vmeta_comp:
1132 |.if X64
1133 | mov L:RB, SAVE_L
1134 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d == BASE.
1135 |.if X64WIN
1136 | lea CARG3d, [BASE+RD*8]
1137 | lea CARG2d, [BASE+RA*8]
1138 |.else
1139 | lea CARG2d, [BASE+RA*8]
1140 | lea CARG3d, [BASE+RD*8]
1141 |.endif
1142 | mov CARG1d, L:RB // Caveat: CARG1d/CARG4d == RA.
1143 | movzx CARG4d, PC_OP
1144 |.else
1145 | movzx RB, PC_OP
1146 | lea RD, [BASE+RD*8]
1147 | lea RA, [BASE+RA*8]
1148 | mov ARG4, RB
1149 | mov L:RB, SAVE_L
1150 | mov ARG3, RD
1151 | mov ARG2, RA
1152 | mov ARG1, L:RB
1153 | mov L:RB->base, BASE
1154 |.endif
1155 | mov SAVE_PC, PC
1156 | call extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
1157 | // 0/1 or TValue * (metamethod) returned in eax (RC).
1158 |3:
1159 | mov BASE, L:RB->base
1160 | cmp RC, 1
1161 | ja ->vmeta_binop
1162 |4:
1163 | lea PC, [PC+4]
1164 | jb >6
1165 |5:
1166 | movzx RD, PC_RD
1167 | branchPC RD
1168 |6:
1169 | ins_next
1170 |
1171 |->cont_condt: // BASE = base, RC = result
1172 | add PC, 4
1173 | cmp dword [RC+4], LJ_TISTRUECOND // Branch if result is true.
1174 | jb <5
1175 | jmp <6
1176 |
1177 |->cont_condf: // BASE = base, RC = result
1178 | cmp dword [RC+4], LJ_TISTRUECOND // Branch if result is false.
1179 | jmp <4
1180 |
1181 |->vmeta_equal:
1182 | sub PC, 4
1183 |.if X64WIN
1184 | mov CARG3d, RD
1185 | mov CARG4d, RB
1186 | mov L:RB, SAVE_L
1187 | mov L:RB->base, BASE // Caveat: CARG2d == BASE.
1188 | mov CARG2d, RA
1189 | mov CARG1d, L:RB // Caveat: CARG1d == RA.
1190 |.elif X64
1191 | mov CARG2d, RA
1192 | mov CARG4d, RB // Caveat: CARG4d == RA.
1193 | mov L:RB, SAVE_L
1194 | mov L:RB->base, BASE // Caveat: CARG3d == BASE.
1195 | mov CARG3d, RD
1196 | mov CARG1d, L:RB
1197 |.else
1198 | mov ARG4, RB
1199 | mov L:RB, SAVE_L
1200 | mov ARG3, RD
1201 | mov ARG2, RA
1202 | mov ARG1, L:RB
1203 | mov L:RB->base, BASE
1204 |.endif
1205 | mov SAVE_PC, PC
1206 | call extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
1207 | // 0/1 or TValue * (metamethod) returned in eax (RC).
1208 | jmp <3
1209 |
1210 |->vmeta_equal_cd:
1211 |.if FFI
1212 | sub PC, 4
1213 | mov L:RB, SAVE_L
1214 | mov L:RB->base, BASE
1215 | mov FCARG1, L:RB
1216 | mov FCARG2, dword [PC-4]
1217 | mov SAVE_PC, PC
1218 | call extern lj_meta_equal_cd@8 // (lua_State *L, BCIns ins)
1219 | // 0/1 or TValue * (metamethod) returned in eax (RC).
1220 | jmp <3
1221 |.endif
1222 |
1223 |->vmeta_istype:
1224 |.if X64
1225 | mov L:RB, SAVE_L
1226 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
1227 | mov CARG2d, RA
1228 | movzx CARG3d, PC_RD
1229 | mov L:CARG1d, L:RB
1230 |.else
1231 | movzx RD, PC_RD
1232 | mov ARG2, RA
1233 | mov L:RB, SAVE_L
1234 | mov ARG3, RD
1235 | mov ARG1, L:RB
1236 | mov L:RB->base, BASE
1237 |.endif
1238 | mov SAVE_PC, PC
1239 | call extern lj_meta_istype // (lua_State *L, BCReg ra, BCReg tp)
1240 | mov BASE, L:RB->base
1241 | jmp <6
1242 |
1243 |//-- Arithmetic metamethods ---------------------------------------------
1244 |
1245 |->vmeta_arith_vno:
1246 |.if DUALNUM
1247 | movzx RB, PC_RB
1248 |.endif
1249 |->vmeta_arith_vn:
1250 | lea RC, [KBASE+RC*8]
1251 | jmp >1
1252 |
1253 |->vmeta_arith_nvo:
1254 |.if DUALNUM
1255 | movzx RC, PC_RC
1256 |.endif
1257 |->vmeta_arith_nv:
1258 | lea RC, [KBASE+RC*8]
1259 | lea RB, [BASE+RB*8]
1260 | xchg RB, RC
1261 | jmp >2
1262 |
1263 |->vmeta_unm:
1264 | lea RC, [BASE+RD*8]
1265 | mov RB, RC
1266 | jmp >2
1267 |
1268 |->vmeta_arith_vvo:
1269 |.if DUALNUM
1270 | movzx RB, PC_RB
1271 |.endif
1272 |->vmeta_arith_vv:
1273 | lea RC, [BASE+RC*8]
1274 |1:
1275 | lea RB, [BASE+RB*8]
1276 |2:
1277 | lea RA, [BASE+RA*8]
1278 |.if X64WIN
1279 | mov CARG3d, RB
1280 | mov CARG4d, RC
1281 | movzx RC, PC_OP
1282 | mov ARG5d, RC
1283 | mov L:RB, SAVE_L
1284 | mov L:RB->base, BASE // Caveat: CARG2d == BASE.
1285 | mov CARG2d, RA
1286 | mov CARG1d, L:RB // Caveat: CARG1d == RA.
1287 |.elif X64
1288 | movzx CARG5d, PC_OP
1289 | mov CARG2d, RA
1290 | mov CARG4d, RC // Caveat: CARG4d == RA.
1291 | mov L:CARG1d, SAVE_L
1292 | mov L:CARG1d->base, BASE // Caveat: CARG3d == BASE.
1293 | mov CARG3d, RB
1294 | mov L:RB, L:CARG1d
1295 |.else
1296 | mov ARG3, RB
1297 | mov L:RB, SAVE_L
1298 | mov ARG4, RC
1299 | movzx RC, PC_OP
1300 | mov ARG2, RA
1301 | mov ARG5, RC
1302 | mov ARG1, L:RB
1303 | mov L:RB->base, BASE
1304 |.endif
1305 | mov SAVE_PC, PC
1306 | call extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
1307 | // NULL (finished) or TValue * (metamethod) returned in eax (RC).
1308 | mov BASE, L:RB->base
1309 | test RC, RC
1310 | jz ->cont_nop
1311 |
1312 | // Call metamethod for binary op.
1313 |->vmeta_binop:
1314 | // BASE = base, RC = new base, stack = cont/func/o1/o2
1315 | mov RA, RC
1316 | sub RC, BASE
1317 | mov [RA-12], PC // [cont|PC]
1318 | lea PC, [RC+FRAME_CONT]
1319 | mov NARGS:RD, 2+1 // 2 args for func(o1, o2).
1320 | jmp ->vm_call_dispatch
1321 |
1322 |->vmeta_len:
1323 | mov L:RB, SAVE_L
1324 | mov L:RB->base, BASE
1325 | lea FCARG2, [BASE+RD*8] // Caveat: FCARG2 == BASE
1326 | mov L:FCARG1, L:RB
1327 | mov SAVE_PC, PC
1328 | call extern lj_meta_len@8 // (lua_State *L, TValue *o)
1329 | // NULL (retry) or TValue * (metamethod) returned in eax (RC).
1330 | mov BASE, L:RB->base
1331#if LJ_52
1332 | test RC, RC
1333 | jne ->vmeta_binop // Binop call for compatibility.
1334 | movzx RD, PC_RD
1335 | mov TAB:FCARG1, [BASE+RD*8]
1336 | jmp ->BC_LEN_Z
1337#else
1338 | jmp ->vmeta_binop // Binop call for compatibility.
1339#endif
1340 |
1341 |//-- Call metamethod ----------------------------------------------------
1342 |
1343 |->vmeta_call_ra:
1344 | lea RA, [BASE+RA*8+8]
1345 |->vmeta_call: // Resolve and call __call metamethod.
1346 | // BASE = old base, RA = new base, RC = nargs+1, PC = return
1347 | mov TMP2, RA // Save RA, RC for us.
1348 | mov TMP1, NARGS:RD
1349 | sub RA, 8
1350 |.if X64
1351 | mov L:RB, SAVE_L
1352 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
1353 | mov CARG2d, RA
1354 | lea CARG3d, [RA+NARGS:RD*8]
1355 | mov CARG1d, L:RB // Caveat: CARG1d may be RA.
1356 |.else
1357 | lea RC, [RA+NARGS:RD*8]
1358 | mov L:RB, SAVE_L
1359 | mov ARG2, RA
1360 | mov ARG3, RC
1361 | mov ARG1, L:RB
1362 | mov L:RB->base, BASE // This is the callers base!
1363 |.endif
1364 | mov SAVE_PC, PC
1365 | call extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
1366 | mov BASE, L:RB->base
1367 | mov RA, TMP2
1368 | mov NARGS:RD, TMP1
1369 | mov LFUNC:RB, [RA-8]
1370 | add NARGS:RD, 1
1371 | // This is fragile. L->base must not move, KBASE must always be defined.
1372 |.if X64
1373 | cmp KBASEa, rdx // Continue with CALLT if flag set.
1374 |.else
1375 | cmp KBASE, BASE // Continue with CALLT if flag set.
1376 |.endif
1377 | je ->BC_CALLT_Z
1378 | mov BASE, RA
1379 | ins_call // Otherwise call resolved metamethod.
1380 |
1381 |//-- Argument coercion for 'for' statement ------------------------------
1382 |
1383 |->vmeta_for:
1384 | mov L:RB, SAVE_L
1385 | mov L:RB->base, BASE
1386 | mov FCARG2, RA // Caveat: FCARG2 == BASE
1387 | mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
1388 | mov SAVE_PC, PC
1389 | call extern lj_meta_for@8 // (lua_State *L, TValue *base)
1390 | mov BASE, L:RB->base
1391 | mov RC, [PC-4]
1392 | movzx RA, RCH
1393 | movzx OP, RCL
1394 | shr RC, 16
1395 |.if X64
1396 | jmp aword [DISPATCH+OP*8+GG_DISP2STATIC] // Retry FORI or JFORI.
1397 |.else
1398 | jmp aword [DISPATCH+OP*4+GG_DISP2STATIC] // Retry FORI or JFORI.
1399 |.endif
1400 |
1401 |//-----------------------------------------------------------------------
1402 |//-- Fast functions -----------------------------------------------------
1403 |//-----------------------------------------------------------------------
1404 |
1405 |.macro .ffunc, name
1406 |->ff_ .. name:
1407 |.endmacro
1408 |
1409 |.macro .ffunc_1, name
1410 |->ff_ .. name:
1411 | cmp NARGS:RD, 1+1; jb ->fff_fallback
1412 |.endmacro
1413 |
1414 |.macro .ffunc_2, name
1415 |->ff_ .. name:
1416 | cmp NARGS:RD, 2+1; jb ->fff_fallback
1417 |.endmacro
1418 |
1419 |.macro .ffunc_nsse, name, op
1420 | .ffunc_1 name
1421 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1422 | op xmm0, qword [BASE]
1423 |.endmacro
1424 |
1425 |.macro .ffunc_nsse, name
1426 | .ffunc_nsse name, movsd
1427 |.endmacro
1428 |
1429 |.macro .ffunc_nnsse, name
1430 | .ffunc_2 name
1431 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1432 | cmp dword [BASE+12], LJ_TISNUM; jae ->fff_fallback
1433 | movsd xmm0, qword [BASE]
1434 | movsd xmm1, qword [BASE+8]
1435 |.endmacro
1436 |
1437 |.macro .ffunc_nnr, name
1438 | .ffunc_2 name
1439 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
1440 | cmp dword [BASE+12], LJ_TISNUM; jae ->fff_fallback
1441 | fld qword [BASE+8]
1442 | fld qword [BASE]
1443 |.endmacro
1444 |
1445 |// Inlined GC threshold check. Caveat: uses label 1.
1446 |.macro ffgccheck
1447 | mov RB, [DISPATCH+DISPATCH_GL(gc.total)]
1448 | cmp RB, [DISPATCH+DISPATCH_GL(gc.threshold)]
1449 | jb >1
1450 | call ->fff_gcstep
1451 |1:
1452 |.endmacro
1453 |
1454 |//-- Base library: checks -----------------------------------------------
1455 |
1456 |.ffunc_1 assert
1457 | mov RB, [BASE+4]
1458 | cmp RB, LJ_TISTRUECOND; jae ->fff_fallback
1459 | mov PC, [BASE-4]
1460 | mov MULTRES, RD
1461 | mov [BASE-4], RB
1462 | mov RB, [BASE]
1463 | mov [BASE-8], RB
1464 | sub RD, 2
1465 | jz >2
1466 | mov RA, BASE
1467 |1:
1468 | add RA, 8
1469 |.if X64
1470 | mov RBa, [RA]
1471 | mov [RA-8], RBa
1472 |.else
1473 | mov RB, [RA+4]
1474 | mov [RA-4], RB
1475 | mov RB, [RA]
1476 | mov [RA-8], RB
1477 |.endif
1478 | sub RD, 1
1479 | jnz <1
1480 |2:
1481 | mov RD, MULTRES
1482 | jmp ->fff_res_
1483 |
1484 |.ffunc_1 type
1485 | mov RB, [BASE+4]
1486 |.if X64
1487 | mov RA, RB
1488 | sar RA, 15
1489 | cmp RA, -2
1490 | je >3
1491 |.endif
1492 | mov RC, ~LJ_TNUMX
1493 | not RB
1494 | cmp RC, RB
1495 | cmova RC, RB
1496 |2:
1497 | mov CFUNC:RB, [BASE-8]
1498 | mov STR:RC, [CFUNC:RB+RC*8+((char *)(&((GCfuncC *)0)->upvalue))]
1499 | mov PC, [BASE-4]
1500 | mov dword [BASE-4], LJ_TSTR
1501 | mov [BASE-8], STR:RC
1502 | jmp ->fff_res1
1503 |.if X64
1504 |3:
1505 | mov RC, ~LJ_TLIGHTUD
1506 | jmp <2
1507 |.endif
1508 |
1509 |//-- Base library: getters and setters ---------------------------------
1510 |
1511 |.ffunc_1 getmetatable
1512 | mov RB, [BASE+4]
1513 | mov PC, [BASE-4]
1514 | cmp RB, LJ_TTAB; jne >6
1515 |1: // Field metatable must be at same offset for GCtab and GCudata!
1516 | mov TAB:RB, [BASE]
1517 | mov TAB:RB, TAB:RB->metatable
1518 |2:
1519 | test TAB:RB, TAB:RB
1520 | mov dword [BASE-4], LJ_TNIL
1521 | jz ->fff_res1
1522 | mov STR:RC, [DISPATCH+DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable)]
1523 | mov dword [BASE-4], LJ_TTAB // Store metatable as default result.
1524 | mov [BASE-8], TAB:RB
1525 | mov RA, TAB:RB->hmask
1526 | and RA, STR:RC->sid
1527 | imul RA, #NODE
1528 | add NODE:RA, TAB:RB->node
1529 |3: // Rearranged logic, because we expect _not_ to find the key.
1530 | cmp dword NODE:RA->key.it, LJ_TSTR
1531 | jne >4
1532 | cmp dword NODE:RA->key.gcr, STR:RC
1533 | je >5
1534 |4:
1535 | mov NODE:RA, NODE:RA->next
1536 | test NODE:RA, NODE:RA
1537 | jnz <3
1538 | jmp ->fff_res1 // Not found, keep default result.
1539 |5:
1540 | mov RB, [RA+4]
1541 | cmp RB, LJ_TNIL; je ->fff_res1 // Ditto for nil value.
1542 | mov RC, [RA]
1543 | mov [BASE-4], RB // Return value of mt.__metatable.
1544 | mov [BASE-8], RC
1545 | jmp ->fff_res1
1546 |
1547 |6:
1548 | cmp RB, LJ_TUDATA; je <1
1549 |.if X64
1550 | cmp RB, LJ_TNUMX; ja >8
1551 | cmp RB, LJ_TISNUM; jbe >7
1552 | mov RB, LJ_TLIGHTUD
1553 | jmp >8
1554 |7:
1555 |.else
1556 | cmp RB, LJ_TISNUM; ja >8
1557 |.endif
1558 | mov RB, LJ_TNUMX
1559 |8:
1560 | not RB
1561 | mov TAB:RB, [DISPATCH+RB*4+DISPATCH_GL(gcroot[GCROOT_BASEMT])]
1562 | jmp <2
1563 |
1564 |.ffunc_2 setmetatable
1565 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1566 | // Fast path: no mt for table yet and not clearing the mt.
1567 | mov TAB:RB, [BASE]
1568 | cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
1569 | cmp dword [BASE+12], LJ_TTAB; jne ->fff_fallback
1570 | mov TAB:RC, [BASE+8]
1571 | mov TAB:RB->metatable, TAB:RC
1572 | mov PC, [BASE-4]
1573 | mov dword [BASE-4], LJ_TTAB // Return original table.
1574 | mov [BASE-8], TAB:RB
1575 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
1576 | jz >1
1577 | // Possible write barrier. Table is black, but skip iswhite(mt) check.
1578 | barrierback TAB:RB, RC
1579 |1:
1580 | jmp ->fff_res1
1581 |
1582 |.ffunc_2 rawget
1583 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1584 |.if X64WIN
1585 | mov RB, BASE // Save BASE.
1586 | lea CARG3d, [BASE+8]
1587 | mov CARG2d, [BASE] // Caveat: CARG2d == BASE.
1588 | mov CARG1d, SAVE_L
1589 |.elif X64
1590 | mov RB, BASE // Save BASE.
1591 | mov CARG2d, [BASE]
1592 | lea CARG3d, [BASE+8] // Caveat: CARG3d == BASE.
1593 | mov CARG1d, SAVE_L
1594 |.else
1595 | mov TAB:RD, [BASE]
1596 | mov L:RB, SAVE_L
1597 | mov ARG2, TAB:RD
1598 | mov ARG1, L:RB
1599 | mov RB, BASE // Save BASE.
1600 | add BASE, 8
1601 | mov ARG3, BASE
1602 |.endif
1603 | call extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key)
1604 | // cTValue * returned in eax (RD).
1605 | mov BASE, RB // Restore BASE.
1606 | // Copy table slot.
1607 |.if X64
1608 | mov RBa, [RD]
1609 | mov PC, [BASE-4]
1610 | mov [BASE-8], RBa
1611 |.else
1612 | mov RB, [RD]
1613 | mov RD, [RD+4]
1614 | mov PC, [BASE-4]
1615 | mov [BASE-8], RB
1616 | mov [BASE-4], RD
1617 |.endif
1618 | jmp ->fff_res1
1619 |
1620 |//-- Base library: conversions ------------------------------------------
1621 |
1622 |.ffunc tonumber
1623 | // Only handles the number case inline (without a base argument).
1624 | cmp NARGS:RD, 1+1; jne ->fff_fallback // Exactly one argument.
1625 | cmp dword [BASE+4], LJ_TISNUM
1626 |.if DUALNUM
1627 | jne >1
1628 | mov RB, dword [BASE]; jmp ->fff_resi
1629 |1:
1630 | ja ->fff_fallback
1631 |.else
1632 | jae ->fff_fallback
1633 |.endif
1634 | movsd xmm0, qword [BASE]; jmp ->fff_resxmm0
1635 |
1636 |.ffunc_1 tostring
1637 | // Only handles the string or number case inline.
1638 | mov PC, [BASE-4]
1639 | cmp dword [BASE+4], LJ_TSTR; jne >3
1640 | // A __tostring method in the string base metatable is ignored.
1641 | mov STR:RD, [BASE]
1642 |2:
1643 | mov dword [BASE-4], LJ_TSTR
1644 | mov [BASE-8], STR:RD
1645 | jmp ->fff_res1
1646 |3: // Handle numbers inline, unless a number base metatable is present.
1647 | cmp dword [BASE+4], LJ_TISNUM; ja ->fff_fallback
1648 | cmp dword [DISPATCH+DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])], 0
1649 | jne ->fff_fallback
1650 | ffgccheck // Caveat: uses label 1.
1651 | mov L:RB, SAVE_L
1652 | mov L:RB->base, BASE // Add frame since C call can throw.
1653 | mov SAVE_PC, PC // Redundant (but a defined value).
1654 |.if X64 and not X64WIN
1655 | mov FCARG2, BASE // Otherwise: FCARG2 == BASE
1656 |.endif
1657 | mov L:FCARG1, L:RB
1658 |.if DUALNUM
1659 | call extern lj_strfmt_number@8 // (lua_State *L, cTValue *o)
1660 |.else
1661 | call extern lj_strfmt_num@8 // (lua_State *L, lua_Number *np)
1662 |.endif
1663 | // GCstr returned in eax (RD).
1664 | mov BASE, L:RB->base
1665 | jmp <2
1666 |
1667 |//-- Base library: iterators -------------------------------------------
1668 |
1669 |.ffunc_1 next
1670 | je >2 // Missing 2nd arg?
1671 |1:
1672 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1673 | mov PC, [BASE-4]
1674 | mov RB, BASE // Save BASE.
1675 |.if X64WIN
1676 | mov CARG1d, [BASE]
1677 | lea CARG3d, [BASE-8]
1678 | lea CARG2d, [BASE+8] // Caveat: CARG2d == BASE.
1679 |.elif X64
1680 | mov CARG1d, [BASE]
1681 | lea CARG2d, [BASE+8]
1682 | lea CARG3d, [BASE-8] // Caveat: CARG3d == BASE.
1683 |.else
1684 | mov TAB:RD, [BASE]
1685 | mov ARG1, TAB:RD
1686 | add BASE, 8
1687 | mov ARG2, BASE
1688 | sub BASE, 8+8
1689 | mov ARG3, BASE
1690 |.endif
1691 | call extern lj_tab_next // (GCtab *t, cTValue *key, TValue *o)
1692 | // 1=found, 0=end, -1=error returned in eax (RD).
1693 | mov BASE, RB // Restore BASE.
1694 | test RD, RD; jg ->fff_res2 // Found key/value.
1695 | js ->fff_fallback_2 // Invalid key.
1696 | // End of traversal: return nil.
1697 | mov dword [BASE-4], LJ_TNIL
1698 | jmp ->fff_res1
1699 |2: // Set missing 2nd arg to nil.
1700 | mov dword [BASE+12], LJ_TNIL
1701 | jmp <1
1702 |
1703 |.ffunc_1 pairs
1704 | mov TAB:RB, [BASE]
1705 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1706#if LJ_52
1707 | cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
1708#endif
1709 | mov CFUNC:RB, [BASE-8]
1710 | mov CFUNC:RD, CFUNC:RB->upvalue[0]
1711 | mov PC, [BASE-4]
1712 | mov dword [BASE-4], LJ_TFUNC
1713 | mov [BASE-8], CFUNC:RD
1714 | mov dword [BASE+12], LJ_TNIL
1715 | mov RD, 1+3
1716 | jmp ->fff_res
1717 |
1718 |.ffunc_2 ipairs_aux
1719 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1720 | cmp dword [BASE+12], LJ_TISNUM
1721 |.if DUALNUM
1722 | jne ->fff_fallback
1723 |.else
1724 | jae ->fff_fallback
1725 |.endif
1726 | mov PC, [BASE-4]
1727 |.if DUALNUM
1728 | mov RD, dword [BASE+8]
1729 | add RD, 1
1730 | mov dword [BASE-4], LJ_TISNUM
1731 | mov dword [BASE-8], RD
1732 |.else
1733 | movsd xmm0, qword [BASE+8]
1734 | sseconst_1 xmm1, RBa
1735 | addsd xmm0, xmm1
1736 | cvttsd2si RD, xmm0
1737 | movsd qword [BASE-8], xmm0
1738 |.endif
1739 | mov TAB:RB, [BASE]
1740 | cmp RD, TAB:RB->asize; jae >2 // Not in array part?
1741 | shl RD, 3
1742 | add RD, TAB:RB->array
1743 |1:
1744 | cmp dword [RD+4], LJ_TNIL; je ->fff_res0
1745 | // Copy array slot.
1746 |.if X64
1747 | mov RBa, [RD]
1748 | mov [BASE], RBa
1749 |.else
1750 | mov RB, [RD]
1751 | mov RD, [RD+4]
1752 | mov [BASE], RB
1753 | mov [BASE+4], RD
1754 |.endif
1755 |->fff_res2:
1756 | mov RD, 1+2
1757 | jmp ->fff_res
1758 |2: // Check for empty hash part first. Otherwise call C function.
1759 | cmp dword TAB:RB->hmask, 0; je ->fff_res0
1760 | mov FCARG1, TAB:RB
1761 | mov RB, BASE // Save BASE.
1762 | mov FCARG2, RD // Caveat: FCARG2 == BASE
1763 | call extern lj_tab_getinth@8 // (GCtab *t, int32_t key)
1764 | // cTValue * or NULL returned in eax (RD).
1765 | mov BASE, RB
1766 | test RD, RD
1767 | jnz <1
1768 |->fff_res0:
1769 | mov RD, 1+0
1770 | jmp ->fff_res
1771 |
1772 |.ffunc_1 ipairs
1773 | mov TAB:RB, [BASE]
1774 | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
1775#if LJ_52
1776 | cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
1777#endif
1778 | mov CFUNC:RB, [BASE-8]
1779 | mov CFUNC:RD, CFUNC:RB->upvalue[0]
1780 | mov PC, [BASE-4]
1781 | mov dword [BASE-4], LJ_TFUNC
1782 | mov [BASE-8], CFUNC:RD
1783 |.if DUALNUM
1784 | mov dword [BASE+12], LJ_TISNUM
1785 | mov dword [BASE+8], 0
1786 |.else
1787 | xorps xmm0, xmm0
1788 | movsd qword [BASE+8], xmm0
1789 |.endif
1790 | mov RD, 1+3
1791 | jmp ->fff_res
1792 |
1793 |//-- Base library: catch errors ----------------------------------------
1794 |
1795 |.ffunc_1 pcall
1796 | mov L:RB, SAVE_L
1797 | lea RA, [BASE+NARGS:RD*8]
1798 | cmp RA, L:RB->maxstack; ja ->fff_fallback
1799 | lea RA, [BASE+8]
1800 | sub NARGS:RD, 1
1801 | mov PC, 8+FRAME_PCALL
1802 |1:
1803 | movzx RB, byte [DISPATCH+DISPATCH_GL(hookmask)]
1804 | shr RB, HOOK_ACTIVE_SHIFT
1805 | and RB, 1
1806 | add PC, RB // Remember active hook before pcall.
1807 | jmp ->vm_call_dispatch
1808 |
1809 |.ffunc_2 xpcall
1810 | mov L:RB, SAVE_L
1811 | lea RA, [BASE+NARGS:RD*8]
1812 | cmp RA, L:RB->maxstack; ja ->fff_fallback
1813 | cmp dword [BASE+12], LJ_TFUNC; jne ->fff_fallback
1814 | mov RB, [BASE+4] // Swap function and traceback.
1815 | mov [BASE+12], RB
1816 | mov dword [BASE+4], LJ_TFUNC
1817 | mov LFUNC:RB, [BASE]
1818 | mov PC, [BASE+8]
1819 | mov [BASE+8], LFUNC:RB
1820 | mov [BASE], PC
1821 | lea RA, [BASE+16]
1822 | sub NARGS:RD, 2
1823 | mov PC, 16+FRAME_PCALL
1824 | jmp <1
1825 |
1826 |//-- Coroutine library --------------------------------------------------
1827 |
1828 |.macro coroutine_resume_wrap, resume
1829 |.if resume
1830 |.ffunc_1 coroutine_resume
1831 | mov L:RB, [BASE]
1832 |.else
1833 |.ffunc coroutine_wrap_aux
1834 | mov CFUNC:RB, [BASE-8]
1835 | mov L:RB, CFUNC:RB->upvalue[0].gcr
1836 |.endif
1837 | mov PC, [BASE-4]
1838 | mov SAVE_PC, PC
1839 |.if X64
1840 | mov TMP1, L:RB
1841 |.else
1842 | mov ARG1, L:RB
1843 |.endif
1844 |.if resume
1845 | cmp dword [BASE+4], LJ_TTHREAD; jne ->fff_fallback
1846 |.endif
1847 | cmp aword L:RB->cframe, 0; jne ->fff_fallback
1848 | cmp byte L:RB->status, LUA_YIELD; ja ->fff_fallback
1849 | mov RA, L:RB->top
1850 | je >1 // Status != LUA_YIELD (i.e. 0)?
1851 | cmp RA, L:RB->base // Check for presence of initial func.
1852 | je ->fff_fallback
1853 |1:
1854 |.if resume
1855 | lea PC, [RA+NARGS:RD*8-16] // Check stack space (-1-thread).
1856 |.else
1857 | lea PC, [RA+NARGS:RD*8-8] // Check stack space (-1).
1858 |.endif
1859 | cmp PC, L:RB->maxstack; ja ->fff_fallback
1860 | mov L:RB->top, PC
1861 |
1862 | mov L:RB, SAVE_L
1863 | mov L:RB->base, BASE
1864 |.if resume
1865 | add BASE, 8 // Keep resumed thread in stack for GC.
1866 |.endif
1867 | mov L:RB->top, BASE
1868 |.if resume
1869 | lea RB, [BASE+NARGS:RD*8-24] // RB = end of source for stack move.
1870 |.else
1871 | lea RB, [BASE+NARGS:RD*8-16] // RB = end of source for stack move.
1872 |.endif
1873 | sub RBa, PCa // Relative to PC.
1874 |
1875 | cmp PC, RA
1876 | je >3
1877 |2: // Move args to coroutine.
1878 |.if X64
1879 | mov RCa, [PC+RB]
1880 | mov [PC-8], RCa
1881 |.else
1882 | mov RC, [PC+RB+4]
1883 | mov [PC-4], RC
1884 | mov RC, [PC+RB]
1885 | mov [PC-8], RC
1886 |.endif
1887 | sub PC, 8
1888 | cmp PC, RA
1889 | jne <2
1890 |3:
1891 |.if X64
1892 | mov CARG2d, RA
1893 | mov CARG1d, TMP1
1894 |.else
1895 | mov ARG2, RA
1896 | xor RA, RA
1897 | mov ARG4, RA
1898 | mov ARG3, RA
1899 |.endif
1900 | call ->vm_resume // (lua_State *L, TValue *base, 0, 0)
1901 |
1902 | mov L:RB, SAVE_L
1903 |.if X64
1904 | mov L:PC, TMP1
1905 |.else
1906 | mov L:PC, ARG1 // The callee doesn't modify SAVE_L.
1907 |.endif
1908 | mov BASE, L:RB->base
1909 | mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
1910 | set_vmstate INTERP
1911 |
1912 | cmp eax, LUA_YIELD
1913 | ja >8
1914 |4:
1915 | mov RA, L:PC->base
1916 | mov KBASE, L:PC->top
1917 | mov L:PC->top, RA // Clear coroutine stack.
1918 | mov PC, KBASE
1919 | sub PC, RA
1920 | je >6 // No results?
1921 | lea RD, [BASE+PC]
1922 | shr PC, 3
1923 | cmp RD, L:RB->maxstack
1924 | ja >9 // Need to grow stack?
1925 |
1926 | mov RB, BASE
1927 | sub RBa, RAa
1928 |5: // Move results from coroutine.
1929 |.if X64
1930 | mov RDa, [RA]
1931 | mov [RA+RB], RDa
1932 |.else
1933 | mov RD, [RA]
1934 | mov [RA+RB], RD
1935 | mov RD, [RA+4]
1936 | mov [RA+RB+4], RD
1937 |.endif
1938 | add RA, 8
1939 | cmp RA, KBASE
1940 | jne <5
1941 |6:
1942 |.if resume
1943 | lea RD, [PC+2] // nresults+1 = 1 + true + results.
1944 | mov dword [BASE-4], LJ_TTRUE // Prepend true to results.
1945 |.else
1946 | lea RD, [PC+1] // nresults+1 = 1 + results.
1947 |.endif
1948 |7:
1949 | mov PC, SAVE_PC
1950 | mov MULTRES, RD
1951 |.if resume
1952 | mov RAa, -8
1953 |.else
1954 | xor RA, RA
1955 |.endif
1956 | test PC, FRAME_TYPE
1957 | jz ->BC_RET_Z
1958 | jmp ->vm_return
1959 |
1960 |8: // Coroutine returned with error (at co->top-1).
1961 |.if resume
1962 | mov dword [BASE-4], LJ_TFALSE // Prepend false to results.
1963 | mov RA, L:PC->top
1964 | sub RA, 8
1965 | mov L:PC->top, RA // Clear error from coroutine stack.
1966 | // Copy error message.
1967 |.if X64
1968 | mov RDa, [RA]
1969 | mov [BASE], RDa
1970 |.else
1971 | mov RD, [RA]
1972 | mov [BASE], RD
1973 | mov RD, [RA+4]
1974 | mov [BASE+4], RD
1975 |.endif
1976 | mov RD, 1+2 // nresults+1 = 1 + false + error.
1977 | jmp <7
1978 |.else
1979 | mov FCARG2, L:PC
1980 | mov FCARG1, L:RB
1981 | call extern lj_ffh_coroutine_wrap_err@8 // (lua_State *L, lua_State *co)
1982 | // Error function does not return.
1983 |.endif
1984 |
1985 |9: // Handle stack expansion on return from yield.
1986 |.if X64
1987 | mov L:RA, TMP1
1988 |.else
1989 | mov L:RA, ARG1 // The callee doesn't modify SAVE_L.
1990 |.endif
1991 | mov L:RA->top, KBASE // Undo coroutine stack clearing.
1992 | mov FCARG2, PC
1993 | mov FCARG1, L:RB
1994 | call extern lj_state_growstack@8 // (lua_State *L, int n)
1995 |.if X64
1996 | mov L:PC, TMP1
1997 |.else
1998 | mov L:PC, ARG1
1999 |.endif
2000 | mov BASE, L:RB->base
2001 | jmp <4 // Retry the stack move.
2002 |.endmacro
2003 |
2004 | coroutine_resume_wrap 1 // coroutine.resume
2005 | coroutine_resume_wrap 0 // coroutine.wrap
2006 |
2007 |.ffunc coroutine_yield
2008 | mov L:RB, SAVE_L
2009 | test aword L:RB->cframe, CFRAME_RESUME
2010 | jz ->fff_fallback
2011 | mov L:RB->base, BASE
2012 | lea RD, [BASE+NARGS:RD*8-8]
2013 | mov L:RB->top, RD
2014 | xor RD, RD
2015 | mov aword L:RB->cframe, RDa
2016 | mov al, LUA_YIELD
2017 | mov byte L:RB->status, al
2018 | jmp ->vm_leave_unw
2019 |
2020 |//-- Math library -------------------------------------------------------
2021 |
2022 |.if not DUALNUM
2023 |->fff_resi: // Dummy.
2024 |.endif
2025 |
2026 |->fff_resn:
2027 | mov PC, [BASE-4]
2028 | fstp qword [BASE-8]
2029 | jmp ->fff_res1
2030 |
2031 | .ffunc_1 math_abs
2032 |.if DUALNUM
2033 | cmp dword [BASE+4], LJ_TISNUM; jne >2
2034 | mov RB, dword [BASE]
2035 | cmp RB, 0; jns ->fff_resi
2036 | neg RB; js >1
2037 |->fff_resbit:
2038 |->fff_resi:
2039 | mov PC, [BASE-4]
2040 | mov dword [BASE-4], LJ_TISNUM
2041 | mov dword [BASE-8], RB
2042 | jmp ->fff_res1
2043 |1:
2044 | mov PC, [BASE-4]
2045 | mov dword [BASE-4], 0x41e00000 // 2^31.
2046 | mov dword [BASE-8], 0
2047 | jmp ->fff_res1
2048 |2:
2049 | ja ->fff_fallback
2050 |.else
2051 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2052 |.endif
2053 | movsd xmm0, qword [BASE]
2054 | sseconst_abs xmm1, RDa
2055 | andps xmm0, xmm1
2056 |->fff_resxmm0:
2057 | mov PC, [BASE-4]
2058 | movsd qword [BASE-8], xmm0
2059 | // fallthrough
2060 |
2061 |->fff_res1:
2062 | mov RD, 1+1
2063 |->fff_res:
2064 | mov MULTRES, RD
2065 |->fff_res_:
2066 | test PC, FRAME_TYPE
2067 | jnz >7
2068 |5:
2069 | cmp PC_RB, RDL // More results expected?
2070 | ja >6
2071 | // Adjust BASE. KBASE is assumed to be set for the calling frame.
2072 | movzx RA, PC_RA
2073 | not RAa // Note: ~RA = -(RA+1)
2074 | lea BASE, [BASE+RA*8] // base = base - (RA+1)*8
2075 | ins_next
2076 |
2077 |6: // Fill up results with nil.
2078 | mov dword [BASE+RD*8-12], LJ_TNIL
2079 | add RD, 1
2080 | jmp <5
2081 |
2082 |7: // Non-standard return case.
2083 | mov RAa, -8 // Results start at BASE+RA = BASE-8.
2084 | jmp ->vm_return
2085 |
2086 |.if X64
2087 |.define fff_resfp, fff_resxmm0
2088 |.else
2089 |.define fff_resfp, fff_resn
2090 |.endif
2091 |
2092 |.macro math_round, func
2093 | .ffunc math_ .. func
2094 |.if DUALNUM
2095 | cmp dword [BASE+4], LJ_TISNUM; jne >1
2096 | mov RB, dword [BASE]; jmp ->fff_resi
2097 |1:
2098 | ja ->fff_fallback
2099 |.else
2100 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2101 |.endif
2102 | movsd xmm0, qword [BASE]
2103 | call ->vm_ .. func .. _sse
2104 |.if DUALNUM
2105 | cvttsd2si RB, xmm0
2106 | cmp RB, 0x80000000
2107 | jne ->fff_resi
2108 | cvtsi2sd xmm1, RB
2109 | ucomisd xmm0, xmm1
2110 | jp ->fff_resxmm0
2111 | je ->fff_resi
2112 |.endif
2113 | jmp ->fff_resxmm0
2114 |.endmacro
2115 |
2116 | math_round floor
2117 | math_round ceil
2118 |
2119 |.ffunc_nsse math_sqrt, sqrtsd; jmp ->fff_resxmm0
2120 |
2121 |.ffunc math_log
2122 | cmp NARGS:RD, 1+1; jne ->fff_fallback // Exactly one argument.
2123 | cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2124 | movsd xmm0, qword [BASE]
2125 |.if not X64
2126 | movsd FPARG1, xmm0
2127 |.endif
2128 | mov RB, BASE
2129 | call extern log
2130 | mov BASE, RB
2131 | jmp ->fff_resfp
2132 |
2133 |.macro math_extern, func
2134 | .ffunc_nsse math_ .. func
2135 |.if not X64
2136 | movsd FPARG1, xmm0
2137 |.endif
2138 | mov RB, BASE
2139 | call extern func
2140 | mov BASE, RB
2141 | jmp ->fff_resfp
2142 |.endmacro
2143 |
2144 |.macro math_extern2, func
2145 | .ffunc_nnsse math_ .. func
2146 |.if not X64
2147 | movsd FPARG1, xmm0
2148 | movsd FPARG3, xmm1
2149 |.endif
2150 | mov RB, BASE
2151 | call extern func
2152 | mov BASE, RB
2153 | jmp ->fff_resfp
2154 |.endmacro
2155 |
2156 | math_extern log10
2157 | math_extern exp
2158 | math_extern sin
2159 | math_extern cos
2160 | math_extern tan
2161 | math_extern asin
2162 | math_extern acos
2163 | math_extern atan
2164 | math_extern sinh
2165 | math_extern cosh
2166 | math_extern tanh
2167 | math_extern2 pow
2168 | math_extern2 atan2
2169 | math_extern2 fmod
2170 |
2171 |.ffunc_nnr math_ldexp; fscale; fpop1; jmp ->fff_resn
2172 |
2173 |.ffunc_1 math_frexp
2174 | mov RB, [BASE+4]
2175 | cmp RB, LJ_TISNUM; jae ->fff_fallback
2176 | mov PC, [BASE-4]
2177 | mov RC, [BASE]
2178 | mov [BASE-4], RB; mov [BASE-8], RC
2179 | shl RB, 1; cmp RB, 0xffe00000; jae >3
2180 | or RC, RB; jz >3
2181 | mov RC, 1022
2182 | cmp RB, 0x00200000; jb >4
2183 |1:
2184 | shr RB, 21; sub RB, RC // Extract and unbias exponent.
2185 | cvtsi2sd xmm0, RB
2186 | mov RB, [BASE-4]
2187 | and RB, 0x800fffff // Mask off exponent.
2188 | or RB, 0x3fe00000 // Put mantissa in range [0.5,1) or 0.
2189 | mov [BASE-4], RB
2190 |2:
2191 | movsd qword [BASE], xmm0
2192 | mov RD, 1+2
2193 | jmp ->fff_res
2194 |3: // Return +-0, +-Inf, NaN unmodified and an exponent of 0.
2195 | xorps xmm0, xmm0; jmp <2
2196 |4: // Handle denormals by multiplying with 2^54 and adjusting the bias.
2197 | movsd xmm0, qword [BASE]
2198 | sseconst_hi xmm1, RBa, 43500000 // 2^54.
2199 | mulsd xmm0, xmm1
2200 | movsd qword [BASE-8], xmm0
2201 | mov RB, [BASE-4]; mov RC, 1076; shl RB, 1; jmp <1
2202 |
2203 |.ffunc_nsse math_modf
2204 | mov RB, [BASE+4]
2205 | mov PC, [BASE-4]
2206 | shl RB, 1; cmp RB, 0xffe00000; je >4 // +-Inf?
2207 | movaps xmm4, xmm0
2208 | call ->vm_trunc_sse
2209 | subsd xmm4, xmm0
2210 |1:
2211 | movsd qword [BASE-8], xmm0
2212 | movsd qword [BASE], xmm4
2213 | mov RC, [BASE-4]; mov RB, [BASE+4]
2214 | xor RC, RB; js >3 // Need to adjust sign?
2215 |2:
2216 | mov RD, 1+2
2217 | jmp ->fff_res
2218 |3:
2219 | xor RB, 0x80000000; mov [BASE+4], RB // Flip sign of fraction.
2220 | jmp <2
2221 |4:
2222 | xorps xmm4, xmm4; jmp <1 // Return +-Inf and +-0.
2223 |
2224 |.macro math_minmax, name, cmovop, sseop
2225 | .ffunc_1 name
2226 | mov RA, 2
2227 | cmp dword [BASE+4], LJ_TISNUM
2228 |.if DUALNUM
2229 | jne >4
2230 | mov RB, dword [BASE]
2231 |1: // Handle integers.
2232 | cmp RA, RD; jae ->fff_resi
2233 | cmp dword [BASE+RA*8-4], LJ_TISNUM; jne >3
2234 | cmp RB, dword [BASE+RA*8-8]
2235 | cmovop RB, dword [BASE+RA*8-8]
2236 | add RA, 1
2237 | jmp <1
2238 |3:
2239 | ja ->fff_fallback
2240 | // Convert intermediate result to number and continue below.
2241 | cvtsi2sd xmm0, RB
2242 | jmp >6
2243 |4:
2244 | ja ->fff_fallback
2245 |.else
2246 | jae ->fff_fallback
2247 |.endif
2248 |
2249 | movsd xmm0, qword [BASE]
2250 |5: // Handle numbers or integers.
2251 | cmp RA, RD; jae ->fff_resxmm0
2252 | cmp dword [BASE+RA*8-4], LJ_TISNUM
2253 |.if DUALNUM
2254 | jb >6
2255 | ja ->fff_fallback
2256 | cvtsi2sd xmm1, dword [BASE+RA*8-8]
2257 | jmp >7
2258 |.else
2259 | jae ->fff_fallback
2260 |.endif
2261 |6:
2262 | movsd xmm1, qword [BASE+RA*8-8]
2263 |7:
2264 | sseop xmm0, xmm1
2265 | add RA, 1
2266 | jmp <5
2267 |.endmacro
2268 |
2269 | math_minmax math_min, cmovg, minsd
2270 | math_minmax math_max, cmovl, maxsd
2271 |
2272 |//-- String library -----------------------------------------------------
2273 |
2274 |.ffunc string_byte // Only handle the 1-arg case here.
2275 | cmp NARGS:RD, 1+1; jne ->fff_fallback
2276 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2277 | mov STR:RB, [BASE]
2278 | mov PC, [BASE-4]
2279 | cmp dword STR:RB->len, 1
2280 | jb ->fff_res0 // Return no results for empty string.
2281 | movzx RB, byte STR:RB[1]
2282 |.if DUALNUM
2283 | jmp ->fff_resi
2284 |.else
2285 | cvtsi2sd xmm0, RB; jmp ->fff_resxmm0
2286 |.endif
2287 |
2288 |.ffunc string_char // Only handle the 1-arg case here.
2289 | ffgccheck
2290 | cmp NARGS:RD, 1+1; jne ->fff_fallback // *Exactly* 1 arg.
2291 | cmp dword [BASE+4], LJ_TISNUM
2292 |.if DUALNUM
2293 | jne ->fff_fallback
2294 | mov RB, dword [BASE]
2295 | cmp RB, 255; ja ->fff_fallback
2296 | mov TMP2, RB
2297 |.else
2298 | jae ->fff_fallback
2299 | cvttsd2si RB, qword [BASE]
2300 | cmp RB, 255; ja ->fff_fallback
2301 | mov TMP2, RB
2302 |.endif
2303 |.if X64
2304 | mov TMP3, 1
2305 |.else
2306 | mov ARG3, 1
2307 |.endif
2308 | lea RDa, TMP2 // Points to stack. Little-endian.
2309 |->fff_newstr:
2310 | mov L:RB, SAVE_L
2311 | mov L:RB->base, BASE
2312 |.if X64
2313 | mov CARG3d, TMP3 // Zero-extended to size_t.
2314 | mov CARG2, RDa // May be 64 bit ptr to stack.
2315 | mov CARG1d, L:RB
2316 |.else
2317 | mov ARG2, RD
2318 | mov ARG1, L:RB
2319 |.endif
2320 | mov SAVE_PC, PC
2321 | call extern lj_str_new // (lua_State *L, char *str, size_t l)
2322 |->fff_resstr:
2323 | // GCstr * returned in eax (RD).
2324 | mov BASE, L:RB->base
2325 | mov PC, [BASE-4]
2326 | mov dword [BASE-4], LJ_TSTR
2327 | mov [BASE-8], STR:RD
2328 | jmp ->fff_res1
2329 |
2330 |.ffunc string_sub
2331 | ffgccheck
2332 | mov TMP2, -1
2333 | cmp NARGS:RD, 1+2; jb ->fff_fallback
2334 | jna >1
2335 | cmp dword [BASE+20], LJ_TISNUM
2336 |.if DUALNUM
2337 | jne ->fff_fallback
2338 | mov RB, dword [BASE+16]
2339 | mov TMP2, RB
2340 |.else
2341 | jae ->fff_fallback
2342 | cvttsd2si RB, qword [BASE+16]
2343 | mov TMP2, RB
2344 |.endif
2345 |1:
2346 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2347 | cmp dword [BASE+12], LJ_TISNUM
2348 |.if DUALNUM
2349 | jne ->fff_fallback
2350 |.else
2351 | jae ->fff_fallback
2352 |.endif
2353 | mov STR:RB, [BASE]
2354 | mov TMP3, STR:RB
2355 | mov RB, STR:RB->len
2356 |.if DUALNUM
2357 | mov RA, dword [BASE+8]
2358 |.else
2359 | cvttsd2si RA, qword [BASE+8]
2360 |.endif
2361 | mov RC, TMP2
2362 | cmp RB, RC // len < end? (unsigned compare)
2363 | jb >5
2364 |2:
2365 | test RA, RA // start <= 0?
2366 | jle >7
2367 |3:
2368 | mov STR:RB, TMP3
2369 | sub RC, RA // start > end?
2370 | jl ->fff_emptystr
2371 | lea RB, [STR:RB+RA+#STR-1]
2372 | add RC, 1
2373 |4:
2374 |.if X64
2375 | mov TMP3, RC
2376 |.else
2377 | mov ARG3, RC
2378 |.endif
2379 | mov RD, RB
2380 | jmp ->fff_newstr
2381 |
2382 |5: // Negative end or overflow.
2383 | jl >6
2384 | lea RC, [RC+RB+1] // end = end+(len+1)
2385 | jmp <2
2386 |6: // Overflow.
2387 | mov RC, RB // end = len
2388 | jmp <2
2389 |
2390 |7: // Negative start or underflow.
2391 | je >8
2392 | add RA, RB // start = start+(len+1)
2393 | add RA, 1
2394 | jg <3 // start > 0?
2395 |8: // Underflow.
2396 | mov RA, 1 // start = 1
2397 | jmp <3
2398 |
2399 |->fff_emptystr: // Range underflow.
2400 | xor RC, RC // Zero length. Any ptr in RB is ok.
2401 | jmp <4
2402 |
2403 |.macro ffstring_op, name
2404 | .ffunc_1 string_ .. name
2405 | ffgccheck
2406 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2407 | mov L:RB, SAVE_L
2408 | lea SBUF:FCARG1, [DISPATCH+DISPATCH_GL(tmpbuf)]
2409 | mov L:RB->base, BASE
2410 | mov STR:FCARG2, [BASE] // Caveat: FCARG2 == BASE
2411 | mov RCa, SBUF:FCARG1->b
2412 | mov SBUF:FCARG1->L, L:RB
2413 | mov SBUF:FCARG1->w, RCa
2414 | mov SAVE_PC, PC
2415 | call extern lj_buf_putstr_ .. name .. @8
2416 | mov FCARG1, eax
2417 | call extern lj_buf_tostr@4
2418 | jmp ->fff_resstr
2419 |.endmacro
2420 |
2421 |ffstring_op reverse
2422 |ffstring_op lower
2423 |ffstring_op upper
2424 |
2425 |//-- Bit library --------------------------------------------------------
2426 |
2427 |.macro .ffunc_bit, name, kind, fdef
2428 | fdef name
2429 |.if kind == 2
2430 | sseconst_tobit xmm1, RBa
2431 |.endif
2432 | cmp dword [BASE+4], LJ_TISNUM
2433 |.if DUALNUM
2434 | jne >1
2435 | mov RB, dword [BASE]
2436 |.if kind > 0
2437 | jmp >2
2438 |.else
2439 | jmp ->fff_resbit
2440 |.endif
2441 |1:
2442 | ja ->fff_fallback
2443 |.else
2444 | jae ->fff_fallback
2445 |.endif
2446 | movsd xmm0, qword [BASE]
2447 |.if kind < 2
2448 | sseconst_tobit xmm1, RBa
2449 |.endif
2450 | addsd xmm0, xmm1
2451 | movd RB, xmm0
2452 |2:
2453 |.endmacro
2454 |
2455 |.macro .ffunc_bit, name, kind
2456 | .ffunc_bit name, kind, .ffunc_1
2457 |.endmacro
2458 |
2459 |.ffunc_bit bit_tobit, 0
2460 | jmp ->fff_resbit
2461 |
2462 |.macro .ffunc_bit_op, name, ins
2463 | .ffunc_bit name, 2
2464 | mov TMP2, NARGS:RD // Save for fallback.
2465 | lea RD, [BASE+NARGS:RD*8-16]
2466 |1:
2467 | cmp RD, BASE
2468 | jbe ->fff_resbit
2469 | cmp dword [RD+4], LJ_TISNUM
2470 |.if DUALNUM
2471 | jne >2
2472 | ins RB, dword [RD]
2473 | sub RD, 8
2474 | jmp <1
2475 |2:
2476 | ja ->fff_fallback_bit_op
2477 |.else
2478 | jae ->fff_fallback_bit_op
2479 |.endif
2480 | movsd xmm0, qword [RD]
2481 | addsd xmm0, xmm1
2482 | movd RA, xmm0
2483 | ins RB, RA
2484 | sub RD, 8
2485 | jmp <1
2486 |.endmacro
2487 |
2488 |.ffunc_bit_op bit_band, and
2489 |.ffunc_bit_op bit_bor, or
2490 |.ffunc_bit_op bit_bxor, xor
2491 |
2492 |.ffunc_bit bit_bswap, 1
2493 | bswap RB
2494 | jmp ->fff_resbit
2495 |
2496 |.ffunc_bit bit_bnot, 1
2497 | not RB
2498 |.if DUALNUM
2499 | jmp ->fff_resbit
2500 |.else
2501 |->fff_resbit:
2502 | cvtsi2sd xmm0, RB
2503 | jmp ->fff_resxmm0
2504 |.endif
2505 |
2506 |->fff_fallback_bit_op:
2507 | mov NARGS:RD, TMP2 // Restore for fallback
2508 | jmp ->fff_fallback
2509 |
2510 |.macro .ffunc_bit_sh, name, ins
2511 |.if DUALNUM
2512 | .ffunc_bit name, 1, .ffunc_2
2513 | // Note: no inline conversion from number for 2nd argument!
2514 | cmp dword [BASE+12], LJ_TISNUM; jne ->fff_fallback
2515 | mov RA, dword [BASE+8]
2516 |.else
2517 | .ffunc_nnsse name
2518 | sseconst_tobit xmm2, RBa
2519 | addsd xmm0, xmm2
2520 | addsd xmm1, xmm2
2521 | movd RB, xmm0
2522 | movd RA, xmm1
2523 |.endif
2524 | ins RB, cl // Assumes RA is ecx.
2525 | jmp ->fff_resbit
2526 |.endmacro
2527 |
2528 |.ffunc_bit_sh bit_lshift, shl
2529 |.ffunc_bit_sh bit_rshift, shr
2530 |.ffunc_bit_sh bit_arshift, sar
2531 |.ffunc_bit_sh bit_rol, rol
2532 |.ffunc_bit_sh bit_ror, ror
2533 |
2534 |//-----------------------------------------------------------------------
2535 |
2536 |->fff_fallback_2:
2537 | mov NARGS:RD, 1+2 // Other args are ignored, anyway.
2538 | jmp ->fff_fallback
2539 |->fff_fallback_1:
2540 | mov NARGS:RD, 1+1 // Other args are ignored, anyway.
2541 |->fff_fallback: // Call fast function fallback handler.
2542 | // BASE = new base, RD = nargs+1
2543 | mov L:RB, SAVE_L
2544 | mov PC, [BASE-4] // Fallback may overwrite PC.
2545 | mov SAVE_PC, PC // Redundant (but a defined value).
2546 | mov L:RB->base, BASE
2547 | lea RD, [BASE+NARGS:RD*8-8]
2548 | lea RA, [RD+8*LUA_MINSTACK] // Ensure enough space for handler.
2549 | mov L:RB->top, RD
2550 | mov CFUNC:RD, [BASE-8]
2551 | cmp RA, L:RB->maxstack
2552 | ja >5 // Need to grow stack.
2553 |.if X64
2554 | mov CARG1d, L:RB
2555 |.else
2556 | mov ARG1, L:RB
2557 |.endif
2558 | call aword CFUNC:RD->f // (lua_State *L)
2559 | mov BASE, L:RB->base
2560 | // Either throws an error, or recovers and returns -1, 0 or nresults+1.
2561 | test RD, RD; jg ->fff_res // Returned nresults+1?
2562 |1:
2563 | mov RA, L:RB->top
2564 | sub RA, BASE
2565 | shr RA, 3
2566 | test RD, RD
2567 | lea NARGS:RD, [RA+1]
2568 | mov LFUNC:RB, [BASE-8]
2569 | jne ->vm_call_tail // Returned -1?
2570 | ins_callt // Returned 0: retry fast path.
2571 |
2572 |// Reconstruct previous base for vmeta_call during tailcall.
2573 |->vm_call_tail:
2574 | mov RA, BASE
2575 | test PC, FRAME_TYPE
2576 | jnz >3
2577 | movzx RB, PC_RA
2578 | not RBa // Note: ~RB = -(RB+1)
2579 | lea BASE, [BASE+RB*8] // base = base - (RB+1)*8
2580 | jmp ->vm_call_dispatch // Resolve again for tailcall.
2581 |3:
2582 | mov RB, PC
2583 | and RB, -8
2584 | sub BASE, RB
2585 | jmp ->vm_call_dispatch // Resolve again for tailcall.
2586 |
2587 |5: // Grow stack for fallback handler.
2588 | mov FCARG2, LUA_MINSTACK
2589 | mov FCARG1, L:RB
2590 | call extern lj_state_growstack@8 // (lua_State *L, int n)
2591 | mov BASE, L:RB->base
2592 | xor RD, RD // Simulate a return 0.
2593 | jmp <1 // Dumb retry (goes through ff first).
2594 |
2595 |->fff_gcstep: // Call GC step function.
2596 | // BASE = new base, RD = nargs+1
2597 | pop RBa // Must keep stack at same level.
2598 | mov TMPa, RBa // Save return address
2599 | mov L:RB, SAVE_L
2600 | mov SAVE_PC, PC // Redundant (but a defined value).
2601 | mov L:RB->base, BASE
2602 | lea RD, [BASE+NARGS:RD*8-8]
2603 | mov FCARG1, L:RB
2604 | mov L:RB->top, RD
2605 | call extern lj_gc_step@4 // (lua_State *L)
2606 | mov BASE, L:RB->base
2607 | mov RD, L:RB->top
2608 | sub RD, BASE
2609 | shr RD, 3
2610 | add NARGS:RD, 1
2611 | mov RBa, TMPa
2612 | push RBa // Restore return address.
2613 | ret
2614 |
2615 |//-----------------------------------------------------------------------
2616 |//-- Special dispatch targets -------------------------------------------
2617 |//-----------------------------------------------------------------------
2618 |
2619 |->vm_record: // Dispatch target for recording phase.
2620 |.if JIT
2621 | movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
2622 | test RDL, HOOK_VMEVENT // No recording while in vmevent.
2623 | jnz >5
2624 | // Decrement the hookcount for consistency, but always do the call.
2625 | test RDL, HOOK_ACTIVE
2626 | jnz >1
2627 | test RDL, LUA_MASKLINE|LUA_MASKCOUNT
2628 | jz >1
2629 | dec dword [DISPATCH+DISPATCH_GL(hookcount)]
2630 | jmp >1
2631 |.endif
2632 |
2633 |->vm_rethook: // Dispatch target for return hooks.
2634 | movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
2635 | test RDL, HOOK_ACTIVE // Hook already active?
2636 | jnz >5
2637 | jmp >1
2638 |
2639 |->vm_inshook: // Dispatch target for instr/line hooks.
2640 | movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
2641 | test RDL, HOOK_ACTIVE // Hook already active?
2642 | jnz >5
2643 |
2644 | test RDL, LUA_MASKLINE|LUA_MASKCOUNT
2645 | jz >5
2646 | dec dword [DISPATCH+DISPATCH_GL(hookcount)]
2647 | jz >1
2648 | test RDL, LUA_MASKLINE
2649 | jz >5
2650 |1:
2651 | mov L:RB, SAVE_L
2652 | mov L:RB->base, BASE
2653 | mov FCARG2, PC // Caveat: FCARG2 == BASE
2654 | mov FCARG1, L:RB
2655 | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
2656 | call extern lj_dispatch_ins@8 // (lua_State *L, const BCIns *pc)
2657 |3:
2658 | mov BASE, L:RB->base
2659 |4:
2660 | movzx RA, PC_RA
2661 |5:
2662 | movzx OP, PC_OP
2663 | movzx RD, PC_RD
2664 |.if X64
2665 | jmp aword [DISPATCH+OP*8+GG_DISP2STATIC] // Re-dispatch to static ins.
2666 |.else
2667 | jmp aword [DISPATCH+OP*4+GG_DISP2STATIC] // Re-dispatch to static ins.
2668 |.endif
2669 |
2670 |->cont_hook: // Continue from hook yield.
2671 | add PC, 4
2672 | mov RA, [RB-24]
2673 | mov MULTRES, RA // Restore MULTRES for *M ins.
2674 | jmp <4
2675 |
2676 |->vm_hotloop: // Hot loop counter underflow.
2677 |.if JIT
2678 | mov LFUNC:RB, [BASE-8] // Same as curr_topL(L).
2679 | mov RB, LFUNC:RB->pc
2680 | movzx RD, byte [RB+PC2PROTO(framesize)]
2681 | lea RD, [BASE+RD*8]
2682 | mov L:RB, SAVE_L
2683 | mov L:RB->base, BASE
2684 | mov L:RB->top, RD
2685 | mov FCARG2, PC
2686 | lea FCARG1, [DISPATCH+GG_DISP2J]
2687 | mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
2688 | mov SAVE_PC, PC
2689 | call extern lj_trace_hot@8 // (jit_State *J, const BCIns *pc)
2690 | jmp <3
2691 |.endif
2692 |
2693 |->vm_callhook: // Dispatch target for call hooks.
2694 | mov SAVE_PC, PC
2695 |.if JIT
2696 | jmp >1
2697 |.endif
2698 |
2699 |->vm_hotcall: // Hot call counter underflow.
2700 |.if JIT
2701 | mov SAVE_PC, PC
2702 | or PC, 1 // Marker for hot call.
2703 |1:
2704 |.endif
2705 | lea RD, [BASE+NARGS:RD*8-8]
2706 | mov L:RB, SAVE_L
2707 | mov L:RB->base, BASE
2708 | mov L:RB->top, RD
2709 | mov FCARG2, PC
2710 | mov FCARG1, L:RB
2711 | call extern lj_dispatch_call@8 // (lua_State *L, const BCIns *pc)
2712 | // ASMFunction returned in eax/rax (RDa).
2713 | mov SAVE_PC, 0 // Invalidate for subsequent line hook.
2714 |.if JIT
2715 | and PC, -2
2716 |.endif
2717 | mov BASE, L:RB->base
2718 | mov RAa, RDa
2719 | mov RD, L:RB->top
2720 | sub RD, BASE
2721 | mov RBa, RAa
2722 | movzx RA, PC_RA
2723 | shr RD, 3
2724 | add NARGS:RD, 1
2725 | jmp RBa
2726 |
2727 |->cont_stitch: // Trace stitching.
2728 |.if JIT
2729 | // BASE = base, RC = result, RB = mbase
2730 | mov TRACE:RA, [RB-24] // Save previous trace.
2731 | mov TMP1, TRACE:RA
2732 | mov TMP3, DISPATCH // Need one more register.
2733 | mov DISPATCH, MULTRES
2734 | movzx RA, PC_RA
2735 | lea RA, [BASE+RA*8] // Call base.
2736 | sub DISPATCH, 1
2737 | jz >2
2738 |1: // Move results down.
2739 |.if X64
2740 | mov RBa, [RC]
2741 | mov [RA], RBa
2742 |.else
2743 | mov RB, [RC]
2744 | mov [RA], RB
2745 | mov RB, [RC+4]
2746 | mov [RA+4], RB
2747 |.endif
2748 | add RC, 8
2749 | add RA, 8
2750 | sub DISPATCH, 1
2751 | jnz <1
2752 |2:
2753 | movzx RC, PC_RA
2754 | movzx RB, PC_RB
2755 | add RC, RB
2756 | lea RC, [BASE+RC*8-8]
2757 |3:
2758 | cmp RC, RA
2759 | ja >9 // More results wanted?
2760 |
2761 | mov DISPATCH, TMP3
2762 | mov TRACE:RD, TMP1 // Get previous trace.
2763 | movzx RB, word TRACE:RD->traceno
2764 | movzx RD, word TRACE:RD->link
2765 | cmp RD, RB
2766 | je ->cont_nop // Blacklisted.
2767 | test RD, RD
2768 | jne =>BC_JLOOP // Jump to stitched trace.
2769 |
2770 | // Stitch a new trace to the previous trace.
2771 | mov [DISPATCH+DISPATCH_J(exitno)], RB
2772 | mov L:RB, SAVE_L
2773 | mov L:RB->base, BASE
2774 | mov FCARG2, PC
2775 | lea FCARG1, [DISPATCH+GG_DISP2J]
2776 | mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
2777 | call extern lj_dispatch_stitch@8 // (jit_State *J, const BCIns *pc)
2778 | mov BASE, L:RB->base
2779 | jmp ->cont_nop
2780 |
2781 |9: // Fill up results with nil.
2782 | mov dword [RA+4], LJ_TNIL
2783 | add RA, 8
2784 | jmp <3
2785 |.endif
2786 |
2787 |->vm_profhook: // Dispatch target for profiler hook.
2788#if LJ_HASPROFILE
2789 | mov L:RB, SAVE_L
2790 | mov L:RB->base, BASE
2791 | mov FCARG2, PC // Caveat: FCARG2 == BASE
2792 | mov FCARG1, L:RB
2793 | call extern lj_dispatch_profile@8 // (lua_State *L, const BCIns *pc)
2794 | mov BASE, L:RB->base
2795 | // HOOK_PROFILE is off again, so re-dispatch to dynamic instruction.
2796 | sub PC, 4
2797 | jmp ->cont_nop
2798#endif
2799 |
2800 |//-----------------------------------------------------------------------
2801 |//-- Trace exit handler -------------------------------------------------
2802 |//-----------------------------------------------------------------------
2803 |
2804 |// Called from an exit stub with the exit number on the stack.
2805 |// The 16 bit exit number is stored with two (sign-extended) push imm8.
2806 |->vm_exit_handler:
2807 |.if JIT
2808 |.if X64
2809 | push r13; push r12
2810 | push r11; push r10; push r9; push r8
2811 | push rdi; push rsi; push rbp; lea rbp, [rsp+88]; push rbp
2812 | push rbx; push rdx; push rcx; push rax
2813 | movzx RC, byte [rbp-8] // Reconstruct exit number.
2814 | mov RCH, byte [rbp-16]
2815 | mov [rbp-8], r15; mov [rbp-16], r14
2816 |.else
2817 | push ebp; lea ebp, [esp+12]; push ebp
2818 | push ebx; push edx; push ecx; push eax
2819 | movzx RC, byte [ebp-4] // Reconstruct exit number.
2820 | mov RCH, byte [ebp-8]
2821 | mov [ebp-4], edi; mov [ebp-8], esi
2822 |.endif
2823 | // Caveat: DISPATCH is ebx.
2824 | mov DISPATCH, [ebp]
2825 | mov RA, [DISPATCH+DISPATCH_GL(vmstate)] // Get trace number.
2826 | set_vmstate EXIT
2827 | mov [DISPATCH+DISPATCH_J(exitno)], RC
2828 | mov [DISPATCH+DISPATCH_J(parent)], RA
2829 |.if X64
2830 |.if X64WIN
2831 | sub rsp, 16*8+4*8 // Room for SSE regs + save area.
2832 |.else
2833 | sub rsp, 16*8 // Room for SSE regs.
2834 |.endif
2835 | add rbp, -128
2836 | movsd qword [rbp-8], xmm15; movsd qword [rbp-16], xmm14
2837 | movsd qword [rbp-24], xmm13; movsd qword [rbp-32], xmm12
2838 | movsd qword [rbp-40], xmm11; movsd qword [rbp-48], xmm10
2839 | movsd qword [rbp-56], xmm9; movsd qword [rbp-64], xmm8
2840 | movsd qword [rbp-72], xmm7; movsd qword [rbp-80], xmm6
2841 | movsd qword [rbp-88], xmm5; movsd qword [rbp-96], xmm4
2842 | movsd qword [rbp-104], xmm3; movsd qword [rbp-112], xmm2
2843 | movsd qword [rbp-120], xmm1; movsd qword [rbp-128], xmm0
2844 |.else
2845 | sub esp, 8*8+16 // Room for SSE regs + args.
2846 | movsd qword [ebp-40], xmm7; movsd qword [ebp-48], xmm6
2847 | movsd qword [ebp-56], xmm5; movsd qword [ebp-64], xmm4
2848 | movsd qword [ebp-72], xmm3; movsd qword [ebp-80], xmm2
2849 | movsd qword [ebp-88], xmm1; movsd qword [ebp-96], xmm0
2850 |.endif
2851 | // Caveat: RB is ebp.
2852 | mov L:RB, [DISPATCH+DISPATCH_GL(cur_L)]
2853 | mov BASE, [DISPATCH+DISPATCH_GL(jit_base)]
2854 | mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
2855 | mov L:RB->base, BASE
2856 |.if X64WIN
2857 | lea CARG2, [rsp+4*8]
2858 |.elif X64
2859 | mov CARG2, rsp
2860 |.else
2861 | lea FCARG2, [esp+16]
2862 |.endif
2863 | lea FCARG1, [DISPATCH+GG_DISP2J]
2864 | mov dword [DISPATCH+DISPATCH_GL(jit_base)], 0
2865 | call extern lj_trace_exit@8 // (jit_State *J, ExitState *ex)
2866 | // MULTRES or negated error code returned in eax (RD).
2867 | mov RAa, L:RB->cframe
2868 | and RAa, CFRAME_RAWMASK
2869 |.if X64WIN
2870 | // Reposition stack later.
2871 |.elif X64
2872 | mov rsp, RAa // Reposition stack to C frame.
2873 |.else
2874 | mov esp, RAa // Reposition stack to C frame.
2875 |.endif
2876 | mov [RAa+CFRAME_OFS_L], L:RB // Set SAVE_L (on-trace resume/yield).
2877 | mov BASE, L:RB->base
2878 | mov PC, [RAa+CFRAME_OFS_PC] // Get SAVE_PC.
2879 |.if X64
2880 | jmp >1
2881 |.endif
2882 |.endif
2883 |->vm_exit_interp:
2884 | // RD = MULTRES or negated error code, BASE, PC and DISPATCH set.
2885 |.if JIT
2886 |.if X64
2887 | // Restore additional callee-save registers only used in compiled code.
2888 |.if X64WIN
2889 | lea RAa, [rsp+9*16+4*8]
2890 |1:
2891 | movdqa xmm15, [RAa-9*16]
2892 | movdqa xmm14, [RAa-8*16]
2893 | movdqa xmm13, [RAa-7*16]
2894 | movdqa xmm12, [RAa-6*16]
2895 | movdqa xmm11, [RAa-5*16]
2896 | movdqa xmm10, [RAa-4*16]
2897 | movdqa xmm9, [RAa-3*16]
2898 | movdqa xmm8, [RAa-2*16]
2899 | movdqa xmm7, [RAa-1*16]
2900 | mov rsp, RAa // Reposition stack to C frame.
2901 | movdqa xmm6, [RAa]
2902 | mov r15, CSAVE_3
2903 | mov r14, CSAVE_4
2904 |.else
2905 | add rsp, 16 // Reposition stack to C frame.
2906 |1:
2907 |.endif
2908 | mov r13, TMPa
2909 | mov r12, TMPQ
2910 |.endif
2911 | cmp RD, -LUA_ERRERR; jae >9 // Check for error from exit.
2912 | mov L:RB, SAVE_L
2913 | mov MULTRES, RD
2914 | mov LFUNC:KBASE, [BASE-8]
2915 | mov KBASE, LFUNC:KBASE->pc
2916 | mov KBASE, [KBASE+PC2PROTO(k)]
2917 | mov L:RB->base, BASE
2918 | mov dword [DISPATCH+DISPATCH_GL(jit_base)], 0
2919 | set_vmstate INTERP
2920 | // Modified copy of ins_next which handles function header dispatch, too.
2921 | mov RC, [PC]
2922 | movzx RA, RCH
2923 | movzx OP, RCL
2924 | add PC, 4
2925 | shr RC, 16
2926 | cmp MULTRES, -17 // Static dispatch?
2927 | je >5
2928 | cmp OP, BC_FUNCF // Function header?
2929 | jb >3
2930 | cmp OP, BC_FUNCC+2 // Fast function?
2931 | jae >4
2932 |2:
2933 | mov RC, MULTRES // RC/RD holds nres+1.
2934 |3:
2935 |.if X64
2936 | jmp aword [DISPATCH+OP*8]
2937 |.else
2938 | jmp aword [DISPATCH+OP*4]
2939 |.endif
2940 |
2941 |4: // Check frame below fast function.
2942 | mov RC, [BASE-4]
2943 | test RC, FRAME_TYPE
2944 | jnz <2 // Trace stitching continuation?
2945 | // Otherwise set KBASE for Lua function below fast function.
2946 | movzx RC, byte [RC-3]
2947 | not RCa
2948 | mov LFUNC:KBASE, [BASE+RC*8-8]
2949 | mov KBASE, LFUNC:KBASE->pc
2950 | mov KBASE, [KBASE+PC2PROTO(k)]
2951 | jmp <2
2952 |
2953 |5: // Dispatch to static entry of original ins replaced by BC_JLOOP.
2954 | mov RA, [DISPATCH+DISPATCH_J(trace)]
2955 | mov TRACE:RA, [RA+RD*4]
2956 | mov RC, TRACE:RA->startins
2957 | movzx RA, RCH
2958 | movzx OP, RCL
2959 | shr RC, 16
2960 |.if X64
2961 | jmp aword [DISPATCH+OP*8+GG_DISP2STATIC]
2962 |.else
2963 | jmp aword [DISPATCH+OP*4+GG_DISP2STATIC]
2964 |.endif
2965 |
2966 |9: // Rethrow error from the right C frame.
2967 | mov FCARG2, RD
2968 | mov FCARG1, L:RB
2969 | neg FCARG2
2970 | call extern lj_err_trace@8 // (lua_State *L, int errcode)
2971 |.endif
2972 |
2973 |//-----------------------------------------------------------------------
2974 |//-- Math helper functions ----------------------------------------------
2975 |//-----------------------------------------------------------------------
2976 |
2977 |// FP value rounding. Called by math.floor/math.ceil fast functions
2978 |// and from JIT code. arg/ret is xmm0. xmm0-xmm3 and RD (eax) modified.
2979 |.macro vm_round, name, mode, cond
2980 |->name:
2981 |.if not X64 and cond
2982 | movsd xmm0, qword [esp+4]
2983 | call ->name .. _sse
2984 | movsd qword [esp+4], xmm0 // Overwrite callee-owned arg.
2985 | fld qword [esp+4]
2986 | ret
2987 |.endif
2988 |
2989 |->name .. _sse:
2990 | sseconst_abs xmm2, RDa
2991 | sseconst_2p52 xmm3, RDa
2992 | movaps xmm1, xmm0
2993 | andpd xmm1, xmm2 // |x|
2994 | ucomisd xmm3, xmm1 // No truncation if 2^52 <= |x|.
2995 | jbe >1
2996 | andnpd xmm2, xmm0 // Isolate sign bit.
2997 |.if mode == 2 // trunc(x)?
2998 | movaps xmm0, xmm1
2999 | addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
3000 | subsd xmm1, xmm3
3001 | sseconst_1 xmm3, RDa
3002 | cmpsd xmm0, xmm1, 1 // |x| < result?
3003 | andpd xmm0, xmm3
3004 | subsd xmm1, xmm0 // If yes, subtract -1.
3005 | orpd xmm1, xmm2 // Merge sign bit back in.
3006 |.else
3007 | addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
3008 | subsd xmm1, xmm3
3009 | orpd xmm1, xmm2 // Merge sign bit back in.
3010 | sseconst_1 xmm3, RDa
3011 | .if mode == 1 // ceil(x)?
3012 | cmpsd xmm0, xmm1, 6 // x > result?
3013 | andpd xmm0, xmm3
3014 | addsd xmm1, xmm0 // If yes, add 1.
3015 | orpd xmm1, xmm2 // Merge sign bit back in (again).
3016 | .else // floor(x)?
3017 | cmpsd xmm0, xmm1, 1 // x < result?
3018 | andpd xmm0, xmm3
3019 | subsd xmm1, xmm0 // If yes, subtract 1.
3020 | .endif
3021 |.endif
3022 | movaps xmm0, xmm1
3023 |1:
3024 | ret
3025 |.endmacro
3026 |
3027 | vm_round vm_floor, 0, 1
3028 | vm_round vm_ceil, 1, JIT
3029 | vm_round vm_trunc, 2, JIT
3030 |
3031 |// FP modulo x%y. Called by BC_MOD* and vm_arith.
3032 |->vm_mod:
3033 |// Args in xmm0/xmm1, return value in xmm0.
3034 |// Caveat: xmm0-xmm5 and RC (eax) modified!
3035 | movaps xmm5, xmm0
3036 | divsd xmm0, xmm1
3037 | sseconst_abs xmm2, RDa
3038 | sseconst_2p52 xmm3, RDa
3039 | movaps xmm4, xmm0
3040 | andpd xmm4, xmm2 // |x/y|
3041 | ucomisd xmm3, xmm4 // No truncation if 2^52 <= |x/y|.
3042 | jbe >1
3043 | andnpd xmm2, xmm0 // Isolate sign bit.
3044 | addsd xmm4, xmm3 // (|x/y| + 2^52) - 2^52
3045 | subsd xmm4, xmm3
3046 | orpd xmm4, xmm2 // Merge sign bit back in.
3047 | sseconst_1 xmm2, RDa
3048 | cmpsd xmm0, xmm4, 1 // x/y < result?
3049 | andpd xmm0, xmm2
3050 | subsd xmm4, xmm0 // If yes, subtract 1.0.
3051 | movaps xmm0, xmm5
3052 | mulsd xmm1, xmm4
3053 | subsd xmm0, xmm1
3054 | ret
3055 |1:
3056 | mulsd xmm1, xmm0
3057 | movaps xmm0, xmm5
3058 | subsd xmm0, xmm1
3059 | ret
3060 |
3061 |//-----------------------------------------------------------------------
3062 |//-- Number conversion functions ----------------------------------------
3063 |//-----------------------------------------------------------------------
3064 |
3065 |// int64_t lj_vm_num2int_check(double x)
3066 |->vm_num2int_check:
3067 |.if not X64
3068 | movsd xmm0, qword [esp+4]
3069 |.endif
3070 | cvttsd2si eax, xmm0
3071 | xorps xmm1, xmm1
3072 | cvtsi2sd xmm1, eax
3073 | ucomisd xmm1, xmm0
3074 | jp >1
3075 | jne >1
3076 |.if not X64
3077 | xor edx, edx
3078 |.endif
3079 | ret
3080 |1:
3081 |.if X64
3082 | mov64 rax, U64x(80000000,80000000)
3083 |.else
3084 | mov eax, 0x80000000
3085 | mov edx, eax
3086 |.endif
3087 | ret
3088 |
3089 |// int64_t lj_vm_num2i64(double x)
3090 |->vm_num2i64:
3091 |.if X64
3092 | cvttsd2si rax, xmm0
3093 | ret
3094 |.else
3095 | sub esp, 12
3096 | fld qword [esp+16]
3097 | fisttp qword [esp]
3098 | mov eax, dword [esp]
3099 | mov edx, dword [esp+4]
3100 | add esp, 12
3101 | ret
3102 |.endif
3103 |
3104 |// uint64_t lj_vm_num2u64(double x)
3105 |->vm_num2u64:
3106 |.if X64
3107 | cvttsd2si rax, xmm0 // Convert [-2^63..2^63) range.
3108 | cmp rax, 1 // Indefinite result -0x8000000000000000LL - 1 sets overflow.
3109 | jo >1
3110 | ret
3111 |1:
3112 | mov64 rdx, U64x(c3f00000,00000000) // -0x1p64 (double).
3113 | movd xmm1, rdx
3114 | addsd xmm0, xmm1
3115 | cvttsd2si rax, xmm0 // Convert [2^63..2^64+2^63) range.
3116 | // Note that -0x1p63 converts to -0x8000000000000000LL either way.
3117 | ret
3118 |.else
3119 | sub esp, 12
3120 | fld qword [esp+16]
3121 | fld st0
3122 | fisttp qword [esp]
3123 | mov edx, dword [esp+4]
3124 | mov eax, dword [esp]
3125 | cmp edx, 1
3126 | jo >2
3127 |1:
3128 | fpop
3129 | add esp, 12
3130 | ret
3131 |2:
3132 | cmp eax, 0
3133 | jne <1
3134 | mov dword [esp+8], 0xdf800000 // -0x1p64 (float).
3135 | fadd dword [esp+8]
3136 | fisttp qword [esp]
3137 | mov eax, dword [esp]
3138 | mov edx, dword [esp+4]
3139 | add esp, 12
3140 | ret
3141 |.endif
3142 |
3143 |// int32_t lj_vm_tobit(double x)
3144 |->vm_tobit:
3145 |.if not X64
3146 | movsd xmm0, qword [esp+4]
3147 |.endif
3148 | sseconst_tobit xmm1, RCa
3149 | addsd xmm0, xmm1
3150 | movd eax, xmm0
3151 | ret
3152 |
3153 |//-----------------------------------------------------------------------
3154 |//-- Miscellaneous functions --------------------------------------------
3155 |//-----------------------------------------------------------------------
3156 |
3157 |// int lj_vm_cpuid(uint32_t f, uint32_t res[4])
3158 |->vm_cpuid:
3159 |.if X64
3160 | mov eax, CARG1d
3161 | .if X64WIN; push rsi; mov rsi, CARG2; .endif
3162 | push rbx
3163 | xor ecx, ecx
3164 | cpuid
3165 | mov [rsi], eax
3166 | mov [rsi+4], ebx
3167 | mov [rsi+8], ecx
3168 | mov [rsi+12], edx
3169 | pop rbx
3170 | .if X64WIN; pop rsi; .endif
3171 | ret
3172 |.else
3173 | pushfd
3174 | pop edx
3175 | mov ecx, edx
3176 | xor edx, 0x00200000 // Toggle ID bit in flags.
3177 | push edx
3178 | popfd
3179 | pushfd
3180 | pop edx
3181 | xor eax, eax // Zero means no features supported.
3182 | cmp ecx, edx
3183 | jz >1 // No ID toggle means no CPUID support.
3184 | mov eax, [esp+4] // Argument 1 is function number.
3185 | push edi
3186 | push ebx
3187 | xor ecx, ecx
3188 | cpuid
3189 | mov edi, [esp+16] // Argument 2 is result area.
3190 | mov [edi], eax
3191 | mov [edi+4], ebx
3192 | mov [edi+8], ecx
3193 | mov [edi+12], edx
3194 | pop ebx
3195 | pop edi
3196 |1:
3197 | ret
3198 |.endif
3199 |
3200 |.define NEXT_TAB, TAB:FCARG1
3201 |.define NEXT_IDX, FCARG2
3202 |.define NEXT_PTR, RCa
3203 |.define NEXT_PTRd, RC
3204 |.macro NEXT_RES_IDXL, op2; lea edx, [NEXT_IDX+op2]; .endmacro
3205 |.if X64
3206 |.define NEXT_TMP, CARG3d
3207 |.define NEXT_TMPq, CARG3
3208 |.define NEXT_ASIZE, CARG4d
3209 |.macro NEXT_ENTER; .endmacro
3210 |.macro NEXT_LEAVE; ret; .endmacro
3211 |.if X64WIN
3212 |.define NEXT_RES_PTR, [rsp+aword*5]
3213 |.macro NEXT_RES_IDX, op2; add NEXT_IDX, op2; .endmacro
3214 |.else
3215 |.define NEXT_RES_PTR, [rsp+aword*1]
3216 |.macro NEXT_RES_IDX, op2; lea edx, [NEXT_IDX+op2]; .endmacro
3217 |.endif
3218 |.else
3219 |.define NEXT_ASIZE, esi
3220 |.define NEXT_TMP, edi
3221 |.macro NEXT_ENTER; push esi; push edi; .endmacro
3222 |.macro NEXT_LEAVE; pop edi; pop esi; ret; .endmacro
3223 |.define NEXT_RES_PTR, [esp+dword*3]
3224 |.macro NEXT_RES_IDX, op2; add NEXT_IDX, op2; .endmacro
3225 |.endif
3226 |
3227 |// TValue *lj_vm_next(GCtab *t, uint32_t idx)
3228 |// Next idx returned in edx.
3229 |->vm_next:
3230 |.if JIT
3231 | NEXT_ENTER
3232 | mov NEXT_ASIZE, NEXT_TAB->asize
3233 |1: // Traverse array part.
3234 | cmp NEXT_IDX, NEXT_ASIZE; jae >5
3235 | mov NEXT_TMP, NEXT_TAB->array
3236 | cmp dword [NEXT_TMP+NEXT_IDX*8+4], LJ_TNIL; je >2
3237 | lea NEXT_PTR, NEXT_RES_PTR
3238 |.if X64
3239 | mov NEXT_TMPq, qword [NEXT_TMP+NEXT_IDX*8]
3240 | mov qword [NEXT_PTR], NEXT_TMPq
3241 |.else
3242 | mov NEXT_ASIZE, dword [NEXT_TMP+NEXT_IDX*8+4]
3243 | mov NEXT_TMP, dword [NEXT_TMP+NEXT_IDX*8]
3244 | mov dword [NEXT_PTR+4], NEXT_ASIZE
3245 | mov dword [NEXT_PTR], NEXT_TMP
3246 |.endif
3247 |.if DUALNUM
3248 | mov dword [NEXT_PTR+dword*3], LJ_TISNUM
3249 | mov dword [NEXT_PTR+dword*2], NEXT_IDX
3250 |.else
3251 | cvtsi2sd xmm0, NEXT_IDX
3252 | movsd qword [NEXT_PTR+dword*2], xmm0
3253 |.endif
3254 | NEXT_RES_IDX 1
3255 | NEXT_LEAVE
3256 |2: // Skip holes in array part.
3257 | add NEXT_IDX, 1
3258 | jmp <1
3259 |
3260 |5: // Traverse hash part.
3261 | sub NEXT_IDX, NEXT_ASIZE
3262 |6:
3263 | cmp NEXT_IDX, NEXT_TAB->hmask; ja >9
3264 | imul NEXT_PTRd, NEXT_IDX, #NODE
3265 | add NODE:NEXT_PTRd, dword NEXT_TAB->node
3266 | cmp dword NODE:NEXT_PTR->val.it, LJ_TNIL; je >7
3267 | NEXT_RES_IDXL NEXT_ASIZE+1
3268 | NEXT_LEAVE
3269 |7: // Skip holes in hash part.
3270 | add NEXT_IDX, 1
3271 | jmp <6
3272 |
3273 |9: // End of iteration. Set the key to nil (not the value).
3274 | NEXT_RES_IDX NEXT_ASIZE
3275 | lea NEXT_PTR, NEXT_RES_PTR
3276 | mov dword [NEXT_PTR+dword*3], LJ_TNIL
3277 | NEXT_LEAVE
3278 |.endif
3279 |
3280 |//-----------------------------------------------------------------------
3281 |//-- Assertions ---------------------------------------------------------
3282 |//-----------------------------------------------------------------------
3283 |
3284 |->assert_bad_for_arg_type:
3285#ifdef LUA_USE_ASSERT
3286 | int3
3287#endif
3288 | int3
3289 |
3290 |//-----------------------------------------------------------------------
3291 |//-- FFI helper functions -----------------------------------------------
3292 |//-----------------------------------------------------------------------
3293 |
3294 |// Handler for callback functions. Callback slot number in ah/al.
3295 |->vm_ffi_callback:
3296 |.if FFI
3297 |.type CTSTATE, CTState, PC
3298 |.if not X64
3299 | sub esp, 16 // Leave room for SAVE_ERRF etc.
3300 |.endif
3301 | saveregs_ // ebp/rbp already saved. ebp now holds global_State *.
3302 | lea DISPATCH, [ebp+GG_G2DISP]
3303 | mov CTSTATE, GL:ebp->ctype_state
3304 | movzx eax, ax
3305 | mov CTSTATE->cb.slot, eax
3306 |.if X64
3307 | mov CTSTATE->cb.gpr[0], CARG1
3308 | mov CTSTATE->cb.gpr[1], CARG2
3309 | mov CTSTATE->cb.gpr[2], CARG3
3310 | mov CTSTATE->cb.gpr[3], CARG4
3311 | movsd qword CTSTATE->cb.fpr[0], xmm0
3312 | movsd qword CTSTATE->cb.fpr[1], xmm1
3313 | movsd qword CTSTATE->cb.fpr[2], xmm2
3314 | movsd qword CTSTATE->cb.fpr[3], xmm3
3315 |.if X64WIN
3316 | lea rax, [rsp+CFRAME_SIZE+4*8]
3317 |.else
3318 | lea rax, [rsp+CFRAME_SIZE]
3319 | mov CTSTATE->cb.gpr[4], CARG5
3320 | mov CTSTATE->cb.gpr[5], CARG6
3321 | movsd qword CTSTATE->cb.fpr[4], xmm4
3322 | movsd qword CTSTATE->cb.fpr[5], xmm5
3323 | movsd qword CTSTATE->cb.fpr[6], xmm6
3324 | movsd qword CTSTATE->cb.fpr[7], xmm7
3325 |.endif
3326 | mov CTSTATE->cb.stack, rax
3327 | mov CARG2, rsp
3328 |.else
3329 | lea eax, [esp+CFRAME_SIZE+16]
3330 | mov CTSTATE->cb.gpr[0], FCARG1
3331 | mov CTSTATE->cb.gpr[1], FCARG2
3332 | mov CTSTATE->cb.stack, eax
3333 | mov FCARG1, [esp+CFRAME_SIZE+12] // Move around misplaced retaddr/ebp.
3334 | mov FCARG2, [esp+CFRAME_SIZE+8]
3335 | mov SAVE_RET, FCARG1
3336 | mov SAVE_R4, FCARG2
3337 | mov FCARG2, esp
3338 |.endif
3339 | mov SAVE_PC, CTSTATE // Any value outside of bytecode is ok.
3340 | mov FCARG1, CTSTATE
3341 | call extern lj_ccallback_enter@8 // (CTState *cts, void *cf)
3342 | // lua_State * returned in eax (RD).
3343 | set_vmstate INTERP
3344 | mov BASE, L:RD->base
3345 | mov RD, L:RD->top
3346 | sub RD, BASE
3347 | mov LFUNC:RB, [BASE-8]
3348 | shr RD, 3
3349 | add RD, 1
3350 | ins_callt
3351 |.endif
3352 |
3353 |->cont_ffi_callback: // Return from FFI callback.
3354 |.if FFI
3355 | mov L:RA, SAVE_L
3356 | mov CTSTATE, [DISPATCH+DISPATCH_GL(ctype_state)]
3357 | mov aword CTSTATE->L, L:RAa
3358 | mov L:RA->base, BASE
3359 | mov L:RA->top, RB
3360 | mov FCARG1, CTSTATE
3361 | mov FCARG2, RC
3362 | call extern lj_ccallback_leave@8 // (CTState *cts, TValue *o)
3363 |.if X64
3364 | mov rax, CTSTATE->cb.gpr[0]
3365 | movsd xmm0, qword CTSTATE->cb.fpr[0]
3366 | jmp ->vm_leave_unw
3367 |.else
3368 | mov L:RB, SAVE_L
3369 | mov eax, CTSTATE->cb.gpr[0]
3370 | mov edx, CTSTATE->cb.gpr[1]
3371 | cmp dword CTSTATE->cb.gpr[2], 1
3372 | jb >7
3373 | je >6
3374 | fld qword CTSTATE->cb.fpr[0].d
3375 | jmp >7
3376 |6:
3377 | fld dword CTSTATE->cb.fpr[0].f
3378 |7:
3379 | mov ecx, L:RB->top
3380 | movzx ecx, word [ecx+6] // Get stack adjustment and copy up.
3381 | mov SAVE_L, ecx // Must be one slot above SAVE_RET
3382 | restoreregs
3383 | pop ecx // Move return addr from SAVE_RET.
3384 | add esp, [esp] // Adjust stack.
3385 | add esp, 16
3386 | push ecx
3387 | ret
3388 |.endif
3389 |.endif
3390 |
3391 |->vm_ffi_call@4: // Call C function via FFI.
3392 | // Caveat: needs special frame unwinding, see below.
3393 |.if FFI
3394 |.if X64
3395 | .type CCSTATE, CCallState, rbx
3396 | push rbp; mov rbp, rsp; push rbx; mov CCSTATE, CARG1
3397 |.else
3398 | .type CCSTATE, CCallState, ebx
3399 | push ebp; mov ebp, esp; push ebx; mov CCSTATE, FCARG1
3400 |.endif
3401 |
3402 | // Readjust stack.
3403 |.if X64
3404 | mov eax, CCSTATE->spadj
3405 | sub rsp, rax
3406 |.else
3407 | sub esp, CCSTATE->spadj
3408 |.if WIN
3409 | mov CCSTATE->spadj, esp
3410 |.endif
3411 |.endif
3412 |
3413 | // Copy stack slots.
3414 | movzx ecx, byte CCSTATE->nsp
3415 |.if X64
3416 | sub ecx, 8
3417 | js >2
3418 |1:
3419 | mov rax, [CCSTATE+rcx+offsetof(CCallState, stack)]
3420 | mov [rsp+rcx+CCALL_SPS_EXTRA*8], rax
3421 | sub ecx, 8
3422 | jns <1
3423 |2:
3424 |.else
3425 | sub ecx, 4
3426 | js >2
3427 |1:
3428 | mov eax, [CCSTATE+ecx+offsetof(CCallState, stack)]
3429 | mov [esp+ecx], eax
3430 | sub ecx, 4
3431 | jns <1
3432 |2:
3433 |.endif
3434 |
3435 |.if X64
3436 | movzx eax, byte CCSTATE->nfpr
3437 | mov CARG1, CCSTATE->gpr[0]
3438 | mov CARG2, CCSTATE->gpr[1]
3439 | mov CARG3, CCSTATE->gpr[2]
3440 | mov CARG4, CCSTATE->gpr[3]
3441 |.if not X64WIN
3442 | mov CARG5, CCSTATE->gpr[4]
3443 | mov CARG6, CCSTATE->gpr[5]
3444 |.endif
3445 | test eax, eax; jz >5
3446 | movaps xmm0, CCSTATE->fpr[0]
3447 | movaps xmm1, CCSTATE->fpr[1]
3448 | movaps xmm2, CCSTATE->fpr[2]
3449 | movaps xmm3, CCSTATE->fpr[3]
3450 |.if not X64WIN
3451 | cmp eax, 4; jbe >5
3452 | movaps xmm4, CCSTATE->fpr[4]
3453 | movaps xmm5, CCSTATE->fpr[5]
3454 | movaps xmm6, CCSTATE->fpr[6]
3455 | movaps xmm7, CCSTATE->fpr[7]
3456 |.endif
3457 |5:
3458 |.else
3459 | mov FCARG1, CCSTATE->gpr[0]
3460 | mov FCARG2, CCSTATE->gpr[1]
3461 |.endif
3462 |
3463 | call aword CCSTATE->func
3464 |
3465 |.if X64
3466 | mov CCSTATE->gpr[0], rax
3467 | movaps CCSTATE->fpr[0], xmm0
3468 |.if not X64WIN
3469 | mov CCSTATE->gpr[1], rdx
3470 | movaps CCSTATE->fpr[1], xmm1
3471 |.endif
3472 |.else
3473 | mov CCSTATE->gpr[0], eax
3474 | mov CCSTATE->gpr[1], edx
3475 | cmp byte CCSTATE->resx87, 1
3476 | jb >7
3477 | je >6
3478 | fstp qword CCSTATE->fpr[0].d[0]
3479 | jmp >7
3480 |6:
3481 | fstp dword CCSTATE->fpr[0].f[0]
3482 |7:
3483 |.if WIN
3484 | sub CCSTATE->spadj, esp
3485 |.endif
3486 |.endif
3487 |
3488 |.if X64
3489 | mov rbx, [rbp-8]; leave; ret
3490 |.else
3491 | mov ebx, [ebp-4]; leave; ret
3492 |.endif
3493 |.endif
3494 |// Note: vm_ffi_call must be the last function in this object file!
3495 |
3496 |//-----------------------------------------------------------------------
3497}
3498
3499/* Generate the code for a single instruction. */
3500static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3501{
3502 int vk = 0;
3503 |// Note: aligning all instructions does not pay off.
3504 |=>defop:
3505
3506 switch (op) {
3507
3508 /* -- Comparison ops ---------------------------------------------------- */
3509
3510 /* Remember: all ops branch for a true comparison, fall through otherwise. */
3511
3512 |.macro jmp_comp, lt, ge, le, gt, target
3513 ||switch (op) {
3514 ||case BC_ISLT:
3515 | lt target
3516 ||break;
3517 ||case BC_ISGE:
3518 | ge target
3519 ||break;
3520 ||case BC_ISLE:
3521 | le target
3522 ||break;
3523 ||case BC_ISGT:
3524 | gt target
3525 ||break;
3526 ||default: break; /* Shut up GCC. */
3527 ||}
3528 |.endmacro
3529
3530 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
3531 | // RA = src1, RD = src2, JMP with RD = target
3532 | ins_AD
3533 |.if DUALNUM
3534 | checkint RA, >7
3535 | checkint RD, >8
3536 | mov RB, dword [BASE+RA*8]
3537 | add PC, 4
3538 | cmp RB, dword [BASE+RD*8]
3539 | jmp_comp jge, jl, jg, jle, >9
3540 |6:
3541 | movzx RD, PC_RD
3542 | branchPC RD
3543 |9:
3544 | ins_next
3545 |
3546 |7: // RA is not an integer.
3547 | ja ->vmeta_comp
3548 | // RA is a number.
3549 | cmp dword [BASE+RD*8+4], LJ_TISNUM; jb >1; jne ->vmeta_comp
3550 | // RA is a number, RD is an integer.
3551 | cvtsi2sd xmm0, dword [BASE+RD*8]
3552 | jmp >2
3553 |
3554 |8: // RA is an integer, RD is not an integer.
3555 | ja ->vmeta_comp
3556 | // RA is an integer, RD is a number.
3557 | cvtsi2sd xmm1, dword [BASE+RA*8]
3558 | movsd xmm0, qword [BASE+RD*8]
3559 | add PC, 4
3560 | ucomisd xmm0, xmm1
3561 | jmp_comp jbe, ja, jb, jae, <9
3562 | jmp <6
3563 |.else
3564 | checknum RA, ->vmeta_comp
3565 | checknum RD, ->vmeta_comp
3566 |.endif
3567 |1:
3568 | movsd xmm0, qword [BASE+RD*8]
3569 |2:
3570 | add PC, 4
3571 | ucomisd xmm0, qword [BASE+RA*8]
3572 |3:
3573 | // Unordered: all of ZF CF PF set, ordered: PF clear.
3574 | // To preserve NaN semantics GE/GT branch on unordered, but LT/LE don't.
3575 |.if DUALNUM
3576 | jmp_comp jbe, ja, jb, jae, <9
3577 | jmp <6
3578 |.else
3579 | jmp_comp jbe, ja, jb, jae, >1
3580 | movzx RD, PC_RD
3581 | branchPC RD
3582 |1:
3583 | ins_next
3584 |.endif
3585 break;
3586
3587 case BC_ISEQV: case BC_ISNEV:
3588 vk = op == BC_ISEQV;
3589 | ins_AD // RA = src1, RD = src2, JMP with RD = target
3590 | mov RB, [BASE+RD*8+4]
3591 | add PC, 4
3592 |.if DUALNUM
3593 | cmp RB, LJ_TISNUM; jne >7
3594 | checkint RA, >8
3595 | mov RB, dword [BASE+RD*8]
3596 | cmp RB, dword [BASE+RA*8]
3597 if (vk) {
3598 | jne >9
3599 } else {
3600 | je >9
3601 }
3602 | movzx RD, PC_RD
3603 | branchPC RD
3604 |9:
3605 | ins_next
3606 |
3607 |7: // RD is not an integer.
3608 | ja >5
3609 | // RD is a number.
3610 | cmp dword [BASE+RA*8+4], LJ_TISNUM; jb >1; jne >5
3611 | // RD is a number, RA is an integer.
3612 | cvtsi2sd xmm0, dword [BASE+RA*8]
3613 | jmp >2
3614 |
3615 |8: // RD is an integer, RA is not an integer.
3616 | ja >5
3617 | // RD is an integer, RA is a number.
3618 | cvtsi2sd xmm0, dword [BASE+RD*8]
3619 | ucomisd xmm0, qword [BASE+RA*8]
3620 | jmp >4
3621 |
3622 |.else
3623 | cmp RB, LJ_TISNUM; jae >5
3624 | checknum RA, >5
3625 |.endif
3626 |1:
3627 | movsd xmm0, qword [BASE+RA*8]
3628 |2:
3629 | ucomisd xmm0, qword [BASE+RD*8]
3630 |4:
3631 iseqne_fp:
3632 if (vk) {
3633 | jp >2 // Unordered means not equal.
3634 | jne >2
3635 } else {
3636 | jp >2 // Unordered means not equal.
3637 | je >1
3638 }
3639 iseqne_end:
3640 if (vk) {
3641 |1: // EQ: Branch to the target.
3642 | movzx RD, PC_RD
3643 | branchPC RD
3644 |2: // NE: Fallthrough to next instruction.
3645 |.if not FFI
3646 |3:
3647 |.endif
3648 } else {
3649 |.if not FFI
3650 |3:
3651 |.endif
3652 |2: // NE: Branch to the target.
3653 | movzx RD, PC_RD
3654 | branchPC RD
3655 |1: // EQ: Fallthrough to next instruction.
3656 }
3657 if (LJ_DUALNUM && (op == BC_ISEQV || op == BC_ISNEV ||
3658 op == BC_ISEQN || op == BC_ISNEN)) {
3659 | jmp <9
3660 } else {
3661 | ins_next
3662 }
3663 |
3664 if (op == BC_ISEQV || op == BC_ISNEV) {
3665 |5: // Either or both types are not numbers.
3666 |.if FFI
3667 | cmp RB, LJ_TCDATA; je ->vmeta_equal_cd
3668 | checktp RA, LJ_TCDATA; je ->vmeta_equal_cd
3669 |.endif
3670 | checktp RA, RB // Compare types.
3671 | jne <2 // Not the same type?
3672 | cmp RB, LJ_TISPRI
3673 | jae <1 // Same type and primitive type?
3674 |
3675 | // Same types and not a primitive type. Compare GCobj or pvalue.
3676 | mov RA, [BASE+RA*8]
3677 | mov RD, [BASE+RD*8]
3678 | cmp RA, RD
3679 | je <1 // Same GCobjs or pvalues?
3680 | cmp RB, LJ_TISTABUD
3681 | ja <2 // Different objects and not table/ud?
3682 |.if X64
3683 | cmp RB, LJ_TUDATA // And not 64 bit lightuserdata.
3684 | jb <2
3685 |.endif
3686 |
3687 | // Different tables or userdatas. Need to check __eq metamethod.
3688 | // Field metatable must be at same offset for GCtab and GCudata!
3689 | mov TAB:RB, TAB:RA->metatable
3690 | test TAB:RB, TAB:RB
3691 | jz <2 // No metatable?
3692 | test byte TAB:RB->nomm, 1<<MM_eq
3693 | jnz <2 // Or 'no __eq' flag set?
3694 if (vk) {
3695 | xor RB, RB // ne = 0
3696 } else {
3697 | mov RB, 1 // ne = 1
3698 }
3699 | jmp ->vmeta_equal // Handle __eq metamethod.
3700 } else {
3701 |.if FFI
3702 |3:
3703 | cmp RB, LJ_TCDATA
3704 if (LJ_DUALNUM && vk) {
3705 | jne <9
3706 } else {
3707 | jne <2
3708 }
3709 | jmp ->vmeta_equal_cd
3710 |.endif
3711 }
3712 break;
3713 case BC_ISEQS: case BC_ISNES:
3714 vk = op == BC_ISEQS;
3715 | ins_AND // RA = src, RD = str const, JMP with RD = target
3716 | mov RB, [BASE+RA*8+4]
3717 | add PC, 4
3718 | cmp RB, LJ_TSTR; jne >3
3719 | mov RA, [BASE+RA*8]
3720 | cmp RA, [KBASE+RD*4]
3721 iseqne_test:
3722 if (vk) {
3723 | jne >2
3724 } else {
3725 | je >1
3726 }
3727 goto iseqne_end;
3728 case BC_ISEQN: case BC_ISNEN:
3729 vk = op == BC_ISEQN;
3730 | ins_AD // RA = src, RD = num const, JMP with RD = target
3731 | mov RB, [BASE+RA*8+4]
3732 | add PC, 4
3733 |.if DUALNUM
3734 | cmp RB, LJ_TISNUM; jne >7
3735 | cmp dword [KBASE+RD*8+4], LJ_TISNUM; jne >8
3736 | mov RB, dword [KBASE+RD*8]
3737 | cmp RB, dword [BASE+RA*8]
3738 if (vk) {
3739 | jne >9
3740 } else {
3741 | je >9
3742 }
3743 | movzx RD, PC_RD
3744 | branchPC RD
3745 |9:
3746 | ins_next
3747 |
3748 |7: // RA is not an integer.
3749 | ja >3
3750 | // RA is a number.
3751 | cmp dword [KBASE+RD*8+4], LJ_TISNUM; jb >1
3752 | // RA is a number, RD is an integer.
3753 | cvtsi2sd xmm0, dword [KBASE+RD*8]
3754 | jmp >2
3755 |
3756 |8: // RA is an integer, RD is a number.
3757 | cvtsi2sd xmm0, dword [BASE+RA*8]
3758 | ucomisd xmm0, qword [KBASE+RD*8]
3759 | jmp >4
3760 |.else
3761 | cmp RB, LJ_TISNUM; jae >3
3762 |.endif
3763 |1:
3764 | movsd xmm0, qword [KBASE+RD*8]
3765 |2:
3766 | ucomisd xmm0, qword [BASE+RA*8]
3767 |4:
3768 goto iseqne_fp;
3769 case BC_ISEQP: case BC_ISNEP:
3770 vk = op == BC_ISEQP;
3771 | ins_AND // RA = src, RD = primitive type (~), JMP with RD = target
3772 | mov RB, [BASE+RA*8+4]
3773 | add PC, 4
3774 | cmp RB, RD
3775 if (!LJ_HASFFI) goto iseqne_test;
3776 if (vk) {
3777 | jne >3
3778 | movzx RD, PC_RD
3779 | branchPC RD
3780 |2:
3781 | ins_next
3782 |3:
3783 | cmp RB, LJ_TCDATA; jne <2
3784 | jmp ->vmeta_equal_cd
3785 } else {
3786 | je >2
3787 | cmp RB, LJ_TCDATA; je ->vmeta_equal_cd
3788 | movzx RD, PC_RD
3789 | branchPC RD
3790 |2:
3791 | ins_next
3792 }
3793 break;
3794
3795 /* -- Unary test and copy ops ------------------------------------------- */
3796
3797 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
3798 | ins_AD // RA = dst or unused, RD = src, JMP with RD = target
3799 | mov RB, [BASE+RD*8+4]
3800 | add PC, 4
3801 | cmp RB, LJ_TISTRUECOND
3802 if (op == BC_IST || op == BC_ISTC) {
3803 | jae >1
3804 } else {
3805 | jb >1
3806 }
3807 if (op == BC_ISTC || op == BC_ISFC) {
3808 | mov [BASE+RA*8+4], RB
3809 | mov RB, [BASE+RD*8]
3810 | mov [BASE+RA*8], RB
3811 }
3812 | movzx RD, PC_RD
3813 | branchPC RD
3814 |1: // Fallthrough to the next instruction.
3815 | ins_next
3816 break;
3817
3818 case BC_ISTYPE:
3819 | ins_AD // RA = src, RD = -type
3820 | add RD, [BASE+RA*8+4]
3821 | jne ->vmeta_istype
3822 | ins_next
3823 break;
3824 case BC_ISNUM:
3825 | ins_AD // RA = src, RD = -(TISNUM-1)
3826 | checknum RA, ->vmeta_istype
3827 | ins_next
3828 break;
3829
3830 /* -- Unary ops --------------------------------------------------------- */
3831
3832 case BC_MOV:
3833 | ins_AD // RA = dst, RD = src
3834 |.if X64
3835 | mov RBa, [BASE+RD*8]
3836 | mov [BASE+RA*8], RBa
3837 |.else
3838 | mov RB, [BASE+RD*8+4]
3839 | mov RD, [BASE+RD*8]
3840 | mov [BASE+RA*8+4], RB
3841 | mov [BASE+RA*8], RD
3842 |.endif
3843 | ins_next_
3844 break;
3845 case BC_NOT:
3846 | ins_AD // RA = dst, RD = src
3847 | xor RB, RB
3848 | checktp RD, LJ_TISTRUECOND
3849 | adc RB, LJ_TTRUE
3850 | mov [BASE+RA*8+4], RB
3851 | ins_next
3852 break;
3853 case BC_UNM:
3854 | ins_AD // RA = dst, RD = src
3855 |.if DUALNUM
3856 | checkint RD, >5
3857 | mov RB, [BASE+RD*8]
3858 | neg RB
3859 | jz >3
3860 | jo >4
3861 | mov dword [BASE+RA*8+4], LJ_TISNUM
3862 |8:
3863 | mov dword [BASE+RA*8], RB
3864 |9:
3865 | ins_next
3866 |3:
3867 | mov dword [BASE+RA*8+4], 0x80000000 // -0.
3868 | jmp <8
3869 |4:
3870 | mov dword [BASE+RA*8+4], 0x41e00000 // 2^31.
3871 | mov dword [BASE+RA*8], 0
3872 | jmp <9
3873 |5:
3874 | ja ->vmeta_unm
3875 |.else
3876 | checknum RD, ->vmeta_unm
3877 |.endif
3878 | movsd xmm0, qword [BASE+RD*8]
3879 | sseconst_sign xmm1, RDa
3880 | xorps xmm0, xmm1
3881 | movsd qword [BASE+RA*8], xmm0
3882 |.if DUALNUM
3883 | jmp <9
3884 |.else
3885 | ins_next
3886 |.endif
3887 break;
3888 case BC_LEN:
3889 | ins_AD // RA = dst, RD = src
3890 | checkstr RD, >2
3891 | mov STR:RD, [BASE+RD*8]
3892 |.if DUALNUM
3893 | mov RD, dword STR:RD->len
3894 |1:
3895 | mov dword [BASE+RA*8+4], LJ_TISNUM
3896 | mov dword [BASE+RA*8], RD
3897 |.else
3898 | xorps xmm0, xmm0
3899 | cvtsi2sd xmm0, dword STR:RD->len
3900 |1:
3901 | movsd qword [BASE+RA*8], xmm0
3902 |.endif
3903 | ins_next
3904 |2:
3905 | checktab RD, ->vmeta_len
3906 | mov TAB:FCARG1, [BASE+RD*8]
3907#if LJ_52
3908 | mov TAB:RB, TAB:FCARG1->metatable
3909 | cmp TAB:RB, 0
3910 | jnz >9
3911 |3:
3912#endif
3913 |->BC_LEN_Z:
3914 | mov RB, BASE // Save BASE.
3915 | call extern lj_tab_len@4 // (GCtab *t)
3916 | // Length of table returned in eax (RD).
3917 |.if DUALNUM
3918 | // Nothing to do.
3919 |.else
3920 | cvtsi2sd xmm0, RD
3921 |.endif
3922 | mov BASE, RB // Restore BASE.
3923 | movzx RA, PC_RA
3924 | jmp <1
3925#if LJ_52
3926 |9: // Check for __len.
3927 | test byte TAB:RB->nomm, 1<<MM_len
3928 | jnz <3
3929 | jmp ->vmeta_len // 'no __len' flag NOT set: check.
3930#endif
3931 break;
3932
3933 /* -- Binary ops -------------------------------------------------------- */
3934
3935 |.macro ins_arithpre, sseins, ssereg
3936 | ins_ABC
3937 ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
3938 ||switch (vk) {
3939 ||case 0:
3940 | checknum RB, ->vmeta_arith_vn
3941 | .if DUALNUM
3942 | cmp dword [KBASE+RC*8+4], LJ_TISNUM; jae ->vmeta_arith_vn
3943 | .endif
3944 | movsd xmm0, qword [BASE+RB*8]
3945 | sseins ssereg, qword [KBASE+RC*8]
3946 || break;
3947 ||case 1:
3948 | checknum RB, ->vmeta_arith_nv
3949 | .if DUALNUM
3950 | cmp dword [KBASE+RC*8+4], LJ_TISNUM; jae ->vmeta_arith_nv
3951 | .endif
3952 | movsd xmm0, qword [KBASE+RC*8]
3953 | sseins ssereg, qword [BASE+RB*8]
3954 || break;
3955 ||default:
3956 | checknum RB, ->vmeta_arith_vv
3957 | checknum RC, ->vmeta_arith_vv
3958 | movsd xmm0, qword [BASE+RB*8]
3959 | sseins ssereg, qword [BASE+RC*8]
3960 || break;
3961 ||}
3962 |.endmacro
3963 |
3964 |.macro ins_arithdn, intins
3965 | ins_ABC
3966 ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
3967 ||switch (vk) {
3968 ||case 0:
3969 | checkint RB, ->vmeta_arith_vn
3970 | cmp dword [KBASE+RC*8+4], LJ_TISNUM; jne ->vmeta_arith_vn
3971 | mov RB, [BASE+RB*8]
3972 | intins RB, [KBASE+RC*8]; jo ->vmeta_arith_vno
3973 || break;
3974 ||case 1:
3975 | checkint RB, ->vmeta_arith_nv
3976 | cmp dword [KBASE+RC*8+4], LJ_TISNUM; jne ->vmeta_arith_nv
3977 | mov RC, [KBASE+RC*8]
3978 | intins RC, [BASE+RB*8]; jo ->vmeta_arith_nvo
3979 || break;
3980 ||default:
3981 | checkint RB, ->vmeta_arith_vv
3982 | checkint RC, ->vmeta_arith_vv
3983 | mov RB, [BASE+RB*8]
3984 | intins RB, [BASE+RC*8]; jo ->vmeta_arith_vvo
3985 || break;
3986 ||}
3987 | mov dword [BASE+RA*8+4], LJ_TISNUM
3988 ||if (vk == 1) {
3989 | mov dword [BASE+RA*8], RC
3990 ||} else {
3991 | mov dword [BASE+RA*8], RB
3992 ||}
3993 | ins_next
3994 |.endmacro
3995 |
3996 |.macro ins_arithpost
3997 | movsd qword [BASE+RA*8], xmm0
3998 |.endmacro
3999 |
4000 |.macro ins_arith, sseins
4001 | ins_arithpre sseins, xmm0
4002 | ins_arithpost
4003 | ins_next
4004 |.endmacro
4005 |
4006 |.macro ins_arith, intins, sseins
4007 |.if DUALNUM
4008 | ins_arithdn intins
4009 |.else
4010 | ins_arith, sseins
4011 |.endif
4012 |.endmacro
4013
4014 | // RA = dst, RB = src1 or num const, RC = src2 or num const
4015 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
4016 | ins_arith add, addsd
4017 break;
4018 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
4019 | ins_arith sub, subsd
4020 break;
4021 case BC_MULVN: case BC_MULNV: case BC_MULVV:
4022 | ins_arith imul, mulsd
4023 break;
4024 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
4025 | ins_arith divsd
4026 break;
4027 case BC_MODVN:
4028 | ins_arithpre movsd, xmm1
4029 |->BC_MODVN_Z:
4030 | call ->vm_mod
4031 | ins_arithpost
4032 | ins_next
4033 break;
4034 case BC_MODNV: case BC_MODVV:
4035 | ins_arithpre movsd, xmm1
4036 | jmp ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway.
4037 break;
4038 case BC_POW:
4039 | ins_arithpre movsd, xmm1
4040 | mov RB, BASE
4041 |.if not X64
4042 | movsd FPARG1, xmm0
4043 | movsd FPARG3, xmm1
4044 |.endif
4045 | call extern pow
4046 | movzx RA, PC_RA
4047 | mov BASE, RB
4048 |.if X64
4049 | ins_arithpost
4050 |.else
4051 | fstp qword [BASE+RA*8]
4052 |.endif
4053 | ins_next
4054 break;
4055
4056 case BC_CAT:
4057 | ins_ABC // RA = dst, RB = src_start, RC = src_end
4058 |.if X64
4059 | mov L:CARG1d, SAVE_L
4060 | mov L:CARG1d->base, BASE
4061 | lea CARG2d, [BASE+RC*8]
4062 | mov CARG3d, RC
4063 | sub CARG3d, RB
4064 |->BC_CAT_Z:
4065 | mov L:RB, L:CARG1d
4066 |.else
4067 | lea RA, [BASE+RC*8]
4068 | sub RC, RB
4069 | mov ARG2, RA
4070 | mov ARG3, RC
4071 |->BC_CAT_Z:
4072 | mov L:RB, SAVE_L
4073 | mov ARG1, L:RB
4074 | mov L:RB->base, BASE
4075 |.endif
4076 | mov SAVE_PC, PC
4077 | call extern lj_meta_cat // (lua_State *L, TValue *top, int left)
4078 | // NULL (finished) or TValue * (metamethod) returned in eax (RC).
4079 | mov BASE, L:RB->base
4080 | test RC, RC
4081 | jnz ->vmeta_binop
4082 | movzx RB, PC_RB // Copy result to Stk[RA] from Stk[RB].
4083 | movzx RA, PC_RA
4084 |.if X64
4085 | mov RCa, [BASE+RB*8]
4086 | mov [BASE+RA*8], RCa
4087 |.else
4088 | mov RC, [BASE+RB*8+4]
4089 | mov RB, [BASE+RB*8]
4090 | mov [BASE+RA*8+4], RC
4091 | mov [BASE+RA*8], RB
4092 |.endif
4093 | ins_next
4094 break;
4095
4096 /* -- Constant ops ------------------------------------------------------ */
4097
4098 case BC_KSTR:
4099 | ins_AND // RA = dst, RD = str const (~)
4100 | mov RD, [KBASE+RD*4]
4101 | mov dword [BASE+RA*8+4], LJ_TSTR
4102 | mov [BASE+RA*8], RD
4103 | ins_next
4104 break;
4105 case BC_KCDATA:
4106 |.if FFI
4107 | ins_AND // RA = dst, RD = cdata const (~)
4108 | mov RD, [KBASE+RD*4]
4109 | mov dword [BASE+RA*8+4], LJ_TCDATA
4110 | mov [BASE+RA*8], RD
4111 | ins_next
4112 |.endif
4113 break;
4114 case BC_KSHORT:
4115 | ins_AD // RA = dst, RD = signed int16 literal
4116 |.if DUALNUM
4117 | movsx RD, RDW
4118 | mov dword [BASE+RA*8+4], LJ_TISNUM
4119 | mov dword [BASE+RA*8], RD
4120 |.else
4121 | movsx RD, RDW // Sign-extend literal.
4122 | cvtsi2sd xmm0, RD
4123 | movsd qword [BASE+RA*8], xmm0
4124 |.endif
4125 | ins_next
4126 break;
4127 case BC_KNUM:
4128 | ins_AD // RA = dst, RD = num const
4129 | movsd xmm0, qword [KBASE+RD*8]
4130 | movsd qword [BASE+RA*8], xmm0
4131 | ins_next
4132 break;
4133 case BC_KPRI:
4134 | ins_AND // RA = dst, RD = primitive type (~)
4135 | mov [BASE+RA*8+4], RD
4136 | ins_next
4137 break;
4138 case BC_KNIL:
4139 | ins_AD // RA = dst_start, RD = dst_end
4140 | lea RA, [BASE+RA*8+12]
4141 | lea RD, [BASE+RD*8+4]
4142 | mov RB, LJ_TNIL
4143 | mov [RA-8], RB // Sets minimum 2 slots.
4144 |1:
4145 | mov [RA], RB
4146 | add RA, 8
4147 | cmp RA, RD
4148 | jbe <1
4149 | ins_next
4150 break;
4151
4152 /* -- Upvalue and function ops ------------------------------------------ */
4153
4154 case BC_UGET:
4155 | ins_AD // RA = dst, RD = upvalue #
4156 | mov LFUNC:RB, [BASE-8]
4157 | mov UPVAL:RB, [LFUNC:RB+RD*4+offsetof(GCfuncL, uvptr)]
4158 | mov RB, UPVAL:RB->v
4159 |.if X64
4160 | mov RDa, [RB]
4161 | mov [BASE+RA*8], RDa
4162 |.else
4163 | mov RD, [RB+4]
4164 | mov RB, [RB]
4165 | mov [BASE+RA*8+4], RD
4166 | mov [BASE+RA*8], RB
4167 |.endif
4168 | ins_next
4169 break;
4170 case BC_USETV:
4171#define TV2MARKOFS \
4172 ((int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv))
4173 | ins_AD // RA = upvalue #, RD = src
4174 | mov LFUNC:RB, [BASE-8]
4175 | mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
4176 | cmp byte UPVAL:RB->closed, 0
4177 | mov RB, UPVAL:RB->v
4178 | mov RA, [BASE+RD*8]
4179 | mov RD, [BASE+RD*8+4]
4180 | mov [RB], RA
4181 | mov [RB+4], RD
4182 | jz >1
4183 | // Check barrier for closed upvalue.
4184 | test byte [RB+TV2MARKOFS], LJ_GC_BLACK // isblack(uv)
4185 | jnz >2
4186 |1:
4187 | ins_next
4188 |
4189 |2: // Upvalue is black. Check if new value is collectable and white.
4190 | sub RD, LJ_TISGCV
4191 | cmp RD, LJ_TNUMX - LJ_TISGCV // tvisgcv(v)
4192 | jbe <1
4193 | test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES // iswhite(v)
4194 | jz <1
4195 | // Crossed a write barrier. Move the barrier forward.
4196 |.if X64 and not X64WIN
4197 | mov FCARG2, RB
4198 | mov RB, BASE // Save BASE.
4199 |.else
4200 | xchg FCARG2, RB // Save BASE (FCARG2 == BASE).
4201 |.endif
4202 | lea GL:FCARG1, [DISPATCH+GG_DISP2G]
4203 | call extern lj_gc_barrieruv@8 // (global_State *g, TValue *tv)
4204 | mov BASE, RB // Restore BASE.
4205 | jmp <1
4206 break;
4207#undef TV2MARKOFS
4208 case BC_USETS:
4209 | ins_AND // RA = upvalue #, RD = str const (~)
4210 | mov LFUNC:RB, [BASE-8]
4211 | mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
4212 | mov GCOBJ:RA, [KBASE+RD*4]
4213 | mov RD, UPVAL:RB->v
4214 | mov [RD], GCOBJ:RA
4215 | mov dword [RD+4], LJ_TSTR
4216 | test byte UPVAL:RB->marked, LJ_GC_BLACK // isblack(uv)
4217 | jnz >2
4218 |1:
4219 | ins_next
4220 |
4221 |2: // Check if string is white and ensure upvalue is closed.
4222 | test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES // iswhite(str)
4223 | jz <1
4224 | cmp byte UPVAL:RB->closed, 0
4225 | jz <1
4226 | // Crossed a write barrier. Move the barrier forward.
4227 | mov RB, BASE // Save BASE (FCARG2 == BASE).
4228 | mov FCARG2, RD
4229 | lea GL:FCARG1, [DISPATCH+GG_DISP2G]
4230 | call extern lj_gc_barrieruv@8 // (global_State *g, TValue *tv)
4231 | mov BASE, RB // Restore BASE.
4232 | jmp <1
4233 break;
4234 case BC_USETN:
4235 | ins_AD // RA = upvalue #, RD = num const
4236 | mov LFUNC:RB, [BASE-8]
4237 | movsd xmm0, qword [KBASE+RD*8]
4238 | mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
4239 | mov RA, UPVAL:RB->v
4240 | movsd qword [RA], xmm0
4241 | ins_next
4242 break;
4243 case BC_USETP:
4244 | ins_AND // RA = upvalue #, RD = primitive type (~)
4245 | mov LFUNC:RB, [BASE-8]
4246 | mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
4247 | mov RA, UPVAL:RB->v
4248 | mov [RA+4], RD
4249 | ins_next
4250 break;
4251 case BC_UCLO:
4252 | ins_AD // RA = level, RD = target
4253 | branchPC RD // Do this first to free RD.
4254 | mov L:RB, SAVE_L
4255 | cmp dword L:RB->openupval, 0
4256 | je >1
4257 | mov L:RB->base, BASE
4258 | lea FCARG2, [BASE+RA*8] // Caveat: FCARG2 == BASE
4259 | mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
4260 | call extern lj_func_closeuv@8 // (lua_State *L, TValue *level)
4261 | mov BASE, L:RB->base
4262 |1:
4263 | ins_next
4264 break;
4265
4266 case BC_FNEW:
4267 | ins_AND // RA = dst, RD = proto const (~) (holding function prototype)
4268 |.if X64
4269 | mov L:RB, SAVE_L
4270 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
4271 | mov CARG3d, [BASE-8]
4272 | mov CARG2d, [KBASE+RD*4] // Fetch GCproto *.
4273 | mov CARG1d, L:RB
4274 |.else
4275 | mov LFUNC:RA, [BASE-8]
4276 | mov PROTO:RD, [KBASE+RD*4] // Fetch GCproto *.
4277 | mov L:RB, SAVE_L
4278 | mov ARG3, LFUNC:RA
4279 | mov ARG2, PROTO:RD
4280 | mov ARG1, L:RB
4281 | mov L:RB->base, BASE
4282 |.endif
4283 | mov SAVE_PC, PC
4284 | // (lua_State *L, GCproto *pt, GCfuncL *parent)
4285 | call extern lj_func_newL_gc
4286 | // GCfuncL * returned in eax (RC).
4287 | mov BASE, L:RB->base
4288 | movzx RA, PC_RA
4289 | mov [BASE+RA*8], LFUNC:RC
4290 | mov dword [BASE+RA*8+4], LJ_TFUNC
4291 | ins_next
4292 break;
4293
4294 /* -- Table ops --------------------------------------------------------- */
4295
4296 case BC_TNEW:
4297 | ins_AD // RA = dst, RD = hbits|asize
4298 | mov L:RB, SAVE_L
4299 | mov L:RB->base, BASE
4300 | mov RA, [DISPATCH+DISPATCH_GL(gc.total)]
4301 | cmp RA, [DISPATCH+DISPATCH_GL(gc.threshold)]
4302 | mov SAVE_PC, PC
4303 | jae >5
4304 |1:
4305 |.if X64
4306 | mov CARG3d, RD
4307 | and RD, 0x7ff
4308 | shr CARG3d, 11
4309 |.else
4310 | mov RA, RD
4311 | and RD, 0x7ff
4312 | shr RA, 11
4313 | mov ARG3, RA
4314 |.endif
4315 | cmp RD, 0x7ff
4316 | je >3
4317 |2:
4318 |.if X64
4319 | mov L:CARG1d, L:RB
4320 | mov CARG2d, RD
4321 |.else
4322 | mov ARG1, L:RB
4323 | mov ARG2, RD
4324 |.endif
4325 | call extern lj_tab_new // (lua_State *L, int32_t asize, uint32_t hbits)
4326 | // Table * returned in eax (RC).
4327 | mov BASE, L:RB->base
4328 | movzx RA, PC_RA
4329 | mov [BASE+RA*8], TAB:RC
4330 | mov dword [BASE+RA*8+4], LJ_TTAB
4331 | ins_next
4332 |3: // Turn 0x7ff into 0x801.
4333 | mov RD, 0x801
4334 | jmp <2
4335 |5:
4336 | mov L:FCARG1, L:RB
4337 | call extern lj_gc_step_fixtop@4 // (lua_State *L)
4338 | movzx RD, PC_RD
4339 | jmp <1
4340 break;
4341 case BC_TDUP:
4342 | ins_AND // RA = dst, RD = table const (~) (holding template table)
4343 | mov L:RB, SAVE_L
4344 | mov RA, [DISPATCH+DISPATCH_GL(gc.total)]
4345 | mov SAVE_PC, PC
4346 | cmp RA, [DISPATCH+DISPATCH_GL(gc.threshold)]
4347 | mov L:RB->base, BASE
4348 | jae >3
4349 |2:
4350 | mov TAB:FCARG2, [KBASE+RD*4] // Caveat: FCARG2 == BASE
4351 | mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
4352 | call extern lj_tab_dup@8 // (lua_State *L, Table *kt)
4353 | // Table * returned in eax (RC).
4354 | mov BASE, L:RB->base
4355 | movzx RA, PC_RA
4356 | mov [BASE+RA*8], TAB:RC
4357 | mov dword [BASE+RA*8+4], LJ_TTAB
4358 | ins_next
4359 |3:
4360 | mov L:FCARG1, L:RB
4361 | call extern lj_gc_step_fixtop@4 // (lua_State *L)
4362 | movzx RD, PC_RD // Need to reload RD.
4363 | not RDa
4364 | jmp <2
4365 break;
4366
4367 case BC_GGET:
4368 | ins_AND // RA = dst, RD = str const (~)
4369 | mov LFUNC:RB, [BASE-8]
4370 | mov TAB:RB, LFUNC:RB->env
4371 | mov STR:RC, [KBASE+RD*4]
4372 | jmp ->BC_TGETS_Z
4373 break;
4374 case BC_GSET:
4375 | ins_AND // RA = src, RD = str const (~)
4376 | mov LFUNC:RB, [BASE-8]
4377 | mov TAB:RB, LFUNC:RB->env
4378 | mov STR:RC, [KBASE+RD*4]
4379 | jmp ->BC_TSETS_Z
4380 break;
4381
4382 case BC_TGETV:
4383 | ins_ABC // RA = dst, RB = table, RC = key
4384 | checktab RB, ->vmeta_tgetv
4385 | mov TAB:RB, [BASE+RB*8]
4386 |
4387 | // Integer key?
4388 |.if DUALNUM
4389 | checkint RC, >5
4390 | mov RC, dword [BASE+RC*8]
4391 |.else
4392 | // Convert number to int and back and compare.
4393 | checknum RC, >5
4394 | movsd xmm0, qword [BASE+RC*8]
4395 | cvttsd2si RC, xmm0
4396 | cvtsi2sd xmm1, RC
4397 | ucomisd xmm0, xmm1
4398 | jne ->vmeta_tgetv // Generic numeric key? Use fallback.
4399 |.endif
4400 | cmp RC, TAB:RB->asize // Takes care of unordered, too.
4401 | jae ->vmeta_tgetv // Not in array part? Use fallback.
4402 | shl RC, 3
4403 | add RC, TAB:RB->array
4404 | cmp dword [RC+4], LJ_TNIL // Avoid overwriting RB in fastpath.
4405 | je >2
4406 | // Get array slot.
4407 |.if X64
4408 | mov RBa, [RC]
4409 | mov [BASE+RA*8], RBa
4410 |.else
4411 | mov RB, [RC]
4412 | mov RC, [RC+4]
4413 | mov [BASE+RA*8], RB
4414 | mov [BASE+RA*8+4], RC
4415 |.endif
4416 |1:
4417 | ins_next
4418 |
4419 |2: // Check for __index if table value is nil.
4420 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
4421 | jz >3
4422 | mov TAB:RA, TAB:RB->metatable
4423 | test byte TAB:RA->nomm, 1<<MM_index
4424 | jz ->vmeta_tgetv // 'no __index' flag NOT set: check.
4425 | movzx RA, PC_RA // Restore RA.
4426 |3:
4427 | mov dword [BASE+RA*8+4], LJ_TNIL
4428 | jmp <1
4429 |
4430 |5: // String key?
4431 | checkstr RC, ->vmeta_tgetv
4432 | mov STR:RC, [BASE+RC*8]
4433 | jmp ->BC_TGETS_Z
4434 break;
4435 case BC_TGETS:
4436 | ins_ABC // RA = dst, RB = table, RC = str const (~)
4437 | not RCa
4438 | mov STR:RC, [KBASE+RC*4]
4439 | checktab RB, ->vmeta_tgets
4440 | mov TAB:RB, [BASE+RB*8]
4441 |->BC_TGETS_Z: // RB = GCtab *, RC = GCstr *, refetches PC_RA.
4442 | mov RA, TAB:RB->hmask
4443 | and RA, STR:RC->sid
4444 | imul RA, #NODE
4445 | add NODE:RA, TAB:RB->node
4446 |1:
4447 | cmp dword NODE:RA->key.it, LJ_TSTR
4448 | jne >4
4449 | cmp dword NODE:RA->key.gcr, STR:RC
4450 | jne >4
4451 | // Ok, key found. Assumes: offsetof(Node, val) == 0
4452 | cmp dword [RA+4], LJ_TNIL // Avoid overwriting RB in fastpath.
4453 | je >5 // Key found, but nil value?
4454 | movzx RC, PC_RA
4455 | // Get node value.
4456 |.if X64
4457 | mov RBa, [RA]
4458 | mov [BASE+RC*8], RBa
4459 |.else
4460 | mov RB, [RA]
4461 | mov RA, [RA+4]
4462 | mov [BASE+RC*8], RB
4463 | mov [BASE+RC*8+4], RA
4464 |.endif
4465 |2:
4466 | ins_next
4467 |
4468 |3:
4469 | movzx RC, PC_RA
4470 | mov dword [BASE+RC*8+4], LJ_TNIL
4471 | jmp <2
4472 |
4473 |4: // Follow hash chain.
4474 | mov NODE:RA, NODE:RA->next
4475 | test NODE:RA, NODE:RA
4476 | jnz <1
4477 | // End of hash chain: key not found, nil result.
4478 |
4479 |5: // Check for __index if table value is nil.
4480 | mov TAB:RA, TAB:RB->metatable
4481 | test TAB:RA, TAB:RA
4482 | jz <3 // No metatable: done.
4483 | test byte TAB:RA->nomm, 1<<MM_index
4484 | jnz <3 // 'no __index' flag set: done.
4485 | jmp ->vmeta_tgets // Caveat: preserve STR:RC.
4486 break;
4487 case BC_TGETB:
4488 | ins_ABC // RA = dst, RB = table, RC = byte literal
4489 | checktab RB, ->vmeta_tgetb
4490 | mov TAB:RB, [BASE+RB*8]
4491 | cmp RC, TAB:RB->asize
4492 | jae ->vmeta_tgetb
4493 | shl RC, 3
4494 | add RC, TAB:RB->array
4495 | cmp dword [RC+4], LJ_TNIL // Avoid overwriting RB in fastpath.
4496 | je >2
4497 | // Get array slot.
4498 |.if X64
4499 | mov RBa, [RC]
4500 | mov [BASE+RA*8], RBa
4501 |.else
4502 | mov RB, [RC]
4503 | mov RC, [RC+4]
4504 | mov [BASE+RA*8], RB
4505 | mov [BASE+RA*8+4], RC
4506 |.endif
4507 |1:
4508 | ins_next
4509 |
4510 |2: // Check for __index if table value is nil.
4511 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
4512 | jz >3
4513 | mov TAB:RA, TAB:RB->metatable
4514 | test byte TAB:RA->nomm, 1<<MM_index
4515 | jz ->vmeta_tgetb // 'no __index' flag NOT set: check.
4516 | movzx RA, PC_RA // Restore RA.
4517 |3:
4518 | mov dword [BASE+RA*8+4], LJ_TNIL
4519 | jmp <1
4520 break;
4521 case BC_TGETR:
4522 | ins_ABC // RA = dst, RB = table, RC = key
4523 | mov TAB:RB, [BASE+RB*8]
4524 |.if DUALNUM
4525 | mov RC, dword [BASE+RC*8]
4526 |.else
4527 | cvttsd2si RC, qword [BASE+RC*8]
4528 |.endif
4529 | cmp RC, TAB:RB->asize
4530 | jae ->vmeta_tgetr // Not in array part? Use fallback.
4531 | shl RC, 3
4532 | add RC, TAB:RB->array
4533 | // Get array slot.
4534 |->BC_TGETR_Z:
4535 |.if X64
4536 | mov RBa, [RC]
4537 | mov [BASE+RA*8], RBa
4538 |.else
4539 | mov RB, [RC]
4540 | mov RC, [RC+4]
4541 | mov [BASE+RA*8], RB
4542 | mov [BASE+RA*8+4], RC
4543 |.endif
4544 |->BC_TGETR2_Z:
4545 | ins_next
4546 break;
4547
4548 case BC_TSETV:
4549 | ins_ABC // RA = src, RB = table, RC = key
4550 | checktab RB, ->vmeta_tsetv
4551 | mov TAB:RB, [BASE+RB*8]
4552 |
4553 | // Integer key?
4554 |.if DUALNUM
4555 | checkint RC, >5
4556 | mov RC, dword [BASE+RC*8]
4557 |.else
4558 | // Convert number to int and back and compare.
4559 | checknum RC, >5
4560 | movsd xmm0, qword [BASE+RC*8]
4561 | cvttsd2si RC, xmm0
4562 | cvtsi2sd xmm1, RC
4563 | ucomisd xmm0, xmm1
4564 | jne ->vmeta_tsetv // Generic numeric key? Use fallback.
4565 |.endif
4566 | cmp RC, TAB:RB->asize // Takes care of unordered, too.
4567 | jae ->vmeta_tsetv
4568 | shl RC, 3
4569 | add RC, TAB:RB->array
4570 | cmp dword [RC+4], LJ_TNIL
4571 | je >3 // Previous value is nil?
4572 |1:
4573 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
4574 | jnz >7
4575 |2: // Set array slot.
4576 |.if X64
4577 | mov RBa, [BASE+RA*8]
4578 | mov [RC], RBa
4579 |.else
4580 | mov RB, [BASE+RA*8+4]
4581 | mov RA, [BASE+RA*8]
4582 | mov [RC+4], RB
4583 | mov [RC], RA
4584 |.endif
4585 | ins_next
4586 |
4587 |3: // Check for __newindex if previous value is nil.
4588 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
4589 | jz <1
4590 | mov TAB:RA, TAB:RB->metatable
4591 | test byte TAB:RA->nomm, 1<<MM_newindex
4592 | jz ->vmeta_tsetv // 'no __newindex' flag NOT set: check.
4593 | movzx RA, PC_RA // Restore RA.
4594 | jmp <1
4595 |
4596 |5: // String key?
4597 | checkstr RC, ->vmeta_tsetv
4598 | mov STR:RC, [BASE+RC*8]
4599 | jmp ->BC_TSETS_Z
4600 |
4601 |7: // Possible table write barrier for the value. Skip valiswhite check.
4602 | barrierback TAB:RB, RA
4603 | movzx RA, PC_RA // Restore RA.
4604 | jmp <2
4605 break;
4606 case BC_TSETS:
4607 | ins_ABC // RA = src, RB = table, RC = str const (~)
4608 | not RCa
4609 | mov STR:RC, [KBASE+RC*4]
4610 | checktab RB, ->vmeta_tsets
4611 | mov TAB:RB, [BASE+RB*8]
4612 |->BC_TSETS_Z: // RB = GCtab *, RC = GCstr *, refetches PC_RA.
4613 | mov RA, TAB:RB->hmask
4614 | and RA, STR:RC->sid
4615 | imul RA, #NODE
4616 | mov byte TAB:RB->nomm, 0 // Clear metamethod cache.
4617 | add NODE:RA, TAB:RB->node
4618 |1:
4619 | cmp dword NODE:RA->key.it, LJ_TSTR
4620 | jne >5
4621 | cmp dword NODE:RA->key.gcr, STR:RC
4622 | jne >5
4623 | // Ok, key found. Assumes: offsetof(Node, val) == 0
4624 | cmp dword [RA+4], LJ_TNIL
4625 | je >4 // Previous value is nil?
4626 |2:
4627 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
4628 | jnz >7
4629 |3: // Set node value.
4630 | movzx RC, PC_RA
4631 |.if X64
4632 | mov RBa, [BASE+RC*8]
4633 | mov [RA], RBa
4634 |.else
4635 | mov RB, [BASE+RC*8+4]
4636 | mov RC, [BASE+RC*8]
4637 | mov [RA+4], RB
4638 | mov [RA], RC
4639 |.endif
4640 | ins_next
4641 |
4642 |4: // Check for __newindex if previous value is nil.
4643 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
4644 | jz <2
4645 | mov TMP1, RA // Save RA.
4646 | mov TAB:RA, TAB:RB->metatable
4647 | test byte TAB:RA->nomm, 1<<MM_newindex
4648 | jz ->vmeta_tsets // 'no __newindex' flag NOT set: check.
4649 | mov RA, TMP1 // Restore RA.
4650 | jmp <2
4651 |
4652 |5: // Follow hash chain.
4653 | mov NODE:RA, NODE:RA->next
4654 | test NODE:RA, NODE:RA
4655 | jnz <1
4656 | // End of hash chain: key not found, add a new one.
4657 |
4658 | // But check for __newindex first.
4659 | mov TAB:RA, TAB:RB->metatable
4660 | test TAB:RA, TAB:RA
4661 | jz >6 // No metatable: continue.
4662 | test byte TAB:RA->nomm, 1<<MM_newindex
4663 | jz ->vmeta_tsets // 'no __newindex' flag NOT set: check.
4664 |6:
4665 | mov TMP1, STR:RC
4666 | mov TMP2, LJ_TSTR
4667 | mov TMP3, TAB:RB // Save TAB:RB for us.
4668 |.if X64
4669 | mov L:CARG1d, SAVE_L
4670 | mov L:CARG1d->base, BASE
4671 | lea CARG3, TMP1
4672 | mov CARG2d, TAB:RB
4673 | mov L:RB, L:CARG1d
4674 |.else
4675 | lea RC, TMP1 // Store temp. TValue in TMP1/TMP2.
4676 | mov ARG2, TAB:RB
4677 | mov L:RB, SAVE_L
4678 | mov ARG3, RC
4679 | mov ARG1, L:RB
4680 | mov L:RB->base, BASE
4681 |.endif
4682 | mov SAVE_PC, PC
4683 | call extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k)
4684 | // Handles write barrier for the new key. TValue * returned in eax (RC).
4685 | mov BASE, L:RB->base
4686 | mov TAB:RB, TMP3 // Need TAB:RB for barrier.
4687 | mov RA, eax
4688 | jmp <2 // Must check write barrier for value.
4689 |
4690 |7: // Possible table write barrier for the value. Skip valiswhite check.
4691 | barrierback TAB:RB, RC // Destroys STR:RC.
4692 | jmp <3
4693 break;
4694 case BC_TSETB:
4695 | ins_ABC // RA = src, RB = table, RC = byte literal
4696 | checktab RB, ->vmeta_tsetb
4697 | mov TAB:RB, [BASE+RB*8]
4698 | cmp RC, TAB:RB->asize
4699 | jae ->vmeta_tsetb
4700 | shl RC, 3
4701 | add RC, TAB:RB->array
4702 | cmp dword [RC+4], LJ_TNIL
4703 | je >3 // Previous value is nil?
4704 |1:
4705 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
4706 | jnz >7
4707 |2: // Set array slot.
4708 |.if X64
4709 | mov RAa, [BASE+RA*8]
4710 | mov [RC], RAa
4711 |.else
4712 | mov RB, [BASE+RA*8+4]
4713 | mov RA, [BASE+RA*8]
4714 | mov [RC+4], RB
4715 | mov [RC], RA
4716 |.endif
4717 | ins_next
4718 |
4719 |3: // Check for __newindex if previous value is nil.
4720 | cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
4721 | jz <1
4722 | mov TAB:RA, TAB:RB->metatable
4723 | test byte TAB:RA->nomm, 1<<MM_newindex
4724 | jz ->vmeta_tsetb // 'no __newindex' flag NOT set: check.
4725 | movzx RA, PC_RA // Restore RA.
4726 | jmp <1
4727 |
4728 |7: // Possible table write barrier for the value. Skip valiswhite check.
4729 | barrierback TAB:RB, RA
4730 | movzx RA, PC_RA // Restore RA.
4731 | jmp <2
4732 break;
4733 case BC_TSETR:
4734 | ins_ABC // RA = src, RB = table, RC = key
4735 | mov TAB:RB, [BASE+RB*8]
4736 |.if DUALNUM
4737 | mov RC, dword [BASE+RC*8]
4738 |.else
4739 | cvttsd2si RC, qword [BASE+RC*8]
4740 |.endif
4741 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
4742 | jnz >7
4743 |2:
4744 | cmp RC, TAB:RB->asize
4745 | jae ->vmeta_tsetr
4746 | shl RC, 3
4747 | add RC, TAB:RB->array
4748 | // Set array slot.
4749 |->BC_TSETR_Z:
4750 |.if X64
4751 | mov RBa, [BASE+RA*8]
4752 | mov [RC], RBa
4753 |.else
4754 | mov RB, [BASE+RA*8+4]
4755 | mov RA, [BASE+RA*8]
4756 | mov [RC+4], RB
4757 | mov [RC], RA
4758 |.endif
4759 | ins_next
4760 |
4761 |7: // Possible table write barrier for the value. Skip valiswhite check.
4762 | barrierback TAB:RB, RA
4763 | movzx RA, PC_RA // Restore RA.
4764 | jmp <2
4765 break;
4766
4767 case BC_TSETM:
4768 | ins_AD // RA = base (table at base-1), RD = num const (start index)
4769 | mov TMP1, KBASE // Need one more free register.
4770 | mov KBASE, dword [KBASE+RD*8] // Integer constant is in lo-word.
4771 |1:
4772 | lea RA, [BASE+RA*8]
4773 | mov TAB:RB, [RA-8] // Guaranteed to be a table.
4774 | test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
4775 | jnz >7
4776 |2:
4777 | mov RD, MULTRES
4778 | sub RD, 1
4779 | jz >4 // Nothing to copy?
4780 | add RD, KBASE // Compute needed size.
4781 | cmp RD, TAB:RB->asize
4782 | ja >5 // Doesn't fit into array part?
4783 | sub RD, KBASE
4784 | shl KBASE, 3
4785 | add KBASE, TAB:RB->array
4786 |3: // Copy result slots to table.
4787 |.if X64
4788 | mov RBa, [RA]
4789 | add RA, 8
4790 | mov [KBASE], RBa
4791 |.else
4792 | mov RB, [RA]
4793 | mov [KBASE], RB
4794 | mov RB, [RA+4]
4795 | add RA, 8
4796 | mov [KBASE+4], RB
4797 |.endif
4798 | add KBASE, 8
4799 | sub RD, 1
4800 | jnz <3
4801 |4:
4802 | mov KBASE, TMP1
4803 | ins_next
4804 |
4805 |5: // Need to resize array part.
4806 |.if X64
4807 | mov L:CARG1d, SAVE_L
4808 | mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
4809 | mov CARG2d, TAB:RB
4810 | mov CARG3d, RD
4811 | mov L:RB, L:CARG1d
4812 |.else
4813 | mov ARG2, TAB:RB
4814 | mov L:RB, SAVE_L
4815 | mov L:RB->base, BASE
4816 | mov ARG3, RD
4817 | mov ARG1, L:RB
4818 |.endif
4819 | mov SAVE_PC, PC
4820 | call extern lj_tab_reasize // (lua_State *L, GCtab *t, int nasize)
4821 | mov BASE, L:RB->base
4822 | movzx RA, PC_RA // Restore RA.
4823 | jmp <1 // Retry.
4824 |
4825 |7: // Possible table write barrier for any value. Skip valiswhite check.
4826 | barrierback TAB:RB, RD
4827 | jmp <2
4828 break;
4829
4830 /* -- Calls and vararg handling ----------------------------------------- */
4831
4832 case BC_CALL: case BC_CALLM:
4833 | ins_A_C // RA = base, (RB = nresults+1,) RC = nargs+1 | extra_nargs
4834 if (op == BC_CALLM) {
4835 | add NARGS:RD, MULTRES
4836 }
4837 | cmp dword [BASE+RA*8+4], LJ_TFUNC
4838 | mov LFUNC:RB, [BASE+RA*8]
4839 | jne ->vmeta_call_ra
4840 | lea BASE, [BASE+RA*8+8]
4841 | ins_call
4842 break;
4843
4844 case BC_CALLMT:
4845 | ins_AD // RA = base, RD = extra_nargs
4846 | add NARGS:RD, MULTRES
4847 | // Fall through. Assumes BC_CALLT follows and ins_AD is a no-op.
4848 break;
4849 case BC_CALLT:
4850 | ins_AD // RA = base, RD = nargs+1
4851 | lea RA, [BASE+RA*8+8]
4852 | mov KBASE, BASE // Use KBASE for move + vmeta_call hint.
4853 | mov LFUNC:RB, [RA-8]
4854 | cmp dword [RA-4], LJ_TFUNC
4855 | jne ->vmeta_call
4856 |->BC_CALLT_Z:
4857 | mov PC, [BASE-4]
4858 | test PC, FRAME_TYPE
4859 | jnz >7
4860 |1:
4861 | mov [BASE-8], LFUNC:RB // Copy function down, reloaded below.
4862 | mov MULTRES, NARGS:RD
4863 | sub NARGS:RD, 1
4864 | jz >3
4865 |2: // Move args down.
4866 |.if X64
4867 | mov RBa, [RA]
4868 | add RA, 8
4869 | mov [KBASE], RBa
4870 |.else
4871 | mov RB, [RA]
4872 | mov [KBASE], RB
4873 | mov RB, [RA+4]
4874 | add RA, 8
4875 | mov [KBASE+4], RB
4876 |.endif
4877 | add KBASE, 8
4878 | sub NARGS:RD, 1
4879 | jnz <2
4880 |
4881 | mov LFUNC:RB, [BASE-8]
4882 |3:
4883 | mov NARGS:RD, MULTRES
4884 | cmp byte LFUNC:RB->ffid, 1 // (> FF_C) Calling a fast function?
4885 | ja >5
4886 |4:
4887 | ins_callt
4888 |
4889 |5: // Tailcall to a fast function.
4890 | test PC, FRAME_TYPE // Lua frame below?
4891 | jnz <4
4892 | movzx RA, PC_RA
4893 | not RAa
4894 | mov LFUNC:KBASE, [BASE+RA*8-8] // Need to prepare KBASE.
4895 | mov KBASE, LFUNC:KBASE->pc
4896 | mov KBASE, [KBASE+PC2PROTO(k)]
4897 | jmp <4
4898 |
4899 |7: // Tailcall from a vararg function.
4900 | sub PC, FRAME_VARG
4901 | test PC, FRAME_TYPEP
4902 | jnz >8 // Vararg frame below?
4903 | sub BASE, PC // Need to relocate BASE/KBASE down.
4904 | mov KBASE, BASE
4905 | mov PC, [BASE-4]
4906 | jmp <1
4907 |8:
4908 | add PC, FRAME_VARG
4909 | jmp <1
4910 break;
4911
4912 case BC_ITERC:
4913 | ins_A // RA = base, (RB = nresults+1,) RC = nargs+1 (2+1)
4914 | lea RA, [BASE+RA*8+8] // fb = base+1
4915 |.if X64
4916 | mov RBa, [RA-24] // Copy state. fb[0] = fb[-3].
4917 | mov RCa, [RA-16] // Copy control var. fb[1] = fb[-2].
4918 | mov [RA], RBa
4919 | mov [RA+8], RCa
4920 |.else
4921 | mov RB, [RA-24] // Copy state. fb[0] = fb[-3].
4922 | mov RC, [RA-20]
4923 | mov [RA], RB
4924 | mov [RA+4], RC
4925 | mov RB, [RA-16] // Copy control var. fb[1] = fb[-2].
4926 | mov RC, [RA-12]
4927 | mov [RA+8], RB
4928 | mov [RA+12], RC
4929 |.endif
4930 | mov LFUNC:RB, [RA-32] // Copy callable. fb[-1] = fb[-4]
4931 | mov RC, [RA-28]
4932 | mov [RA-8], LFUNC:RB
4933 | mov [RA-4], RC
4934 | cmp RC, LJ_TFUNC // Handle like a regular 2-arg call.
4935 | mov NARGS:RD, 2+1
4936 | jne ->vmeta_call
4937 | mov BASE, RA
4938 | ins_call
4939 break;
4940
4941 case BC_ITERN:
4942 |.if JIT
4943 | hotloop RB
4944 |.endif
4945 |->vm_IITERN:
4946 | ins_A // RA = base, (RB = nresults+1, RC = nargs+1 (2+1))
4947 | mov TMP1, KBASE // Need two more free registers.
4948 | mov TMP2, DISPATCH
4949 | mov TAB:RB, [BASE+RA*8-16]
4950 | mov RC, [BASE+RA*8-8] // Get index from control var.
4951 | mov DISPATCH, TAB:RB->asize
4952 | add PC, 4
4953 | mov KBASE, TAB:RB->array
4954 |1: // Traverse array part.
4955 | cmp RC, DISPATCH; jae >5 // Index points after array part?
4956 | cmp dword [KBASE+RC*8+4], LJ_TNIL; je >4
4957 |.if DUALNUM
4958 | mov dword [BASE+RA*8+4], LJ_TISNUM
4959 | mov dword [BASE+RA*8], RC
4960 |.else
4961 | cvtsi2sd xmm0, RC
4962 |.endif
4963 | // Copy array slot to returned value.
4964 |.if X64
4965 | mov RBa, [KBASE+RC*8]
4966 | mov [BASE+RA*8+8], RBa
4967 |.else
4968 | mov RB, [KBASE+RC*8+4]
4969 | mov [BASE+RA*8+12], RB
4970 | mov RB, [KBASE+RC*8]
4971 | mov [BASE+RA*8+8], RB
4972 |.endif
4973 | add RC, 1
4974 | // Return array index as a numeric key.
4975 |.if DUALNUM
4976 | // See above.
4977 |.else
4978 | movsd qword [BASE+RA*8], xmm0
4979 |.endif
4980 | mov [BASE+RA*8-8], RC // Update control var.
4981 |2:
4982 | movzx RD, PC_RD // Get target from ITERL.
4983 | branchPC RD
4984 |3:
4985 | mov DISPATCH, TMP2
4986 | mov KBASE, TMP1
4987 | ins_next
4988 |
4989 |4: // Skip holes in array part.
4990 | add RC, 1
4991 | jmp <1
4992 |
4993 |5: // Traverse hash part.
4994 | sub RC, DISPATCH
4995 |6:
4996 | cmp RC, TAB:RB->hmask; ja <3 // End of iteration? Branch to ITERL+1.
4997 | imul KBASE, RC, #NODE
4998 | add NODE:KBASE, TAB:RB->node
4999 | cmp dword NODE:KBASE->val.it, LJ_TNIL; je >7
5000 | lea DISPATCH, [RC+DISPATCH+1]
5001 | // Copy key and value from hash slot.
5002 |.if X64
5003 | mov RBa, NODE:KBASE->key
5004 | mov RCa, NODE:KBASE->val
5005 | mov [BASE+RA*8], RBa
5006 | mov [BASE+RA*8+8], RCa
5007 |.else
5008 | mov RB, NODE:KBASE->key.gcr
5009 | mov RC, NODE:KBASE->key.it
5010 | mov [BASE+RA*8], RB
5011 | mov [BASE+RA*8+4], RC
5012 | mov RB, NODE:KBASE->val.gcr
5013 | mov RC, NODE:KBASE->val.it
5014 | mov [BASE+RA*8+8], RB
5015 | mov [BASE+RA*8+12], RC
5016 |.endif
5017 | mov [BASE+RA*8-8], DISPATCH
5018 | jmp <2
5019 |
5020 |7: // Skip holes in hash part.
5021 | add RC, 1
5022 | jmp <6
5023 break;
5024
5025 case BC_ISNEXT:
5026 | ins_AD // RA = base, RD = target (points to ITERN)
5027 | cmp dword [BASE+RA*8-20], LJ_TFUNC; jne >5
5028 | mov CFUNC:RB, [BASE+RA*8-24]
5029 | cmp dword [BASE+RA*8-12], LJ_TTAB; jne >5
5030 | cmp dword [BASE+RA*8-4], LJ_TNIL; jne >5
5031 | cmp byte CFUNC:RB->ffid, FF_next_N; jne >5
5032 | branchPC RD
5033 | mov dword [BASE+RA*8-8], 0 // Initialize control var.
5034 | mov dword [BASE+RA*8-4], LJ_KEYINDEX
5035 |1:
5036 | ins_next
5037 |5: // Despecialize bytecode if any of the checks fail.
5038 | mov PC_OP, BC_JMP
5039 | branchPC RD
5040 |.if JIT
5041 | cmp byte [PC], BC_ITERN
5042 | jne >6
5043 |.endif
5044 | mov byte [PC], BC_ITERC
5045 | jmp <1
5046 |.if JIT
5047 |6: // Unpatch JLOOP.
5048 | mov RA, [DISPATCH+DISPATCH_J(trace)]
5049 | movzx RC, word [PC+2]
5050 | mov TRACE:RA, [RA+RC*4]
5051 | mov eax, TRACE:RA->startins
5052 | mov al, BC_ITERC
5053 | mov dword [PC], eax
5054 | jmp <1
5055 |.endif
5056 break;
5057
5058 case BC_VARG:
5059 | ins_ABC // RA = base, RB = nresults+1, RC = numparams
5060 | mov TMP1, KBASE // Need one more free register.
5061 | lea KBASE, [BASE+RC*8+(8+FRAME_VARG)]
5062 | lea RA, [BASE+RA*8]
5063 | sub KBASE, [BASE-4]
5064 | // Note: KBASE may now be even _above_ BASE if nargs was < numparams.
5065 | test RB, RB
5066 | jz >5 // Copy all varargs?
5067 | lea RB, [RA+RB*8-8]
5068 | cmp KBASE, BASE // No vararg slots?
5069 | jnb >2
5070 |1: // Copy vararg slots to destination slots.
5071 |.if X64
5072 | mov RCa, [KBASE-8]
5073 | add KBASE, 8
5074 | mov [RA], RCa
5075 |.else
5076 | mov RC, [KBASE-8]
5077 | mov [RA], RC
5078 | mov RC, [KBASE-4]
5079 | add KBASE, 8
5080 | mov [RA+4], RC
5081 |.endif
5082 | add RA, 8
5083 | cmp RA, RB // All destination slots filled?
5084 | jnb >3
5085 | cmp KBASE, BASE // No more vararg slots?
5086 | jb <1
5087 |2: // Fill up remainder with nil.
5088 | mov dword [RA+4], LJ_TNIL
5089 | add RA, 8
5090 | cmp RA, RB
5091 | jb <2
5092 |3:
5093 | mov KBASE, TMP1
5094 | ins_next
5095 |
5096 |5: // Copy all varargs.
5097 | mov MULTRES, 1 // MULTRES = 0+1
5098 | mov RC, BASE
5099 | sub RC, KBASE
5100 | jbe <3 // No vararg slots?
5101 | mov RB, RC
5102 | shr RB, 3
5103 | add RB, 1
5104 | mov MULTRES, RB // MULTRES = #varargs+1
5105 | mov L:RB, SAVE_L
5106 | add RC, RA
5107 | cmp RC, L:RB->maxstack
5108 | ja >7 // Need to grow stack?
5109 |6: // Copy all vararg slots.
5110 |.if X64
5111 | mov RCa, [KBASE-8]
5112 | add KBASE, 8
5113 | mov [RA], RCa
5114 |.else
5115 | mov RC, [KBASE-8]
5116 | mov [RA], RC
5117 | mov RC, [KBASE-4]
5118 | add KBASE, 8
5119 | mov [RA+4], RC
5120 |.endif
5121 | add RA, 8
5122 | cmp KBASE, BASE // No more vararg slots?
5123 | jb <6
5124 | jmp <3
5125 |
5126 |7: // Grow stack for varargs.
5127 | mov L:RB->base, BASE
5128 | mov L:RB->top, RA
5129 | mov SAVE_PC, PC
5130 | sub KBASE, BASE // Need delta, because BASE may change.
5131 | mov FCARG2, MULTRES
5132 | sub FCARG2, 1
5133 | mov FCARG1, L:RB
5134 | call extern lj_state_growstack@8 // (lua_State *L, int n)
5135 | mov BASE, L:RB->base
5136 | mov RA, L:RB->top
5137 | add KBASE, BASE
5138 | jmp <6
5139 break;
5140
5141 /* -- Returns ----------------------------------------------------------- */
5142
5143 case BC_RETM:
5144 | ins_AD // RA = results, RD = extra_nresults
5145 | add RD, MULTRES // MULTRES >=1, so RD >=1.
5146 | // Fall through. Assumes BC_RET follows and ins_AD is a no-op.
5147 break;
5148
5149 case BC_RET: case BC_RET0: case BC_RET1:
5150 | ins_AD // RA = results, RD = nresults+1
5151 if (op != BC_RET0) {
5152 | shl RA, 3
5153 }
5154 |1:
5155 | mov PC, [BASE-4]
5156 | mov MULTRES, RD // Save nresults+1.
5157 | test PC, FRAME_TYPE // Check frame type marker.
5158 | jnz >7 // Not returning to a fixarg Lua func?
5159 switch (op) {
5160 case BC_RET:
5161 |->BC_RET_Z:
5162 | mov KBASE, BASE // Use KBASE for result move.
5163 | sub RD, 1
5164 | jz >3
5165 |2: // Move results down.
5166 |.if X64
5167 | mov RBa, [KBASE+RA]
5168 | mov [KBASE-8], RBa
5169 |.else
5170 | mov RB, [KBASE+RA]
5171 | mov [KBASE-8], RB
5172 | mov RB, [KBASE+RA+4]
5173 | mov [KBASE-4], RB
5174 |.endif
5175 | add KBASE, 8
5176 | sub RD, 1
5177 | jnz <2
5178 |3:
5179 | mov RD, MULTRES // Note: MULTRES may be >255.
5180 | movzx RB, PC_RB // So cannot compare with RDL!
5181 |5:
5182 | cmp RB, RD // More results expected?
5183 | ja >6
5184 break;
5185 case BC_RET1:
5186 |.if X64
5187 | mov RBa, [BASE+RA]
5188 | mov [BASE-8], RBa
5189 |.else
5190 | mov RB, [BASE+RA+4]
5191 | mov [BASE-4], RB
5192 | mov RB, [BASE+RA]
5193 | mov [BASE-8], RB
5194 |.endif
5195 /* fallthrough */
5196 case BC_RET0:
5197 |5:
5198 | cmp PC_RB, RDL // More results expected?
5199 | ja >6
5200 default:
5201 break;
5202 }
5203 | movzx RA, PC_RA
5204 | not RAa // Note: ~RA = -(RA+1)
5205 | lea BASE, [BASE+RA*8] // base = base - (RA+1)*8
5206 | mov LFUNC:KBASE, [BASE-8]
5207 | mov KBASE, LFUNC:KBASE->pc
5208 | mov KBASE, [KBASE+PC2PROTO(k)]
5209 | ins_next
5210 |
5211 |6: // Fill up results with nil.
5212 if (op == BC_RET) {
5213 | mov dword [KBASE-4], LJ_TNIL // Note: relies on shifted base.
5214 | add KBASE, 8
5215 } else {
5216 | mov dword [BASE+RD*8-12], LJ_TNIL
5217 }
5218 | add RD, 1
5219 | jmp <5
5220 |
5221 |7: // Non-standard return case.
5222 | lea RB, [PC-FRAME_VARG]
5223 | test RB, FRAME_TYPEP
5224 | jnz ->vm_return
5225 | // Return from vararg function: relocate BASE down and RA up.
5226 | sub BASE, RB
5227 if (op != BC_RET0) {
5228 | add RA, RB
5229 }
5230 | jmp <1
5231 break;
5232
5233 /* -- Loops and branches ------------------------------------------------ */
5234
5235 |.define FOR_IDX, [RA]; .define FOR_TIDX, dword [RA+4]
5236 |.define FOR_STOP, [RA+8]; .define FOR_TSTOP, dword [RA+12]
5237 |.define FOR_STEP, [RA+16]; .define FOR_TSTEP, dword [RA+20]
5238 |.define FOR_EXT, [RA+24]; .define FOR_TEXT, dword [RA+28]
5239
5240 case BC_FORL:
5241 |.if JIT
5242 | hotloop RB
5243 |.endif
5244 | // Fall through. Assumes BC_IFORL follows and ins_AJ is a no-op.
5245 break;
5246
5247 case BC_JFORI:
5248 case BC_JFORL:
5249#if !LJ_HASJIT
5250 break;
5251#endif
5252 case BC_FORI:
5253 case BC_IFORL:
5254 vk = (op == BC_IFORL || op == BC_JFORL);
5255 | ins_AJ // RA = base, RD = target (after end of loop or start of loop)
5256 | lea RA, [BASE+RA*8]
5257 if (LJ_DUALNUM) {
5258 | cmp FOR_TIDX, LJ_TISNUM; jne >9
5259 if (!vk) {
5260 | cmp FOR_TSTOP, LJ_TISNUM; jne ->vmeta_for
5261 | cmp FOR_TSTEP, LJ_TISNUM; jne ->vmeta_for
5262 | mov RB, dword FOR_IDX
5263 | cmp dword FOR_STEP, 0; jl >5
5264 } else {
5265#ifdef LUA_USE_ASSERT
5266 | cmp FOR_TSTOP, LJ_TISNUM; jne ->assert_bad_for_arg_type
5267 | cmp FOR_TSTEP, LJ_TISNUM; jne ->assert_bad_for_arg_type
5268#endif
5269 | mov RB, dword FOR_STEP
5270 | test RB, RB; js >5
5271 | add RB, dword FOR_IDX; jo >1
5272 | mov dword FOR_IDX, RB
5273 }
5274 | cmp RB, dword FOR_STOP
5275 | mov FOR_TEXT, LJ_TISNUM
5276 | mov dword FOR_EXT, RB
5277 if (op == BC_FORI) {
5278 | jle >7
5279 |1:
5280 |6:
5281 | branchPC RD
5282 } else if (op == BC_JFORI) {
5283 | branchPC RD
5284 | movzx RD, PC_RD
5285 | jle =>BC_JLOOP
5286 |1:
5287 |6:
5288 } else if (op == BC_IFORL) {
5289 | jg >7
5290 |6:
5291 | branchPC RD
5292 |1:
5293 } else {
5294 | jle =>BC_JLOOP
5295 |1:
5296 |6:
5297 }
5298 |7:
5299 | ins_next
5300 |
5301 |5: // Invert check for negative step.
5302 if (vk) {
5303 | add RB, dword FOR_IDX; jo <1
5304 | mov dword FOR_IDX, RB
5305 }
5306 | cmp RB, dword FOR_STOP
5307 | mov FOR_TEXT, LJ_TISNUM
5308 | mov dword FOR_EXT, RB
5309 if (op == BC_FORI) {
5310 | jge <7
5311 } else if (op == BC_JFORI) {
5312 | branchPC RD
5313 | movzx RD, PC_RD
5314 | jge =>BC_JLOOP
5315 } else if (op == BC_IFORL) {
5316 | jl <7
5317 } else {
5318 | jge =>BC_JLOOP
5319 }
5320 | jmp <6
5321 |9: // Fallback to FP variant.
5322 } else if (!vk) {
5323 | cmp FOR_TIDX, LJ_TISNUM
5324 }
5325 if (!vk) {
5326 | jae ->vmeta_for
5327 | cmp FOR_TSTOP, LJ_TISNUM; jae ->vmeta_for
5328 } else {
5329#ifdef LUA_USE_ASSERT
5330 | cmp FOR_TSTOP, LJ_TISNUM; jae ->assert_bad_for_arg_type
5331 | cmp FOR_TSTEP, LJ_TISNUM; jae ->assert_bad_for_arg_type
5332#endif
5333 }
5334 | mov RB, FOR_TSTEP // Load type/hiword of for step.
5335 if (!vk) {
5336 | cmp RB, LJ_TISNUM; jae ->vmeta_for
5337 }
5338 | movsd xmm0, qword FOR_IDX
5339 | movsd xmm1, qword FOR_STOP
5340 if (vk) {
5341 | addsd xmm0, qword FOR_STEP
5342 | movsd qword FOR_IDX, xmm0
5343 | test RB, RB; js >3
5344 } else {
5345 | jl >3
5346 }
5347 | ucomisd xmm1, xmm0
5348 |1:
5349 | movsd qword FOR_EXT, xmm0
5350 if (op == BC_FORI) {
5351 |.if DUALNUM
5352 | jnb <7
5353 |.else
5354 | jnb >2
5355 | branchPC RD
5356 |.endif
5357 } else if (op == BC_JFORI) {
5358 | branchPC RD
5359 | movzx RD, PC_RD
5360 | jnb =>BC_JLOOP
5361 } else if (op == BC_IFORL) {
5362 |.if DUALNUM
5363 | jb <7
5364 |.else
5365 | jb >2
5366 | branchPC RD
5367 |.endif
5368 } else {
5369 | jnb =>BC_JLOOP
5370 }
5371 |.if DUALNUM
5372 | jmp <6
5373 |.else
5374 |2:
5375 | ins_next
5376 |.endif
5377 |
5378 |3: // Invert comparison if step is negative.
5379 | ucomisd xmm0, xmm1
5380 | jmp <1
5381 break;
5382
5383 case BC_ITERL:
5384 |.if JIT
5385 | hotloop RB
5386 |.endif
5387 | // Fall through. Assumes BC_IITERL follows and ins_AJ is a no-op.
5388 break;
5389
5390 case BC_JITERL:
5391#if !LJ_HASJIT
5392 break;
5393#endif
5394 case BC_IITERL:
5395 | ins_AJ // RA = base, RD = target
5396 | lea RA, [BASE+RA*8]
5397 | mov RB, [RA+4]
5398 | cmp RB, LJ_TNIL; je >1 // Stop if iterator returned nil.
5399 if (op == BC_JITERL) {
5400 | mov [RA-4], RB
5401 | mov RB, [RA]
5402 | mov [RA-8], RB
5403 | jmp =>BC_JLOOP
5404 } else {
5405 | branchPC RD // Otherwise save control var + branch.
5406 | mov RD, [RA]
5407 | mov [RA-4], RB
5408 | mov [RA-8], RD
5409 }
5410 |1:
5411 | ins_next
5412 break;
5413
5414 case BC_LOOP:
5415 | ins_A // RA = base, RD = target (loop extent)
5416 | // Note: RA/RD is only used by trace recorder to determine scope/extent
5417 | // This opcode does NOT jump, it's only purpose is to detect a hot loop.
5418 |.if JIT
5419 | hotloop RB
5420 |.endif
5421 | // Fall through. Assumes BC_ILOOP follows and ins_A is a no-op.
5422 break;
5423
5424 case BC_ILOOP:
5425 | ins_A // RA = base, RD = target (loop extent)
5426 | ins_next
5427 break;
5428
5429 case BC_JLOOP:
5430 |.if JIT
5431 | ins_AD // RA = base (ignored), RD = traceno
5432 | mov RA, [DISPATCH+DISPATCH_J(trace)]
5433 | mov TRACE:RD, [RA+RD*4]
5434 | mov RDa, TRACE:RD->mcode
5435 | mov L:RB, SAVE_L
5436 | mov [DISPATCH+DISPATCH_GL(jit_base)], BASE
5437 | mov [DISPATCH+DISPATCH_GL(tmpbuf.L)], L:RB
5438 | // Save additional callee-save registers only used in compiled code.
5439 |.if X64WIN
5440 | mov TMPQ, r12
5441 | mov TMPa, r13
5442 | mov CSAVE_4, r14
5443 | mov CSAVE_3, r15
5444 | mov RAa, rsp
5445 | sub rsp, 9*16+4*8
5446 | movdqa [RAa], xmm6
5447 | movdqa [RAa-1*16], xmm7
5448 | movdqa [RAa-2*16], xmm8
5449 | movdqa [RAa-3*16], xmm9
5450 | movdqa [RAa-4*16], xmm10
5451 | movdqa [RAa-5*16], xmm11
5452 | movdqa [RAa-6*16], xmm12
5453 | movdqa [RAa-7*16], xmm13
5454 | movdqa [RAa-8*16], xmm14
5455 | movdqa [RAa-9*16], xmm15
5456 |.elif X64
5457 | mov TMPQ, r12
5458 | mov TMPa, r13
5459 | sub rsp, 16
5460 |.endif
5461 | jmp RDa
5462 |.endif
5463 break;
5464
5465 case BC_JMP:
5466 | ins_AJ // RA = unused, RD = target
5467 | branchPC RD
5468 | ins_next
5469 break;
5470
5471 /* -- Function headers -------------------------------------------------- */
5472
5473 /*
5474 ** Reminder: A function may be called with func/args above L->maxstack,
5475 ** i.e. occupying EXTRA_STACK slots. And vmeta_call may add one extra slot,
5476 ** too. This means all FUNC* ops (including fast functions) must check
5477 ** for stack overflow _before_ adding more slots!
5478 */
5479
5480 case BC_FUNCF:
5481 |.if JIT
5482 | hotcall RB
5483 |.endif
5484 case BC_FUNCV: /* NYI: compiled vararg functions. */
5485 | // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow and ins_AD is a no-op.
5486 break;
5487
5488 case BC_JFUNCF:
5489#if !LJ_HASJIT
5490 break;
5491#endif
5492 case BC_IFUNCF:
5493 | ins_AD // BASE = new base, RA = framesize, RD = nargs+1
5494 | mov KBASE, [PC-4+PC2PROTO(k)]
5495 | mov L:RB, SAVE_L
5496 | lea RA, [BASE+RA*8] // Top of frame.
5497 | cmp RA, L:RB->maxstack
5498 | ja ->vm_growstack_f
5499 | movzx RA, byte [PC-4+PC2PROTO(numparams)]
5500 | cmp NARGS:RD, RA // Check for missing parameters.
5501 | jbe >3
5502 |2:
5503 if (op == BC_JFUNCF) {
5504 | movzx RD, PC_RD
5505 | jmp =>BC_JLOOP
5506 } else {
5507 | ins_next
5508 }
5509 |
5510 |3: // Clear missing parameters.
5511 | mov dword [BASE+NARGS:RD*8-4], LJ_TNIL
5512 | add NARGS:RD, 1
5513 | cmp NARGS:RD, RA
5514 | jbe <3
5515 | jmp <2
5516 break;
5517
5518 case BC_JFUNCV:
5519#if !LJ_HASJIT
5520 break;
5521#endif
5522 | int3 // NYI: compiled vararg functions
5523 break; /* NYI: compiled vararg functions. */
5524
5525 case BC_IFUNCV:
5526 | ins_AD // BASE = new base, RA = framesize, RD = nargs+1
5527 | lea RB, [NARGS:RD*8+FRAME_VARG]
5528 | lea RD, [BASE+NARGS:RD*8]
5529 | mov LFUNC:KBASE, [BASE-8]
5530 | mov [RD-4], RB // Store delta + FRAME_VARG.
5531 | mov [RD-8], LFUNC:KBASE // Store copy of LFUNC.
5532 | mov L:RB, SAVE_L
5533 | lea RA, [RD+RA*8]
5534 | cmp RA, L:RB->maxstack
5535 | ja ->vm_growstack_v // Need to grow stack.
5536 | mov RA, BASE
5537 | mov BASE, RD
5538 | movzx RB, byte [PC-4+PC2PROTO(numparams)]
5539 | test RB, RB
5540 | jz >2
5541 |1: // Copy fixarg slots up to new frame.
5542 | add RA, 8
5543 | cmp RA, BASE
5544 | jnb >3 // Less args than parameters?
5545 | mov KBASE, [RA-8]
5546 | mov [RD], KBASE
5547 | mov KBASE, [RA-4]
5548 | mov [RD+4], KBASE
5549 | add RD, 8
5550 | mov dword [RA-4], LJ_TNIL // Clear old fixarg slot (help the GC).
5551 | sub RB, 1
5552 | jnz <1
5553 |2:
5554 if (op == BC_JFUNCV) {
5555 | movzx RD, PC_RD
5556 | jmp =>BC_JLOOP
5557 } else {
5558 | mov KBASE, [PC-4+PC2PROTO(k)]
5559 | ins_next
5560 }
5561 |
5562 |3: // Clear missing parameters.
5563 | mov dword [RD+4], LJ_TNIL
5564 | add RD, 8
5565 | sub RB, 1
5566 | jnz <3
5567 | jmp <2
5568 break;
5569
5570 case BC_FUNCC:
5571 case BC_FUNCCW:
5572 | ins_AD // BASE = new base, RA = ins RA|RD (unused), RD = nargs+1
5573 | mov CFUNC:RB, [BASE-8]
5574 | mov KBASEa, CFUNC:RB->f
5575 | mov L:RB, SAVE_L
5576 | lea RD, [BASE+NARGS:RD*8-8]
5577 | mov L:RB->base, BASE
5578 | lea RA, [RD+8*LUA_MINSTACK]
5579 | cmp RA, L:RB->maxstack
5580 | mov L:RB->top, RD
5581 if (op == BC_FUNCC) {
5582 |.if X64
5583 | mov CARG1d, L:RB // Caveat: CARG1d may be RA.
5584 |.else
5585 | mov ARG1, L:RB
5586 |.endif
5587 } else {
5588 |.if X64
5589 | mov CARG2, KBASEa
5590 | mov CARG1d, L:RB // Caveat: CARG1d may be RA.
5591 |.else
5592 | mov ARG2, KBASEa
5593 | mov ARG1, L:RB
5594 |.endif
5595 }
5596 | ja ->vm_growstack_c // Need to grow stack.
5597 | set_vmstate C
5598 if (op == BC_FUNCC) {
5599 | call KBASEa // (lua_State *L)
5600 } else {
5601 | // (lua_State *L, lua_CFunction f)
5602 | call aword [DISPATCH+DISPATCH_GL(wrapf)]
5603 }
5604 | // nresults returned in eax (RD).
5605 | mov BASE, L:RB->base
5606 | mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
5607 | set_vmstate INTERP
5608 | lea RA, [BASE+RD*8]
5609 | neg RA
5610 | add RA, L:RB->top // RA = (L->top-(L->base+nresults))*8
5611 | mov PC, [BASE-4] // Fetch PC of caller.
5612 | jmp ->vm_returnc
5613 break;
5614
5615 /* ---------------------------------------------------------------------- */
5616
5617 default:
5618 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
5619 exit(2);
5620 break;
5621 }
5622}
5623
5624static int build_backend(BuildCtx *ctx)
5625{
5626 int op;
5627 dasm_growpc(Dst, BC__MAX);
5628 build_subroutines(ctx);
5629 |.code_op
5630 for (op = 0; op < BC__MAX; op++)
5631 build_ins(ctx, (BCOp)op, op);
5632 return BC__MAX;
5633}
5634
5635/* Emit pseudo frame-info for all assembler functions. */
5636static void emit_asm_debug(BuildCtx *ctx)
5637{
5638 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
5639#if LJ_64
5640#define SZPTR "8"
5641#define BSZPTR "3"
5642#define REG_SP "0x7"
5643#define REG_RA "0x10"
5644#else
5645#define SZPTR "4"
5646#define BSZPTR "2"
5647#define REG_SP "0x4"
5648#define REG_RA "0x8"
5649#endif
5650 switch (ctx->mode) {
5651 case BUILD_elfasm:
5652 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
5653 fprintf(ctx->fp,
5654 ".Lframe0:\n"
5655 "\t.long .LECIE0-.LSCIE0\n"
5656 ".LSCIE0:\n"
5657 "\t.long 0xffffffff\n"
5658 "\t.byte 0x1\n"
5659 "\t.string \"\"\n"
5660 "\t.uleb128 0x1\n"
5661 "\t.sleb128 -" SZPTR "\n"
5662 "\t.byte " REG_RA "\n"
5663 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
5664 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
5665 "\t.align " SZPTR "\n"
5666 ".LECIE0:\n\n");
5667 fprintf(ctx->fp,
5668 ".LSFDE0:\n"
5669 "\t.long .LEFDE0-.LASFDE0\n"
5670 ".LASFDE0:\n"
5671 "\t.long .Lframe0\n"
5672#if LJ_64
5673 "\t.quad .Lbegin\n"
5674 "\t.quad %d\n"
5675 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
5676 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
5677 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
5678 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
5679 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
5680#if LJ_NO_UNWIND
5681 "\t.byte 0x8d\n\t.uleb128 0x6\n" /* offset r13 */
5682 "\t.byte 0x8c\n\t.uleb128 0x7\n" /* offset r12 */
5683#endif
5684#else
5685 "\t.long .Lbegin\n"
5686 "\t.long %d\n"
5687 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
5688 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
5689 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
5690 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
5691 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
5692#endif
5693 "\t.align " SZPTR "\n"
5694 ".LEFDE0:\n\n", fcofs, CFRAME_SIZE);
5695#if LJ_HASFFI
5696 fprintf(ctx->fp,
5697 ".LSFDE1:\n"
5698 "\t.long .LEFDE1-.LASFDE1\n"
5699 ".LASFDE1:\n"
5700 "\t.long .Lframe0\n"
5701#if LJ_64
5702 "\t.quad lj_vm_ffi_call\n"
5703 "\t.quad %d\n"
5704 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
5705 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
5706 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
5707 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
5708#else
5709 "\t.long lj_vm_ffi_call\n"
5710 "\t.long %d\n"
5711 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
5712 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
5713 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
5714 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
5715#endif
5716 "\t.align " SZPTR "\n"
5717 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
5718#endif
5719#if !LJ_NO_UNWIND
5720#if LJ_TARGET_SOLARIS
5721#if LJ_64
5722 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@unwind\n");
5723#else
5724 fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n");
5725#endif
5726#else
5727 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
5728#endif
5729 fprintf(ctx->fp,
5730 ".Lframe1:\n"
5731 "\t.long .LECIE1-.LSCIE1\n"
5732 ".LSCIE1:\n"
5733 "\t.long 0\n"
5734 "\t.byte 0x1\n"
5735 "\t.string \"zPR\"\n"
5736 "\t.uleb128 0x1\n"
5737 "\t.sleb128 -" SZPTR "\n"
5738 "\t.byte " REG_RA "\n"
5739 "\t.uleb128 6\n" /* augmentation length */
5740 "\t.byte 0x1b\n" /* pcrel|sdata4 */
5741 "\t.long lj_err_unwind_dwarf-.\n"
5742 "\t.byte 0x1b\n" /* pcrel|sdata4 */
5743 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
5744 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
5745 "\t.align " SZPTR "\n"
5746 ".LECIE1:\n\n");
5747 fprintf(ctx->fp,
5748 ".LSFDE2:\n"
5749 "\t.long .LEFDE2-.LASFDE2\n"
5750 ".LASFDE2:\n"
5751 "\t.long .LASFDE2-.Lframe1\n"
5752 "\t.long .Lbegin-.\n"
5753 "\t.long %d\n"
5754 "\t.uleb128 0\n" /* augmentation length */
5755 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
5756#if LJ_64
5757 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
5758 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
5759 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
5760 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
5761#else
5762 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
5763 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
5764 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
5765 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
5766#endif
5767 "\t.align " SZPTR "\n"
5768 ".LEFDE2:\n\n", fcofs, CFRAME_SIZE);
5769#if LJ_HASFFI
5770 fprintf(ctx->fp,
5771 ".Lframe2:\n"
5772 "\t.long .LECIE2-.LSCIE2\n"
5773 ".LSCIE2:\n"
5774 "\t.long 0\n"
5775 "\t.byte 0x1\n"
5776 "\t.string \"zR\"\n"
5777 "\t.uleb128 0x1\n"
5778 "\t.sleb128 -" SZPTR "\n"
5779 "\t.byte " REG_RA "\n"
5780 "\t.uleb128 1\n" /* augmentation length */
5781 "\t.byte 0x1b\n" /* pcrel|sdata4 */
5782 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
5783 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
5784 "\t.align " SZPTR "\n"
5785 ".LECIE2:\n\n");
5786 fprintf(ctx->fp,
5787 ".LSFDE3:\n"
5788 "\t.long .LEFDE3-.LASFDE3\n"
5789 ".LASFDE3:\n"
5790 "\t.long .LASFDE3-.Lframe2\n"
5791 "\t.long lj_vm_ffi_call-.\n"
5792 "\t.long %d\n"
5793 "\t.uleb128 0\n" /* augmentation length */
5794#if LJ_64
5795 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
5796 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
5797 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
5798 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
5799#else
5800 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
5801 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
5802 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
5803 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
5804#endif
5805 "\t.align " SZPTR "\n"
5806 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
5807#endif
5808#endif
5809 break;
5810#if !LJ_NO_UNWIND
5811 /* Mental note: never let Apple design an assembler.
5812 ** Or a linker. Or a plastic case. But I digress.
5813 */
5814 case BUILD_machasm: {
5815#if LJ_HASFFI
5816 int fcsize = 0;
5817#endif
5818 int i;
5819 fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
5820 fprintf(ctx->fp,
5821 "EH_frame1:\n"
5822 "\t.set L$set$x,LECIEX-LSCIEX\n"
5823 "\t.long L$set$x\n"
5824 "LSCIEX:\n"
5825 "\t.long 0\n"
5826 "\t.byte 0x1\n"
5827 "\t.ascii \"zPR\\0\"\n"
5828 "\t.byte 0x1\n"
5829 "\t.byte 128-" SZPTR "\n"
5830 "\t.byte " REG_RA "\n"
5831 "\t.byte 6\n" /* augmentation length */
5832 "\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
5833#if LJ_64
5834 "\t.long _lj_err_unwind_dwarf+4@GOTPCREL\n"
5835 "\t.byte 0x1b\n" /* pcrel|sdata4 */
5836 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
5837#else
5838 "\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
5839 "\t.byte 0x1b\n" /* pcrel|sdata4 */
5840 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH-O. */
5841#endif
5842 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
5843 "\t.align " BSZPTR "\n"
5844 "LECIEX:\n\n");
5845 for (i = 0; i < ctx->nsym; i++) {
5846 const char *name = ctx->sym[i].name;
5847 int32_t size = ctx->sym[i+1].ofs - ctx->sym[i].ofs;
5848 if (size == 0) continue;
5849#if LJ_HASFFI
5850 if (!strcmp(name, "_lj_vm_ffi_call")) { fcsize = size; continue; }
5851#endif
5852 fprintf(ctx->fp,
5853 "%s.eh:\n"
5854 "LSFDE%d:\n"
5855 "\t.set L$set$%d,LEFDE%d-LASFDE%d\n"
5856 "\t.long L$set$%d\n"
5857 "LASFDE%d:\n"
5858 "\t.long LASFDE%d-EH_frame1\n"
5859 "\t.long %s-.\n"
5860 "\t.long %d\n"
5861 "\t.byte 0\n" /* augmentation length */
5862 "\t.byte 0xe\n\t.byte %d\n" /* def_cfa_offset */
5863#if LJ_64
5864 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
5865 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
5866 "\t.byte 0x8f\n\t.byte 0x4\n" /* offset r15 */
5867 "\t.byte 0x8e\n\t.byte 0x5\n" /* offset r14 */
5868#else
5869 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
5870 "\t.byte 0x87\n\t.byte 0x3\n" /* offset edi */
5871 "\t.byte 0x86\n\t.byte 0x4\n" /* offset esi */
5872 "\t.byte 0x83\n\t.byte 0x5\n" /* offset ebx */
5873#endif
5874 "\t.align " BSZPTR "\n"
5875 "LEFDE%d:\n\n",
5876 name, i, i, i, i, i, i, i, name, size, CFRAME_SIZE, i);
5877 }
5878#if LJ_HASFFI
5879 if (fcsize) {
5880 fprintf(ctx->fp,
5881 "EH_frame2:\n"
5882 "\t.set L$set$y,LECIEY-LSCIEY\n"
5883 "\t.long L$set$y\n"
5884 "LSCIEY:\n"
5885 "\t.long 0\n"
5886 "\t.byte 0x1\n"
5887 "\t.ascii \"zR\\0\"\n"
5888 "\t.byte 0x1\n"
5889 "\t.byte 128-" SZPTR "\n"
5890 "\t.byte " REG_RA "\n"
5891 "\t.byte 1\n" /* augmentation length */
5892#if LJ_64
5893 "\t.byte 0x1b\n" /* pcrel|sdata4 */
5894 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
5895#else
5896 "\t.byte 0x1b\n" /* pcrel|sdata4 */
5897 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH. */
5898#endif
5899 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
5900 "\t.align " BSZPTR "\n"
5901 "LECIEY:\n\n");
5902 fprintf(ctx->fp,
5903 "_lj_vm_ffi_call.eh:\n"
5904 "LSFDEY:\n"
5905 "\t.set L$set$yy,LEFDEY-LASFDEY\n"
5906 "\t.long L$set$yy\n"
5907 "LASFDEY:\n"
5908 "\t.long LASFDEY-EH_frame2\n"
5909 "\t.long _lj_vm_ffi_call-.\n"
5910 "\t.long %d\n"
5911 "\t.byte 0\n" /* augmentation length */
5912#if LJ_64
5913 "\t.byte 0xe\n\t.byte 16\n" /* def_cfa_offset */
5914 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
5915 "\t.byte 0xd\n\t.byte 0x6\n" /* def_cfa_register rbp */
5916 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
5917#else
5918 "\t.byte 0xe\n\t.byte 8\n" /* def_cfa_offset */
5919 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
5920 "\t.byte 0xd\n\t.byte 0x4\n" /* def_cfa_register ebp */
5921 "\t.byte 0x83\n\t.byte 0x3\n" /* offset ebx */
5922#endif
5923 "\t.align " BSZPTR "\n"
5924 "LEFDEY:\n\n", fcsize);
5925 }
5926#endif
5927#if !LJ_64
5928 fprintf(ctx->fp,
5929 "\t.non_lazy_symbol_pointer\n"
5930 "L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
5931 ".indirect_symbol _lj_err_unwind_dwarf\n"
5932 ".long 0\n\n");
5933 fprintf(ctx->fp, "\t.section __IMPORT,__jump_table,symbol_stubs,pure_instructions+self_modifying_code,5\n");
5934 {
5935 const char *const *xn;
5936 for (xn = ctx->extnames; *xn; xn++)
5937 if (strncmp(*xn, LABEL_PREFIX, sizeof(LABEL_PREFIX)-1))
5938 fprintf(ctx->fp, "L_%s$stub:\n\t.indirect_symbol _%s\n\t.ascii \"\\364\\364\\364\\364\\364\"\n", *xn, *xn);
5939 }
5940#endif
5941 }
5942 break;
5943#endif
5944 default: /* Difficult for other modes. */
5945 break;
5946 }
5947}
5948