Merge remote-tracking branch 'origin/5.5' into dev
Change-Id: If9fd98525b6b4ca07e5e006fc98bf372a73b8a21bb10
commit
20cac3d9c9
|
|
@ -13,7 +13,7 @@ http://qt-project.org
|
|||
|
||||
Be sure to check out the release notes, which will list any known
|
||||
problems or limitations of this version:
|
||||
https://wiki.qt.io/?title=Category:Release
|
||||
https://wiki.qt.io/Category:Release
|
||||
|
||||
|
||||
Overview
|
||||
|
|
@ -101,7 +101,7 @@ Building Qt 5 from Source
|
|||
-------------------------
|
||||
|
||||
See <install_dir>/<version>/src/README and
|
||||
http://wiki.qt.io/?title=Building_Qt_5_from_Git
|
||||
http://wiki.qt.io/Building_Qt_5_from_Git
|
||||
for instructions on building Qt from source.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -106,4 +106,4 @@ More Information
|
|||
================
|
||||
|
||||
For more information about Qt 5's documentation, refer to the Qt Project wiki:
|
||||
http://wiki.qt.io/?title=Qt5DocumentationProject
|
||||
http://wiki.qt.io/Qt5DocumentationProject
|
||||
|
|
|
|||
|
|
@ -448,11 +448,6 @@
|
|||
\title publicsuffix.org
|
||||
*/
|
||||
|
||||
/*!
|
||||
\externalpage http://wiki.forum.nokia.com/
|
||||
\title Forum Nokia Wiki
|
||||
*/
|
||||
|
||||
/*!
|
||||
\externalpage http://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/_accessible_event_i_d_8idl.html
|
||||
\title AccessibleEventID.idl File Reference
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
*/
|
||||
|
||||
/*!
|
||||
\externalpage http://wiki.qt.io/?title=Qt_Coding_Style
|
||||
\externalpage http://wiki.qt.io/Qt_Coding_Style
|
||||
\title Qt Coding Style
|
||||
*/
|
||||
/*!
|
||||
|
|
@ -78,16 +78,16 @@
|
|||
\title Pimp my video
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://wiki.qt.io/?title=QtMediaHub
|
||||
\externalpage http://wiki.qt.io/QtMediaHub
|
||||
\title QtMediaHub
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://wiki.qt.io/?title=Qt_RaspberryPi
|
||||
\externalpage http://wiki.qt.io/Qt_RaspberryPi
|
||||
\title QtonPi
|
||||
*/
|
||||
|
||||
/*!
|
||||
\externalpage http://wiki.qt.io/?title=jom
|
||||
\externalpage http://wiki.qt.io/jom
|
||||
\title jom
|
||||
*/
|
||||
|
||||
|
|
@ -102,11 +102,11 @@
|
|||
*/
|
||||
|
||||
/*!
|
||||
\externalpage http://wiki.qt.io/?title=Qt_Localization
|
||||
\externalpage http://wiki.qt.io/Qt_Localization
|
||||
\title external: Translating Qt Into Other Languages
|
||||
*/
|
||||
|
||||
/*!
|
||||
\externalpage http://wiki.qt.io/?title=BlackBerry
|
||||
\externalpage http://wiki.qt.io/BlackBerry
|
||||
\title Qt for BlackBerry
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ HTML.footer += \
|
|||
" <li id=\"menu-item-1356\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1356\"><a href=\"http://qt.io/qt-features/\">Qt Features</a></li>\n" \
|
||||
" <li id=\"menu-item-1359\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1359\"><a href=\"http://qt.io/qt-quick/\">Qt Quick</a></li>\n" \
|
||||
" <li id=\"menu-item-1357\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1357\"><a href=\"http://qt.io/qt-for-device-creation/\">Qt for Device Creation</a></li>\n" \
|
||||
" <li id=\"menu-item-34\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-34\"><a href=\"http://qt.io/qt-in-use/\">Qt in Use</a></li>\n" \
|
||||
" <li id=\"menu-item-10159\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-10159\"><a href=\"http://qt.io/mobile-app-development/\">Qt for Mobile Apps</a></li>\n" \
|
||||
" <li id=\"menu-item-1366\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1366\"><a href=\"http://showroom.qt-project.org/\">Showroom</a></li>\n" \
|
||||
"</ul>\n" \
|
||||
"</li>\n" \
|
||||
|
|
@ -37,8 +37,8 @@ HTML.footer += \
|
|||
" <li id=\"menu-item-1364\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1364\"><a href=\"http://doc.qt.io/qt-5/qtexamplesandtutorials.html\">Examples & Tutorials</a></li>\n" \
|
||||
" <li id=\"menu-item-1363\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1363\"><a href=\"http://doc.qt.io/qt-5/topics-app-development.html\">Tools</a></li>\n" \
|
||||
" <li id=\"menu-item-1361\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1361\"><a href=\"http://wiki.qt.io/\">Wiki</a></li>\n" \
|
||||
" <li id=\"menu-item-1360\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1360\"><a href=\"http://qt-project.org/forums\">Forums</a></li>\n" \
|
||||
" <li id=\"menu-item-1362\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1362\"><a href=\"http://wiki.qt.io/?title=Qt_Contribution_Guidelines\">Contribute to Qt</a></li>\n" \
|
||||
" <li id=\"menu-item-1360\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1360\"><a href=\"http://forum.qt.io/\">Forums</a></li>\n" \
|
||||
" <li id=\"menu-item-1362\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1362\"><a href=\"http://wiki.qt.io/Qt_Contribution_Guidelines\">Contribute to Qt</a></li>\n" \
|
||||
"</ul>\n" \
|
||||
"</li>\n" \
|
||||
"<li id=\"menu-item-1347\" class=\"menu-item menu-item-type-post_type menu-item-object-page current-menu-ancestor current-menu-parent current_page_parent current_page_ancestor menu-item-has-children menu-item-1347\"><a href=\"http://qt.io/services/\">Services</a>\n" \
|
||||
|
|
@ -48,6 +48,7 @@ HTML.footer += \
|
|||
" <li id=\"menu-item-4027\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-4027\"><a href=\"http://qt.io/services-proof-of-concept/\">Proof of Concept</a></li>\n" \
|
||||
" <li id=\"menu-item-4026\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-4026\"><a href=\"http://qt.io/services-design-implementation/\">Design & Implementation</a></li>\n" \
|
||||
" <li id=\"menu-item-4025\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-4025\"><a href=\"http://qt.io/services-productization/\">Productization</a></li>\n" \
|
||||
" <li id=\"menu-item-5124\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-5124\"><a href=\"https://qtcloudservices.com/\">Qt Cloud Services</a></li>\n" \
|
||||
"</ul>\n" \
|
||||
"</li>\n" \
|
||||
"<li id=\"menu-item-1403\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1403\"><a href=\"http://qt.io/download/\">Download</a>\n" \
|
||||
|
|
@ -60,11 +61,10 @@ HTML.footer += \
|
|||
"</ul>\n" \
|
||||
"</li>\n" \
|
||||
"</ul></div></nav>\n" \
|
||||
"<a href=\"http://digia.com\" target=\"_blank\" class=\"footer-logo retina\" data-icon=\"\">\n" \
|
||||
" </a>\n" \
|
||||
"<a href=\"http://qt.io/about-us/\" target=\"_blank\" class=\"theqtcompany\"></a>\n" \
|
||||
" <div class=\"footer-social clearfix\">\n" \
|
||||
" <div class=\"facebook\">\n" \
|
||||
" <div class=\"fb-like fb_iframe_widget\" data-href=\"https://www.facebook.com/qtbydigia\" data-layout=\"button_count\" data-action=\"like\" data-show-faces=\"true\" data-share=\"false\" fb-xfbml-state=\"parsed\" fb-iframe-plugin-query=\"action=like&app_id=207346529386114&href=https%3A%2F%2Fwww.facebook.com%2Fqtbydigia&layout=button_count&locale=en_US&sdk=joey&share=false&show_faces=true\" style=\"display: block;\"><iframe style=\"width: 30px; height: 19px; border: 0px;\"></iframe></div>\n" \
|
||||
" <iframe scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" src=\"//www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwww.facebook.com%2Fqtbydigia&width&layout=button_count&action=like&show_faces=true&share=false&height=21\" style=\"border:none;overflow:hidden;height:21px;\"></iframe>\n" \
|
||||
" </div>\n" \
|
||||
" <div class=\"twitter\">\n" \
|
||||
" <iframe id=\"twitter-widget-0\" scrolling=\"no\" frameborder=\"0\" allowtransparency=\"true\" src=\"http://platform.twitter.com/widgets/follow_button.33b190ea0cba008796487b65df7f6d8e.en.html#_=1414403615717&id=twitter-widget-0&lang=en&screen_name=qtproject&show_count=true&show_screen_name=false&size=m\" class=\"twitter-follow-button twitter-follow-button\" title=\"Twitter Follow Button\" data-twttr-rendered=\"true\" style=\"width: 160px; height: 20px;\"></iframe>\n" \
|
||||
|
|
@ -75,8 +75,9 @@ HTML.footer += \
|
|||
"<div class=\"disclaimer\">\n" \
|
||||
"<div class=\"container clearfix no_discs\">\n" \
|
||||
" <ul id=\"menu-footer-submenu\" class=\"right clearfix\"><li id=\"menu-item-1795\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1795\"><a title=\"Sign into your account.\" href=\"https://account.qt.io/login\">Sign In</a></li>\n" \
|
||||
" <li id=\"menu-item-1494\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1494\"><a href=\"http://qt.io/contact-us/\">Contact us</a></li>\n" \
|
||||
" <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://www.digia.com\">© 2015 Digia Oyj</a></li>\n" \
|
||||
" <li id=\"menu-item-10375\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-10375\"><a href=\"mailto:feedback@theqtcompany.com?Subject=Feedback%20about%20doc.qt.io%20site\">Feedback</a></li>\n" \
|
||||
" <li id=\"menu-item-1494\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1494\"><a href=\"http://qt.io/contact-us/\">Contact us</a></li>\n" \
|
||||
" <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2015 The Qt Company</a></li>\n" \
|
||||
" </ul>\n" \
|
||||
"</div>\n" \
|
||||
"</div>\n" \
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ HTML.stylesheets = template/style/online.css \
|
|||
template/style/icomoon.svg \
|
||||
template/style/icomoon.ttf \
|
||||
template/style/icomoon.woff \
|
||||
template/style/doc_search.png
|
||||
template/style/cookiebar-x.png \
|
||||
template/style/doc_search.png \
|
||||
template/style/theqtcompany.png
|
||||
|
||||
#for including files into the qch file. Relative to the outputdir of a QDoc build.
|
||||
qhp.extraFiles += style/online.css \
|
||||
|
|
@ -16,7 +18,10 @@ qhp.extraFiles += style/online.css \
|
|||
style/icomoon.eot \
|
||||
style/icomoon.svg \
|
||||
style/icomoon.ttf \
|
||||
style/icomoon.woff
|
||||
style/icomoon.woff \
|
||||
style/cookiebar-x.png \
|
||||
style/doc_search.png \
|
||||
style/theqtcompany.png
|
||||
|
||||
HTML.headerstyles = \
|
||||
" <link rel=\"stylesheet\" type=\"text/css\" href=\"style/online.css\" />\n" \
|
||||
|
|
@ -116,7 +121,7 @@ HTML.postheader = \
|
|||
" <ul class=\"sub-navigation\">\n" \
|
||||
" <li><a href=\"http://wiki.qt.io/\">Wiki</a></li>\n" \
|
||||
" <li><a href=\"http://doc.qt.io/\" class=\"active\">Documentation</a></li>\n" \
|
||||
" <li><a href=\"http://qt-project.org/forums\">Forum</a></li>\n" \
|
||||
" <li><a href=\"http://forum.qt.io/\">Forum</a></li>\n" \
|
||||
" <li><a href=\"https://bugreports.qt.io/\">Bug Reports</a></li>\n" \
|
||||
" <li><a href=\"https://codereview.qt-project.org/\">Code Review</a></li>\n" \
|
||||
" </ul>\n" \
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
var vOffset = 65;
|
||||
|
||||
$(function () {
|
||||
$('a[href*=#]:not([href=#])').on('click', function () {
|
||||
$('a[href*=#]:not([href=#])').on('click', function (e) {
|
||||
if (e.which == 2)
|
||||
return true;
|
||||
var target = $(this.hash);
|
||||
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
|
||||
if (target.length) {
|
||||
setTimeout(function () {
|
||||
$('html, body').animate({scrollTop: target.offset().top - vOffset}, 50);}, 50);
|
||||
// return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 236 B |
|
|
@ -153,7 +153,8 @@
|
|||
}
|
||||
#mainmenu {
|
||||
float:left;
|
||||
list-style:none
|
||||
list-style:none;
|
||||
margin-left:16px
|
||||
}
|
||||
#mainmenu li {
|
||||
float:left;
|
||||
|
|
@ -212,6 +213,9 @@
|
|||
min-width:85px;
|
||||
font-weight:100
|
||||
}
|
||||
#menuextras li:last-child a {
|
||||
border-right:1px solid #eee;
|
||||
}
|
||||
#menuextras li a:before {
|
||||
display:inline-block;
|
||||
font-family:'Qt Icons';
|
||||
|
|
@ -372,12 +376,37 @@
|
|||
#menuextras li.navbar-search {
|
||||
padding:5px 0
|
||||
}
|
||||
.container {
|
||||
padding:0 2%
|
||||
#footerbar .container {
|
||||
padding:0
|
||||
}
|
||||
body .main {
|
||||
margin-top:0px
|
||||
}
|
||||
#footerbar .footer-main .footer-nav {
|
||||
padding:3.9% 0 3.9% 3%;
|
||||
border-bottom:1px solid #413d3b;
|
||||
float:none;
|
||||
display:block;
|
||||
width:auto
|
||||
}
|
||||
#footerbar .footer-main .theqtcompany {
|
||||
clear:both;
|
||||
float:left;
|
||||
margin:30px 0 28px 3%
|
||||
}
|
||||
#footerbar .footer-main .footer-social {
|
||||
float:left;
|
||||
padding:30px 0px 0px 3%
|
||||
}
|
||||
#footerbar #menu-footer-submenu {
|
||||
clear:both;
|
||||
float:none;
|
||||
display:block;
|
||||
padding:0px 0px 3.9% 3%
|
||||
}
|
||||
ul#menu-footer-submenu {
|
||||
margin-left: 0
|
||||
}
|
||||
}
|
||||
.in-page-nav {
|
||||
width:100%;
|
||||
|
|
@ -449,8 +478,9 @@ body.qt-account #navbar .navbar-oneQt h2 {
|
|||
margin-bottom:40px
|
||||
}
|
||||
.cookies_yum {
|
||||
background-color:#006325;
|
||||
background-color:#d6d6d6;
|
||||
display:none;
|
||||
line-height:1.625em;
|
||||
width:100%
|
||||
}
|
||||
.cookies_yum img {
|
||||
|
|
@ -462,18 +492,18 @@ body.qt-account #navbar .navbar-oneQt h2 {
|
|||
}
|
||||
.cookies_yum div {
|
||||
margin:0 auto;
|
||||
max-width:1180px;
|
||||
max-width:1280px;
|
||||
min-height:30px;
|
||||
padding:6px 0px 6px 0px;
|
||||
position:relative
|
||||
}
|
||||
.cookies_yum p {
|
||||
color:white;
|
||||
color:#585a5c;
|
||||
margin:0px;
|
||||
font-size:0.79em;
|
||||
display:inline-block;
|
||||
line-height:1.2;
|
||||
padding:0 30px 0 40px
|
||||
padding:0 30px 0 50px
|
||||
}
|
||||
.cookies_yum p a {
|
||||
white-space:nowrap
|
||||
|
|
@ -484,13 +514,14 @@ body.qt-account #navbar .navbar-oneQt h2 {
|
|||
.cookies_yum .close {
|
||||
width:15px;
|
||||
height:15px;
|
||||
background-image:url("../images/cookiebar-x.png");
|
||||
background-image:url("cookiebar-x.png");
|
||||
background-size:15px 30px;
|
||||
background-position:top left;
|
||||
cursor:pointer;
|
||||
top:6px;
|
||||
right:6px;
|
||||
position:absolute
|
||||
top:13px;
|
||||
right:13px;
|
||||
position:absolute;
|
||||
transition:none;
|
||||
}
|
||||
.cookies_yum .close:hover {
|
||||
background-position:bottom left
|
||||
|
|
@ -691,7 +722,7 @@ body.qt-account #navbar .navbar-oneQt h2 {
|
|||
left:0;
|
||||
width:100%
|
||||
}
|
||||
#footerbar .footer-main .footer-nav {
|
||||
#footerbar .footer-nav {
|
||||
display:inline;
|
||||
float:left
|
||||
}
|
||||
|
|
@ -734,29 +765,20 @@ body.qt-account #navbar .navbar-oneQt h2 {
|
|||
#footerbar .footer-main .footer-nav .sub-menu li a:hover,#footerbar .footer-main .footer-nav .sub-menu li.current-menu-item a {
|
||||
color:#eee
|
||||
}
|
||||
#footerbar .footer-main .footer-logo {
|
||||
#footerbar .theqtcompany {
|
||||
background:url("theqtcompany.png") no-repeat;
|
||||
background-size:100%;
|
||||
width:150px;
|
||||
height:68px;
|
||||
display:inline;
|
||||
float:right;
|
||||
padding:29px 0 28px 10px;
|
||||
margin-left:30px;
|
||||
width:56px
|
||||
margin:29px 0 28px 30px
|
||||
}
|
||||
#footerbar .footer-main .footer-logo:before {
|
||||
content:attr(data-icon);
|
||||
font-family:'Qt Icons';
|
||||
width:100%;
|
||||
line-height:1.2;
|
||||
display:inline-block;
|
||||
font-size:1.875em;
|
||||
color:#706e6d
|
||||
}
|
||||
#footerbar .footer-main .footer-logo:hover {
|
||||
padding:31px 0 26px 10px
|
||||
}
|
||||
#footerbar .footer-main .footer-social {
|
||||
#footerbar .footer-social {
|
||||
display:inline;
|
||||
float:right;
|
||||
padding-top:31px
|
||||
padding-top:31px;
|
||||
width:164px
|
||||
}
|
||||
#footerbar .footer-main .footer-social>div {
|
||||
margin-left:0.1em;
|
||||
|
|
@ -848,6 +870,9 @@ body.qt-account #navbar .navbar-oneQt h2 {
|
|||
.clearfix {
|
||||
*zoom:1
|
||||
}
|
||||
.clearfix .right {
|
||||
float:right
|
||||
}
|
||||
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
|
||||
margin:0;
|
||||
padding:0;
|
||||
|
|
@ -1169,7 +1194,7 @@ li a.active {
|
|||
position:absolute
|
||||
}
|
||||
.flowList.odd {
|
||||
background-color:#eee
|
||||
background-color:#f9f9f9
|
||||
}
|
||||
.context ul>li,.doc-column ul>li {
|
||||
list-style-image:url("list_arrow.png");
|
||||
|
|
@ -1203,7 +1228,7 @@ li a.active {
|
|||
vertical-align:initial
|
||||
}
|
||||
table .odd {
|
||||
background-color:#eee
|
||||
background-color:#f9f9f9
|
||||
}
|
||||
table thead {
|
||||
text-align:left;
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -130,7 +130,7 @@ equals(ANDROID_TARGET_ARCH, x86) {
|
|||
QMAKE_CFLAGS_RELEASE = -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64
|
||||
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64
|
||||
QMAKE_CFLAGS_DEBUG = -g -marm -O0 -fno-omit-frame-pointer
|
||||
equals(ANDROID_TARGET_ARCH, armeabi): equals(NDK_TOOLCHAIN_VERSION, 4.8) {
|
||||
equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) {
|
||||
DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND
|
||||
} else {
|
||||
QMAKE_CFLAGS_RELEASE += -mthumb
|
||||
|
|
|
|||
|
|
@ -16,12 +16,14 @@ QMAKE_LINK_SHLIB = $$QMAKE_CXX
|
|||
CONFIG += clang_pch_style
|
||||
QMAKE_PCH_OUTPUT_EXT = .pch
|
||||
|
||||
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -g
|
||||
QMAKE_CFLAGS_ISYSTEM = -isystem
|
||||
QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
|
||||
QMAKE_CFLAGS_USE_PRECOMPILE = -Xclang -include-pch -Xclang ${QMAKE_PCH_OUTPUT}
|
||||
QMAKE_CFLAGS_LTCG = -flto
|
||||
QMAKE_CFLAGS_DISABLE_LTCG = -fno-lto
|
||||
|
||||
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
|
||||
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
|
||||
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
|
||||
QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# qmake configuration for building with arm-linux-uclibcgnueabi-g++
|
||||
#
|
||||
# http://wiki.qt.io/?title=Shiner
|
||||
# http://wiki.qt.io/Shiner
|
||||
#
|
||||
|
||||
MAKEFILE_GENERATOR = UNIX
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
# qmake configuration for Broadcom's Raspberry PI
|
||||
# http://wiki.qt.io/?title=RaspberryPi
|
||||
# http://wiki.qt.io/RaspberryPi
|
||||
|
||||
include(../common/linux_device_pre.conf)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# qmake configuration for linux-g++ using the sh4-linux-g++ crosscompiler
|
||||
#
|
||||
# http://wiki.qt.io/?title=ST7108
|
||||
# http://wiki.qt.io/ST7108
|
||||
#
|
||||
|
||||
MAKEFILE_GENERATOR = UNIX
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# qmake configuration for linux-g++ using the sh4-linux-g++ crosscompiler
|
||||
#
|
||||
# http://wiki.qt.io/?title=ST7540
|
||||
# http://wiki.qt.io/ST7540
|
||||
#
|
||||
|
||||
MAKEFILE_GENERATOR = UNIX
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
# qmake configuration for ST Ericsson's Snowball
|
||||
# http://wiki.qt.io/?title=Snowball
|
||||
# http://wiki.qt.io/Snowball
|
||||
|
||||
MAKEFILE_GENERATOR = UNIX
|
||||
CONFIG += incremental
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ INSTALLS += target
|
|||
|
||||
# Some final setup
|
||||
|
||||
TARGET = $$qtLibraryTarget($$TARGET)
|
||||
TARGET = $$qt5LibraryTarget($$TARGET)
|
||||
|
||||
load(qt_targets)
|
||||
load(qt_common)
|
||||
|
|
|
|||
|
|
@ -18,14 +18,20 @@ defineReplace(qtLibraryTarget) {
|
|||
mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) {
|
||||
QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME
|
||||
export(QMAKE_FRAMEWORK_BUNDLE_NAME)
|
||||
} else {
|
||||
# insert the major version of Qt in the library name
|
||||
# unless it's a framework build
|
||||
LIBRARY_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION,
|
||||
}
|
||||
return($$LIBRARY_NAME$$qtPlatformTargetSuffix())
|
||||
}
|
||||
|
||||
defineReplace(qt5LibraryTarget) {
|
||||
LIBRARY_NAME = $$qtLibraryTarget($$1)
|
||||
isEmpty(QMAKE_FRAMEWORK_BUNDLE_NAME) {
|
||||
# Insert the major version of Qt in the library name
|
||||
# unless it's a framework build.
|
||||
LIBRARY_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION,
|
||||
}
|
||||
return($$LIBRARY_NAME)
|
||||
}
|
||||
|
||||
defineTest(qtAddLibrary) {
|
||||
warning("qtAddLibrary() is deprecated. Use QT+= instead.")
|
||||
|
||||
|
|
@ -100,7 +106,7 @@ defineTest(qtAddModule) {
|
|||
# to give access to sources or include files, and not for linking.
|
||||
!isEmpty(MODULE_LIBS):!contains(MODULE_CONFIG, no_link) {
|
||||
|
||||
# Re-insert the major version in the library name (cf qtLibraryTarget above)
|
||||
# Re-insert the major version in the library name (cf qt5LibraryTarget above)
|
||||
# unless it's a framework build
|
||||
!mac|!contains(MODULE_CONFIG, lib_bundle): \
|
||||
MODULE_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
*-g++*: QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror
|
||||
|
||||
# The flags here come from http://wiki.qt.io/?title=Coding_Conventions#Conventions_for_public_header_files
|
||||
# The flags here come from http://wiki.qt.io/Coding_Conventions#Conventions_for_public_header_files
|
||||
# -Wold-style-cast cannot be used, /usr/include/bits/byteswap.h defines the macro bswap_16 using C style casts :(
|
||||
# -Wfloat-equal cannot be used, qrect.h and qvector2d.h do exact comparisons in isNull and operator==. Would need #pragmas.
|
||||
*-g++*: QMAKE_CXXFLAGS += -Woverloaded-virtual -Wshadow -Wundef
|
||||
|
|
|
|||
|
|
@ -24,4 +24,4 @@ DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin
|
|||
# as in this case they are not linked to the final library/plugin.
|
||||
installed|contains(QT_CONFIG, static): load(qt_installs)
|
||||
|
||||
TARGET = $$qtLibraryTarget($$TARGET)
|
||||
TARGET = $$qt5LibraryTarget($$TARGET)
|
||||
|
|
|
|||
|
|
@ -228,4 +228,4 @@ win32 {
|
|||
DEFINES *= QT_DISABLE_DEPRECATED_BEFORE=0x050000
|
||||
}
|
||||
|
||||
TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end
|
||||
TARGET = $$qt5LibraryTarget($$TARGET$$QT_LIBINFIX) # Do this towards the end
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ CONFIG(static, static|shared)|prefix_build {
|
|||
target.path = $$[QT_INSTALL_PLUGINS]/$$PLUGIN_TYPE
|
||||
INSTALLS += target
|
||||
|
||||
TARGET = $$qtLibraryTarget($$TARGET)
|
||||
TARGET = $$qt5LibraryTarget($$TARGET)
|
||||
|
||||
CONFIG += create_cmake
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
Qt modules need to drop a qmake file here to become part of the current
|
||||
Qt configuration. The file format is documented in
|
||||
http://wiki.qt.io/?title=Creating_a_new_module_or_tool_for_Qt#The_qt_.3Cmodule.3E.pri_files
|
||||
http://wiki.qt.io/Creating_a_new_module_or_tool_for_Qt#The_qt_.3Cmodule.3E.pri_files
|
||||
|
|
|
|||
|
|
@ -2644,7 +2644,7 @@
|
|||
WINRT_MANIFEST.publisher = MyCompany
|
||||
WINRT_MANIFEST.logo_store = someImage.png
|
||||
WINRT_MANIFEST.capabilities += internetClient
|
||||
WINRT_MANIFEST.device_capabilities += location
|
||||
WINRT_MANIFEST.capabilities_device += location
|
||||
\endcode
|
||||
|
||||
Additionally, an input manifest file can be specified by using WINRT_MANIFEST.
|
||||
|
|
|
|||
|
|
@ -802,15 +802,16 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
}
|
||||
//copy the plist
|
||||
while (!project->isActiveConfig("no_plist")) { // 'while' just to be able to 'break'
|
||||
QString info_plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString());
|
||||
if (info_plist.isEmpty())
|
||||
info_plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE");
|
||||
if (!exists(Option::normalizePath(info_plist))) {
|
||||
QString info_plist = project->first("QMAKE_INFO_PLIST").toQString();
|
||||
if (info_plist.isEmpty()) {
|
||||
info_plist = escapeFilePath(specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"));
|
||||
} else if (!exists(Option::normalizePath(info_plist))) {
|
||||
warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.",
|
||||
info_plist.toLatin1().constData());
|
||||
break;
|
||||
} else {
|
||||
info_plist = escapeFilePath(fileFixify(info_plist));
|
||||
}
|
||||
info_plist = escapeFilePath(info_plist);
|
||||
bool isApp = (project->first("TEMPLATE") == "app");
|
||||
QString info_plist_out =
|
||||
bundle_dir + (isApp ? "Contents/Info.plist"
|
||||
|
|
|
|||
|
|
@ -41,9 +41,13 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#ifdef __linux__
|
||||
# define HAVE_PIPE2 1
|
||||
# define HAVE_EVENTFD 1
|
||||
# include <sys/eventfd.h>
|
||||
# if (defined(__GLIBC__) && (__GLIBC__ << 16) + __GLIBC_MINOR__ >= 0x207) || defined(__BIONIC__)
|
||||
# include <sys/eventfd.h>
|
||||
# define HAVE_EVENTFD 1
|
||||
# endif
|
||||
# if (defined(__GLIBC__) && (__GLIBC__ << 16) + __GLIBC_MINOR__ >= 0x209) || defined(__BIONIC__)
|
||||
# define HAVE_PIPE2 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
Index: pcre_compile.c
|
||||
===================================================================
|
||||
--- pcre_compile.c (revision 1494)
|
||||
+++ pcre_compile.c (revision 1495)
|
||||
@@ -8267,12 +8267,16 @@
|
||||
|
||||
/* If it was a capturing subpattern, check to see if it contained any
|
||||
recursive back references. If so, we must wrap it in atomic brackets.
|
||||
- In any event, remove the block from the chain. */
|
||||
+ Because we are moving code along, we must ensure that any pending recursive
|
||||
+ references are updated. In any event, remove the block from the chain. */
|
||||
|
||||
if (capnumber > 0)
|
||||
{
|
||||
if (cd->open_caps->flag)
|
||||
{
|
||||
+ *code = OP_END;
|
||||
+ adjust_recurse(start_bracket, 1 + LINK_SIZE,
|
||||
+ (options & PCRE_UTF8) != 0, cd, cd->hwm);
|
||||
memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
|
||||
IN_UCHARS(code - start_bracket));
|
||||
*start_bracket = OP_ONCE;
|
||||
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
Index: pcre_compile.c
|
||||
===================================================================
|
||||
--- pcre_compile.c (revision 1497)
|
||||
+++ pcre_compile.c (revision 1498)
|
||||
@@ -2374,6 +2374,7 @@
|
||||
if (c == OP_RECURSE)
|
||||
{
|
||||
const pcre_uchar *scode = cd->start_code + GET(code, 1);
|
||||
+ const pcre_uchar *endgroup = scode;
|
||||
BOOL empty_branch;
|
||||
|
||||
/* Test for forward reference or uncompleted reference. This is disabled
|
||||
@@ -2388,24 +2389,20 @@
|
||||
if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
|
||||
}
|
||||
|
||||
- /* If we are scanning a completed pattern, there are no forward references
|
||||
- and all groups are complete. We need to detect whether this is a recursive
|
||||
- call, as otherwise there will be an infinite loop. If it is a recursion,
|
||||
- just skip over it. Simple recursions are easily detected. For mutual
|
||||
- recursions we keep a chain on the stack. */
|
||||
+ /* If the reference is to a completed group, we need to detect whether this
|
||||
+ is a recursive call, as otherwise there will be an infinite loop. If it is
|
||||
+ a recursion, just skip over it. Simple recursions are easily detected. For
|
||||
+ mutual recursions we keep a chain on the stack. */
|
||||
|
||||
+ do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
|
||||
+ if (code >= scode && code <= endgroup) continue; /* Simple recursion */
|
||||
else
|
||||
- {
|
||||
+ {
|
||||
recurse_check *r = recurses;
|
||||
- const pcre_uchar *endgroup = scode;
|
||||
-
|
||||
- do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
|
||||
- if (code >= scode && code <= endgroup) continue; /* Simple recursion */
|
||||
-
|
||||
for (r = recurses; r != NULL; r = r->prev)
|
||||
if (r->group == scode) break;
|
||||
if (r != NULL) continue; /* Mutual recursion */
|
||||
- }
|
||||
+ }
|
||||
|
||||
/* Completed reference; scan the referenced group, remembering it on the
|
||||
stack chain to detect mutual recursions. */
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
Index: pcre_exec.c
|
||||
===================================================================
|
||||
--- pcre_exec.c (revisione 1512)
|
||||
+++ pcre_exec.c (revisione 1513)
|
||||
@@ -1404,8 +1404,11 @@
|
||||
condition = TRUE;
|
||||
|
||||
/* Advance ecode past the assertion to the start of the first branch,
|
||||
- but adjust it so that the general choosing code below works. */
|
||||
-
|
||||
+ but adjust it so that the general choosing code below works. If the
|
||||
+ assertion has a quantifier that allows zero repeats we must skip over
|
||||
+ the BRAZERO. This is a lunatic thing to do, but somebody did! */
|
||||
+
|
||||
+ if (*ecode == OP_BRAZERO) ecode++;
|
||||
ecode += GET(ecode, 1);
|
||||
while (*ecode == OP_ALT) ecode += GET(ecode, 1);
|
||||
ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];
|
||||
|
|
@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
/* The current PCRE version information. */
|
||||
|
||||
#define PCRE_MAJOR 8
|
||||
#define PCRE_MINOR 35
|
||||
#define PCRE_PRERELEASE
|
||||
#define PCRE_DATE 2014-04-04
|
||||
#define PCRE_MINOR 37
|
||||
#define PCRE_PRERELEASE -RC1
|
||||
#define PCRE_DATE 2015-02-03
|
||||
|
||||
/* When an application links to a PCRE DLL in Windows, the symbols that are
|
||||
imported have to be identified as such. When building PCRE, the appropriate
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ supporting internal functions that are not used by other modules. */
|
|||
#endif
|
||||
|
||||
#define NLBLOCK cd /* Block containing newline information */
|
||||
#define PSSTART start_pattern /* Field containing processed string start */
|
||||
#define PSEND end_pattern /* Field containing processed string end */
|
||||
#define PSSTART start_pattern /* Field containing pattern start */
|
||||
#define PSEND end_pattern /* Field containing pattern end */
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
|
@ -549,6 +549,7 @@ static const char error_texts[] =
|
|||
"group name must start with a non-digit\0"
|
||||
/* 85 */
|
||||
"parentheses are too deeply nested (stack check)\0"
|
||||
"digits missing in \\x{} or \\o{}\0"
|
||||
;
|
||||
|
||||
/* Table to identify digits and hex digits. This is used when compiling
|
||||
|
|
@ -1259,6 +1260,7 @@ else
|
|||
|
||||
case CHAR_o:
|
||||
if (ptr[1] != CHAR_LEFT_CURLY_BRACKET) *errorcodeptr = ERR81; else
|
||||
if (ptr[2] == CHAR_RIGHT_CURLY_BRACKET) *errorcodeptr = ERR86; else
|
||||
{
|
||||
ptr += 2;
|
||||
c = 0;
|
||||
|
|
@ -1328,6 +1330,11 @@ else
|
|||
if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
|
||||
{
|
||||
ptr += 2;
|
||||
if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
|
||||
{
|
||||
*errorcodeptr = ERR86;
|
||||
break;
|
||||
}
|
||||
c = 0;
|
||||
overflow = FALSE;
|
||||
while (MAX_255(*ptr) && (digitab[*ptr] & ctype_xdigit) != 0)
|
||||
|
|
@ -1583,29 +1590,29 @@ read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr)
|
|||
int min = 0;
|
||||
int max = -1;
|
||||
|
||||
/* Read the minimum value and do a paranoid check: a negative value indicates
|
||||
an integer overflow. */
|
||||
|
||||
while (IS_DIGIT(*p)) min = min * 10 + (int)(*p++ - CHAR_0);
|
||||
if (min < 0 || min > 65535)
|
||||
while (IS_DIGIT(*p))
|
||||
{
|
||||
*errorcodeptr = ERR5;
|
||||
return p;
|
||||
min = min * 10 + (int)(*p++ - CHAR_0);
|
||||
if (min > 65535)
|
||||
{
|
||||
*errorcodeptr = ERR5;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the maximum value if there is one, and again do a paranoid on its size.
|
||||
Also, max must not be less than min. */
|
||||
|
||||
if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else
|
||||
{
|
||||
if (*(++p) != CHAR_RIGHT_CURLY_BRACKET)
|
||||
{
|
||||
max = 0;
|
||||
while(IS_DIGIT(*p)) max = max * 10 + (int)(*p++ - CHAR_0);
|
||||
if (max < 0 || max > 65535)
|
||||
while(IS_DIGIT(*p))
|
||||
{
|
||||
*errorcodeptr = ERR5;
|
||||
return p;
|
||||
max = max * 10 + (int)(*p++ - CHAR_0);
|
||||
if (max > 65535)
|
||||
{
|
||||
*errorcodeptr = ERR5;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
if (max < min)
|
||||
{
|
||||
|
|
@ -1615,9 +1622,6 @@ if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else
|
|||
}
|
||||
}
|
||||
|
||||
/* Fill in the required variables, and pass back the pointer to the terminating
|
||||
'}'. */
|
||||
|
||||
*minp = min;
|
||||
*maxp = max;
|
||||
return p;
|
||||
|
|
@ -2125,32 +2129,60 @@ for (;;)
|
|||
{
|
||||
case OP_CHAR:
|
||||
case OP_CHARI:
|
||||
case OP_NOT:
|
||||
case OP_NOTI:
|
||||
case OP_EXACT:
|
||||
case OP_EXACTI:
|
||||
case OP_NOTEXACT:
|
||||
case OP_NOTEXACTI:
|
||||
case OP_UPTO:
|
||||
case OP_UPTOI:
|
||||
case OP_NOTUPTO:
|
||||
case OP_NOTUPTOI:
|
||||
case OP_MINUPTO:
|
||||
case OP_MINUPTOI:
|
||||
case OP_NOTMINUPTO:
|
||||
case OP_NOTMINUPTOI:
|
||||
case OP_POSUPTO:
|
||||
case OP_POSUPTOI:
|
||||
case OP_NOTPOSUPTO:
|
||||
case OP_NOTPOSUPTOI:
|
||||
case OP_STAR:
|
||||
case OP_STARI:
|
||||
case OP_NOTSTAR:
|
||||
case OP_NOTSTARI:
|
||||
case OP_MINSTAR:
|
||||
case OP_MINSTARI:
|
||||
case OP_NOTMINSTAR:
|
||||
case OP_NOTMINSTARI:
|
||||
case OP_POSSTAR:
|
||||
case OP_POSSTARI:
|
||||
case OP_NOTPOSSTAR:
|
||||
case OP_NOTPOSSTARI:
|
||||
case OP_PLUS:
|
||||
case OP_PLUSI:
|
||||
case OP_NOTPLUS:
|
||||
case OP_NOTPLUSI:
|
||||
case OP_MINPLUS:
|
||||
case OP_MINPLUSI:
|
||||
case OP_NOTMINPLUS:
|
||||
case OP_NOTMINPLUSI:
|
||||
case OP_POSPLUS:
|
||||
case OP_POSPLUSI:
|
||||
case OP_NOTPOSPLUS:
|
||||
case OP_NOTPOSPLUSI:
|
||||
case OP_QUERY:
|
||||
case OP_QUERYI:
|
||||
case OP_NOTQUERY:
|
||||
case OP_NOTQUERYI:
|
||||
case OP_MINQUERY:
|
||||
case OP_MINQUERYI:
|
||||
case OP_NOTMINQUERY:
|
||||
case OP_NOTMINQUERYI:
|
||||
case OP_POSQUERY:
|
||||
case OP_POSQUERYI:
|
||||
case OP_NOTPOSQUERY:
|
||||
case OP_NOTPOSQUERYI:
|
||||
if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
|
||||
break;
|
||||
}
|
||||
|
|
@ -2393,12 +2425,12 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
|
|||
do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
|
||||
if (code >= scode && code <= endgroup) continue; /* Simple recursion */
|
||||
else
|
||||
{
|
||||
{
|
||||
recurse_check *r = recurses;
|
||||
for (r = recurses; r != NULL; r = r->prev)
|
||||
if (r->group == scode) break;
|
||||
if (r != NULL) continue; /* Mutual recursion */
|
||||
}
|
||||
}
|
||||
|
||||
/* Completed reference; scan the referenced group, remembering it on the
|
||||
stack chain to detect mutual recursions. */
|
||||
|
|
@ -3035,7 +3067,7 @@ switch(c)
|
|||
end += 1 + 2 * IMM2_SIZE;
|
||||
break;
|
||||
}
|
||||
list[2] = end - code;
|
||||
list[2] = (pcre_uint32)(end - code);
|
||||
return end;
|
||||
}
|
||||
return NULL; /* Opcode not accepted */
|
||||
|
|
@ -3076,6 +3108,7 @@ const pcre_uint8 *class_bitset;
|
|||
const pcre_uint8 *set1, *set2, *set_end;
|
||||
pcre_uint32 chr;
|
||||
BOOL accepted, invert_bits;
|
||||
BOOL entered_a_group = FALSE;
|
||||
|
||||
/* Note: the base_list[1] contains whether the current opcode has greedy
|
||||
(represented by a non-zero value) quantifier. This is a different from
|
||||
|
|
@ -3129,8 +3162,10 @@ for(;;)
|
|||
case OP_ONCE:
|
||||
case OP_ONCE_NC:
|
||||
/* Atomic sub-patterns and assertions can always auto-possessify their
|
||||
last iterator. */
|
||||
return TRUE;
|
||||
last iterator. However, if the group was entered as a result of checking
|
||||
a previous iterator, this is not possible. */
|
||||
|
||||
return !entered_a_group;
|
||||
}
|
||||
|
||||
code += PRIV(OP_lengths)[c];
|
||||
|
|
@ -3149,6 +3184,8 @@ for(;;)
|
|||
code = next_code + 1 + LINK_SIZE;
|
||||
next_code += GET(next_code, 1);
|
||||
}
|
||||
|
||||
entered_a_group = TRUE;
|
||||
continue;
|
||||
|
||||
case OP_BRAZERO:
|
||||
|
|
@ -3168,6 +3205,9 @@ for(;;)
|
|||
|
||||
code += PRIV(OP_lengths)[c];
|
||||
continue;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for a supported opcode, and load its properties. */
|
||||
|
|
@ -3406,8 +3446,7 @@ for(;;)
|
|||
rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP &&
|
||||
autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP];
|
||||
|
||||
if (!accepted)
|
||||
return FALSE;
|
||||
if (!accepted) return FALSE;
|
||||
|
||||
if (list[1] == 0) return TRUE;
|
||||
/* Might be an empty repeat. */
|
||||
|
|
@ -3599,6 +3638,14 @@ for (;;)
|
|||
{
|
||||
c = *code;
|
||||
|
||||
/* When a pattern with bad UTF-8 encoding is compiled with NO_UTF_CHECK,
|
||||
it may compile without complaining, but may get into a loop here if the code
|
||||
pointer points to a bad value. This is, of course a documentated possibility,
|
||||
when NO_UTF_CHECK is set, so it isn't a bug, but we can detect this case and
|
||||
just give up on this optimization. */
|
||||
|
||||
if (c >= OP_TABLE_LENGTH) return;
|
||||
|
||||
if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
|
||||
{
|
||||
c -= get_repeat_base(c) - OP_STAR;
|
||||
|
|
@ -3936,14 +3983,14 @@ Arguments:
|
|||
adjust the amount by which the group is to be moved
|
||||
utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
|
||||
cd contains pointers to tables etc.
|
||||
save_hwm the hwm forward reference pointer at the start of the group
|
||||
save_hwm_offset the hwm forward reference offset at the start of the group
|
||||
|
||||
Returns: nothing
|
||||
*/
|
||||
|
||||
static void
|
||||
adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
|
||||
pcre_uchar *save_hwm)
|
||||
size_t save_hwm_offset)
|
||||
{
|
||||
pcre_uchar *ptr = group;
|
||||
|
||||
|
|
@ -3955,7 +4002,8 @@ while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
|
|||
/* See if this recursion is on the forward reference list. If so, adjust the
|
||||
reference. */
|
||||
|
||||
for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
|
||||
for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
|
||||
hc += LINK_SIZE)
|
||||
{
|
||||
offset = (int)GET(hc, 0);
|
||||
if (cd->start_code + offset == ptr + 1)
|
||||
|
|
@ -4400,7 +4448,7 @@ const pcre_uchar *tempptr;
|
|||
const pcre_uchar *nestptr = NULL;
|
||||
pcre_uchar *previous = NULL;
|
||||
pcre_uchar *previous_callout = NULL;
|
||||
pcre_uchar *save_hwm = NULL;
|
||||
size_t save_hwm_offset = 0;
|
||||
pcre_uint8 classbits[32];
|
||||
|
||||
/* We can fish out the UTF-8 setting once and for all into a BOOL, but we
|
||||
|
|
@ -4680,7 +4728,8 @@ for (;; ptr++)
|
|||
previous = NULL;
|
||||
if ((options & PCRE_MULTILINE) != 0)
|
||||
{
|
||||
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
|
||||
if (firstcharflags == REQ_UNSET)
|
||||
zerofirstcharflags = firstcharflags = REQ_NONE;
|
||||
*code++ = OP_CIRCM;
|
||||
}
|
||||
else *code++ = OP_CIRC;
|
||||
|
|
@ -4860,7 +4909,7 @@ for (;; ptr++)
|
|||
if (lengthptr != NULL && class_uchardata > class_uchardata_base)
|
||||
{
|
||||
xclass = TRUE;
|
||||
*lengthptr += class_uchardata - class_uchardata_base;
|
||||
*lengthptr += (int)(class_uchardata - class_uchardata_base);
|
||||
class_uchardata = class_uchardata_base;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -5310,7 +5359,7 @@ for (;; ptr++)
|
|||
whatever repeat count may follow. In the case of reqchar, save the
|
||||
previous value for reinstating. */
|
||||
|
||||
if (class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
||||
if (!inescq && class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
||||
{
|
||||
ptr++;
|
||||
zeroreqchar = reqchar;
|
||||
|
|
@ -5912,7 +5961,7 @@ for (;; ptr++)
|
|||
if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
|
||||
{
|
||||
*code = OP_END;
|
||||
adjust_recurse(previous, 1, utf, cd, save_hwm);
|
||||
adjust_recurse(previous, 1, utf, cd, save_hwm_offset);
|
||||
memmove(previous + 1, previous, IN_UCHARS(len));
|
||||
code++;
|
||||
if (repeat_max == 0)
|
||||
|
|
@ -5936,7 +5985,7 @@ for (;; ptr++)
|
|||
{
|
||||
int offset;
|
||||
*code = OP_END;
|
||||
adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
|
||||
adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
|
||||
code += 2 + LINK_SIZE;
|
||||
*previous++ = OP_BRAZERO + repeat_type;
|
||||
|
|
@ -5999,26 +6048,25 @@ for (;; ptr++)
|
|||
for (i = 1; i < repeat_min; i++)
|
||||
{
|
||||
pcre_uchar *hc;
|
||||
pcre_uchar *this_hwm = cd->hwm;
|
||||
size_t this_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
memcpy(code, previous, IN_UCHARS(len));
|
||||
|
||||
while (cd->hwm > cd->start_workspace + cd->workspace_size -
|
||||
WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
|
||||
WORK_SIZE_SAFETY_MARGIN -
|
||||
(this_hwm_offset - save_hwm_offset))
|
||||
{
|
||||
int save_offset = save_hwm - cd->start_workspace;
|
||||
int this_offset = this_hwm - cd->start_workspace;
|
||||
*errorcodeptr = expand_workspace(cd);
|
||||
if (*errorcodeptr != 0) goto FAILED;
|
||||
save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
|
||||
this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
|
||||
}
|
||||
|
||||
for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
|
||||
for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
|
||||
hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
|
||||
hc += LINK_SIZE)
|
||||
{
|
||||
PUT(cd->hwm, 0, GET(hc, 0) + len);
|
||||
cd->hwm += LINK_SIZE;
|
||||
}
|
||||
save_hwm = this_hwm;
|
||||
save_hwm_offset = this_hwm_offset;
|
||||
code += len;
|
||||
}
|
||||
}
|
||||
|
|
@ -6063,7 +6111,7 @@ for (;; ptr++)
|
|||
else for (i = repeat_max - 1; i >= 0; i--)
|
||||
{
|
||||
pcre_uchar *hc;
|
||||
pcre_uchar *this_hwm = cd->hwm;
|
||||
size_t this_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
|
||||
*code++ = OP_BRAZERO + repeat_type;
|
||||
|
||||
|
|
@ -6085,22 +6133,21 @@ for (;; ptr++)
|
|||
copying them. */
|
||||
|
||||
while (cd->hwm > cd->start_workspace + cd->workspace_size -
|
||||
WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
|
||||
WORK_SIZE_SAFETY_MARGIN -
|
||||
(this_hwm_offset - save_hwm_offset))
|
||||
{
|
||||
int save_offset = save_hwm - cd->start_workspace;
|
||||
int this_offset = this_hwm - cd->start_workspace;
|
||||
*errorcodeptr = expand_workspace(cd);
|
||||
if (*errorcodeptr != 0) goto FAILED;
|
||||
save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
|
||||
this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
|
||||
}
|
||||
|
||||
for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
|
||||
for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
|
||||
hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
|
||||
hc += LINK_SIZE)
|
||||
{
|
||||
PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
|
||||
cd->hwm += LINK_SIZE;
|
||||
}
|
||||
save_hwm = this_hwm;
|
||||
save_hwm_offset = this_hwm_offset;
|
||||
code += len;
|
||||
}
|
||||
|
||||
|
|
@ -6196,7 +6243,7 @@ for (;; ptr++)
|
|||
{
|
||||
int nlen = (int)(code - bracode);
|
||||
*code = OP_END;
|
||||
adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);
|
||||
adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
|
||||
code += 1 + LINK_SIZE;
|
||||
nlen += 1 + LINK_SIZE;
|
||||
|
|
@ -6330,7 +6377,7 @@ for (;; ptr++)
|
|||
else
|
||||
{
|
||||
*code = OP_END;
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
|
||||
code += 1 + LINK_SIZE;
|
||||
len += 1 + LINK_SIZE;
|
||||
|
|
@ -6379,7 +6426,7 @@ for (;; ptr++)
|
|||
|
||||
default:
|
||||
*code = OP_END;
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
|
||||
code += 1 + LINK_SIZE;
|
||||
len += 1 + LINK_SIZE;
|
||||
|
|
@ -6411,7 +6458,7 @@ for (;; ptr++)
|
|||
newoptions = options;
|
||||
skipbytes = 0;
|
||||
bravalue = OP_CBRA;
|
||||
save_hwm = cd->hwm;
|
||||
save_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
reset_bracount = FALSE;
|
||||
|
||||
/* First deal with various "verbs" that can be introduced by '*'. */
|
||||
|
|
@ -6609,7 +6656,10 @@ for (;; ptr++)
|
|||
(tempptr[2] == CHAR_EQUALS_SIGN ||
|
||||
tempptr[2] == CHAR_EXCLAMATION_MARK ||
|
||||
tempptr[2] == CHAR_LESS_THAN_SIGN))
|
||||
{
|
||||
cd->iscondassert = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Other conditions use OP_CREF/OP_DNCREF/OP_RREF/OP_DNRREF, and all
|
||||
need to skip at least 1+IMM2_SIZE bytes at the start of the group. */
|
||||
|
|
@ -6722,6 +6772,7 @@ for (;; ptr++)
|
|||
goto FAILED;
|
||||
}
|
||||
PUT2(code, 2+LINK_SIZE, recno);
|
||||
if (recno > cd->top_backref) cd->top_backref = recno;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -6744,12 +6795,15 @@ for (;; ptr++)
|
|||
int offset = i++;
|
||||
int count = 1;
|
||||
recno = GET2(slot, 0); /* Number from first found */
|
||||
if (recno > cd->top_backref) cd->top_backref = recno;
|
||||
for (; i < cd->names_found; i++)
|
||||
{
|
||||
slot += cd->name_entry_size;
|
||||
if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) != 0) break;
|
||||
if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) != 0 ||
|
||||
(slot+IMM2_SIZE)[namelen] != 0) break;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
PUT2(code, 2+LINK_SIZE, offset);
|
||||
|
|
@ -7098,6 +7152,12 @@ for (;; ptr++)
|
|||
/* Count named back references. */
|
||||
|
||||
if (!is_recurse) cd->namedrefcount++;
|
||||
|
||||
/* We have to allow for a named reference to a duplicated name (this
|
||||
cannot be determined until the second pass). This needs an extra
|
||||
16-bit data item. */
|
||||
|
||||
*lengthptr += IMM2_SIZE;
|
||||
}
|
||||
|
||||
/* In the real compile, search the name table. We check the name
|
||||
|
|
@ -7144,6 +7204,8 @@ for (;; ptr++)
|
|||
for (i++; i < cd->names_found; i++)
|
||||
{
|
||||
if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break;
|
||||
|
||||
|
||||
count++;
|
||||
cslot += cd->name_entry_size;
|
||||
}
|
||||
|
|
@ -7452,12 +7514,22 @@ for (;; ptr++)
|
|||
goto FAILED;
|
||||
}
|
||||
|
||||
/* Assertions used not to be repeatable, but this was changed for Perl
|
||||
compatibility, so all kinds can now be repeated. We copy code into a
|
||||
/* All assertions used not to be repeatable, but this was changed for Perl
|
||||
compatibility. All kinds can now be repeated except for assertions that are
|
||||
conditions (Perl also forbids these to be repeated). We copy code into a
|
||||
non-register variable (tempcode) in order to be able to pass its address
|
||||
because some compilers complain otherwise. */
|
||||
because some compilers complain otherwise. At the start of a conditional
|
||||
group whose condition is an assertion, cd->iscondassert is set. We unset it
|
||||
here so as to allow assertions later in the group to be quantified. */
|
||||
|
||||
if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT &&
|
||||
cd->iscondassert)
|
||||
{
|
||||
previous = NULL;
|
||||
cd->iscondassert = FALSE;
|
||||
}
|
||||
else previous = code;
|
||||
|
||||
previous = code; /* For handling repetition */
|
||||
*code = bravalue;
|
||||
tempcode = code;
|
||||
tempreqvary = cd->req_varyopt; /* Save value before bracket */
|
||||
|
|
@ -7704,7 +7776,7 @@ for (;; ptr++)
|
|||
const pcre_uchar *p;
|
||||
pcre_uint32 cf;
|
||||
|
||||
save_hwm = cd->hwm; /* Normally this is set when '(' is read */
|
||||
save_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */
|
||||
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
|
||||
CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
|
||||
|
||||
|
|
@ -8031,6 +8103,7 @@ int length;
|
|||
unsigned int orig_bracount;
|
||||
unsigned int max_bracount;
|
||||
branch_chain bc;
|
||||
size_t save_hwm_offset;
|
||||
|
||||
/* If set, call the external function that checks for stack availability. */
|
||||
|
||||
|
|
@ -8048,6 +8121,8 @@ bc.current_branch = code;
|
|||
firstchar = reqchar = 0;
|
||||
firstcharflags = reqcharflags = REQ_UNSET;
|
||||
|
||||
save_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
|
||||
/* Accumulate the length for use in the pre-compile phase. Start with the
|
||||
length of the BRA and KET and any extra bytes that are required at the
|
||||
beginning. We accumulate in a local variable to save frequent testing of
|
||||
|
|
@ -8250,7 +8325,7 @@ for (;;)
|
|||
{
|
||||
*code = OP_END;
|
||||
adjust_recurse(start_bracket, 1 + LINK_SIZE,
|
||||
(options & PCRE_UTF8) != 0, cd, cd->hwm);
|
||||
(options & PCRE_UTF8) != 0, cd, save_hwm_offset);
|
||||
memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
|
||||
IN_UCHARS(code - start_bracket));
|
||||
*start_bracket = OP_ONCE;
|
||||
|
|
@ -9058,6 +9133,7 @@ cd->dupnames = FALSE;
|
|||
cd->namedrefcount = 0;
|
||||
cd->start_code = cworkspace;
|
||||
cd->hwm = cworkspace;
|
||||
cd->iscondassert = FALSE;
|
||||
cd->start_workspace = cworkspace;
|
||||
cd->workspace_size = COMPILE_WORK_SIZE;
|
||||
cd->named_groups = named_groups;
|
||||
|
|
@ -9095,13 +9171,6 @@ if (length > MAX_PATTERN_SIZE)
|
|||
goto PCRE_EARLY_ERROR_RETURN;
|
||||
}
|
||||
|
||||
/* If there are groups with duplicate names and there are also references by
|
||||
name, we must allow for the possibility of named references to duplicated
|
||||
groups. These require an extra data item each. */
|
||||
|
||||
if (cd->dupnames && cd->namedrefcount > 0)
|
||||
length += cd->namedrefcount * IMM2_SIZE * sizeof(pcre_uchar);
|
||||
|
||||
/* Compute the size of the data block for storing the compiled pattern. Integer
|
||||
overflow should no longer be possible because nowadays we limit the maximum
|
||||
value of cd->names_found and cd->name_entry_size. */
|
||||
|
|
@ -9160,6 +9229,7 @@ cd->name_table = (pcre_uchar *)re + re->name_table_offset;
|
|||
codestart = cd->name_table + re->name_entry_size * re->name_count;
|
||||
cd->start_code = codestart;
|
||||
cd->hwm = (pcre_uchar *)(cd->start_workspace);
|
||||
cd->iscondassert = FALSE;
|
||||
cd->req_varyopt = 0;
|
||||
cd->had_accept = FALSE;
|
||||
cd->had_pruneorskip = FALSE;
|
||||
|
|
@ -9255,11 +9325,18 @@ subpattern. */
|
|||
|
||||
if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15;
|
||||
|
||||
/* Unless disabled, check whether single character iterators can be
|
||||
auto-possessified. The function overwrites the appropriate opcode values. */
|
||||
/* Unless disabled, check whether any single character iterators can be
|
||||
auto-possessified. The function overwrites the appropriate opcode values, so
|
||||
the type of the pointer must be cast. NOTE: the intermediate variable "temp" is
|
||||
used in this code because at least one compiler gives a warning about loss of
|
||||
"const" attribute if the cast (pcre_uchar *)codestart is used directly in the
|
||||
function call. */
|
||||
|
||||
if ((options & PCRE_NO_AUTO_POSSESS) == 0)
|
||||
auto_possessify((pcre_uchar *)codestart, utf, cd);
|
||||
{
|
||||
pcre_uchar *temp = (pcre_uchar *)codestart;
|
||||
auto_possessify(temp, utf, cd);
|
||||
}
|
||||
|
||||
/* If there were any lookbehind assertions that contained OP_RECURSE
|
||||
(recursions or subroutine calls), a flag is set for them to be checked here,
|
||||
|
|
|
|||
|
|
@ -3242,7 +3242,7 @@ md->callout_data = NULL;
|
|||
|
||||
if (extra_data != NULL)
|
||||
{
|
||||
unsigned int flags = extra_data->flags;
|
||||
unsigned long int flags = extra_data->flags;
|
||||
if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
|
||||
study = (const pcre_study_data *)extra_data->study_data;
|
||||
if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT;
|
||||
|
|
|
|||
|
|
@ -1136,88 +1136,81 @@ for (;;)
|
|||
printf("\n");
|
||||
#endif
|
||||
|
||||
if (offset < md->offset_max)
|
||||
if (offset >= md->offset_max) goto POSSESSIVE_NON_CAPTURE;
|
||||
|
||||
matched_once = FALSE;
|
||||
code_offset = (int)(ecode - md->start_code);
|
||||
|
||||
save_offset1 = md->offset_vector[offset];
|
||||
save_offset2 = md->offset_vector[offset+1];
|
||||
save_offset3 = md->offset_vector[md->offset_end - number];
|
||||
save_capture_last = md->capture_last;
|
||||
|
||||
DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
|
||||
|
||||
/* Each time round the loop, save the current subject position for use
|
||||
when the group matches. For MATCH_MATCH, the group has matched, so we
|
||||
restart it with a new subject starting position, remembering that we had
|
||||
at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
|
||||
usual. If we haven't matched any alternatives in any iteration, check to
|
||||
see if a previous iteration matched. If so, the group has matched;
|
||||
continue from afterwards. Otherwise it has failed; restore the previous
|
||||
capture values before returning NOMATCH. */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
matched_once = FALSE;
|
||||
code_offset = (int)(ecode - md->start_code);
|
||||
|
||||
save_offset1 = md->offset_vector[offset];
|
||||
save_offset2 = md->offset_vector[offset+1];
|
||||
save_offset3 = md->offset_vector[md->offset_end - number];
|
||||
save_capture_last = md->capture_last;
|
||||
|
||||
DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
|
||||
|
||||
/* Each time round the loop, save the current subject position for use
|
||||
when the group matches. For MATCH_MATCH, the group has matched, so we
|
||||
restart it with a new subject starting position, remembering that we had
|
||||
at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
|
||||
usual. If we haven't matched any alternatives in any iteration, check to
|
||||
see if a previous iteration matched. If so, the group has matched;
|
||||
continue from afterwards. Otherwise it has failed; restore the previous
|
||||
capture values before returning NOMATCH. */
|
||||
|
||||
for (;;)
|
||||
md->offset_vector[md->offset_end - number] =
|
||||
(int)(eptr - md->start_subject);
|
||||
if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
|
||||
RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
|
||||
eptrb, RM63);
|
||||
if (rrc == MATCH_KETRPOS)
|
||||
{
|
||||
md->offset_vector[md->offset_end - number] =
|
||||
(int)(eptr - md->start_subject);
|
||||
if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
|
||||
RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
|
||||
eptrb, RM63);
|
||||
if (rrc == MATCH_KETRPOS)
|
||||
offset_top = md->end_offset_top;
|
||||
ecode = md->start_code + code_offset;
|
||||
save_capture_last = md->capture_last;
|
||||
matched_once = TRUE;
|
||||
mstart = md->start_match_ptr; /* In case \K changed it */
|
||||
if (eptr == md->end_match_ptr) /* Matched an empty string */
|
||||
{
|
||||
offset_top = md->end_offset_top;
|
||||
eptr = md->end_match_ptr;
|
||||
ecode = md->start_code + code_offset;
|
||||
save_capture_last = md->capture_last;
|
||||
matched_once = TRUE;
|
||||
mstart = md->start_match_ptr; /* In case \K changed it */
|
||||
continue;
|
||||
do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* See comment in the code for capturing groups above about handling
|
||||
THEN. */
|
||||
|
||||
if (rrc == MATCH_THEN)
|
||||
{
|
||||
next = ecode + GET(ecode,1);
|
||||
if (md->start_match_ptr < next &&
|
||||
(*ecode == OP_ALT || *next == OP_ALT))
|
||||
rrc = MATCH_NOMATCH;
|
||||
}
|
||||
|
||||
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
|
||||
md->capture_last = save_capture_last;
|
||||
ecode += GET(ecode, 1);
|
||||
if (*ecode != OP_ALT) break;
|
||||
eptr = md->end_match_ptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!matched_once)
|
||||
/* See comment in the code for capturing groups above about handling
|
||||
THEN. */
|
||||
|
||||
if (rrc == MATCH_THEN)
|
||||
{
|
||||
md->offset_vector[offset] = save_offset1;
|
||||
md->offset_vector[offset+1] = save_offset2;
|
||||
md->offset_vector[md->offset_end - number] = save_offset3;
|
||||
next = ecode + GET(ecode,1);
|
||||
if (md->start_match_ptr < next &&
|
||||
(*ecode == OP_ALT || *next == OP_ALT))
|
||||
rrc = MATCH_NOMATCH;
|
||||
}
|
||||
|
||||
if (allow_zero || matched_once)
|
||||
{
|
||||
ecode += 1 + LINK_SIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
RRETURN(MATCH_NOMATCH);
|
||||
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
|
||||
md->capture_last = save_capture_last;
|
||||
ecode += GET(ecode, 1);
|
||||
if (*ecode != OP_ALT) break;
|
||||
}
|
||||
|
||||
/* FALL THROUGH ... Insufficient room for saving captured contents. Treat
|
||||
as a non-capturing bracket. */
|
||||
if (!matched_once)
|
||||
{
|
||||
md->offset_vector[offset] = save_offset1;
|
||||
md->offset_vector[offset+1] = save_offset2;
|
||||
md->offset_vector[md->offset_end - number] = save_offset3;
|
||||
}
|
||||
|
||||
/* VVVVVVVVVVVVVVVVVVVVVVVVV */
|
||||
/* VVVVVVVVVVVVVVVVVVVVVVVVV */
|
||||
if (allow_zero || matched_once)
|
||||
{
|
||||
ecode += 1 + LINK_SIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINTF(("insufficient capture room: treat as non-capturing\n"));
|
||||
|
||||
/* VVVVVVVVVVVVVVVVVVVVVVVVV */
|
||||
/* VVVVVVVVVVVVVVVVVVVVVVVVV */
|
||||
RRETURN(MATCH_NOMATCH);
|
||||
|
||||
/* Non-capturing possessive bracket with unlimited repeat. We come here
|
||||
from BRAZERO with allow_zero = TRUE. The code is similar to the above,
|
||||
|
|
@ -1241,10 +1234,15 @@ for (;;)
|
|||
if (rrc == MATCH_KETRPOS)
|
||||
{
|
||||
offset_top = md->end_offset_top;
|
||||
eptr = md->end_match_ptr;
|
||||
ecode = md->start_code + code_offset;
|
||||
matched_once = TRUE;
|
||||
mstart = md->start_match_ptr; /* In case \K reset it */
|
||||
if (eptr == md->end_match_ptr) /* Matched an empty string */
|
||||
{
|
||||
do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
|
||||
break;
|
||||
}
|
||||
eptr = md->end_match_ptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1394,11 +1392,11 @@ for (;;)
|
|||
condition = TRUE;
|
||||
|
||||
/* Advance ecode past the assertion to the start of the first branch,
|
||||
but adjust it so that the general choosing code below works. If the
|
||||
assertion has a quantifier that allows zero repeats we must skip over
|
||||
but adjust it so that the general choosing code below works. If the
|
||||
assertion has a quantifier that allows zero repeats we must skip over
|
||||
the BRAZERO. This is a lunatic thing to do, but somebody did! */
|
||||
|
||||
if (*ecode == OP_BRAZERO) ecode++;
|
||||
|
||||
if (*ecode == OP_BRAZERO) ecode++;
|
||||
ecode += GET(ecode, 1);
|
||||
while (*ecode == OP_ALT) ecode += GET(ecode, 1);
|
||||
ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];
|
||||
|
|
@ -1467,7 +1465,18 @@ for (;;)
|
|||
md->offset_vector[offset] =
|
||||
md->offset_vector[md->offset_end - number];
|
||||
md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
|
||||
if (offset_top <= offset) offset_top = offset + 2;
|
||||
|
||||
/* If this group is at or above the current highwater mark, ensure that
|
||||
any groups between the current high water mark and this group are marked
|
||||
unset and then update the high water mark. */
|
||||
|
||||
if (offset >= offset_top)
|
||||
{
|
||||
register int *iptr = md->offset_vector + offset_top;
|
||||
register int *iend = md->offset_vector + offset;
|
||||
while (iptr < iend) *iptr++ = -1;
|
||||
offset_top = offset + 2;
|
||||
}
|
||||
}
|
||||
ecode += 1 + IMM2_SIZE;
|
||||
break;
|
||||
|
|
@ -1819,7 +1828,11 @@ for (;;)
|
|||
are defined in a range that can be tested for. */
|
||||
|
||||
if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
|
||||
{
|
||||
if (new_recursive.offset_save != stacksave)
|
||||
(PUBL(free))(new_recursive.offset_save);
|
||||
RRETURN(MATCH_NOMATCH);
|
||||
}
|
||||
|
||||
/* Any return code other than NOMATCH is an error. */
|
||||
|
||||
|
|
@ -1982,6 +1995,19 @@ for (;;)
|
|||
}
|
||||
}
|
||||
|
||||
/* OP_KETRPOS is a possessive repeating ket. Remember the current position,
|
||||
and return the MATCH_KETRPOS. This makes it possible to do the repeats one
|
||||
at a time from the outer level, thus saving stack. This must precede the
|
||||
empty string test - in this case that test is done at the outer level. */
|
||||
|
||||
if (*ecode == OP_KETRPOS)
|
||||
{
|
||||
md->start_match_ptr = mstart; /* In case \K reset it */
|
||||
md->end_match_ptr = eptr;
|
||||
md->end_offset_top = offset_top;
|
||||
RRETURN(MATCH_KETRPOS);
|
||||
}
|
||||
|
||||
/* For an ordinary non-repeating ket, just continue at this level. This
|
||||
also happens for a repeating ket if no characters were matched in the
|
||||
group. This is the forcible breaking of infinite loops as implemented in
|
||||
|
|
@ -2004,18 +2030,6 @@ for (;;)
|
|||
break;
|
||||
}
|
||||
|
||||
/* OP_KETRPOS is a possessive repeating ket. Remember the current position,
|
||||
and return the MATCH_KETRPOS. This makes it possible to do the repeats one
|
||||
at a time from the outer level, thus saving stack. */
|
||||
|
||||
if (*ecode == OP_KETRPOS)
|
||||
{
|
||||
md->start_match_ptr = mstart; /* In case \K reset it */
|
||||
md->end_match_ptr = eptr;
|
||||
md->end_offset_top = offset_top;
|
||||
RRETURN(MATCH_KETRPOS);
|
||||
}
|
||||
|
||||
/* The normal repeating kets try the rest of the pattern or restart from
|
||||
the preceding bracket, in the appropriate order. In the second case, we can
|
||||
use tail recursion to avoid using another stack frame, unless we have an
|
||||
|
|
@ -5684,54 +5698,25 @@ for (;;)
|
|||
switch(ctype)
|
||||
{
|
||||
case OP_ANY:
|
||||
if (max < INT_MAX)
|
||||
for (i = min; i < max; i++)
|
||||
{
|
||||
for (i = min; i < max; i++)
|
||||
if (eptr >= md->end_subject)
|
||||
{
|
||||
if (eptr >= md->end_subject)
|
||||
{
|
||||
SCHECK_PARTIAL();
|
||||
break;
|
||||
}
|
||||
if (IS_NEWLINE(eptr)) break;
|
||||
if (md->partial != 0 && /* Take care with CRLF partial */
|
||||
eptr + 1 >= md->end_subject &&
|
||||
NLBLOCK->nltype == NLTYPE_FIXED &&
|
||||
NLBLOCK->nllen == 2 &&
|
||||
UCHAR21(eptr) == NLBLOCK->nl[0])
|
||||
{
|
||||
md->hitend = TRUE;
|
||||
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
|
||||
}
|
||||
eptr++;
|
||||
ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
|
||||
SCHECK_PARTIAL();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle unlimited UTF-8 repeat */
|
||||
|
||||
else
|
||||
{
|
||||
for (i = min; i < max; i++)
|
||||
if (IS_NEWLINE(eptr)) break;
|
||||
if (md->partial != 0 && /* Take care with CRLF partial */
|
||||
eptr + 1 >= md->end_subject &&
|
||||
NLBLOCK->nltype == NLTYPE_FIXED &&
|
||||
NLBLOCK->nllen == 2 &&
|
||||
UCHAR21(eptr) == NLBLOCK->nl[0])
|
||||
{
|
||||
if (eptr >= md->end_subject)
|
||||
{
|
||||
SCHECK_PARTIAL();
|
||||
break;
|
||||
}
|
||||
if (IS_NEWLINE(eptr)) break;
|
||||
if (md->partial != 0 && /* Take care with CRLF partial */
|
||||
eptr + 1 >= md->end_subject &&
|
||||
NLBLOCK->nltype == NLTYPE_FIXED &&
|
||||
NLBLOCK->nllen == 2 &&
|
||||
UCHAR21(eptr) == NLBLOCK->nl[0])
|
||||
{
|
||||
md->hitend = TRUE;
|
||||
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
|
||||
}
|
||||
eptr++;
|
||||
ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
|
||||
md->hitend = TRUE;
|
||||
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
|
||||
}
|
||||
eptr++;
|
||||
ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -6522,7 +6507,7 @@ tables = re->tables;
|
|||
|
||||
if (extra_data != NULL)
|
||||
{
|
||||
register unsigned int flags = extra_data->flags;
|
||||
unsigned long int flags = extra_data->flags;
|
||||
if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
|
||||
study = (const pcre_study_data *)extra_data->study_data;
|
||||
if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
|
||||
|
|
|
|||
|
|
@ -2281,7 +2281,7 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
|
|||
ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
|
||||
ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69,
|
||||
ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79,
|
||||
ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERRCOUNT };
|
||||
ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERRCOUNT };
|
||||
|
||||
/* JIT compiling modes. The function list is indexed by them. */
|
||||
|
||||
|
|
@ -2446,6 +2446,7 @@ typedef struct compile_data {
|
|||
BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
|
||||
BOOL check_lookbehind; /* Lookbehinds need later checking */
|
||||
BOOL dupnames; /* Duplicate names exist */
|
||||
BOOL iscondassert; /* Next assert is a condition */
|
||||
int nltype; /* Newline type */
|
||||
int nllen; /* Newline string length */
|
||||
pcre_uchar nl[4]; /* Newline string when fixed length */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -393,7 +393,7 @@ for (;;)
|
|||
ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(slot, 0));
|
||||
if (cs == NULL) return -2;
|
||||
do ce += GET(ce, 1); while (*ce == OP_ALT);
|
||||
if (cc > cs && cc < ce)
|
||||
if ((cc > cs && cc < ce) || recurse_depth > 10)
|
||||
{
|
||||
d = 0;
|
||||
had_recurse = TRUE;
|
||||
|
|
@ -401,7 +401,7 @@ for (;;)
|
|||
}
|
||||
else
|
||||
{
|
||||
int dd = find_minlength(re, cs, startcode, options, recurse_depth);
|
||||
int dd = find_minlength(re, cs, startcode, options, recurse_depth+1);
|
||||
if (dd < d) d = dd;
|
||||
}
|
||||
slot += re->name_entry_size;
|
||||
|
|
@ -418,14 +418,14 @@ for (;;)
|
|||
ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1));
|
||||
if (cs == NULL) return -2;
|
||||
do ce += GET(ce, 1); while (*ce == OP_ALT);
|
||||
if (cc > cs && cc < ce)
|
||||
if ((cc > cs && cc < ce) || recurse_depth > 10)
|
||||
{
|
||||
d = 0;
|
||||
had_recurse = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
d = find_minlength(re, cs, startcode, options, recurse_depth);
|
||||
d = find_minlength(re, cs, startcode, options, recurse_depth + 1);
|
||||
}
|
||||
}
|
||||
else d = 0;
|
||||
|
|
@ -863,7 +863,6 @@ do
|
|||
case OP_NOTUPTOI:
|
||||
case OP_NOT_HSPACE:
|
||||
case OP_NOT_VSPACE:
|
||||
case OP_PROP:
|
||||
case OP_PRUNE:
|
||||
case OP_PRUNE_ARG:
|
||||
case OP_RECURSE:
|
||||
|
|
@ -881,6 +880,31 @@ do
|
|||
case OP_THEN_ARG:
|
||||
return SSB_FAIL;
|
||||
|
||||
/* A "real" property test implies no starting bits, but the fake property
|
||||
PT_CLIST identifies a list of characters. These lists are short, as they
|
||||
are used for characters with more than one "other case", so there is no
|
||||
point in recognizing them for OP_NOTPROP. */
|
||||
|
||||
case OP_PROP:
|
||||
if (tcode[1] != PT_CLIST) return SSB_FAIL;
|
||||
{
|
||||
const pcre_uint32 *p = PRIV(ucd_caseless_sets) + tcode[2];
|
||||
while ((c = *p++) < NOTACHAR)
|
||||
{
|
||||
#if defined SUPPORT_UTF && defined COMPILE_PCRE8
|
||||
if (utf)
|
||||
{
|
||||
pcre_uchar buff[6];
|
||||
(void)PRIV(ord2utf)(c, buff);
|
||||
c = buff[0];
|
||||
}
|
||||
#endif
|
||||
if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);
|
||||
}
|
||||
}
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
/* We can ignore word boundary tests. */
|
||||
|
||||
case OP_WORD_BOUNDARY:
|
||||
|
|
@ -1106,24 +1130,17 @@ do
|
|||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to
|
||||
ensure it is set as not whitespace. Luckily, the code value is the same
|
||||
(0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate bit. */
|
||||
/* The cbit_space table has vertical tab as whitespace; we no longer
|
||||
have to play fancy tricks because Perl added VT to its whitespace at
|
||||
release 5.18. PCRE added it at release 8.34. */
|
||||
|
||||
case OP_NOT_WHITESPACE:
|
||||
set_nottype_bits(start_bits, cbit_space, table_limit, cd);
|
||||
start_bits[1] |= 0x08;
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to not
|
||||
set it from the table. Luckily, the code value is the same (0x0b) in
|
||||
ASCII and EBCDIC, so we can just adjust the appropriate bit. */
|
||||
|
||||
case OP_WHITESPACE:
|
||||
c = start_bits[1]; /* Save in case it was already set */
|
||||
set_type_bits(start_bits, cbit_space, table_limit, cd);
|
||||
start_bits[1] = (start_bits[1] & ~0x08) | c;
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
|||
#define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0"
|
||||
#define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"
|
||||
#define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0"
|
||||
#define STRING_Bassa_Vah0 STR_B STR_a STR_s STR_s STR_a STR_UNDERSCORE STR_V STR_a STR_h "\0"
|
||||
#define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0"
|
||||
#define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0"
|
||||
#define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
|
||||
|
|
@ -223,6 +224,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
|||
#define STRING_C0 STR_C "\0"
|
||||
#define STRING_Canadian_Aboriginal0 STR_C STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0"
|
||||
#define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0"
|
||||
#define STRING_Caucasian_Albanian0 STR_C STR_a STR_u STR_c STR_a STR_s STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_l STR_b STR_a STR_n STR_i STR_a STR_n "\0"
|
||||
#define STRING_Cc0 STR_C STR_c "\0"
|
||||
#define STRING_Cf0 STR_C STR_f "\0"
|
||||
#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0"
|
||||
|
|
@ -238,11 +240,14 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
|||
#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
|
||||
#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"
|
||||
#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
|
||||
#define STRING_Duployan0 STR_D STR_u STR_p STR_l STR_o STR_y STR_a STR_n "\0"
|
||||
#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
|
||||
#define STRING_Elbasan0 STR_E STR_l STR_b STR_a STR_s STR_a STR_n "\0"
|
||||
#define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"
|
||||
#define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"
|
||||
#define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"
|
||||
#define STRING_Gothic0 STR_G STR_o STR_t STR_h STR_i STR_c "\0"
|
||||
#define STRING_Grantha0 STR_G STR_r STR_a STR_n STR_t STR_h STR_a "\0"
|
||||
#define STRING_Greek0 STR_G STR_r STR_e STR_e STR_k "\0"
|
||||
#define STRING_Gujarati0 STR_G STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0"
|
||||
#define STRING_Gurmukhi0 STR_G STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0"
|
||||
|
|
@ -262,12 +267,15 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
|||
#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"
|
||||
#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
|
||||
#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"
|
||||
#define STRING_Khojki0 STR_K STR_h STR_o STR_j STR_k STR_i "\0"
|
||||
#define STRING_Khudawadi0 STR_K STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i "\0"
|
||||
#define STRING_L0 STR_L "\0"
|
||||
#define STRING_L_AMPERSAND0 STR_L STR_AMPERSAND "\0"
|
||||
#define STRING_Lao0 STR_L STR_a STR_o "\0"
|
||||
#define STRING_Latin0 STR_L STR_a STR_t STR_i STR_n "\0"
|
||||
#define STRING_Lepcha0 STR_L STR_e STR_p STR_c STR_h STR_a "\0"
|
||||
#define STRING_Limbu0 STR_L STR_i STR_m STR_b STR_u "\0"
|
||||
#define STRING_Linear_A0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_A "\0"
|
||||
#define STRING_Linear_B0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_B "\0"
|
||||
#define STRING_Lisu0 STR_L STR_i STR_s STR_u "\0"
|
||||
#define STRING_Ll0 STR_L STR_l "\0"
|
||||
|
|
@ -278,18 +286,24 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
|||
#define STRING_Lycian0 STR_L STR_y STR_c STR_i STR_a STR_n "\0"
|
||||
#define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0"
|
||||
#define STRING_M0 STR_M "\0"
|
||||
#define STRING_Mahajani0 STR_M STR_a STR_h STR_a STR_j STR_a STR_n STR_i "\0"
|
||||
#define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
|
||||
#define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0"
|
||||
#define STRING_Manichaean0 STR_M STR_a STR_n STR_i STR_c STR_h STR_a STR_e STR_a STR_n "\0"
|
||||
#define STRING_Mc0 STR_M STR_c "\0"
|
||||
#define STRING_Me0 STR_M STR_e "\0"
|
||||
#define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0"
|
||||
#define STRING_Mende_Kikakui0 STR_M STR_e STR_n STR_d STR_e STR_UNDERSCORE STR_K STR_i STR_k STR_a STR_k STR_u STR_i "\0"
|
||||
#define STRING_Meroitic_Cursive0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_C STR_u STR_r STR_s STR_i STR_v STR_e "\0"
|
||||
#define STRING_Meroitic_Hieroglyphs0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
|
||||
#define STRING_Miao0 STR_M STR_i STR_a STR_o "\0"
|
||||
#define STRING_Mn0 STR_M STR_n "\0"
|
||||
#define STRING_Modi0 STR_M STR_o STR_d STR_i "\0"
|
||||
#define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"
|
||||
#define STRING_Mro0 STR_M STR_r STR_o "\0"
|
||||
#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"
|
||||
#define STRING_N0 STR_N "\0"
|
||||
#define STRING_Nabataean0 STR_N STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0"
|
||||
#define STRING_Nd0 STR_N STR_d "\0"
|
||||
#define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0"
|
||||
#define STRING_Nko0 STR_N STR_k STR_o "\0"
|
||||
|
|
@ -298,12 +312,17 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
|||
#define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0"
|
||||
#define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0"
|
||||
#define STRING_Old_Italic0 STR_O STR_l STR_d STR_UNDERSCORE STR_I STR_t STR_a STR_l STR_i STR_c "\0"
|
||||
#define STRING_Old_North_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_N STR_o STR_r STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
|
||||
#define STRING_Old_Permic0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_m STR_i STR_c "\0"
|
||||
#define STRING_Old_Persian0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_s STR_i STR_a STR_n "\0"
|
||||
#define STRING_Old_South_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_u STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
|
||||
#define STRING_Old_Turkic0 STR_O STR_l STR_d STR_UNDERSCORE STR_T STR_u STR_r STR_k STR_i STR_c "\0"
|
||||
#define STRING_Oriya0 STR_O STR_r STR_i STR_y STR_a "\0"
|
||||
#define STRING_Osmanya0 STR_O STR_s STR_m STR_a STR_n STR_y STR_a "\0"
|
||||
#define STRING_P0 STR_P "\0"
|
||||
#define STRING_Pahawh_Hmong0 STR_P STR_a STR_h STR_a STR_w STR_h STR_UNDERSCORE STR_H STR_m STR_o STR_n STR_g "\0"
|
||||
#define STRING_Palmyrene0 STR_P STR_a STR_l STR_m STR_y STR_r STR_e STR_n STR_e "\0"
|
||||
#define STRING_Pau_Cin_Hau0 STR_P STR_a STR_u STR_UNDERSCORE STR_C STR_i STR_n STR_UNDERSCORE STR_H STR_a STR_u "\0"
|
||||
#define STRING_Pc0 STR_P STR_c "\0"
|
||||
#define STRING_Pd0 STR_P STR_d "\0"
|
||||
#define STRING_Pe0 STR_P STR_e "\0"
|
||||
|
|
@ -313,6 +332,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
|||
#define STRING_Pi0 STR_P STR_i "\0"
|
||||
#define STRING_Po0 STR_P STR_o "\0"
|
||||
#define STRING_Ps0 STR_P STR_s "\0"
|
||||
#define STRING_Psalter_Pahlavi0 STR_P STR_s STR_a STR_l STR_t STR_e STR_r STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"
|
||||
#define STRING_Rejang0 STR_R STR_e STR_j STR_a STR_n STR_g "\0"
|
||||
#define STRING_Runic0 STR_R STR_u STR_n STR_i STR_c "\0"
|
||||
#define STRING_S0 STR_S "\0"
|
||||
|
|
@ -321,6 +341,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
|||
#define STRING_Sc0 STR_S STR_c "\0"
|
||||
#define STRING_Sharada0 STR_S STR_h STR_a STR_r STR_a STR_d STR_a "\0"
|
||||
#define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0"
|
||||
#define STRING_Siddham0 STR_S STR_i STR_d STR_d STR_h STR_a STR_m "\0"
|
||||
#define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0"
|
||||
#define STRING_Sk0 STR_S STR_k "\0"
|
||||
#define STRING_Sm0 STR_S STR_m "\0"
|
||||
|
|
@ -341,8 +362,10 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
|||
#define STRING_Thai0 STR_T STR_h STR_a STR_i "\0"
|
||||
#define STRING_Tibetan0 STR_T STR_i STR_b STR_e STR_t STR_a STR_n "\0"
|
||||
#define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0"
|
||||
#define STRING_Tirhuta0 STR_T STR_i STR_r STR_h STR_u STR_t STR_a "\0"
|
||||
#define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"
|
||||
#define STRING_Vai0 STR_V STR_a STR_i "\0"
|
||||
#define STRING_Warang_Citi0 STR_W STR_a STR_r STR_a STR_n STR_g STR_UNDERSCORE STR_C STR_i STR_t STR_i "\0"
|
||||
#define STRING_Xan0 STR_X STR_a STR_n "\0"
|
||||
#define STRING_Xps0 STR_X STR_p STR_s "\0"
|
||||
#define STRING_Xsp0 STR_X STR_s STR_p "\0"
|
||||
|
|
@ -361,6 +384,7 @@ const char PRIV(utt_names)[] =
|
|||
STRING_Avestan0
|
||||
STRING_Balinese0
|
||||
STRING_Bamum0
|
||||
STRING_Bassa_Vah0
|
||||
STRING_Batak0
|
||||
STRING_Bengali0
|
||||
STRING_Bopomofo0
|
||||
|
|
@ -371,6 +395,7 @@ const char PRIV(utt_names)[] =
|
|||
STRING_C0
|
||||
STRING_Canadian_Aboriginal0
|
||||
STRING_Carian0
|
||||
STRING_Caucasian_Albanian0
|
||||
STRING_Cc0
|
||||
STRING_Cf0
|
||||
STRING_Chakma0
|
||||
|
|
@ -386,11 +411,14 @@ const char PRIV(utt_names)[] =
|
|||
STRING_Cyrillic0
|
||||
STRING_Deseret0
|
||||
STRING_Devanagari0
|
||||
STRING_Duployan0
|
||||
STRING_Egyptian_Hieroglyphs0
|
||||
STRING_Elbasan0
|
||||
STRING_Ethiopic0
|
||||
STRING_Georgian0
|
||||
STRING_Glagolitic0
|
||||
STRING_Gothic0
|
||||
STRING_Grantha0
|
||||
STRING_Greek0
|
||||
STRING_Gujarati0
|
||||
STRING_Gurmukhi0
|
||||
|
|
@ -410,12 +438,15 @@ const char PRIV(utt_names)[] =
|
|||
STRING_Kayah_Li0
|
||||
STRING_Kharoshthi0
|
||||
STRING_Khmer0
|
||||
STRING_Khojki0
|
||||
STRING_Khudawadi0
|
||||
STRING_L0
|
||||
STRING_L_AMPERSAND0
|
||||
STRING_Lao0
|
||||
STRING_Latin0
|
||||
STRING_Lepcha0
|
||||
STRING_Limbu0
|
||||
STRING_Linear_A0
|
||||
STRING_Linear_B0
|
||||
STRING_Lisu0
|
||||
STRING_Ll0
|
||||
|
|
@ -426,18 +457,24 @@ const char PRIV(utt_names)[] =
|
|||
STRING_Lycian0
|
||||
STRING_Lydian0
|
||||
STRING_M0
|
||||
STRING_Mahajani0
|
||||
STRING_Malayalam0
|
||||
STRING_Mandaic0
|
||||
STRING_Manichaean0
|
||||
STRING_Mc0
|
||||
STRING_Me0
|
||||
STRING_Meetei_Mayek0
|
||||
STRING_Mende_Kikakui0
|
||||
STRING_Meroitic_Cursive0
|
||||
STRING_Meroitic_Hieroglyphs0
|
||||
STRING_Miao0
|
||||
STRING_Mn0
|
||||
STRING_Modi0
|
||||
STRING_Mongolian0
|
||||
STRING_Mro0
|
||||
STRING_Myanmar0
|
||||
STRING_N0
|
||||
STRING_Nabataean0
|
||||
STRING_Nd0
|
||||
STRING_New_Tai_Lue0
|
||||
STRING_Nko0
|
||||
|
|
@ -446,12 +483,17 @@ const char PRIV(utt_names)[] =
|
|||
STRING_Ogham0
|
||||
STRING_Ol_Chiki0
|
||||
STRING_Old_Italic0
|
||||
STRING_Old_North_Arabian0
|
||||
STRING_Old_Permic0
|
||||
STRING_Old_Persian0
|
||||
STRING_Old_South_Arabian0
|
||||
STRING_Old_Turkic0
|
||||
STRING_Oriya0
|
||||
STRING_Osmanya0
|
||||
STRING_P0
|
||||
STRING_Pahawh_Hmong0
|
||||
STRING_Palmyrene0
|
||||
STRING_Pau_Cin_Hau0
|
||||
STRING_Pc0
|
||||
STRING_Pd0
|
||||
STRING_Pe0
|
||||
|
|
@ -461,6 +503,7 @@ const char PRIV(utt_names)[] =
|
|||
STRING_Pi0
|
||||
STRING_Po0
|
||||
STRING_Ps0
|
||||
STRING_Psalter_Pahlavi0
|
||||
STRING_Rejang0
|
||||
STRING_Runic0
|
||||
STRING_S0
|
||||
|
|
@ -469,6 +512,7 @@ const char PRIV(utt_names)[] =
|
|||
STRING_Sc0
|
||||
STRING_Sharada0
|
||||
STRING_Shavian0
|
||||
STRING_Siddham0
|
||||
STRING_Sinhala0
|
||||
STRING_Sk0
|
||||
STRING_Sm0
|
||||
|
|
@ -489,8 +533,10 @@ const char PRIV(utt_names)[] =
|
|||
STRING_Thai0
|
||||
STRING_Tibetan0
|
||||
STRING_Tifinagh0
|
||||
STRING_Tirhuta0
|
||||
STRING_Ugaritic0
|
||||
STRING_Vai0
|
||||
STRING_Warang_Citi0
|
||||
STRING_Xan0
|
||||
STRING_Xps0
|
||||
STRING_Xsp0
|
||||
|
|
@ -509,146 +555,169 @@ const ucp_type_table PRIV(utt)[] = {
|
|||
{ 20, PT_SC, ucp_Avestan },
|
||||
{ 28, PT_SC, ucp_Balinese },
|
||||
{ 37, PT_SC, ucp_Bamum },
|
||||
{ 43, PT_SC, ucp_Batak },
|
||||
{ 49, PT_SC, ucp_Bengali },
|
||||
{ 57, PT_SC, ucp_Bopomofo },
|
||||
{ 66, PT_SC, ucp_Brahmi },
|
||||
{ 73, PT_SC, ucp_Braille },
|
||||
{ 81, PT_SC, ucp_Buginese },
|
||||
{ 90, PT_SC, ucp_Buhid },
|
||||
{ 96, PT_GC, ucp_C },
|
||||
{ 98, PT_SC, ucp_Canadian_Aboriginal },
|
||||
{ 118, PT_SC, ucp_Carian },
|
||||
{ 125, PT_PC, ucp_Cc },
|
||||
{ 128, PT_PC, ucp_Cf },
|
||||
{ 131, PT_SC, ucp_Chakma },
|
||||
{ 138, PT_SC, ucp_Cham },
|
||||
{ 143, PT_SC, ucp_Cherokee },
|
||||
{ 152, PT_PC, ucp_Cn },
|
||||
{ 155, PT_PC, ucp_Co },
|
||||
{ 158, PT_SC, ucp_Common },
|
||||
{ 165, PT_SC, ucp_Coptic },
|
||||
{ 172, PT_PC, ucp_Cs },
|
||||
{ 175, PT_SC, ucp_Cuneiform },
|
||||
{ 185, PT_SC, ucp_Cypriot },
|
||||
{ 193, PT_SC, ucp_Cyrillic },
|
||||
{ 202, PT_SC, ucp_Deseret },
|
||||
{ 210, PT_SC, ucp_Devanagari },
|
||||
{ 221, PT_SC, ucp_Egyptian_Hieroglyphs },
|
||||
{ 242, PT_SC, ucp_Ethiopic },
|
||||
{ 251, PT_SC, ucp_Georgian },
|
||||
{ 260, PT_SC, ucp_Glagolitic },
|
||||
{ 271, PT_SC, ucp_Gothic },
|
||||
{ 278, PT_SC, ucp_Greek },
|
||||
{ 284, PT_SC, ucp_Gujarati },
|
||||
{ 293, PT_SC, ucp_Gurmukhi },
|
||||
{ 302, PT_SC, ucp_Han },
|
||||
{ 306, PT_SC, ucp_Hangul },
|
||||
{ 313, PT_SC, ucp_Hanunoo },
|
||||
{ 321, PT_SC, ucp_Hebrew },
|
||||
{ 328, PT_SC, ucp_Hiragana },
|
||||
{ 337, PT_SC, ucp_Imperial_Aramaic },
|
||||
{ 354, PT_SC, ucp_Inherited },
|
||||
{ 364, PT_SC, ucp_Inscriptional_Pahlavi },
|
||||
{ 386, PT_SC, ucp_Inscriptional_Parthian },
|
||||
{ 409, PT_SC, ucp_Javanese },
|
||||
{ 418, PT_SC, ucp_Kaithi },
|
||||
{ 425, PT_SC, ucp_Kannada },
|
||||
{ 433, PT_SC, ucp_Katakana },
|
||||
{ 442, PT_SC, ucp_Kayah_Li },
|
||||
{ 451, PT_SC, ucp_Kharoshthi },
|
||||
{ 462, PT_SC, ucp_Khmer },
|
||||
{ 468, PT_GC, ucp_L },
|
||||
{ 470, PT_LAMP, 0 },
|
||||
{ 473, PT_SC, ucp_Lao },
|
||||
{ 477, PT_SC, ucp_Latin },
|
||||
{ 483, PT_SC, ucp_Lepcha },
|
||||
{ 490, PT_SC, ucp_Limbu },
|
||||
{ 496, PT_SC, ucp_Linear_B },
|
||||
{ 505, PT_SC, ucp_Lisu },
|
||||
{ 510, PT_PC, ucp_Ll },
|
||||
{ 513, PT_PC, ucp_Lm },
|
||||
{ 516, PT_PC, ucp_Lo },
|
||||
{ 519, PT_PC, ucp_Lt },
|
||||
{ 522, PT_PC, ucp_Lu },
|
||||
{ 525, PT_SC, ucp_Lycian },
|
||||
{ 532, PT_SC, ucp_Lydian },
|
||||
{ 539, PT_GC, ucp_M },
|
||||
{ 541, PT_SC, ucp_Malayalam },
|
||||
{ 551, PT_SC, ucp_Mandaic },
|
||||
{ 559, PT_PC, ucp_Mc },
|
||||
{ 562, PT_PC, ucp_Me },
|
||||
{ 565, PT_SC, ucp_Meetei_Mayek },
|
||||
{ 578, PT_SC, ucp_Meroitic_Cursive },
|
||||
{ 595, PT_SC, ucp_Meroitic_Hieroglyphs },
|
||||
{ 616, PT_SC, ucp_Miao },
|
||||
{ 621, PT_PC, ucp_Mn },
|
||||
{ 624, PT_SC, ucp_Mongolian },
|
||||
{ 634, PT_SC, ucp_Myanmar },
|
||||
{ 642, PT_GC, ucp_N },
|
||||
{ 644, PT_PC, ucp_Nd },
|
||||
{ 647, PT_SC, ucp_New_Tai_Lue },
|
||||
{ 659, PT_SC, ucp_Nko },
|
||||
{ 663, PT_PC, ucp_Nl },
|
||||
{ 666, PT_PC, ucp_No },
|
||||
{ 669, PT_SC, ucp_Ogham },
|
||||
{ 675, PT_SC, ucp_Ol_Chiki },
|
||||
{ 684, PT_SC, ucp_Old_Italic },
|
||||
{ 695, PT_SC, ucp_Old_Persian },
|
||||
{ 707, PT_SC, ucp_Old_South_Arabian },
|
||||
{ 725, PT_SC, ucp_Old_Turkic },
|
||||
{ 736, PT_SC, ucp_Oriya },
|
||||
{ 742, PT_SC, ucp_Osmanya },
|
||||
{ 750, PT_GC, ucp_P },
|
||||
{ 752, PT_PC, ucp_Pc },
|
||||
{ 755, PT_PC, ucp_Pd },
|
||||
{ 758, PT_PC, ucp_Pe },
|
||||
{ 761, PT_PC, ucp_Pf },
|
||||
{ 764, PT_SC, ucp_Phags_Pa },
|
||||
{ 773, PT_SC, ucp_Phoenician },
|
||||
{ 784, PT_PC, ucp_Pi },
|
||||
{ 787, PT_PC, ucp_Po },
|
||||
{ 790, PT_PC, ucp_Ps },
|
||||
{ 793, PT_SC, ucp_Rejang },
|
||||
{ 800, PT_SC, ucp_Runic },
|
||||
{ 806, PT_GC, ucp_S },
|
||||
{ 808, PT_SC, ucp_Samaritan },
|
||||
{ 818, PT_SC, ucp_Saurashtra },
|
||||
{ 829, PT_PC, ucp_Sc },
|
||||
{ 832, PT_SC, ucp_Sharada },
|
||||
{ 840, PT_SC, ucp_Shavian },
|
||||
{ 848, PT_SC, ucp_Sinhala },
|
||||
{ 856, PT_PC, ucp_Sk },
|
||||
{ 859, PT_PC, ucp_Sm },
|
||||
{ 862, PT_PC, ucp_So },
|
||||
{ 865, PT_SC, ucp_Sora_Sompeng },
|
||||
{ 878, PT_SC, ucp_Sundanese },
|
||||
{ 888, PT_SC, ucp_Syloti_Nagri },
|
||||
{ 901, PT_SC, ucp_Syriac },
|
||||
{ 908, PT_SC, ucp_Tagalog },
|
||||
{ 916, PT_SC, ucp_Tagbanwa },
|
||||
{ 925, PT_SC, ucp_Tai_Le },
|
||||
{ 932, PT_SC, ucp_Tai_Tham },
|
||||
{ 941, PT_SC, ucp_Tai_Viet },
|
||||
{ 950, PT_SC, ucp_Takri },
|
||||
{ 956, PT_SC, ucp_Tamil },
|
||||
{ 962, PT_SC, ucp_Telugu },
|
||||
{ 969, PT_SC, ucp_Thaana },
|
||||
{ 976, PT_SC, ucp_Thai },
|
||||
{ 981, PT_SC, ucp_Tibetan },
|
||||
{ 989, PT_SC, ucp_Tifinagh },
|
||||
{ 998, PT_SC, ucp_Ugaritic },
|
||||
{ 1007, PT_SC, ucp_Vai },
|
||||
{ 1011, PT_ALNUM, 0 },
|
||||
{ 1015, PT_PXSPACE, 0 },
|
||||
{ 1019, PT_SPACE, 0 },
|
||||
{ 1023, PT_UCNC, 0 },
|
||||
{ 1027, PT_WORD, 0 },
|
||||
{ 1031, PT_SC, ucp_Yi },
|
||||
{ 1034, PT_GC, ucp_Z },
|
||||
{ 1036, PT_PC, ucp_Zl },
|
||||
{ 1039, PT_PC, ucp_Zp },
|
||||
{ 1042, PT_PC, ucp_Zs }
|
||||
{ 43, PT_SC, ucp_Bassa_Vah },
|
||||
{ 53, PT_SC, ucp_Batak },
|
||||
{ 59, PT_SC, ucp_Bengali },
|
||||
{ 67, PT_SC, ucp_Bopomofo },
|
||||
{ 76, PT_SC, ucp_Brahmi },
|
||||
{ 83, PT_SC, ucp_Braille },
|
||||
{ 91, PT_SC, ucp_Buginese },
|
||||
{ 100, PT_SC, ucp_Buhid },
|
||||
{ 106, PT_GC, ucp_C },
|
||||
{ 108, PT_SC, ucp_Canadian_Aboriginal },
|
||||
{ 128, PT_SC, ucp_Carian },
|
||||
{ 135, PT_SC, ucp_Caucasian_Albanian },
|
||||
{ 154, PT_PC, ucp_Cc },
|
||||
{ 157, PT_PC, ucp_Cf },
|
||||
{ 160, PT_SC, ucp_Chakma },
|
||||
{ 167, PT_SC, ucp_Cham },
|
||||
{ 172, PT_SC, ucp_Cherokee },
|
||||
{ 181, PT_PC, ucp_Cn },
|
||||
{ 184, PT_PC, ucp_Co },
|
||||
{ 187, PT_SC, ucp_Common },
|
||||
{ 194, PT_SC, ucp_Coptic },
|
||||
{ 201, PT_PC, ucp_Cs },
|
||||
{ 204, PT_SC, ucp_Cuneiform },
|
||||
{ 214, PT_SC, ucp_Cypriot },
|
||||
{ 222, PT_SC, ucp_Cyrillic },
|
||||
{ 231, PT_SC, ucp_Deseret },
|
||||
{ 239, PT_SC, ucp_Devanagari },
|
||||
{ 250, PT_SC, ucp_Duployan },
|
||||
{ 259, PT_SC, ucp_Egyptian_Hieroglyphs },
|
||||
{ 280, PT_SC, ucp_Elbasan },
|
||||
{ 288, PT_SC, ucp_Ethiopic },
|
||||
{ 297, PT_SC, ucp_Georgian },
|
||||
{ 306, PT_SC, ucp_Glagolitic },
|
||||
{ 317, PT_SC, ucp_Gothic },
|
||||
{ 324, PT_SC, ucp_Grantha },
|
||||
{ 332, PT_SC, ucp_Greek },
|
||||
{ 338, PT_SC, ucp_Gujarati },
|
||||
{ 347, PT_SC, ucp_Gurmukhi },
|
||||
{ 356, PT_SC, ucp_Han },
|
||||
{ 360, PT_SC, ucp_Hangul },
|
||||
{ 367, PT_SC, ucp_Hanunoo },
|
||||
{ 375, PT_SC, ucp_Hebrew },
|
||||
{ 382, PT_SC, ucp_Hiragana },
|
||||
{ 391, PT_SC, ucp_Imperial_Aramaic },
|
||||
{ 408, PT_SC, ucp_Inherited },
|
||||
{ 418, PT_SC, ucp_Inscriptional_Pahlavi },
|
||||
{ 440, PT_SC, ucp_Inscriptional_Parthian },
|
||||
{ 463, PT_SC, ucp_Javanese },
|
||||
{ 472, PT_SC, ucp_Kaithi },
|
||||
{ 479, PT_SC, ucp_Kannada },
|
||||
{ 487, PT_SC, ucp_Katakana },
|
||||
{ 496, PT_SC, ucp_Kayah_Li },
|
||||
{ 505, PT_SC, ucp_Kharoshthi },
|
||||
{ 516, PT_SC, ucp_Khmer },
|
||||
{ 522, PT_SC, ucp_Khojki },
|
||||
{ 529, PT_SC, ucp_Khudawadi },
|
||||
{ 539, PT_GC, ucp_L },
|
||||
{ 541, PT_LAMP, 0 },
|
||||
{ 544, PT_SC, ucp_Lao },
|
||||
{ 548, PT_SC, ucp_Latin },
|
||||
{ 554, PT_SC, ucp_Lepcha },
|
||||
{ 561, PT_SC, ucp_Limbu },
|
||||
{ 567, PT_SC, ucp_Linear_A },
|
||||
{ 576, PT_SC, ucp_Linear_B },
|
||||
{ 585, PT_SC, ucp_Lisu },
|
||||
{ 590, PT_PC, ucp_Ll },
|
||||
{ 593, PT_PC, ucp_Lm },
|
||||
{ 596, PT_PC, ucp_Lo },
|
||||
{ 599, PT_PC, ucp_Lt },
|
||||
{ 602, PT_PC, ucp_Lu },
|
||||
{ 605, PT_SC, ucp_Lycian },
|
||||
{ 612, PT_SC, ucp_Lydian },
|
||||
{ 619, PT_GC, ucp_M },
|
||||
{ 621, PT_SC, ucp_Mahajani },
|
||||
{ 630, PT_SC, ucp_Malayalam },
|
||||
{ 640, PT_SC, ucp_Mandaic },
|
||||
{ 648, PT_SC, ucp_Manichaean },
|
||||
{ 659, PT_PC, ucp_Mc },
|
||||
{ 662, PT_PC, ucp_Me },
|
||||
{ 665, PT_SC, ucp_Meetei_Mayek },
|
||||
{ 678, PT_SC, ucp_Mende_Kikakui },
|
||||
{ 692, PT_SC, ucp_Meroitic_Cursive },
|
||||
{ 709, PT_SC, ucp_Meroitic_Hieroglyphs },
|
||||
{ 730, PT_SC, ucp_Miao },
|
||||
{ 735, PT_PC, ucp_Mn },
|
||||
{ 738, PT_SC, ucp_Modi },
|
||||
{ 743, PT_SC, ucp_Mongolian },
|
||||
{ 753, PT_SC, ucp_Mro },
|
||||
{ 757, PT_SC, ucp_Myanmar },
|
||||
{ 765, PT_GC, ucp_N },
|
||||
{ 767, PT_SC, ucp_Nabataean },
|
||||
{ 777, PT_PC, ucp_Nd },
|
||||
{ 780, PT_SC, ucp_New_Tai_Lue },
|
||||
{ 792, PT_SC, ucp_Nko },
|
||||
{ 796, PT_PC, ucp_Nl },
|
||||
{ 799, PT_PC, ucp_No },
|
||||
{ 802, PT_SC, ucp_Ogham },
|
||||
{ 808, PT_SC, ucp_Ol_Chiki },
|
||||
{ 817, PT_SC, ucp_Old_Italic },
|
||||
{ 828, PT_SC, ucp_Old_North_Arabian },
|
||||
{ 846, PT_SC, ucp_Old_Permic },
|
||||
{ 857, PT_SC, ucp_Old_Persian },
|
||||
{ 869, PT_SC, ucp_Old_South_Arabian },
|
||||
{ 887, PT_SC, ucp_Old_Turkic },
|
||||
{ 898, PT_SC, ucp_Oriya },
|
||||
{ 904, PT_SC, ucp_Osmanya },
|
||||
{ 912, PT_GC, ucp_P },
|
||||
{ 914, PT_SC, ucp_Pahawh_Hmong },
|
||||
{ 927, PT_SC, ucp_Palmyrene },
|
||||
{ 937, PT_SC, ucp_Pau_Cin_Hau },
|
||||
{ 949, PT_PC, ucp_Pc },
|
||||
{ 952, PT_PC, ucp_Pd },
|
||||
{ 955, PT_PC, ucp_Pe },
|
||||
{ 958, PT_PC, ucp_Pf },
|
||||
{ 961, PT_SC, ucp_Phags_Pa },
|
||||
{ 970, PT_SC, ucp_Phoenician },
|
||||
{ 981, PT_PC, ucp_Pi },
|
||||
{ 984, PT_PC, ucp_Po },
|
||||
{ 987, PT_PC, ucp_Ps },
|
||||
{ 990, PT_SC, ucp_Psalter_Pahlavi },
|
||||
{ 1006, PT_SC, ucp_Rejang },
|
||||
{ 1013, PT_SC, ucp_Runic },
|
||||
{ 1019, PT_GC, ucp_S },
|
||||
{ 1021, PT_SC, ucp_Samaritan },
|
||||
{ 1031, PT_SC, ucp_Saurashtra },
|
||||
{ 1042, PT_PC, ucp_Sc },
|
||||
{ 1045, PT_SC, ucp_Sharada },
|
||||
{ 1053, PT_SC, ucp_Shavian },
|
||||
{ 1061, PT_SC, ucp_Siddham },
|
||||
{ 1069, PT_SC, ucp_Sinhala },
|
||||
{ 1077, PT_PC, ucp_Sk },
|
||||
{ 1080, PT_PC, ucp_Sm },
|
||||
{ 1083, PT_PC, ucp_So },
|
||||
{ 1086, PT_SC, ucp_Sora_Sompeng },
|
||||
{ 1099, PT_SC, ucp_Sundanese },
|
||||
{ 1109, PT_SC, ucp_Syloti_Nagri },
|
||||
{ 1122, PT_SC, ucp_Syriac },
|
||||
{ 1129, PT_SC, ucp_Tagalog },
|
||||
{ 1137, PT_SC, ucp_Tagbanwa },
|
||||
{ 1146, PT_SC, ucp_Tai_Le },
|
||||
{ 1153, PT_SC, ucp_Tai_Tham },
|
||||
{ 1162, PT_SC, ucp_Tai_Viet },
|
||||
{ 1171, PT_SC, ucp_Takri },
|
||||
{ 1177, PT_SC, ucp_Tamil },
|
||||
{ 1183, PT_SC, ucp_Telugu },
|
||||
{ 1190, PT_SC, ucp_Thaana },
|
||||
{ 1197, PT_SC, ucp_Thai },
|
||||
{ 1202, PT_SC, ucp_Tibetan },
|
||||
{ 1210, PT_SC, ucp_Tifinagh },
|
||||
{ 1219, PT_SC, ucp_Tirhuta },
|
||||
{ 1227, PT_SC, ucp_Ugaritic },
|
||||
{ 1236, PT_SC, ucp_Vai },
|
||||
{ 1240, PT_SC, ucp_Warang_Citi },
|
||||
{ 1252, PT_ALNUM, 0 },
|
||||
{ 1256, PT_PXSPACE, 0 },
|
||||
{ 1260, PT_SPACE, 0 },
|
||||
{ 1264, PT_UCNC, 0 },
|
||||
{ 1268, PT_WORD, 0 },
|
||||
{ 1272, PT_SC, ucp_Yi },
|
||||
{ 1275, PT_GC, ucp_Z },
|
||||
{ 1277, PT_PC, ucp_Zl },
|
||||
{ 1280, PT_PC, ucp_Zp },
|
||||
{ 1283, PT_PC, ucp_Zs }
|
||||
};
|
||||
|
||||
const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -96,13 +96,19 @@
|
|||
#define SLJIT_EXECUTABLE_ALLOCATOR 1
|
||||
#endif
|
||||
|
||||
/* Return with error when an invalid argument is passed. */
|
||||
#ifndef SLJIT_ARGUMENT_CHECKS
|
||||
/* Disabled by default */
|
||||
#define SLJIT_ARGUMENT_CHECKS 0
|
||||
#endif
|
||||
|
||||
/* Debug checks (assertions, etc.). */
|
||||
#ifndef SLJIT_DEBUG
|
||||
/* Enabled by default */
|
||||
#define SLJIT_DEBUG 1
|
||||
#endif
|
||||
|
||||
/* Verbose operations */
|
||||
/* Verbose operations. */
|
||||
#ifndef SLJIT_VERBOSE
|
||||
/* Enabled by default */
|
||||
#define SLJIT_VERBOSE 1
|
||||
|
|
|
|||
|
|
@ -28,32 +28,50 @@
|
|||
#define _SLJIT_CONFIG_INTERNAL_H_
|
||||
|
||||
/*
|
||||
SLJIT defines the following macros depending on the target architecture:
|
||||
SLJIT defines the following architecture dependent types and macros:
|
||||
|
||||
Feature detection (boolean) macros:
|
||||
SLJIT_32BIT_ARCHITECTURE : 32 bit architecture
|
||||
SLJIT_64BIT_ARCHITECTURE : 64 bit architecture
|
||||
SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index
|
||||
SLJIT_DOUBLE_SHIFT : the shift required to apply when accessing a double array by index
|
||||
SLJIT_LITTLE_ENDIAN : little endian architecture
|
||||
SLJIT_BIG_ENDIAN : big endian architecture
|
||||
SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!)
|
||||
SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information
|
||||
SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
|
||||
Types:
|
||||
sljit_sb, sljit_ub : signed and unsigned 8 bit byte
|
||||
sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type
|
||||
sljit_si, sljit_ui : signed and unsigned 32 bit integer type
|
||||
sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer
|
||||
sljit_p : unsgined pointer value (usually the same as sljit_uw, but
|
||||
some 64 bit ABIs may use 32 bit pointers)
|
||||
sljit_s : single precision floating point value
|
||||
sljit_d : double precision floating point value
|
||||
|
||||
Types and useful macros:
|
||||
sljit_sb, sljit_ub : signed and unsigned 8 bit byte
|
||||
sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type
|
||||
sljit_si, sljit_ui : signed and unsigned 32 bit integer type
|
||||
sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer
|
||||
sljit_p : unsgined pointer value (usually the same as sljit_uw, but
|
||||
some 64 bit ABIs may use 32 bit pointers)
|
||||
sljit_s : single precision floating point value
|
||||
sljit_d : double precision floating point value
|
||||
SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT
|
||||
SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
|
||||
Macros for feature detection (boolean):
|
||||
SLJIT_32BIT_ARCHITECTURE : 32 bit architecture
|
||||
SLJIT_64BIT_ARCHITECTURE : 64 bit architecture
|
||||
SLJIT_LITTLE_ENDIAN : little endian architecture
|
||||
SLJIT_BIG_ENDIAN : big endian architecture
|
||||
SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!)
|
||||
SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information
|
||||
|
||||
Constants:
|
||||
SLJIT_NUMBER_OF_REGISTERS : number of available registers
|
||||
SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers
|
||||
SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers
|
||||
SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers
|
||||
SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers
|
||||
SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers
|
||||
SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index
|
||||
SLJIT_DOUBLE_SHIFT : the shift required to apply when accessing
|
||||
a double precision floating point array by index
|
||||
SLJIT_SINGLE_SHIFT : the shift required to apply when accessing
|
||||
a single precision floating point array by index
|
||||
SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET)
|
||||
SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
|
||||
|
||||
Other macros:
|
||||
SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT
|
||||
SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
|
||||
*/
|
||||
|
||||
/*****************/
|
||||
/* Sanity check. */
|
||||
/*****************/
|
||||
|
||||
#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
|
||||
|| (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
|
||||
|| (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
|
||||
|
|
@ -71,7 +89,6 @@
|
|||
#error "An architecture must be selected"
|
||||
#endif
|
||||
|
||||
/* Sanity check. */
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
|
||||
+ (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
|
||||
+ (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
|
||||
|
|
@ -89,7 +106,10 @@
|
|||
#error "Multiple architectures are selected"
|
||||
#endif
|
||||
|
||||
/* Auto select option (requires compiler support) */
|
||||
/********************************************************/
|
||||
/* Automatic CPU detection (requires compiler support). */
|
||||
/********************************************************/
|
||||
|
||||
#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
|
||||
|
||||
#ifndef _WIN32
|
||||
|
|
@ -142,26 +162,52 @@
|
|||
#undef SLJIT_EXECUTABLE_ALLOCATOR
|
||||
#endif
|
||||
|
||||
/******************************/
|
||||
/* CPU family type detection. */
|
||||
/******************************/
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
|
||||
|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
||||
#define SLJIT_CONFIG_ARM_32 1
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
#define SLJIT_CONFIG_X86 1
|
||||
#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
||||
#define SLJIT_CONFIG_ARM 1
|
||||
#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
#define SLJIT_CONFIG_PPC 1
|
||||
#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
#define SLJIT_CONFIG_MIPS 1
|
||||
#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) || (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64)
|
||||
#define SLJIT_CONFIG_SPARC 1
|
||||
#endif
|
||||
|
||||
/**********************************/
|
||||
/* External function definitions. */
|
||||
/**********************************/
|
||||
|
||||
#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
|
||||
|
||||
/* These libraries are needed for the macros below. */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#endif /* STD_MACROS_DEFINED */
|
||||
#endif /* SLJIT_STD_MACROS_DEFINED */
|
||||
|
||||
/* General macros:
|
||||
Note: SLJIT is designed to be independent from them as possible.
|
||||
|
||||
In release mode (SLJIT_DEBUG is not defined) only the following macros are needed:
|
||||
In release mode (SLJIT_DEBUG is not defined) only the following
|
||||
external functions are needed:
|
||||
*/
|
||||
|
||||
#ifndef SLJIT_MALLOC
|
||||
#define SLJIT_MALLOC(size) malloc(size)
|
||||
#define SLJIT_MALLOC(size, allocator_data) malloc(size)
|
||||
#endif
|
||||
|
||||
#ifndef SLJIT_FREE
|
||||
#define SLJIT_FREE(ptr) free(ptr)
|
||||
#define SLJIT_FREE(ptr, allocator_data) free(ptr)
|
||||
#endif
|
||||
|
||||
#ifndef SLJIT_MEMMOVE
|
||||
|
|
@ -172,6 +218,10 @@
|
|||
#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)
|
||||
#endif
|
||||
|
||||
/***************************/
|
||||
/* Compiler helper macros. */
|
||||
/***************************/
|
||||
|
||||
#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY)
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 3)
|
||||
|
|
@ -193,6 +243,15 @@
|
|||
#endif
|
||||
#endif /* !SLJIT_INLINE */
|
||||
|
||||
#ifndef SLJIT_NOINLINE
|
||||
/* Not inline functions. */
|
||||
#if defined(__GNUC__)
|
||||
#define SLJIT_NOINLINE __attribute__ ((noinline))
|
||||
#else
|
||||
#define SLJIT_NOINLINE
|
||||
#endif
|
||||
#endif /* !SLJIT_INLINE */
|
||||
|
||||
#ifndef SLJIT_CONST
|
||||
/* Const variables. */
|
||||
#define SLJIT_CONST const
|
||||
|
|
@ -203,6 +262,10 @@
|
|||
#define SLJIT_UNUSED_ARG(arg) (void)arg
|
||||
#endif
|
||||
|
||||
/*********************************/
|
||||
/* Type of public API functions. */
|
||||
/*********************************/
|
||||
|
||||
#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)
|
||||
/* Static ABI functions. For all-in-one programs. */
|
||||
|
||||
|
|
@ -217,9 +280,13 @@
|
|||
#define SLJIT_API_FUNC_ATTRIBUTE
|
||||
#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */
|
||||
|
||||
/****************************/
|
||||
/* Instruction cache flush. */
|
||||
/****************************/
|
||||
|
||||
#ifndef SLJIT_CACHE_FLUSH
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
|
||||
/* Not required to implement on archs with unified caches. */
|
||||
#define SLJIT_CACHE_FLUSH(from, to)
|
||||
|
|
@ -240,7 +307,7 @@
|
|||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
cacheflush((long)(from), (long)(to), 0)
|
||||
|
||||
#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
|
||||
/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
|
|
@ -262,6 +329,10 @@
|
|||
|
||||
#endif /* !SLJIT_CACHE_FLUSH */
|
||||
|
||||
/******************************************************/
|
||||
/* Byte/half/int/word/single/double type definitions. */
|
||||
/******************************************************/
|
||||
|
||||
/* 8 bit byte type. */
|
||||
typedef unsigned char sljit_ub;
|
||||
typedef signed char sljit_sb;
|
||||
|
|
@ -274,7 +345,7 @@ typedef signed short int sljit_sh;
|
|||
typedef unsigned int sljit_ui;
|
||||
typedef signed int sljit_si;
|
||||
|
||||
/* Machine word type. Can encapsulate a pointer.
|
||||
/* Machine word type. Enough for storing a pointer.
|
||||
32 bit for 32 bit machines.
|
||||
64 bit for 64 bit machines. */
|
||||
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
|
|
@ -314,6 +385,7 @@ typedef double sljit_d;
|
|||
|
||||
/* Shift for double precision sized data. */
|
||||
#define SLJIT_DOUBLE_SHIFT 3
|
||||
#define SLJIT_SINGLE_SHIFT 2
|
||||
|
||||
#ifndef SLJIT_W
|
||||
|
||||
|
|
@ -326,44 +398,13 @@ typedef double sljit_d;
|
|||
|
||||
#endif /* !SLJIT_W */
|
||||
|
||||
#ifndef SLJIT_CALL
|
||||
|
||||
/* ABI (Application Binary Interface) types. */
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
|
||||
#define SLJIT_CALL __attribute__ ((fastcall))
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#define SLJIT_CALL __fastcall
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
|
||||
#define SLJIT_CALL __msfastcall
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#else /* Unknown compiler. */
|
||||
|
||||
/* The cdecl attribute is the default. */
|
||||
#define SLJIT_CALL
|
||||
|
||||
#endif
|
||||
|
||||
#else /* Non x86-32 architectures. */
|
||||
|
||||
#define SLJIT_CALL
|
||||
|
||||
#endif /* SLJIT_CONFIG_X86_32 */
|
||||
|
||||
#endif /* !SLJIT_CALL */
|
||||
/*************************/
|
||||
/* Endianness detection. */
|
||||
/*************************/
|
||||
|
||||
#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)
|
||||
|
||||
/* These macros are useful for the applications. */
|
||||
/* These macros are mostly useful for the applications. */
|
||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
|
||||
|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
|
||||
|
|
@ -401,39 +442,6 @@ typedef double sljit_d;
|
|||
#error "Exactly one endianness must be selected"
|
||||
#endif
|
||||
|
||||
#ifndef SLJIT_INDIRECT_CALL
|
||||
#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)) \
|
||||
|| ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX)
|
||||
/* It seems certain ppc compilers use an indirect addressing for functions
|
||||
which makes things complicated. */
|
||||
#define SLJIT_INDIRECT_CALL 1
|
||||
#endif
|
||||
#endif /* SLJIT_INDIRECT_CALL */
|
||||
|
||||
#ifndef SLJIT_RETURN_ADDRESS_OFFSET
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
#define SLJIT_RETURN_ADDRESS_OFFSET 8
|
||||
#else
|
||||
#define SLJIT_RETURN_ADDRESS_OFFSET 0
|
||||
#endif
|
||||
#endif /* SLJIT_RETURN_ADDRESS_OFFSET */
|
||||
|
||||
#ifndef SLJIT_SSE2
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
/* Turn on SSE2 support on x86. */
|
||||
#define SLJIT_SSE2 1
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
/* Auto detect SSE2 support using CPUID.
|
||||
On 64 bit x86 cpus, sse2 must be present. */
|
||||
#define SLJIT_DETECT_SSE2 1
|
||||
#endif
|
||||
|
||||
#endif /* (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) */
|
||||
|
||||
#endif /* !SLJIT_SSE2 */
|
||||
|
||||
#ifndef SLJIT_UNALIGNED
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
|
||||
|
|
@ -448,6 +456,73 @@ typedef double sljit_d;
|
|||
|
||||
#endif /* !SLJIT_UNALIGNED */
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
/* Auto detect SSE2 support using CPUID.
|
||||
On 64 bit x86 cpus, sse2 must be present. */
|
||||
#define SLJIT_DETECT_SSE2 1
|
||||
#endif
|
||||
|
||||
/*****************************************************************************************/
|
||||
/* Calling convention of functions generated by SLJIT or called from the generated code. */
|
||||
/*****************************************************************************************/
|
||||
|
||||
#ifndef SLJIT_CALL
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
|
||||
#define SLJIT_CALL __attribute__ ((fastcall))
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#define SLJIT_CALL __fastcall
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
|
||||
#define SLJIT_CALL __msfastcall
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#else /* Unknown compiler. */
|
||||
|
||||
/* The cdecl attribute is the default. */
|
||||
#define SLJIT_CALL
|
||||
|
||||
#endif
|
||||
|
||||
#else /* Non x86-32 architectures. */
|
||||
|
||||
#define SLJIT_CALL
|
||||
|
||||
#endif /* SLJIT_CONFIG_X86_32 */
|
||||
|
||||
#endif /* !SLJIT_CALL */
|
||||
|
||||
#ifndef SLJIT_INDIRECT_CALL
|
||||
#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)) \
|
||||
|| ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX)
|
||||
/* It seems certain ppc compilers use an indirect addressing for functions
|
||||
which makes things complicated. */
|
||||
#define SLJIT_INDIRECT_CALL 1
|
||||
#endif
|
||||
#endif /* SLJIT_INDIRECT_CALL */
|
||||
|
||||
/* The offset which needs to be substracted from the return address to
|
||||
determine the next executed instruction after return. */
|
||||
#ifndef SLJIT_RETURN_ADDRESS_OFFSET
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
#define SLJIT_RETURN_ADDRESS_OFFSET 8
|
||||
#else
|
||||
#define SLJIT_RETURN_ADDRESS_OFFSET 0
|
||||
#endif
|
||||
#endif /* SLJIT_RETURN_ADDRESS_OFFSET */
|
||||
|
||||
/***************************************************/
|
||||
/* Functions of the built-in executable allocator. */
|
||||
/***************************************************/
|
||||
|
||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
|
||||
|
|
@ -456,6 +531,110 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
|
|||
#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
|
||||
#endif
|
||||
|
||||
/**********************************************/
|
||||
/* Registers and locals offset determination. */
|
||||
/**********************************************/
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 10
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((2 + 4) * sizeof(sljit_sw))
|
||||
#else
|
||||
/* Maximum 3 arguments are passed on the stack, +1 for double alignment. */
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1 + 4) * sizeof(sljit_sw))
|
||||
#endif /* SLJIT_X86_32_FASTCALL */
|
||||
|
||||
#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
|
||||
#ifndef _WIN64
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 12
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (sizeof(sljit_sw))
|
||||
#else
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 12
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((4 + 2) * sizeof(sljit_sw))
|
||||
#endif /* _WIN64 */
|
||||
|
||||
#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 11
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 11
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 25
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (2 * sizeof(sljit_sw))
|
||||
|
||||
#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 22
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * sizeof(sljit_sw))
|
||||
#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
||||
/* Add +1 for double alignment. */
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * sizeof(sljit_sw))
|
||||
#else
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (3 * sizeof(sljit_sw))
|
||||
#endif /* SLJIT_CONFIG_PPC_64 || _AIX */
|
||||
|
||||
#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 17
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (4 * sizeof(sljit_sw))
|
||||
#else
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 18
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 14
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
/* Add +1 for double alignment. */
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw))
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 0
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#endif
|
||||
|
||||
#define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE)
|
||||
|
||||
#define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \
|
||||
(SLJIT_NUMBER_OF_REGISTERS - SLJIT_NUMBER_OF_SAVED_REGISTERS)
|
||||
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 6
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && (defined _WIN64)
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 1
|
||||
#else
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
|
||||
#endif
|
||||
|
||||
#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \
|
||||
(SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS)
|
||||
|
||||
/*************************************/
|
||||
/* Debug and verbose related macros. */
|
||||
/*************************************/
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -56,8 +56,6 @@
|
|||
Disadvantages:
|
||||
- No automatic register allocation, and temporary results are
|
||||
not stored on the stack. (hence the name comes)
|
||||
- Limited number of registers (only 6+4 integer registers, max 3+2
|
||||
scratch, max 3+2 saved and 6 floating point registers)
|
||||
In practice:
|
||||
- This approach is very effective for interpreters
|
||||
- One of the saved registers typically points to a stack interface
|
||||
|
|
@ -97,83 +95,178 @@ of sljitConfigInternal.h */
|
|||
/* Cannot allocate executable memory.
|
||||
Only for sljit_generate_code() */
|
||||
#define SLJIT_ERR_EX_ALLOC_FAILED 3
|
||||
/* return value for SLJIT_CONFIG_UNSUPPORTED empty architecture. */
|
||||
/* Return value for SLJIT_CONFIG_UNSUPPORTED placeholder architecture. */
|
||||
#define SLJIT_ERR_UNSUPPORTED 4
|
||||
/* An ivalid argument is passed to any SLJIT function. */
|
||||
#define SLJIT_ERR_BAD_ARGUMENT 5
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Registers */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
Scratch (R) registers: registers whose may not preserve their values
|
||||
across function calls.
|
||||
|
||||
Saved (S) registers: registers whose preserve their values across
|
||||
function calls.
|
||||
|
||||
The scratch and saved register sets are overlap. The last scratch register
|
||||
is the first saved register, the one before the last is the second saved
|
||||
register, and so on.
|
||||
|
||||
If an architecture provides two scratch and three saved registers,
|
||||
its scratch and saved register sets are the following:
|
||||
|
||||
R0 | [S4] | R0 and S4 represent the same physical register
|
||||
R1 | [S3] | R1 and S3 represent the same physical register
|
||||
[R2] | S2 | R2 and S2 represent the same physical register
|
||||
[R3] | S1 | R3 and S1 represent the same physical register
|
||||
[R4] | S0 | R4 and S0 represent the same physical register
|
||||
|
||||
Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS would be 2 and
|
||||
SLJIT_NUMBER_OF_SAVED_REGISTERS would be 3 for this architecture.
|
||||
|
||||
Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 10
|
||||
and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 5. However, 4 registers
|
||||
are virtual on x86-32. See below.
|
||||
|
||||
The purpose of this definition is convenience. Although a register
|
||||
is either scratch register or saved register, SLJIT allows accessing
|
||||
them from the other set. For example, four registers can be used as
|
||||
scratch registers and the fifth one as saved register on the architecture
|
||||
above. Of course the last two scratch registers (R2 and R3) from this
|
||||
four will be saved on the stack, because they are defined as saved
|
||||
registers in the application binary interface. Still R2 and R3 can be
|
||||
used for referencing to these registers instead of S2 and S1, which
|
||||
makes easier to write platform independent code. Scratch registers
|
||||
can be saved registers in a similar way, but these extra saved
|
||||
registers will not be preserved across function calls! Hence the
|
||||
application must save them on those platforms, where the number of
|
||||
saved registers is too low. This can be done by copy them onto
|
||||
the stack and restore them after a function call.
|
||||
|
||||
Note: To emphasize that registers assigned to R2-R4 are saved
|
||||
registers, they are enclosed by square brackets. S3-S4
|
||||
are marked in a similar way.
|
||||
|
||||
Note: sljit_emit_enter and sljit_set_context defines whether a register
|
||||
is S or R register. E.g: when 3 scratches and 1 saved is mapped
|
||||
by sljit_emit_enter, the allowed register set will be: R0-R2 and
|
||||
S0. Although S2 is mapped to the same position as R2, it does not
|
||||
available in the current configuration. Furthermore the R3 (S1)
|
||||
register does not available as well.
|
||||
*/
|
||||
|
||||
/* When SLJIT_UNUSED is specified as destination, the result is discarded. */
|
||||
#define SLJIT_UNUSED 0
|
||||
|
||||
/* Scratch (temporary) registers whose may not preserve their values
|
||||
across function calls. */
|
||||
#define SLJIT_SCRATCH_REG1 1
|
||||
#define SLJIT_SCRATCH_REG2 2
|
||||
#define SLJIT_SCRATCH_REG3 3
|
||||
/* Note: extra registers cannot be used for memory addressing. */
|
||||
/* Note: on x86-32, these registers are emulated (using stack
|
||||
loads & stores). */
|
||||
#define SLJIT_TEMPORARY_EREG1 4
|
||||
#define SLJIT_TEMPORARY_EREG2 5
|
||||
/* Scratch registers. */
|
||||
#define SLJIT_R0 1
|
||||
#define SLJIT_R1 2
|
||||
#define SLJIT_R2 3
|
||||
/* Note: on x86-32, R3 - R6 (same as S3 - S6) are emulated (they
|
||||
are allocated on the stack). These registers are called virtual
|
||||
and cannot be used for memory addressing (cannot be part of
|
||||
any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such
|
||||
limitation on other CPUs. See sljit_get_register_index(). */
|
||||
#define SLJIT_R3 4
|
||||
#define SLJIT_R4 5
|
||||
#define SLJIT_R5 6
|
||||
#define SLJIT_R6 7
|
||||
#define SLJIT_R7 8
|
||||
#define SLJIT_R8 9
|
||||
#define SLJIT_R9 10
|
||||
/* All R registers provided by the architecture can be accessed by SLJIT_R(i)
|
||||
The i parameter must be >= 0 and < SLJIT_NUMBER_OF_REGISTERS. */
|
||||
#define SLJIT_R(i) (1 + (i))
|
||||
|
||||
/* Saved registers whose preserve their values across function calls. */
|
||||
#define SLJIT_SAVED_REG1 6
|
||||
#define SLJIT_SAVED_REG2 7
|
||||
#define SLJIT_SAVED_REG3 8
|
||||
/* Note: extra registers cannot be used for memory addressing. */
|
||||
/* Note: on x86-32, these registers are emulated (using stack
|
||||
loads & stores). */
|
||||
#define SLJIT_SAVED_EREG1 9
|
||||
#define SLJIT_SAVED_EREG2 10
|
||||
/* Saved registers. */
|
||||
#define SLJIT_S0 (SLJIT_NUMBER_OF_REGISTERS)
|
||||
#define SLJIT_S1 (SLJIT_NUMBER_OF_REGISTERS - 1)
|
||||
#define SLJIT_S2 (SLJIT_NUMBER_OF_REGISTERS - 2)
|
||||
/* Note: on x86-32, S3 - S6 (same as R3 - R6) are emulated (they
|
||||
are allocated on the stack). These registers are called virtual
|
||||
and cannot be used for memory addressing (cannot be part of
|
||||
any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such
|
||||
limitation on other CPUs. See sljit_get_register_index(). */
|
||||
#define SLJIT_S3 (SLJIT_NUMBER_OF_REGISTERS - 3)
|
||||
#define SLJIT_S4 (SLJIT_NUMBER_OF_REGISTERS - 4)
|
||||
#define SLJIT_S5 (SLJIT_NUMBER_OF_REGISTERS - 5)
|
||||
#define SLJIT_S6 (SLJIT_NUMBER_OF_REGISTERS - 6)
|
||||
#define SLJIT_S7 (SLJIT_NUMBER_OF_REGISTERS - 7)
|
||||
#define SLJIT_S8 (SLJIT_NUMBER_OF_REGISTERS - 8)
|
||||
#define SLJIT_S9 (SLJIT_NUMBER_OF_REGISTERS - 9)
|
||||
/* All S registers provided by the architecture can be accessed by SLJIT_S(i)
|
||||
The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_REGISTERS. */
|
||||
#define SLJIT_S(i) (SLJIT_NUMBER_OF_REGISTERS - (i))
|
||||
|
||||
/* Read-only register (cannot be the destination of an operation).
|
||||
Only SLJIT_MEM1(SLJIT_LOCALS_REG) addressing mode is allowed since
|
||||
several ABIs has certain limitations about the stack layout. However
|
||||
sljit_get_local_base() can be used to obtain the offset of a value
|
||||
on the stack. */
|
||||
#define SLJIT_LOCALS_REG 11
|
||||
/* Registers >= SLJIT_FIRST_SAVED_REG are saved registers. */
|
||||
#define SLJIT_FIRST_SAVED_REG (SLJIT_S0 - SLJIT_NUMBER_OF_SAVED_REGISTERS + 1)
|
||||
|
||||
/* Number of registers. */
|
||||
#define SLJIT_NO_TMP_REGISTERS 5
|
||||
#define SLJIT_NO_GEN_REGISTERS 5
|
||||
#define SLJIT_NO_REGISTERS 11
|
||||
/* The SLJIT_SP provides direct access to the linear stack space allocated by
|
||||
sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP).
|
||||
The immediate offset is extended by the relative stack offset automatically.
|
||||
The sljit_get_local_base can be used to obtain the absolute offset. */
|
||||
#define SLJIT_SP (SLJIT_NUMBER_OF_REGISTERS + 1)
|
||||
|
||||
/* Return with machine word. */
|
||||
|
||||
#define SLJIT_RETURN_REG SLJIT_SCRATCH_REG1
|
||||
#define SLJIT_RETURN_REG SLJIT_R0
|
||||
|
||||
/* x86 prefers specific registers for special purposes. In case of shift
|
||||
by register it supports only SLJIT_SCRATCH_REG3 for shift argument
|
||||
by register it supports only SLJIT_R2 for shift argument
|
||||
(which is the src2 argument of sljit_emit_op2). If another register is
|
||||
used, sljit must exchange data between registers which cause a minor
|
||||
slowdown. Other architectures has no such limitation. */
|
||||
|
||||
#define SLJIT_PREF_SHIFT_REG SLJIT_SCRATCH_REG3
|
||||
#define SLJIT_PREF_SHIFT_REG SLJIT_R2
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Floating point registers */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Each floating point register can store a double or single precision
|
||||
value. The FR and FS register sets are overlap in the same way as R
|
||||
and S register sets. See above. */
|
||||
|
||||
/* Note: SLJIT_UNUSED as destination is not valid for floating point
|
||||
operations, since they cannot be used for setting flags. */
|
||||
operations, since they cannot be used for setting flags. */
|
||||
|
||||
/* Floating point operations are performed on double or
|
||||
single precision values. */
|
||||
/* Floating point scratch registers. */
|
||||
#define SLJIT_FR0 1
|
||||
#define SLJIT_FR1 2
|
||||
#define SLJIT_FR2 3
|
||||
#define SLJIT_FR3 4
|
||||
#define SLJIT_FR4 5
|
||||
#define SLJIT_FR5 6
|
||||
/* All FR registers provided by the architecture can be accessed by SLJIT_FR(i)
|
||||
The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */
|
||||
#define SLJIT_FR(i) (1 + (i))
|
||||
|
||||
#define SLJIT_FLOAT_REG1 1
|
||||
#define SLJIT_FLOAT_REG2 2
|
||||
#define SLJIT_FLOAT_REG3 3
|
||||
#define SLJIT_FLOAT_REG4 4
|
||||
#define SLJIT_FLOAT_REG5 5
|
||||
#define SLJIT_FLOAT_REG6 6
|
||||
/* Floating point saved registers. */
|
||||
#define SLJIT_FS0 (SLJIT_NUMBER_OF_FLOAT_REGISTERS)
|
||||
#define SLJIT_FS1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 1)
|
||||
#define SLJIT_FS2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 2)
|
||||
#define SLJIT_FS3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3)
|
||||
#define SLJIT_FS4 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4)
|
||||
#define SLJIT_FS5 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5)
|
||||
/* All S registers provided by the architecture can be accessed by SLJIT_FS(i)
|
||||
The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */
|
||||
#define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i))
|
||||
|
||||
#define SLJIT_NO_FLOAT_REGISTERS 6
|
||||
/* Float registers >= SLJIT_FIRST_SAVED_FLOAT_REG are saved registers. */
|
||||
#define SLJIT_FIRST_SAVED_FLOAT_REG (SLJIT_FS0 - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + 1)
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Main structures and functions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
The following structures are private, and can be changed in the
|
||||
future. Keeping them here allows code inlining.
|
||||
*/
|
||||
|
||||
struct sljit_memory_fragment {
|
||||
struct sljit_memory_fragment *next;
|
||||
sljit_uw used_size;
|
||||
|
|
@ -205,6 +298,7 @@ struct sljit_const {
|
|||
|
||||
struct sljit_compiler {
|
||||
sljit_si error;
|
||||
sljit_si options;
|
||||
|
||||
struct sljit_label *labels;
|
||||
struct sljit_jump *jumps;
|
||||
|
|
@ -213,13 +307,18 @@ struct sljit_compiler {
|
|||
struct sljit_jump *last_jump;
|
||||
struct sljit_const *last_const;
|
||||
|
||||
void *allocator_data;
|
||||
struct sljit_memory_fragment *buf;
|
||||
struct sljit_memory_fragment *abuf;
|
||||
|
||||
/* Used local registers. */
|
||||
/* Used scratch registers. */
|
||||
sljit_si scratches;
|
||||
/* Used saved registers. */
|
||||
sljit_si saveds;
|
||||
/* Used float scratch registers. */
|
||||
sljit_si fscratches;
|
||||
/* Used float saved registers. */
|
||||
sljit_si fsaveds;
|
||||
/* Local stack size. */
|
||||
sljit_si local_size;
|
||||
/* Code size. */
|
||||
|
|
@ -229,16 +328,13 @@ struct sljit_compiler {
|
|||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
sljit_si args;
|
||||
sljit_si locals_offset;
|
||||
sljit_si scratches_start;
|
||||
sljit_si saveds_start;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
sljit_si mode32;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
sljit_si flags_saved;
|
||||
#endif
|
||||
|
||||
|
|
@ -266,18 +362,17 @@ struct sljit_compiler {
|
|||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
||||
sljit_si locals_offset;
|
||||
sljit_si cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
sljit_sw imm;
|
||||
sljit_si cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
||||
sljit_si delay_slot;
|
||||
sljit_si cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
|
|
@ -298,12 +393,15 @@ struct sljit_compiler {
|
|||
FILE* verbose;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|
||||
|| (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
/* Local size passed to the functions. */
|
||||
sljit_si logical_local_size;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|
||||
|| (defined SLJIT_DEBUG && SLJIT_DEBUG) \
|
||||
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
sljit_si skip_checks;
|
||||
#endif
|
||||
};
|
||||
|
|
@ -312,11 +410,16 @@ struct sljit_compiler {
|
|||
/* Main functions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Creates an sljit compiler.
|
||||
Returns NULL if failed. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void);
|
||||
/* Creates an sljit compiler. The allocator_data is required by some
|
||||
custom memory managers. This pointer is passed to SLJIT_MALLOC
|
||||
and SLJIT_FREE macros. Most allocators (including the default
|
||||
one) ignores this value, and it is recommended to pass NULL
|
||||
as a dummy value for allocator_data.
|
||||
|
||||
/* Free everything except the compiled machine code. */
|
||||
Returns NULL if failed. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data);
|
||||
|
||||
/* Frees everything except the compiled machine code. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
|
||||
|
||||
/* Returns the current error code. If an error is occurred, future sljit
|
||||
|
|
@ -326,6 +429,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile
|
|||
these checks increases the performance of the compiling process. */
|
||||
static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
|
||||
|
||||
/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED. After
|
||||
the error code is set, the compiler behaves as if itself detected
|
||||
an allocation failure. This can greatly simplify error management,
|
||||
since only the compiler needs to be checked after compilation. */
|
||||
static SLJIT_INLINE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler) { compiler->error = SLJIT_ERR_ALLOC_FAILED; }
|
||||
|
||||
/*
|
||||
Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
|
||||
and <= 128 bytes on 64 bit architectures. The memory area is owned by the
|
||||
|
|
@ -361,46 +470,69 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler
|
|||
error, they return with SLJIT_SUCCESS. */
|
||||
|
||||
/*
|
||||
The executable code is basically a function call from the viewpoint of
|
||||
the C language. The function calls must obey to the ABI (Application
|
||||
Binary Interface) of the platform, which specify the purpose of machine
|
||||
registers and stack handling among other things. The sljit_emit_enter
|
||||
function emits the necessary instructions for setting up a new context
|
||||
for the executable code and moves function arguments to the saved
|
||||
registers. The number of arguments are specified in the "args"
|
||||
parameter and the first argument goes to SLJIT_SAVED_REG1, the second
|
||||
goes to SLJIT_SAVED_REG2 and so on. The number of scratch and
|
||||
saved registers are passed in "scratches" and "saveds" arguments
|
||||
respectively. Since the saved registers contains the arguments,
|
||||
"args" must be less or equal than "saveds". The sljit_emit_enter
|
||||
is also capable of allocating a stack space for local variables. The
|
||||
"local_size" argument contains the size in bytes of this local area
|
||||
and its staring address is stored in SLJIT_LOCALS_REG. However
|
||||
the SLJIT_LOCALS_REG is not necessary the machine stack pointer.
|
||||
The memory bytes between SLJIT_LOCALS_REG (inclusive) and
|
||||
SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely
|
||||
until the function returns. The stack space is uninitialized.
|
||||
The executable code is a function call from the viewpoint of the C
|
||||
language. The function calls must obey to the ABI (Application
|
||||
Binary Interface) of the platform, which specify the purpose of
|
||||
all machine registers and stack handling among other things. The
|
||||
sljit_emit_enter function emits the necessary instructions for
|
||||
setting up a new context for the executable code and moves function
|
||||
arguments to the saved registers. Furthermore the options argument
|
||||
can be used to pass configuration options to the compiler. The
|
||||
available options are listed before sljit_emit_enter.
|
||||
|
||||
The number of sljit_sw arguments passed to the generated function
|
||||
are specified in the "args" parameter. The number of arguments must
|
||||
be less than or equal to 3. The first argument goes to SLJIT_S0,
|
||||
the second goes to SLJIT_S1 and so on. The register set used by
|
||||
the function must be declared as well. The number of scratch and
|
||||
saved registers used by the function must be passed to sljit_emit_enter.
|
||||
Only R registers between R0 and "scratches" argument can be used
|
||||
later. E.g. if "scratches" is set to 2, the register set will be
|
||||
limited to R0 and R1. The S registers and the floating point
|
||||
registers ("fscratches" and "fsaveds") are specified in a similar
|
||||
way. The sljit_emit_enter is also capable of allocating a stack
|
||||
space for local variables. The "local_size" argument contains the
|
||||
size in bytes of this local area and its staring address is stored
|
||||
in SLJIT_SP. The memory area between SLJIT_SP (inclusive) and
|
||||
SLJIT_SP + local_size (exclusive) can be modified freely until
|
||||
the function returns. The stack space is not initialized.
|
||||
|
||||
Note: the following conditions must met:
|
||||
0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS
|
||||
0 <= saveds <= SLJIT_NUMBER_OF_REGISTERS
|
||||
scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS
|
||||
0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
|
||||
0 <= fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
|
||||
fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
|
||||
|
||||
Note: every call of sljit_emit_enter and sljit_set_context
|
||||
overwrites the previous context. */
|
||||
overwrites the previous context.
|
||||
*/
|
||||
|
||||
/* The absolute address returned by sljit_get_local_base with
|
||||
offset 0 is aligned to sljit_d. Otherwise it is aligned to sljit_uw. */
|
||||
#define SLJIT_DOUBLE_ALIGNMENT 0x00000001
|
||||
|
||||
/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */
|
||||
#define SLJIT_MAX_LOCAL_SIZE 65536
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size);
|
||||
|
||||
/* The machine code has a context (which contains the local stack space size,
|
||||
number of used registers, etc.) which initialized by sljit_emit_enter. Several
|
||||
functions (like sljit_emit_return) requres this context to be able to generate
|
||||
the appropriate code. However, some code fragments (like inline cache) may have
|
||||
no normal entry point so their context is unknown for the compiler. Using the
|
||||
function below we can specify their context.
|
||||
no normal entry point so their context is unknown for the compiler. Their context
|
||||
can be provided to the compiler by the sljit_set_context function.
|
||||
|
||||
Note: every call of sljit_emit_enter and sljit_set_context overwrites
|
||||
the previous context. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size);
|
||||
|
||||
/* Return from machine code. The op argument can be SLJIT_UNUSED which means the
|
||||
function does not return with anything or any opcode between SLJIT_MOV and
|
||||
|
|
@ -549,37 +681,43 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
|||
the instruction does not set flags (See: SLJIT_KEEP_FLAGS).
|
||||
- flag combinations: '|' means 'logical or'. */
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_op0. */
|
||||
#define SLJIT_OP0_BASE 0
|
||||
|
||||
/* Flags: - (never set any flags)
|
||||
Note: breakpoint instruction is not supported by all architectures (namely ppc)
|
||||
It falls back to SLJIT_NOP in those cases. */
|
||||
#define SLJIT_BREAKPOINT 0
|
||||
#define SLJIT_BREAKPOINT (SLJIT_OP0_BASE + 0)
|
||||
/* Flags: - (never set any flags)
|
||||
Note: may or may not cause an extra cycle wait
|
||||
it can even decrease the runtime in a few cases. */
|
||||
#define SLJIT_NOP 1
|
||||
#define SLJIT_NOP (SLJIT_OP0_BASE + 1)
|
||||
/* Flags: - (may destroy flags)
|
||||
Unsigned multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
|
||||
Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
|
||||
#define SLJIT_UMUL 2
|
||||
Unsigned multiplication of SLJIT_R0 and SLJIT_R1.
|
||||
Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
#define SLJIT_LUMUL (SLJIT_OP0_BASE + 2)
|
||||
/* Flags: - (may destroy flags)
|
||||
Signed multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
|
||||
Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
|
||||
#define SLJIT_SMUL 3
|
||||
Signed multiplication of SLJIT_R0 and SLJIT_R1.
|
||||
Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
#define SLJIT_LSMUL (SLJIT_OP0_BASE + 3)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Unsigned divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
|
||||
The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2.
|
||||
Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_UDIV 4
|
||||
#define SLJIT_IUDIV (SLJIT_UDIV | SLJIT_INT_OP)
|
||||
Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1.
|
||||
Note: if SLJIT_R1 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_LUDIV (SLJIT_OP0_BASE + 4)
|
||||
#define SLJIT_ILUDIV (SLJIT_LUDIV | SLJIT_INT_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
|
||||
The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2.
|
||||
Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_SDIV 5
|
||||
#define SLJIT_ISDIV (SLJIT_SDIV | SLJIT_INT_OP)
|
||||
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1.
|
||||
Note: if SLJIT_R1 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_LSDIV (SLJIT_OP0_BASE + 5)
|
||||
#define SLJIT_ILSDIV (SLJIT_LSDIV | SLJIT_INT_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_op1. */
|
||||
#define SLJIT_OP1_BASE 32
|
||||
|
||||
/* Notes for MOV instructions:
|
||||
U = Mov with update (pre form). If source or destination defined as SLJIT_MEM1(r1)
|
||||
or SLJIT_MEM2(r1, r2), r1 is increased by the sum of r2 and the constant argument
|
||||
|
|
@ -592,115 +730,118 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
P = pointer (sljit_p) size */
|
||||
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOV 6
|
||||
#define SLJIT_MOV (SLJIT_OP1_BASE + 0)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_UB 7
|
||||
#define SLJIT_MOV_UB (SLJIT_OP1_BASE + 1)
|
||||
#define SLJIT_IMOV_UB (SLJIT_MOV_UB | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_SB 8
|
||||
#define SLJIT_MOV_SB (SLJIT_OP1_BASE + 2)
|
||||
#define SLJIT_IMOV_SB (SLJIT_MOV_SB | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_UH 9
|
||||
#define SLJIT_MOV_UH (SLJIT_OP1_BASE + 3)
|
||||
#define SLJIT_IMOV_UH (SLJIT_MOV_UH | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_SH 10
|
||||
#define SLJIT_MOV_SH (SLJIT_OP1_BASE + 4)
|
||||
#define SLJIT_IMOV_SH (SLJIT_MOV_SH | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOV_UI 11
|
||||
#define SLJIT_MOV_UI (SLJIT_OP1_BASE + 5)
|
||||
/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOV. */
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOV_SI 12
|
||||
#define SLJIT_MOV_SI (SLJIT_OP1_BASE + 6)
|
||||
#define SLJIT_IMOV (SLJIT_MOV_SI | SLJIT_INT_OP)
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOV_P 13
|
||||
#define SLJIT_MOV_P (SLJIT_OP1_BASE + 7)
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU 14
|
||||
#define SLJIT_MOVU (SLJIT_OP1_BASE + 8)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_UB 15
|
||||
#define SLJIT_MOVU_UB (SLJIT_OP1_BASE + 9)
|
||||
#define SLJIT_IMOVU_UB (SLJIT_MOVU_UB | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_SB 16
|
||||
#define SLJIT_MOVU_SB (SLJIT_OP1_BASE + 10)
|
||||
#define SLJIT_IMOVU_SB (SLJIT_MOVU_SB | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_UH 17
|
||||
#define SLJIT_MOVU_UH (SLJIT_OP1_BASE + 11)
|
||||
#define SLJIT_IMOVU_UH (SLJIT_MOVU_UH | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_SH 18
|
||||
#define SLJIT_MOVU_SH (SLJIT_OP1_BASE + 12)
|
||||
#define SLJIT_IMOVU_SH (SLJIT_MOVU_SH | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOVU_UI 19
|
||||
#define SLJIT_MOVU_UI (SLJIT_OP1_BASE + 13)
|
||||
/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOVU. */
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOVU_SI 20
|
||||
#define SLJIT_MOVU_SI (SLJIT_OP1_BASE + 14)
|
||||
#define SLJIT_IMOVU (SLJIT_MOVU_SI | SLJIT_INT_OP)
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU_P 21
|
||||
#define SLJIT_MOVU_P (SLJIT_OP1_BASE + 15)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_NOT 22
|
||||
#define SLJIT_NOT (SLJIT_OP1_BASE + 16)
|
||||
#define SLJIT_INOT (SLJIT_NOT | SLJIT_INT_OP)
|
||||
/* Flags: I | E | O | K */
|
||||
#define SLJIT_NEG 23
|
||||
#define SLJIT_NEG (SLJIT_OP1_BASE + 17)
|
||||
#define SLJIT_INEG (SLJIT_NEG | SLJIT_INT_OP)
|
||||
/* Count leading zeroes
|
||||
Flags: I | E | K
|
||||
Important note! Sparc 32 does not support K flag, since
|
||||
the required popc instruction is introduced only in sparc 64. */
|
||||
#define SLJIT_CLZ 24
|
||||
#define SLJIT_CLZ (SLJIT_OP1_BASE + 18)
|
||||
#define SLJIT_ICLZ (SLJIT_CLZ | SLJIT_INT_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_op2. */
|
||||
#define SLJIT_OP2_BASE 96
|
||||
|
||||
/* Flags: I | E | O | C | K */
|
||||
#define SLJIT_ADD 25
|
||||
#define SLJIT_ADD (SLJIT_OP2_BASE + 0)
|
||||
#define SLJIT_IADD (SLJIT_ADD | SLJIT_INT_OP)
|
||||
/* Flags: I | C | K */
|
||||
#define SLJIT_ADDC 26
|
||||
#define SLJIT_ADDC (SLJIT_OP2_BASE + 1)
|
||||
#define SLJIT_IADDC (SLJIT_ADDC | SLJIT_INT_OP)
|
||||
/* Flags: I | E | U | S | O | C | K */
|
||||
#define SLJIT_SUB 27
|
||||
#define SLJIT_SUB (SLJIT_OP2_BASE + 2)
|
||||
#define SLJIT_ISUB (SLJIT_SUB | SLJIT_INT_OP)
|
||||
/* Flags: I | C | K */
|
||||
#define SLJIT_SUBC 28
|
||||
#define SLJIT_SUBC (SLJIT_OP2_BASE + 3)
|
||||
#define SLJIT_ISUBC (SLJIT_SUBC | SLJIT_INT_OP)
|
||||
/* Note: integer mul
|
||||
Flags: I | O (see SLJIT_C_MUL_*) | K */
|
||||
#define SLJIT_MUL 29
|
||||
#define SLJIT_MUL (SLJIT_OP2_BASE + 4)
|
||||
#define SLJIT_IMUL (SLJIT_MUL | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_AND 30
|
||||
#define SLJIT_AND (SLJIT_OP2_BASE + 5)
|
||||
#define SLJIT_IAND (SLJIT_AND | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_OR 31
|
||||
#define SLJIT_OR (SLJIT_OP2_BASE + 6)
|
||||
#define SLJIT_IOR (SLJIT_OR | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_XOR 32
|
||||
#define SLJIT_XOR (SLJIT_OP2_BASE + 7)
|
||||
#define SLJIT_IXOR (SLJIT_XOR | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K
|
||||
Let bit_length be the length of the shift operation: 32 or 64.
|
||||
If src2 is immediate, src2w is masked by (bit_length - 1).
|
||||
Otherwise, if the content of src2 is outside the range from 0
|
||||
to bit_length - 1, the operation is undefined. */
|
||||
#define SLJIT_SHL 33
|
||||
to bit_length - 1, the result is undefined. */
|
||||
#define SLJIT_SHL (SLJIT_OP2_BASE + 8)
|
||||
#define SLJIT_ISHL (SLJIT_SHL | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K
|
||||
Let bit_length be the length of the shift operation: 32 or 64.
|
||||
If src2 is immediate, src2w is masked by (bit_length - 1).
|
||||
Otherwise, if the content of src2 is outside the range from 0
|
||||
to bit_length - 1, the operation is undefined. */
|
||||
#define SLJIT_LSHR 34
|
||||
to bit_length - 1, the result is undefined. */
|
||||
#define SLJIT_LSHR (SLJIT_OP2_BASE + 9)
|
||||
#define SLJIT_ILSHR (SLJIT_LSHR | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K
|
||||
Let bit_length be the length of the shift operation: 32 or 64.
|
||||
If src2 is immediate, src2w is masked by (bit_length - 1).
|
||||
Otherwise, if the content of src2 is outside the range from 0
|
||||
to bit_length - 1, the operation is undefined. */
|
||||
#define SLJIT_ASHR 35
|
||||
to bit_length - 1, the result is undefined. */
|
||||
#define SLJIT_ASHR (SLJIT_OP2_BASE + 10)
|
||||
#define SLJIT_IASHR (SLJIT_ASHR | SLJIT_INT_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
|
||||
|
|
@ -709,15 +850,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
sljit_si src2, sljit_sw src2w);
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index of any SLJIT_SCRATCH
|
||||
SLJIT_SAVED or SLJIT_LOCALS register.
|
||||
Note: it returns with -1 for virtual registers (all EREGs on x86-32). */
|
||||
It returns with the real machine register index ( >=0 ) of any SLJIT_R,
|
||||
SLJIT_S and SLJIT_SP registers.
|
||||
|
||||
Note: it returns with -1 for virtual registers (only on x86-32). */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index of any SLJIT_FLOAT register.
|
||||
Note: the index is divided by 2 on ARM 32 bit architectures. */
|
||||
|
||||
Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
|
||||
|
||||
|
|
@ -738,38 +881,62 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void);
|
||||
|
||||
/* Note: dst is the left and src is the right operand for SLJIT_FCMP.
|
||||
Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED is set,
|
||||
the comparison result is unpredictable.
|
||||
/* Starting index of opcodes for sljit_emit_fop1. */
|
||||
#define SLJIT_FOP1_BASE 128
|
||||
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DMOV (SLJIT_FOP1_BASE + 0)
|
||||
#define SLJIT_SMOV (SLJIT_DMOV | SLJIT_SINGLE_OP)
|
||||
/* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE]
|
||||
SRC/DST TYPE can be: D - double, S - single, W - signed word, I - signed int
|
||||
Rounding mode when the destination is W or I: round towards zero. */
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVD_FROMS (SLJIT_FOP1_BASE + 1)
|
||||
#define SLJIT_CONVS_FROMD (SLJIT_CONVD_FROMS | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVW_FROMD (SLJIT_FOP1_BASE + 2)
|
||||
#define SLJIT_CONVW_FROMS (SLJIT_CONVW_FROMD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVI_FROMD (SLJIT_FOP1_BASE + 3)
|
||||
#define SLJIT_CONVI_FROMS (SLJIT_CONVI_FROMD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVD_FROMW (SLJIT_FOP1_BASE + 4)
|
||||
#define SLJIT_CONVS_FROMW (SLJIT_CONVD_FROMW | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVD_FROMI (SLJIT_FOP1_BASE + 5)
|
||||
#define SLJIT_CONVS_FROMI (SLJIT_CONVD_FROMI | SLJIT_SINGLE_OP)
|
||||
/* Note: dst is the left and src is the right operand for SLJIT_CMPD.
|
||||
Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED flag
|
||||
is set, the comparison result is unpredictable.
|
||||
Flags: SP | E | S (see SLJIT_C_FLOAT_*) */
|
||||
#define SLJIT_CMPD 36
|
||||
#define SLJIT_CMPS (SLJIT_CMPD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_DCMP (SLJIT_FOP1_BASE + 6)
|
||||
#define SLJIT_SCMP (SLJIT_DCMP | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_MOVD 37
|
||||
#define SLJIT_MOVS (SLJIT_MOVD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_DNEG (SLJIT_FOP1_BASE + 7)
|
||||
#define SLJIT_SNEG (SLJIT_DNEG | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_NEGD 38
|
||||
#define SLJIT_NEGS (SLJIT_NEGD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_ABSD 39
|
||||
#define SLJIT_ABSS (SLJIT_ABSD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_DABS (SLJIT_FOP1_BASE + 8)
|
||||
#define SLJIT_SABS (SLJIT_DABS | SLJIT_SINGLE_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_fop2. */
|
||||
#define SLJIT_FOP2_BASE 160
|
||||
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_ADDD 40
|
||||
#define SLJIT_ADDS (SLJIT_ADDD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_DADD (SLJIT_FOP2_BASE + 0)
|
||||
#define SLJIT_SADD (SLJIT_DADD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_SUBD 41
|
||||
#define SLJIT_SUBS (SLJIT_SUBD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_DSUB (SLJIT_FOP2_BASE + 1)
|
||||
#define SLJIT_SSUB (SLJIT_DSUB | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_MULD 42
|
||||
#define SLJIT_MULS (SLJIT_MULD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_DMUL (SLJIT_FOP2_BASE + 2)
|
||||
#define SLJIT_SMUL (SLJIT_DMUL | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DIVD 43
|
||||
#define SLJIT_DIVS (SLJIT_DIVD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_DDIV (SLJIT_FOP2_BASE + 3)
|
||||
#define SLJIT_SDIV (SLJIT_DDIV | SLJIT_SINGLE_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
|
|
@ -780,36 +947,64 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);
|
||||
|
||||
/* Invert conditional instruction: xor (^) with 0x1 */
|
||||
#define SLJIT_C_EQUAL 0
|
||||
#define SLJIT_C_ZERO 0
|
||||
#define SLJIT_C_NOT_EQUAL 1
|
||||
#define SLJIT_C_NOT_ZERO 1
|
||||
/* Invert (negate) conditional type: xor (^) with 0x1 */
|
||||
|
||||
#define SLJIT_C_LESS 2
|
||||
#define SLJIT_C_GREATER_EQUAL 3
|
||||
#define SLJIT_C_GREATER 4
|
||||
#define SLJIT_C_LESS_EQUAL 5
|
||||
#define SLJIT_C_SIG_LESS 6
|
||||
#define SLJIT_C_SIG_GREATER_EQUAL 7
|
||||
#define SLJIT_C_SIG_GREATER 8
|
||||
#define SLJIT_C_SIG_LESS_EQUAL 9
|
||||
/* Integer comparison types. */
|
||||
#define SLJIT_EQUAL 0
|
||||
#define SLJIT_I_EQUAL (SLJIT_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_ZERO 0
|
||||
#define SLJIT_I_ZERO (SLJIT_ZERO | SLJIT_INT_OP)
|
||||
#define SLJIT_NOT_EQUAL 1
|
||||
#define SLJIT_I_NOT_EQUAL (SLJIT_NOT_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_NOT_ZERO 1
|
||||
#define SLJIT_I_NOT_ZERO (SLJIT_NOT_ZERO | SLJIT_INT_OP)
|
||||
|
||||
#define SLJIT_C_OVERFLOW 10
|
||||
#define SLJIT_C_NOT_OVERFLOW 11
|
||||
#define SLJIT_LESS 2
|
||||
#define SLJIT_I_LESS (SLJIT_LESS | SLJIT_INT_OP)
|
||||
#define SLJIT_GREATER_EQUAL 3
|
||||
#define SLJIT_I_GREATER_EQUAL (SLJIT_GREATER_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_GREATER 4
|
||||
#define SLJIT_I_GREATER (SLJIT_GREATER | SLJIT_INT_OP)
|
||||
#define SLJIT_LESS_EQUAL 5
|
||||
#define SLJIT_I_LESS_EQUAL (SLJIT_LESS_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_SIG_LESS 6
|
||||
#define SLJIT_I_SIG_LESS (SLJIT_SIG_LESS | SLJIT_INT_OP)
|
||||
#define SLJIT_SIG_GREATER_EQUAL 7
|
||||
#define SLJIT_I_SIG_GREATER_EQUAL (SLJIT_SIG_GREATER_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_SIG_GREATER 8
|
||||
#define SLJIT_I_SIG_GREATER (SLJIT_SIG_GREATER | SLJIT_INT_OP)
|
||||
#define SLJIT_SIG_LESS_EQUAL 9
|
||||
#define SLJIT_I_SIG_LESS_EQUAL (SLJIT_SIG_LESS_EQUAL | SLJIT_INT_OP)
|
||||
|
||||
#define SLJIT_C_MUL_OVERFLOW 12
|
||||
#define SLJIT_C_MUL_NOT_OVERFLOW 13
|
||||
#define SLJIT_OVERFLOW 10
|
||||
#define SLJIT_I_OVERFLOW (SLJIT_OVERFLOW | SLJIT_INT_OP)
|
||||
#define SLJIT_NOT_OVERFLOW 11
|
||||
#define SLJIT_I_NOT_OVERFLOW (SLJIT_NOT_OVERFLOW | SLJIT_INT_OP)
|
||||
|
||||
#define SLJIT_C_FLOAT_EQUAL 14
|
||||
#define SLJIT_C_FLOAT_NOT_EQUAL 15
|
||||
#define SLJIT_C_FLOAT_LESS 16
|
||||
#define SLJIT_C_FLOAT_GREATER_EQUAL 17
|
||||
#define SLJIT_C_FLOAT_GREATER 18
|
||||
#define SLJIT_C_FLOAT_LESS_EQUAL 19
|
||||
#define SLJIT_C_FLOAT_UNORDERED 20
|
||||
#define SLJIT_C_FLOAT_ORDERED 21
|
||||
#define SLJIT_MUL_OVERFLOW 12
|
||||
#define SLJIT_I_MUL_OVERFLOW (SLJIT_MUL_OVERFLOW | SLJIT_INT_OP)
|
||||
#define SLJIT_MUL_NOT_OVERFLOW 13
|
||||
#define SLJIT_I_MUL_NOT_OVERFLOW (SLJIT_MUL_NOT_OVERFLOW | SLJIT_INT_OP)
|
||||
|
||||
/* Floating point comparison types. */
|
||||
#define SLJIT_D_EQUAL 14
|
||||
#define SLJIT_S_EQUAL (SLJIT_D_EQUAL | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_NOT_EQUAL 15
|
||||
#define SLJIT_S_NOT_EQUAL (SLJIT_D_NOT_EQUAL | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_LESS 16
|
||||
#define SLJIT_S_LESS (SLJIT_D_LESS | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_GREATER_EQUAL 17
|
||||
#define SLJIT_S_GREATER_EQUAL (SLJIT_D_GREATER_EQUAL | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_GREATER 18
|
||||
#define SLJIT_S_GREATER (SLJIT_D_GREATER | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_LESS_EQUAL 19
|
||||
#define SLJIT_S_LESS_EQUAL (SLJIT_D_LESS_EQUAL | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_UNORDERED 20
|
||||
#define SLJIT_S_UNORDERED (SLJIT_D_UNORDERED | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_ORDERED 21
|
||||
#define SLJIT_S_ORDERED (SLJIT_D_ORDERED | SLJIT_SINGLE_OP)
|
||||
|
||||
/* Unconditional jump types. */
|
||||
#define SLJIT_JUMP 22
|
||||
#define SLJIT_FAST_CALL 23
|
||||
#define SLJIT_CALL0 24
|
||||
|
|
@ -823,7 +1018,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
#define SLJIT_REWRITABLE_JUMP 0x1000
|
||||
|
||||
/* Emit a jump instruction. The destination is not set, only the type of the jump.
|
||||
type must be between SLJIT_C_EQUAL and SLJIT_CALL3
|
||||
type must be between SLJIT_EQUAL and SLJIT_CALL3
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
Flags: - (never set any flags) for both conditional and unconditional jumps.
|
||||
Flags: destroy all flags for calls. */
|
||||
|
|
@ -832,10 +1027,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
/* Basic arithmetic comparison. In most architectures it is implemented as
|
||||
an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
|
||||
appropriate flags) followed by a sljit_emit_jump. However some
|
||||
architectures (i.e: MIPS) may employ special optimizations here. It is
|
||||
suggested to use this comparison form when appropriate.
|
||||
type must be between SLJIT_C_EQUAL and SLJIT_C_SIG_LESS_EQUAL
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP or SLJIT_INT_OP
|
||||
architectures (i.e: ARM64 or MIPS) may employ special optimizations here.
|
||||
It is suggested to use this comparison form when appropriate.
|
||||
type must be between SLJIT_EQUAL and SLJIT_I_SIG_LESS_EQUAL
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
Flags: destroy flags. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
|
|
@ -846,11 +1041,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
|
|||
sljit_emit_jump. However some architectures (i.e: MIPS) may employ
|
||||
special optimizations here. It is suggested to use this comparison form
|
||||
when appropriate.
|
||||
type must be between SLJIT_C_FLOAT_EQUAL and SLJIT_C_FLOAT_ORDERED
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and SLJIT_SINGLE_OP
|
||||
type must be between SLJIT_D_EQUAL and SLJIT_S_ORDERED
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
Flags: destroy flags.
|
||||
Note: if either operand is NaN, the behaviour is undefined for
|
||||
type <= SLJIT_C_FLOAT_LESS_EQUAL. */
|
||||
types up to SLJIT_S_LESS_EQUAL. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
|
|
@ -869,8 +1064,8 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw);
|
||||
|
||||
/* Perform the operation using the conditional flags as the second argument.
|
||||
Type must always be between SLJIT_C_EQUAL and SLJIT_C_FLOAT_ORDERED. The
|
||||
value represented by the type is 1, if the condition represented by the type
|
||||
Type must always be between SLJIT_EQUAL and SLJIT_S_ORDERED. The value
|
||||
represented by the type is 1, if the condition represented by the type
|
||||
is fulfilled, and 0 otherwise.
|
||||
|
||||
If op == SLJIT_MOV, SLJIT_MOV_SI, SLJIT_MOV_UI:
|
||||
|
|
@ -888,7 +1083,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
sljit_si src, sljit_sw srcw,
|
||||
sljit_si type);
|
||||
|
||||
/* Copies the base address of SLJIT_LOCALS_REG+offset to dst.
|
||||
/* Copies the base address of SLJIT_SP + offset to dst.
|
||||
Flags: - (never set any flags) */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset);
|
||||
|
||||
|
|
@ -912,7 +1107,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define SLJIT_MAJOR_VERSION 0
|
||||
#define SLJIT_MINOR_VERSION 91
|
||||
#define SLJIT_MINOR_VERSION 93
|
||||
|
||||
/* Get the human readable name of the platform. Can be useful on platforms
|
||||
like ARM, where ARM and Thumb2 functions can be mixed, and
|
||||
|
|
@ -958,10 +1153,11 @@ struct sljit_stack {
|
|||
};
|
||||
|
||||
/* Returns NULL if unsuccessful.
|
||||
Note: limit and max_limit contains the size for stack allocation
|
||||
Note: the top field is initialized to base. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack);
|
||||
Note: limit and max_limit contains the size for stack allocation.
|
||||
Note: the top field is initialized to base.
|
||||
Note: see sljit_create_compiler for the explanation of allocator_data. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
|
||||
|
||||
/* Can be used to increase (allocate) or decrease (free) the memory area.
|
||||
Returns with a non-zero value if unsuccessful. If new_limit is greater than
|
||||
|
|
@ -969,7 +1165,7 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* st
|
|||
since the growth ratio can be added to the current limit, and sljit_stack_resize
|
||||
will do all the necessary checks. The fields of the stack are not changed if
|
||||
sljit_stack_resize fails. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack *stack, sljit_uw new_limit);
|
||||
|
||||
#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
|
||||
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
|
|||
}
|
||||
|
||||
/* Last register + 1. */
|
||||
#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
|
||||
#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
|
||||
#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
|
||||
#define TMP_PC (SLJIT_NO_REGISTERS + 4)
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
|
||||
#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 5)
|
||||
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
|
||||
/* In ARM instruction words.
|
||||
Cache lines are usually 32 byte aligned. */
|
||||
|
|
@ -55,8 +55,8 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
|
|||
(((max_diff) / (sljit_si)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))
|
||||
|
||||
/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
|
||||
0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
0, 0, 1, 2, 11, 10, 9, 8, 7, 6, 5, 4, 13, 3, 12, 14, 15
|
||||
};
|
||||
|
||||
#define RM(rm) (reg_map[rm])
|
||||
|
|
@ -102,8 +102,12 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
|
|||
#define VABS_F32 0xeeb00ac0
|
||||
#define VADD_F32 0xee300a00
|
||||
#define VCMP_F32 0xeeb40a40
|
||||
#define VCVT_F32_S32 0xeeb80ac0
|
||||
#define VCVT_F64_F32 0xeeb70ac0
|
||||
#define VCVT_S32_F32 0xeebd0ac0
|
||||
#define VDIV_F32 0xee800a00
|
||||
#define VMOV_F32 0xeeb00a40
|
||||
#define VMOV 0xee000a10
|
||||
#define VMRS 0xeef1fa10
|
||||
#define VMUL_F32 0xee200a00
|
||||
#define VNEG_F32 0xeeb10a40
|
||||
|
|
@ -311,11 +315,13 @@ struct future_patch {
|
|||
sljit_si value;
|
||||
};
|
||||
|
||||
static SLJIT_INLINE sljit_si resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)
|
||||
static sljit_si resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)
|
||||
{
|
||||
sljit_si value;
|
||||
struct future_patch *curr_patch, *prev_patch;
|
||||
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
|
||||
/* Using the values generated by patch_pc_relative_loads. */
|
||||
if (!*first_patch)
|
||||
value = (sljit_si)cpool_start_address[cpool_current_index];
|
||||
|
|
@ -333,7 +339,7 @@ static SLJIT_INLINE sljit_si resolve_const_pool_index(struct future_patch **firs
|
|||
prev_patch->next = curr_patch->next;
|
||||
else
|
||||
*first_patch = curr_patch->next;
|
||||
SLJIT_FREE(curr_patch);
|
||||
SLJIT_FREE(curr_patch, compiler->allocator_data);
|
||||
break;
|
||||
}
|
||||
prev_patch = curr_patch;
|
||||
|
|
@ -343,12 +349,12 @@ static SLJIT_INLINE sljit_si resolve_const_pool_index(struct future_patch **firs
|
|||
|
||||
if (value >= 0) {
|
||||
if ((sljit_uw)value > cpool_current_index) {
|
||||
curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch));
|
||||
curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch), compiler->allocator_data);
|
||||
if (!curr_patch) {
|
||||
while (*first_patch) {
|
||||
curr_patch = *first_patch;
|
||||
*first_patch = (*first_patch)->next;
|
||||
SLJIT_FREE(curr_patch);
|
||||
SLJIT_FREE(curr_patch, compiler->allocator_data);
|
||||
}
|
||||
return SLJIT_ERR_ALLOC_FAILED;
|
||||
}
|
||||
|
|
@ -570,7 +576,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
struct sljit_const *const_;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_generate_code(compiler);
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
/* Second code generation pass. */
|
||||
|
|
@ -619,7 +625,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
cpool_skip_alignment--;
|
||||
}
|
||||
else {
|
||||
if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
|
||||
if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
|
||||
SLJIT_FREE_EXEC(code);
|
||||
compiler->error = SLJIT_ERR_ALLOC_FAILED;
|
||||
return NULL;
|
||||
|
|
@ -709,7 +715,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
buf_end = buf_ptr + compiler->cpool_fill;
|
||||
cpool_current_index = 0;
|
||||
while (buf_ptr < buf_end) {
|
||||
if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
|
||||
if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
|
||||
SLJIT_FREE_EXEC(code);
|
||||
compiler->error = SLJIT_ERR_ALLOC_FAILED;
|
||||
return NULL;
|
||||
|
|
@ -810,9 +816,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
#define SIGNED_DATA 0x40
|
||||
#define LOAD_DATA 0x80
|
||||
|
||||
#define EMIT_INSTRUCTION(inst) \
|
||||
FAIL_IF(push_inst(compiler, (inst)))
|
||||
|
||||
/* Condition: AL. */
|
||||
#define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \
|
||||
(0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2))
|
||||
|
|
@ -822,111 +825,85 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i
|
|||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_si size;
|
||||
sljit_si size, i, tmp;
|
||||
sljit_uw push;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
/* Push saved registers, temporary registers
|
||||
stmdb sp!, {..., lr} */
|
||||
push = PUSH | (1 << 14);
|
||||
if (scratches >= 5)
|
||||
push |= 1 << 11;
|
||||
if (scratches >= 4)
|
||||
push |= 1 << 10;
|
||||
if (saveds >= 5)
|
||||
push |= 1 << 8;
|
||||
if (saveds >= 4)
|
||||
push |= 1 << 7;
|
||||
if (saveds >= 3)
|
||||
push |= 1 << 6;
|
||||
if (saveds >= 2)
|
||||
push |= 1 << 5;
|
||||
if (saveds >= 1)
|
||||
push |= 1 << 4;
|
||||
EMIT_INSTRUCTION(push);
|
||||
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--)
|
||||
push |= 1 << reg_map[i];
|
||||
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
|
||||
push |= 1 << reg_map[i];
|
||||
|
||||
FAIL_IF(push_inst(compiler, push));
|
||||
|
||||
/* Stack must be aligned to 8 bytes: */
|
||||
size = (1 + saveds) * sizeof(sljit_uw);
|
||||
if (scratches >= 4)
|
||||
size += (scratches - 3) * sizeof(sljit_uw);
|
||||
local_size += size;
|
||||
local_size = (local_size + 7) & ~7;
|
||||
local_size -= size;
|
||||
size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
local_size = ((size + local_size + 7) & ~7) - size;
|
||||
compiler->local_size = local_size;
|
||||
if (local_size > 0)
|
||||
FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size));
|
||||
FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size));
|
||||
|
||||
if (args >= 1)
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG1)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S0, SLJIT_UNUSED, RM(SLJIT_R0))));
|
||||
if (args >= 2)
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S1, SLJIT_UNUSED, RM(SLJIT_R1))));
|
||||
if (args >= 3)
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG3)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S2, SLJIT_UNUSED, RM(SLJIT_R2))));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_si size;
|
||||
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
size = (1 + saveds) * sizeof(sljit_uw);
|
||||
if (scratches >= 4)
|
||||
size += (scratches - 3) * sizeof(sljit_uw);
|
||||
local_size += size;
|
||||
local_size = (local_size + 7) & ~7;
|
||||
local_size -= size;
|
||||
compiler->local_size = local_size;
|
||||
size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
compiler->local_size = ((size + local_size + 7) & ~7) - size;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si i, tmp;
|
||||
sljit_uw pop;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
|
||||
if (compiler->local_size > 0)
|
||||
FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
|
||||
FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
|
||||
|
||||
pop = POP | (1 << 15);
|
||||
/* Push saved registers, temporary registers
|
||||
ldmia sp!, {..., pc} */
|
||||
if (compiler->scratches >= 5)
|
||||
pop |= 1 << 11;
|
||||
if (compiler->scratches >= 4)
|
||||
pop |= 1 << 10;
|
||||
if (compiler->saveds >= 5)
|
||||
pop |= 1 << 8;
|
||||
if (compiler->saveds >= 4)
|
||||
pop |= 1 << 7;
|
||||
if (compiler->saveds >= 3)
|
||||
pop |= 1 << 6;
|
||||
if (compiler->saveds >= 2)
|
||||
pop |= 1 << 5;
|
||||
if (compiler->saveds >= 1)
|
||||
pop |= 1 << 4;
|
||||
pop = POP | (1 << 15);
|
||||
|
||||
tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--)
|
||||
pop |= 1 << reg_map[i];
|
||||
|
||||
for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
|
||||
pop |= 1 << reg_map[i];
|
||||
|
||||
return push_inst(compiler, pop);
|
||||
}
|
||||
|
|
@ -1031,7 +1008,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
if (op == SLJIT_MOV_UB)
|
||||
return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff));
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2]));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2])));
|
||||
return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst]));
|
||||
#else
|
||||
return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2));
|
||||
|
|
@ -1050,7 +1027,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
|
||||
if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) {
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2]));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2])));
|
||||
return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst]));
|
||||
#else
|
||||
return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2));
|
||||
|
|
@ -1303,8 +1280,8 @@ static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, slji
|
|||
return 0;
|
||||
}
|
||||
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1));
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2)));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1320,16 +1297,12 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl
|
|||
|
||||
/* Create imm by 1 inst. */
|
||||
tmp = get_imm(imm);
|
||||
if (tmp) {
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp));
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
if (tmp)
|
||||
return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp));
|
||||
|
||||
tmp = get_imm(~imm);
|
||||
if (tmp) {
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp));
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
if (tmp)
|
||||
return push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp));
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
/* Create imm by 2 inst. */
|
||||
|
|
@ -1369,14 +1342,14 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl
|
|||
if (imm) {
|
||||
if (inp_flags & ARG_TEST)
|
||||
return 1;
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm)));
|
||||
return -1;
|
||||
}
|
||||
imm = get_imm(~argw);
|
||||
if (imm) {
|
||||
if (inp_flags & ARG_TEST)
|
||||
return 1;
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm)));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1394,8 +1367,8 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl
|
|||
|
||||
if (inp_flags & ARG_TEST)
|
||||
return 1;
|
||||
EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK,
|
||||
RM(OFFS_REG(arg)) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK,
|
||||
RM(OFFS_REG(arg)) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7))));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -1403,13 +1376,13 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl
|
|||
if (argw >= 0 && argw <= 0xfff) {
|
||||
if (inp_flags & ARG_TEST)
|
||||
return 1;
|
||||
EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, argw));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, argw)));
|
||||
return -1;
|
||||
}
|
||||
if (argw < 0 && argw >= -0xfff) {
|
||||
if (inp_flags & ARG_TEST)
|
||||
return 1;
|
||||
EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, -argw));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, -argw)));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1417,14 +1390,14 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl
|
|||
if (argw >= 0 && argw <= 0xff) {
|
||||
if (inp_flags & ARG_TEST)
|
||||
return 1;
|
||||
EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw))));
|
||||
return -1;
|
||||
}
|
||||
if (argw < 0 && argw >= -0xff) {
|
||||
if (inp_flags & ARG_TEST)
|
||||
return 1;
|
||||
argw = -argw;
|
||||
EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw))));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1477,7 +1450,7 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_
|
|||
/* This can only happen for stores */ \
|
||||
/* since ldr reg, [reg, ...]! has no meaning */ \
|
||||
SLJIT_ASSERT(!(inp_flags & LOAD_DATA)); \
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg))); \
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg)))); \
|
||||
reg = TMP_REG3; \
|
||||
} \
|
||||
}
|
||||
|
|
@ -1537,9 +1510,8 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
|
|||
SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00));
|
||||
if (inp_flags & WRITE_BACK)
|
||||
tmp_r = arg & REG_MASK;
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7)));
|
||||
EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0)));
|
||||
return SLJIT_SUCCESS;
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7))));
|
||||
return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0)));
|
||||
}
|
||||
|
||||
imm = (sljit_uw)(argw - compiler->cache_argw);
|
||||
|
|
@ -1558,7 +1530,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
|
|||
imm = get_imm(argw & ~max_delta);
|
||||
if (imm) {
|
||||
TEST_WRITE_BACK();
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, imm));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, imm)));
|
||||
GETPUT_ARG_DATA_TRANSFER(1, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -1567,15 +1539,14 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
|
|||
if (imm) {
|
||||
argw = -argw;
|
||||
TEST_WRITE_BACK();
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & REG_MASK, imm));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & REG_MASK, imm)));
|
||||
GETPUT_ARG_DATA_TRANSFER(0, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) {
|
||||
TEST_WRITE_BACK();
|
||||
EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
|
||||
return SLJIT_SUCCESS;
|
||||
return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
|
||||
}
|
||||
|
||||
if (argw == next_argw && (next_arg & SLJIT_MEM)) {
|
||||
|
|
@ -1586,15 +1557,14 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
|
|||
compiler->cache_argw = argw;
|
||||
|
||||
TEST_WRITE_BACK();
|
||||
EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
|
||||
return SLJIT_SUCCESS;
|
||||
return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
|
||||
}
|
||||
|
||||
imm = (sljit_uw)(argw - next_argw);
|
||||
if (arg == next_arg && !(inp_flags & WRITE_BACK) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
|
||||
SLJIT_ASSERT(inp_flags & LOAD_DATA);
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & REG_MASK]));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & REG_MASK])));
|
||||
|
||||
compiler->cache_arg = arg;
|
||||
compiler->cache_argw = argw;
|
||||
|
|
@ -1610,8 +1580,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
|
|||
}
|
||||
|
||||
FAIL_IF(load_immediate(compiler, tmp_r, argw));
|
||||
EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0)));
|
||||
return SLJIT_SUCCESS;
|
||||
return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0)));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
|
||||
|
|
@ -1838,39 +1807,39 @@ extern int __aeabi_idivmod(int numerator, int denominator);
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op0(compiler, op);
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
switch (op) {
|
||||
case SLJIT_BREAKPOINT:
|
||||
EMIT_INSTRUCTION(BKPT);
|
||||
FAIL_IF(push_inst(compiler, BKPT));
|
||||
break;
|
||||
case SLJIT_NOP:
|
||||
EMIT_INSTRUCTION(NOP);
|
||||
FAIL_IF(push_inst(compiler, NOP));
|
||||
break;
|
||||
case SLJIT_UMUL:
|
||||
case SLJIT_SMUL:
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
|
||||
| (reg_map[SLJIT_SCRATCH_REG2] << 16)
|
||||
| (reg_map[SLJIT_SCRATCH_REG1] << 12)
|
||||
| (reg_map[SLJIT_SCRATCH_REG1] << 8)
|
||||
| reg_map[SLJIT_SCRATCH_REG2]);
|
||||
return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL)
|
||||
| (reg_map[SLJIT_R1] << 16)
|
||||
| (reg_map[SLJIT_R0] << 12)
|
||||
| (reg_map[SLJIT_R0] << 8)
|
||||
| reg_map[SLJIT_R1]);
|
||||
#else
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2)));
|
||||
return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
|
||||
| (reg_map[SLJIT_SCRATCH_REG2] << 16)
|
||||
| (reg_map[SLJIT_SCRATCH_REG1] << 12)
|
||||
| (reg_map[SLJIT_SCRATCH_REG1] << 8)
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_R1))));
|
||||
return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL)
|
||||
| (reg_map[SLJIT_R1] << 16)
|
||||
| (reg_map[SLJIT_R0] << 12)
|
||||
| (reg_map[SLJIT_R0] << 8)
|
||||
| reg_map[TMP_REG1]);
|
||||
#endif
|
||||
case SLJIT_UDIV:
|
||||
case SLJIT_SDIV:
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
if (compiler->scratches >= 3)
|
||||
EMIT_INSTRUCTION(0xe52d2008 /* str r2, [sp, #-8]! */);
|
||||
FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */));
|
||||
#if defined(__GNUC__)
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
||||
(op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
(op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
#else
|
||||
#error "Software divmod functions are needed"
|
||||
#endif
|
||||
|
|
@ -1887,7 +1856,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
|
|
@ -1932,7 +1901,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_NEG:
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
return sljit_emit_op2(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw);
|
||||
|
|
@ -1950,7 +1920,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
|
@ -1988,22 +1958,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
return reg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_float_register_index(reg);
|
||||
return reg;
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg << 1;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_si size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_custom(compiler, instruction, size);
|
||||
SLJIT_ASSERT(size == 4);
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
|
||||
return push_inst(compiler, *(sljit_uw*)instruction);
|
||||
}
|
||||
|
|
@ -2064,7 +2033,7 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
|
|||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
|
||||
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7))));
|
||||
arg = SLJIT_MEM | TMP_REG1;
|
||||
argw = 0;
|
||||
}
|
||||
|
|
@ -2097,13 +2066,13 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
|
|||
}
|
||||
imm = get_imm(argw & ~0x3fc);
|
||||
if (imm) {
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, imm));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, imm)));
|
||||
return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2));
|
||||
}
|
||||
imm = get_imm(-argw & ~0x3fc);
|
||||
if (imm) {
|
||||
argw = -argw;
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & REG_MASK, imm));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & REG_MASK, imm)));
|
||||
return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2));
|
||||
}
|
||||
}
|
||||
|
|
@ -2112,7 +2081,7 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
|
|||
compiler->cache_argw = argw;
|
||||
if (arg & REG_MASK) {
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, argw));
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & REG_MASK, reg_map[TMP_REG1]));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & REG_MASK, reg_map[TMP_REG1])));
|
||||
}
|
||||
else
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
|
||||
|
|
@ -2120,60 +2089,114 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
|
|||
return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw));
|
||||
src = TMP_FREG1;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_SINGLE_OP, TMP_FREG1, src, 0)));
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
if (FAST_IS_REG(dst))
|
||||
return push_inst(compiler, VMOV | (1 << 20) | RD(dst) | (TMP_FREG1 << 16));
|
||||
|
||||
/* Store the integer value from a VFP register. */
|
||||
return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, VMOV | RD(src) | (TMP_FREG1 << 16)));
|
||||
else if (src & SLJIT_MEM) {
|
||||
/* Load the integer value into a VFP register. */
|
||||
FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw));
|
||||
}
|
||||
else {
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
|
||||
FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | (TMP_FREG1 << 16)));
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_SINGLE_OP, dst_r, TMP_FREG1, 0)));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
if (src1 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w));
|
||||
src1 = TMP_FREG1;
|
||||
}
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w));
|
||||
src2 = TMP_FREG2;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, src1, src2, 0)));
|
||||
return push_inst(compiler, VMRS);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_fr;
|
||||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
if (GET_OPCODE(op) != SLJIT_CONVD_FROMS)
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CMPD) {
|
||||
if (dst & SLJIT_MEM) {
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, dst, dstw));
|
||||
dst = TMP_FREG1;
|
||||
}
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw));
|
||||
src = TMP_FREG2;
|
||||
}
|
||||
EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, dst, src, 0));
|
||||
EMIT_INSTRUCTION(VMRS);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
dst_fr = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_fr, src, srcw));
|
||||
src = dst_fr;
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw));
|
||||
src = dst_r;
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOVD:
|
||||
if (src != dst_fr && dst_fr != TMP_FREG1)
|
||||
EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0));
|
||||
break;
|
||||
case SLJIT_NEGD:
|
||||
EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0));
|
||||
break;
|
||||
case SLJIT_ABSD:
|
||||
EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst_fr == TMP_FREG1) {
|
||||
if (GET_OPCODE(op) == SLJIT_MOVD)
|
||||
dst_fr = src;
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_fr, dst, dstw));
|
||||
case SLJIT_DMOV:
|
||||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1)
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0)));
|
||||
else
|
||||
dst_r = src;
|
||||
}
|
||||
break;
|
||||
case SLJIT_DNEG:
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0)));
|
||||
break;
|
||||
case SLJIT_DABS:
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0)));
|
||||
break;
|
||||
case SLJIT_CONVD_FROMS:
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0)));
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -2182,16 +2205,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si dst_fr;
|
||||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
|
||||
dst_fr = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w));
|
||||
|
|
@ -2204,24 +2230,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_ADDD:
|
||||
EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1));
|
||||
case SLJIT_DADD:
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1)));
|
||||
break;
|
||||
|
||||
case SLJIT_SUBD:
|
||||
EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1));
|
||||
case SLJIT_DSUB:
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1)));
|
||||
break;
|
||||
|
||||
case SLJIT_MULD:
|
||||
EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1));
|
||||
case SLJIT_DMUL:
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1)));
|
||||
break;
|
||||
|
||||
case SLJIT_DIVD:
|
||||
EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1));
|
||||
case SLJIT_DDIV:
|
||||
FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst_fr == TMP_FREG1)
|
||||
if (dst_r == TMP_FREG1)
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
|
@ -2238,7 +2264,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
/* For UNUSED dst. Uncommon, but possible. */
|
||||
|
|
@ -2252,7 +2278,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
|||
if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw))
|
||||
return compiler->error;
|
||||
/* TMP_REG3 is used for caching. */
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3))));
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0);
|
||||
|
|
@ -2261,11 +2287,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src))));
|
||||
else if (src & SLJIT_MEM) {
|
||||
if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw))
|
||||
FAIL_IF(compiler->error);
|
||||
|
|
@ -2273,7 +2299,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
|||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
FAIL_IF(getput_arg(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, 0, 0));
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2)));
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2))));
|
||||
}
|
||||
}
|
||||
else if (src & SLJIT_IMM)
|
||||
|
|
@ -2288,53 +2314,54 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
|||
static sljit_uw get_cc(sljit_si type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_C_EQUAL:
|
||||
case SLJIT_C_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_EQUAL:
|
||||
case SLJIT_EQUAL:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_D_EQUAL:
|
||||
return 0x00000000;
|
||||
|
||||
case SLJIT_C_NOT_EQUAL:
|
||||
case SLJIT_C_MUL_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_NOT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
case SLJIT_D_NOT_EQUAL:
|
||||
return 0x10000000;
|
||||
|
||||
case SLJIT_C_LESS:
|
||||
case SLJIT_C_FLOAT_LESS:
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_LESS:
|
||||
return 0x30000000;
|
||||
|
||||
case SLJIT_C_GREATER_EQUAL:
|
||||
case SLJIT_C_FLOAT_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_GREATER_EQUAL:
|
||||
return 0x20000000;
|
||||
|
||||
case SLJIT_C_GREATER:
|
||||
case SLJIT_C_FLOAT_GREATER:
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER:
|
||||
return 0x80000000;
|
||||
|
||||
case SLJIT_C_LESS_EQUAL:
|
||||
case SLJIT_C_FLOAT_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
return 0x90000000;
|
||||
|
||||
case SLJIT_C_SIG_LESS:
|
||||
case SLJIT_SIG_LESS:
|
||||
return 0xb0000000;
|
||||
|
||||
case SLJIT_C_SIG_GREATER_EQUAL:
|
||||
case SLJIT_SIG_GREATER_EQUAL:
|
||||
return 0xa0000000;
|
||||
|
||||
case SLJIT_C_SIG_GREATER:
|
||||
case SLJIT_SIG_GREATER:
|
||||
return 0xc0000000;
|
||||
|
||||
case SLJIT_C_SIG_LESS_EQUAL:
|
||||
case SLJIT_SIG_LESS_EQUAL:
|
||||
return 0xd0000000;
|
||||
|
||||
case SLJIT_C_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_UNORDERED:
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_D_UNORDERED:
|
||||
return 0x60000000;
|
||||
|
||||
case SLJIT_C_NOT_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_ORDERED:
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_D_ORDERED:
|
||||
return 0x70000000;
|
||||
|
||||
default: /* SLJIT_JUMP */
|
||||
default:
|
||||
SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
|
||||
return 0xe0000000;
|
||||
}
|
||||
}
|
||||
|
|
@ -2344,7 +2371,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
struct sljit_label *label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_label(compiler);
|
||||
CHECK_PTR(check_sljit_emit_label(compiler));
|
||||
|
||||
if (compiler->last_label && compiler->last_label->size == compiler->size)
|
||||
return compiler->last_label;
|
||||
|
|
@ -2360,7 +2387,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
struct sljit_jump *jump;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_jump(compiler, type);
|
||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF(!jump);
|
||||
|
|
@ -2401,7 +2428,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
|||
struct sljit_jump *jump;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_ijump(compiler, type, src, srcw);
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
/* In ARM, we don't need to touch the arguments. */
|
||||
|
|
@ -2442,7 +2469,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
sljit_uw cc, ins;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
|
||||
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
|
|
@ -2450,18 +2477,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
return SLJIT_SUCCESS;
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
cc = get_cc(type);
|
||||
cc = get_cc(type & 0xff);
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
|
||||
|
||||
if (op < SLJIT_ADD) {
|
||||
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0));
|
||||
EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc);
|
||||
FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0)));
|
||||
FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc));
|
||||
return (dst_r == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
ins = (op == SLJIT_AND ? AND_DP : (op == SLJIT_OR ? ORR_DP : EOR_DP));
|
||||
if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) {
|
||||
EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc);
|
||||
FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc));
|
||||
/* The condition must always be set, even if the ORR/EOR is not executed above. */
|
||||
return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -2478,8 +2505,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
srcw = 0;
|
||||
}
|
||||
|
||||
EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc);
|
||||
EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000));
|
||||
FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc));
|
||||
FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)));
|
||||
if (dst_r == TMP_REG2)
|
||||
FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0));
|
||||
|
||||
|
|
@ -2492,7 +2519,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
|||
sljit_si reg;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_const(compiler, dst, dstw, init_value);
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
|
||||
|
|
|
|||
|
|
@ -32,20 +32,19 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
|
|||
/* Length of an instruction word */
|
||||
typedef sljit_ui sljit_ins;
|
||||
|
||||
#define TMP_ZERO 0
|
||||
#define TMP_ZERO (0)
|
||||
|
||||
#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
|
||||
#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
|
||||
#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
|
||||
#define TMP_REG4 (SLJIT_NO_REGISTERS + 4)
|
||||
#define TMP_LR (SLJIT_NO_REGISTERS + 5)
|
||||
#define TMP_SP (SLJIT_NO_REGISTERS + 6)
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
|
||||
#define TMP_LR (SLJIT_NUMBER_OF_REGISTERS + 5)
|
||||
#define TMP_SP (SLJIT_NUMBER_OF_REGISTERS + 6)
|
||||
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = {
|
||||
31, 0, 1, 2, 3, 4, 19, 20, 21, 22, 23, 29, 9, 10, 11, 12, 30, 31
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {
|
||||
31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31
|
||||
};
|
||||
|
||||
#define W_OP (1 << 31)
|
||||
|
|
@ -83,6 +82,8 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = {
|
|||
#define FABS 0x1e60c000
|
||||
#define FADD 0x1e602800
|
||||
#define FCMP 0x1e602000
|
||||
#define FCVT 0x1e224000
|
||||
#define FCVTZS 0x9e780000
|
||||
#define FDIV 0x1e601800
|
||||
#define FMOV 0x1e604000
|
||||
#define FMUL 0x1e600800
|
||||
|
|
@ -104,6 +105,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = {
|
|||
#define RET 0xd65f0000
|
||||
#define SBC 0xda000000
|
||||
#define SBFM 0x93000000
|
||||
#define SCVTF 0x9e620000
|
||||
#define SDIV 0x9ac00c00
|
||||
#define SMADDL 0x9b200000
|
||||
#define SMULH 0x9b403c00
|
||||
|
|
@ -217,7 +219,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
struct sljit_const *const_;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_generate_code(compiler);
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
|
||||
|
|
@ -727,12 +729,12 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
|
|||
return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO));
|
||||
if (flags & INT_OP) {
|
||||
FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10)));
|
||||
FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG4) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10)));
|
||||
return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_REG4) | RM(dst) | (2 << 22) | (63 << 10));
|
||||
FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10)));
|
||||
return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, SMULH | RD(TMP_REG4) | RN(arg1) | RM(arg2)));
|
||||
FAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2)));
|
||||
FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_REG4) | RM(dst) | (2 << 22) | (63 << 10));
|
||||
return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
|
||||
case SLJIT_AND:
|
||||
CHECK_FLAGS(3 << 29);
|
||||
return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
|
||||
|
|
@ -973,9 +975,9 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji
|
|||
FAIL_IF(push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10)));
|
||||
return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg));
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG4) | RN(arg) | RM(other_r) | (argw << 10)));
|
||||
FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG4)));
|
||||
return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_REG4));
|
||||
FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(arg) | RM(other_r) | (argw << 10)));
|
||||
FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_LR)));
|
||||
return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_LR));
|
||||
}
|
||||
|
||||
if (arg & OFFS_REG_MASK) {
|
||||
|
|
@ -1058,109 +1060,153 @@ static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit
|
|||
/* Entry, exit */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
sljit_si i, tmp, offs, prev, saved_regs_size;
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
compiler->locals_offset = (2 + saveds) * sizeof(sljit_sw);
|
||||
local_size = (compiler->locals_offset + local_size + 15) & ~15;
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0);
|
||||
local_size += saved_regs_size + SLJIT_LOCALS_OFFSET;
|
||||
local_size = (local_size + 15) & ~0xf;
|
||||
compiler->local_size = local_size;
|
||||
|
||||
if (local_size <= (64 << 3))
|
||||
if (local_size <= (63 * sizeof(sljit_sw))) {
|
||||
FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
|
||||
| RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15)));
|
||||
else {
|
||||
local_size -= (64 << 3);
|
||||
FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
|
||||
offs = (local_size - saved_regs_size) << (15 - 3);
|
||||
} else {
|
||||
compiler->local_size += 2 * sizeof(sljit_sw);
|
||||
local_size -= saved_regs_size;
|
||||
saved_regs_size += 2 * sizeof(sljit_sw);
|
||||
FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
|
||||
| RN(TMP_SP) | ((-(saved_regs_size >> 3) & 0x7f) << 15)));
|
||||
offs = 2 << 15;
|
||||
}
|
||||
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
prev = -1;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
offs += 2 << 15;
|
||||
prev = -1;
|
||||
}
|
||||
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
offs += 2 << 15;
|
||||
prev = -1;
|
||||
}
|
||||
|
||||
if (prev != -1)
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(prev) | RN(TMP_SP) | (offs >> 5)));
|
||||
|
||||
if (compiler->local_size > (63 * sizeof(sljit_sw))) {
|
||||
/* The local_size is already adjusted by the saved registers. */
|
||||
if (local_size > 0xfff) {
|
||||
FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22)));
|
||||
local_size &= 0xfff;
|
||||
}
|
||||
if (local_size)
|
||||
FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
|
||||
FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) | RN(TMP_SP) | (0x40 << 15)));
|
||||
FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_LOCALS_REG) | RN(TMP_SP)));
|
||||
|
||||
if (saveds >= 2)
|
||||
FAIL_IF(push_inst(compiler, STP | RT(SLJIT_SAVED_REG1) | RT2(SLJIT_SAVED_REG2) | RN(TMP_SP) | (2 << 15)));
|
||||
if (saveds >= 4)
|
||||
FAIL_IF(push_inst(compiler, STP | RT(SLJIT_SAVED_REG3) | RT2(SLJIT_SAVED_EREG1) | RN(TMP_SP) | (4 << 15)));
|
||||
if (saveds == 1)
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(SLJIT_SAVED_REG1) | RN(TMP_SP) | (2 << 10)));
|
||||
if (saveds == 3)
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(SLJIT_SAVED_REG3) | RN(TMP_SP) | (4 << 10)));
|
||||
if (saveds == 5)
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(SLJIT_SAVED_EREG2) | RN(TMP_SP) | (6 << 10)));
|
||||
|
||||
if (args >= 1)
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_SAVED_REG1) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG1)));
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
||||
if (args >= 2)
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_SAVED_REG2) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S1) | RN(TMP_ZERO) | RM(SLJIT_R1)));
|
||||
if (args >= 3)
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_SAVED_REG3) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG3)));
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S2) | RN(TMP_ZERO) | RM(SLJIT_R2)));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
compiler->locals_offset = (2 + saveds) * sizeof(sljit_sw);
|
||||
compiler->local_size = (compiler->locals_offset + local_size + 15) & ~15;
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET;
|
||||
local_size = (local_size + 15) & ~0xf;
|
||||
if (local_size > (63 * sizeof(sljit_sw)))
|
||||
local_size += 2 * sizeof(sljit_sw);
|
||||
compiler->local_size = local_size;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si saveds, local_size;
|
||||
sljit_si local_size;
|
||||
sljit_si i, tmp, offs, prev, saved_regs_size;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
|
||||
saveds = compiler->saveds;
|
||||
|
||||
if (saveds >= 2)
|
||||
FAIL_IF(push_inst(compiler, LDP | RT(SLJIT_SAVED_REG1) | RT2(SLJIT_SAVED_REG2) | RN(TMP_SP) | (2 << 15)));
|
||||
if (saveds >= 4)
|
||||
FAIL_IF(push_inst(compiler, LDP | RT(SLJIT_SAVED_REG3) | RT2(SLJIT_SAVED_EREG1) | RN(TMP_SP) | (4 << 15)));
|
||||
if (saveds == 1)
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(SLJIT_SAVED_REG1) | RN(TMP_SP) | (2 << 10)));
|
||||
if (saveds == 3)
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(SLJIT_SAVED_REG3) | RN(TMP_SP) | (4 << 10)));
|
||||
if (saveds == 5)
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(SLJIT_SAVED_EREG2) | RN(TMP_SP) | (6 << 10)));
|
||||
|
||||
local_size = compiler->local_size;
|
||||
|
||||
if (local_size <= (62 << 3))
|
||||
FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
|
||||
| RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
|
||||
saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0);
|
||||
if (local_size <= (63 * sizeof(sljit_sw)))
|
||||
offs = (local_size - saved_regs_size) << (15 - 3);
|
||||
else {
|
||||
FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) | RN(TMP_SP) | (0x3e << 15)));
|
||||
local_size -= (62 << 3);
|
||||
saved_regs_size += 2 * sizeof(sljit_sw);
|
||||
local_size -= saved_regs_size;
|
||||
if (local_size > 0xfff) {
|
||||
FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22)));
|
||||
local_size &= 0xfff;
|
||||
}
|
||||
if (local_size)
|
||||
FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
|
||||
local_size = saved_regs_size;
|
||||
offs = 2 << 15;
|
||||
}
|
||||
|
||||
tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
prev = -1;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
offs += 2 << 15;
|
||||
prev = -1;
|
||||
}
|
||||
|
||||
for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
offs += 2 << 15;
|
||||
prev = -1;
|
||||
}
|
||||
|
||||
if (prev != -1)
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(TMP_SP) | (offs >> 5)));
|
||||
|
||||
FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
|
||||
| RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
|
||||
|
||||
FAIL_IF(push_inst(compiler, RET | RN(TMP_LR)));
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -1174,7 +1220,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
sljit_ins inv_bits = (op & SLJIT_INT_OP) ? (1 << 31) : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op0(compiler, op);
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
switch (op) {
|
||||
|
|
@ -1182,17 +1228,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
return push_inst(compiler, BRK);
|
||||
case SLJIT_NOP:
|
||||
return push_inst(compiler, NOP);
|
||||
case SLJIT_UMUL:
|
||||
case SLJIT_SMUL:
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG1)));
|
||||
FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_SCRATCH_REG1) | RN(SLJIT_SCRATCH_REG1) | RM(SLJIT_SCRATCH_REG2) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (op == SLJIT_SMUL ? SMULH : UMULH) | RD(SLJIT_SCRATCH_REG2) | RN(TMP_REG1) | RM(SLJIT_SCRATCH_REG2));
|
||||
case SLJIT_UDIV:
|
||||
case SLJIT_SDIV:
|
||||
FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_SCRATCH_REG1)));
|
||||
FAIL_IF(push_inst(compiler, ((op == SLJIT_SDIV ? SDIV : UDIV) ^ inv_bits) | RD(SLJIT_SCRATCH_REG1) | RN(SLJIT_SCRATCH_REG1) | RM(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_SCRATCH_REG2) | RN(SLJIT_SCRATCH_REG1) | RM(SLJIT_SCRATCH_REG2) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_SCRATCH_REG2) | RN(TMP_REG1) | RM(SLJIT_SCRATCH_REG2));
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, ((op == SLJIT_LUDIV ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
|
@ -1206,7 +1252,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
sljit_si op_flags = GET_ALL_FLAGS(op);
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
|
|
@ -1358,7 +1404,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
sljit_si dst_r, flags, mem_flags;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
|
@ -1437,13 +1483,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
return reg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_float_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
|
@ -1451,8 +1497,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co
|
|||
void *instruction, sljit_si size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_custom(compiler, instruction, size);
|
||||
SLJIT_ASSERT(size == 4);
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
|
||||
return push_inst(compiler, *(sljit_ins*)instruction);
|
||||
}
|
||||
|
|
@ -1524,53 +1569,122 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
|
|||
return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
|
||||
sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CONVI_FROMD)
|
||||
inv_bits |= (1 << 31);
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw);
|
||||
src = TMP_FREG1;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src)));
|
||||
|
||||
if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED)
|
||||
return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
|
||||
inv_bits |= (1 << 31);
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw);
|
||||
src = TMP_REG1;
|
||||
} else if (src & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
|
||||
srcw = (sljit_si)srcw;
|
||||
#endif
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
|
||||
src = TMP_REG1;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src)));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_fop_mem(compiler, ((op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
|
||||
sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
|
||||
if (src1 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
|
||||
src1 = TMP_FREG1;
|
||||
}
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);
|
||||
src2 = TMP_FREG2;
|
||||
}
|
||||
|
||||
return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2));
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
|
||||
sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
sljit_ins inv_bits;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CMPD) {
|
||||
if (dst & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, mem_flags, TMP_FREG1, dst, dstw);
|
||||
dst = TMP_FREG1;
|
||||
}
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, mem_flags, TMP_FREG2, src, srcw);
|
||||
src = TMP_FREG2;
|
||||
}
|
||||
return push_inst(compiler, (FCMP ^ inv_bits) | VN(dst) | VM(src));
|
||||
}
|
||||
SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
dst_r = (dst <= REG_MASK) ? dst : TMP_FREG1;
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, mem_flags, dst_r, src, srcw);
|
||||
emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONVD_FROMS) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw);
|
||||
src = dst_r;
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOVD:
|
||||
if (src != dst_r)
|
||||
FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));
|
||||
case SLJIT_DMOV:
|
||||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1)
|
||||
FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));
|
||||
else
|
||||
dst_r = src;
|
||||
}
|
||||
break;
|
||||
case SLJIT_NEGD:
|
||||
case SLJIT_DNEG:
|
||||
FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src)));
|
||||
break;
|
||||
case SLJIT_ABSD:
|
||||
case SLJIT_DABS:
|
||||
FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src)));
|
||||
break;
|
||||
case SLJIT_CONVD_FROMS:
|
||||
FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_SINGLE_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(dst & SLJIT_MEM))
|
||||
return SLJIT_SUCCESS;
|
||||
return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw);
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
|
||||
|
|
@ -1582,12 +1696,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
dst_r = (dst <= REG_MASK) ? dst : TMP_FREG1;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
if (src1 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
|
||||
src1 = TMP_FREG1;
|
||||
|
|
@ -1598,16 +1715,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_ADDD:
|
||||
case SLJIT_DADD:
|
||||
FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
|
||||
break;
|
||||
case SLJIT_SUBD:
|
||||
case SLJIT_DSUB:
|
||||
FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
|
||||
break;
|
||||
case SLJIT_MULD:
|
||||
case SLJIT_DMUL:
|
||||
FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
|
||||
break;
|
||||
case SLJIT_DIVD:
|
||||
case SLJIT_DDIV:
|
||||
FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
|
||||
break;
|
||||
}
|
||||
|
|
@ -1624,14 +1741,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
/* For UNUSED dst. Uncommon, but possible. */
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
if (dst <= REG_MASK)
|
||||
if (FAST_IS_REG(dst))
|
||||
return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR));
|
||||
|
||||
/* Memory. */
|
||||
|
|
@ -1641,10 +1758,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (src <= REG_MASK)
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
|
||||
else if (src & SLJIT_MEM)
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw));
|
||||
|
|
@ -1661,50 +1778,50 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
|||
static sljit_uw get_cc(sljit_si type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_C_EQUAL:
|
||||
case SLJIT_C_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_EQUAL:
|
||||
case SLJIT_EQUAL:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_D_EQUAL:
|
||||
return 0x1;
|
||||
|
||||
case SLJIT_C_NOT_EQUAL:
|
||||
case SLJIT_C_MUL_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_NOT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
case SLJIT_D_NOT_EQUAL:
|
||||
return 0x0;
|
||||
|
||||
case SLJIT_C_LESS:
|
||||
case SLJIT_C_FLOAT_LESS:
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_LESS:
|
||||
return 0x2;
|
||||
|
||||
case SLJIT_C_GREATER_EQUAL:
|
||||
case SLJIT_C_FLOAT_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_GREATER_EQUAL:
|
||||
return 0x3;
|
||||
|
||||
case SLJIT_C_GREATER:
|
||||
case SLJIT_C_FLOAT_GREATER:
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER:
|
||||
return 0x9;
|
||||
|
||||
case SLJIT_C_LESS_EQUAL:
|
||||
case SLJIT_C_FLOAT_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
return 0x8;
|
||||
|
||||
case SLJIT_C_SIG_LESS:
|
||||
case SLJIT_SIG_LESS:
|
||||
return 0xa;
|
||||
|
||||
case SLJIT_C_SIG_GREATER_EQUAL:
|
||||
case SLJIT_SIG_GREATER_EQUAL:
|
||||
return 0xb;
|
||||
|
||||
case SLJIT_C_SIG_GREATER:
|
||||
case SLJIT_SIG_GREATER:
|
||||
return 0xd;
|
||||
|
||||
case SLJIT_C_SIG_LESS_EQUAL:
|
||||
case SLJIT_SIG_LESS_EQUAL:
|
||||
return 0xc;
|
||||
|
||||
case SLJIT_C_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_UNORDERED:
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_D_UNORDERED:
|
||||
return 0x7;
|
||||
|
||||
case SLJIT_C_NOT_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_ORDERED:
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_D_ORDERED:
|
||||
return 0x6;
|
||||
|
||||
default:
|
||||
|
|
@ -1718,7 +1835,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
struct sljit_label *label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_label(compiler);
|
||||
CHECK_PTR(check_sljit_emit_label(compiler));
|
||||
|
||||
if (compiler->last_label && compiler->last_label->size == compiler->size)
|
||||
return compiler->last_label;
|
||||
|
|
@ -1734,7 +1851,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
struct sljit_jump *jump;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_jump(compiler, type);
|
||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF(!jump);
|
||||
|
|
@ -1761,7 +1878,7 @@ static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compi
|
|||
struct sljit_jump *jump;
|
||||
sljit_ins inv_bits = (type & SLJIT_INT_OP) ? (1 << 31) : 0;
|
||||
|
||||
SLJIT_ASSERT((type & 0xff) == SLJIT_C_EQUAL || (type & 0xff) == SLJIT_C_NOT_EQUAL);
|
||||
SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
|
|
@ -1779,7 +1896,7 @@ static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compi
|
|||
}
|
||||
SLJIT_ASSERT(FAST_IS_REG(src));
|
||||
|
||||
if ((type & 0xff) == SLJIT_C_EQUAL)
|
||||
if ((type & 0xff) == SLJIT_EQUAL)
|
||||
inv_bits |= 1 << 24;
|
||||
|
||||
PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src)));
|
||||
|
|
@ -1794,7 +1911,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
|||
struct sljit_jump *jump;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_ijump(compiler, type, src, srcw);
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
/* In ARM, we don't need to touch the arguments. */
|
||||
|
|
@ -1825,15 +1942,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
sljit_ins cc;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
|
||||
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
cc = get_cc(type);
|
||||
dst_r = (dst <= REG_MASK) ? dst : TMP_REG1;
|
||||
cc = get_cc(type & 0xff);
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
|
||||
|
||||
if (GET_OPCODE(op) < SLJIT_ADD) {
|
||||
FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO)));
|
||||
|
|
@ -1872,7 +1989,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
|||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_const(compiler, dst, dstw, init_value);
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
|
||||
|
|
|
|||
|
|
@ -33,17 +33,17 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
|
|||
typedef sljit_ui sljit_ins;
|
||||
|
||||
/* Last register + 1. */
|
||||
#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
|
||||
#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
|
||||
#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
|
||||
#define TMP_PC (SLJIT_NO_REGISTERS + 4)
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
|
||||
#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 5)
|
||||
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
|
||||
/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
|
||||
0, 0, 1, 2, 12, 5, 6, 7, 8, 10, 11, 13, 3, 4, 14, 15
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
0, 0, 1, 2, 12, 11, 10, 9, 8, 7, 6, 5, 13, 3, 4, 14, 15
|
||||
};
|
||||
|
||||
#define COPY_BITS(src, from, to, bits) \
|
||||
|
|
@ -138,9 +138,9 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
|
|||
#define ORRI 0xf0400000
|
||||
#define ORRS 0x4300
|
||||
#define ORR_W 0xea400000
|
||||
#define POP 0xbd00
|
||||
#define POP 0xbc00
|
||||
#define POP_W 0xe8bd0000
|
||||
#define PUSH 0xb500
|
||||
#define PUSH 0xb400
|
||||
#define PUSH_W 0xe92d0000
|
||||
#define RSB_WI 0xf1c00000
|
||||
#define RSBSI 0x4240
|
||||
|
|
@ -169,8 +169,12 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
|
|||
#define VABS_F32 0xeeb00ac0
|
||||
#define VADD_F32 0xee300a00
|
||||
#define VCMP_F32 0xeeb40a40
|
||||
#define VCVT_F32_S32 0xeeb80ac0
|
||||
#define VCVT_F64_F32 0xeeb70ac0
|
||||
#define VCVT_S32_F32 0xeebd0ac0
|
||||
#define VDIV_F32 0xee800a00
|
||||
#define VMOV_F32 0xeeb00a40
|
||||
#define VMOV 0xee000a10
|
||||
#define VMRS 0xeef1fa10
|
||||
#define VMUL_F32 0xee200a00
|
||||
#define VNEG_F32 0xeeb10a40
|
||||
|
|
@ -349,7 +353,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
struct sljit_const *const_;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_generate_code(compiler);
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh));
|
||||
|
|
@ -956,7 +960,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags,
|
|||
}
|
||||
|
||||
/* SP based immediate. */
|
||||
if (SLJIT_UNLIKELY(arg == SLJIT_LOCALS_REG) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) {
|
||||
if (SLJIT_UNLIKELY(arg == SLJIT_SP) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) {
|
||||
FAIL_IF(push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2)));
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1123,86 +1127,73 @@ static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit
|
|||
/* Entry, exit */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_si size;
|
||||
sljit_si size, i, tmp;
|
||||
sljit_ins push;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
push = (1 << 4);
|
||||
if (saveds >= 5)
|
||||
push |= 1 << 11;
|
||||
if (saveds >= 4)
|
||||
push |= 1 << 10;
|
||||
if (saveds >= 3)
|
||||
push |= 1 << 8;
|
||||
if (saveds >= 2)
|
||||
push |= 1 << 7;
|
||||
if (saveds >= 1)
|
||||
push |= 1 << 6;
|
||||
if (scratches >= 5)
|
||||
push |= 1 << 5;
|
||||
FAIL_IF(saveds >= 3
|
||||
? push_inst32(compiler, PUSH_W | (1 << 14) | push)
|
||||
: push_inst16(compiler, PUSH | push));
|
||||
|
||||
/* Stack must be aligned to 8 bytes: */
|
||||
size = (3 + saveds) * sizeof(sljit_uw);
|
||||
local_size += size;
|
||||
local_size = (local_size + 7) & ~7;
|
||||
local_size -= size;
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--)
|
||||
push |= 1 << reg_map[i];
|
||||
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
|
||||
push |= 1 << reg_map[i];
|
||||
|
||||
FAIL_IF((push & 0xff00)
|
||||
? push_inst32(compiler, PUSH_W | (1 << 14) | push)
|
||||
: push_inst16(compiler, PUSH | (1 << 8) | push));
|
||||
|
||||
/* Stack must be aligned to 8 bytes: (LR, R4) */
|
||||
size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2);
|
||||
local_size = ((size + local_size + 7) & ~7) - size;
|
||||
compiler->local_size = local_size;
|
||||
if (local_size > 0) {
|
||||
if (local_size <= (127 << 2))
|
||||
FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2)));
|
||||
else
|
||||
FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, local_size));
|
||||
FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, local_size));
|
||||
}
|
||||
|
||||
if (args >= 1)
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_SCRATCH_REG1)));
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S0, SLJIT_R0)));
|
||||
if (args >= 2)
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S1, SLJIT_R1)));
|
||||
if (args >= 3)
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_SCRATCH_REG3)));
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S2, SLJIT_R2)));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_si size;
|
||||
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
size = (3 + saveds) * sizeof(sljit_uw);
|
||||
local_size += size;
|
||||
local_size = (local_size + 7) & ~7;
|
||||
local_size -= size;
|
||||
compiler->local_size = local_size;
|
||||
size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2);
|
||||
compiler->local_size = ((size + local_size + 7) & ~7) - size;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si i, tmp;
|
||||
sljit_ins pop;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
|
||||
|
|
@ -1210,25 +1201,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
|||
if (compiler->local_size <= (127 << 2))
|
||||
FAIL_IF(push_inst16(compiler, ADD_SP | (compiler->local_size >> 2)));
|
||||
else
|
||||
FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, compiler->local_size));
|
||||
FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_SP, SLJIT_SP, compiler->local_size));
|
||||
}
|
||||
|
||||
pop = (1 << 4);
|
||||
if (compiler->saveds >= 5)
|
||||
pop |= 1 << 11;
|
||||
if (compiler->saveds >= 4)
|
||||
pop |= 1 << 10;
|
||||
if (compiler->saveds >= 3)
|
||||
pop |= 1 << 8;
|
||||
if (compiler->saveds >= 2)
|
||||
pop |= 1 << 7;
|
||||
if (compiler->saveds >= 1)
|
||||
pop |= 1 << 6;
|
||||
if (compiler->scratches >= 5)
|
||||
pop |= 1 << 5;
|
||||
return compiler->saveds >= 3
|
||||
|
||||
tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--)
|
||||
pop |= 1 << reg_map[i];
|
||||
|
||||
for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--)
|
||||
pop |= 1 << reg_map[i];
|
||||
|
||||
return (pop & 0xff00)
|
||||
? push_inst32(compiler, POP_W | (1 << 15) | pop)
|
||||
: push_inst16(compiler, POP | pop);
|
||||
: push_inst16(compiler, POP | (1 << 8) | pop);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
|
@ -1253,7 +1240,7 @@ extern int __aeabi_idivmod(int numerator, int denominator);
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op0(compiler, op);
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
switch (op) {
|
||||
|
|
@ -1261,15 +1248,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
return push_inst16(compiler, BKPT);
|
||||
case SLJIT_NOP:
|
||||
return push_inst16(compiler, NOP);
|
||||
case SLJIT_UMUL:
|
||||
case SLJIT_SMUL:
|
||||
return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
|
||||
| (reg_map[SLJIT_SCRATCH_REG2] << 8)
|
||||
| (reg_map[SLJIT_SCRATCH_REG1] << 12)
|
||||
| (reg_map[SLJIT_SCRATCH_REG1] << 16)
|
||||
| reg_map[SLJIT_SCRATCH_REG2]);
|
||||
case SLJIT_UDIV:
|
||||
case SLJIT_SDIV:
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
return push_inst32(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL)
|
||||
| (reg_map[SLJIT_R1] << 8)
|
||||
| (reg_map[SLJIT_R0] << 12)
|
||||
| (reg_map[SLJIT_R0] << 16)
|
||||
| reg_map[SLJIT_R1]);
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
if (compiler->scratches >= 4) {
|
||||
FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */));
|
||||
FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */));
|
||||
|
|
@ -1277,7 +1264,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */));
|
||||
#if defined(__GNUC__)
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
||||
(op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
(op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
#else
|
||||
#error "Software divmod functions are needed"
|
||||
#endif
|
||||
|
|
@ -1300,7 +1287,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
sljit_si op_flags = GET_ALL_FLAGS(op);
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
|
|
@ -1393,7 +1380,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
}
|
||||
|
||||
if (op == SLJIT_NEG) {
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
return sljit_emit_op2(compiler, SLJIT_SUB | op_flags, dst, dstw, SLJIT_IMM, 0, src, srcw);
|
||||
|
|
@ -1432,7 +1420,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
sljit_si dst_r, flags;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
|
@ -1505,22 +1493,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
return reg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_float_register_index(reg);
|
||||
return reg;
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg << 1;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_si size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_custom(compiler, instruction, size);
|
||||
SLJIT_ASSERT(size == 2 || size == 4);
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
|
||||
if (size == 2)
|
||||
return push_inst16(compiler, *(sljit_uh*)instruction);
|
||||
|
|
@ -1607,6 +1594,69 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
|
|||
return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw));
|
||||
src = TMP_FREG1;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_SINGLE_OP) | DD4(TMP_FREG1) | DM4(src)));
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
if (FAST_IS_REG(dst))
|
||||
return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | DN4(TMP_FREG1));
|
||||
|
||||
/* Store the integer value from a VFP register. */
|
||||
return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1)));
|
||||
else if (src & SLJIT_MEM) {
|
||||
/* Load the integer value into a VFP register. */
|
||||
FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw));
|
||||
}
|
||||
else {
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
|
||||
FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1)));
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(TMP_FREG1)));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
if (src1 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);
|
||||
src1 = TMP_FREG1;
|
||||
}
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w);
|
||||
src2 = TMP_FREG2;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(src1) | DM4(src2)));
|
||||
return push_inst32(compiler, VMRS);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
|
|
@ -1614,48 +1664,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
|
|||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
if (GET_OPCODE(op) != SLJIT_CONVD_FROMS)
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CMPD) {
|
||||
if (dst & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, dst, dstw);
|
||||
dst = TMP_FREG1;
|
||||
}
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw);
|
||||
src = TMP_FREG2;
|
||||
}
|
||||
FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst) | DM4(src)));
|
||||
return push_inst32(compiler, VMRS);
|
||||
}
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
dst_r = (dst <= REG_MASK) ? dst : TMP_FREG1;
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw);
|
||||
src = dst_r;
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOVD:
|
||||
if (src != dst_r)
|
||||
FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src)));
|
||||
case SLJIT_DMOV:
|
||||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1)
|
||||
FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src)));
|
||||
else
|
||||
dst_r = src;
|
||||
}
|
||||
break;
|
||||
case SLJIT_NEGD:
|
||||
case SLJIT_DNEG:
|
||||
FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src)));
|
||||
break;
|
||||
case SLJIT_ABSD:
|
||||
case SLJIT_DABS:
|
||||
FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src)));
|
||||
break;
|
||||
case SLJIT_CONVD_FROMS:
|
||||
FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src)));
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(dst & SLJIT_MEM))
|
||||
return SLJIT_SUCCESS;
|
||||
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw);
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
|
||||
|
|
@ -1666,13 +1713,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
|
||||
dst_r = (dst <= REG_MASK) ? dst : TMP_FREG1;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
if (src1 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);
|
||||
src1 = TMP_FREG1;
|
||||
|
|
@ -1683,16 +1733,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_ADDD:
|
||||
case SLJIT_DADD:
|
||||
FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
break;
|
||||
case SLJIT_SUBD:
|
||||
case SLJIT_DSUB:
|
||||
FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
break;
|
||||
case SLJIT_MULD:
|
||||
case SLJIT_DMUL:
|
||||
FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
break;
|
||||
case SLJIT_DIVD:
|
||||
case SLJIT_DDIV:
|
||||
FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
break;
|
||||
}
|
||||
|
|
@ -1711,14 +1761,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
/* For UNUSED dst. Uncommon, but possible. */
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
if (dst <= REG_MASK)
|
||||
if (FAST_IS_REG(dst))
|
||||
return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3));
|
||||
|
||||
/* Memory. */
|
||||
|
|
@ -1734,10 +1784,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (src <= REG_MASK)
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src)));
|
||||
else if (src & SLJIT_MEM) {
|
||||
if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw))
|
||||
|
|
@ -1761,53 +1811,54 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
|||
static sljit_uw get_cc(sljit_si type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_C_EQUAL:
|
||||
case SLJIT_C_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_EQUAL:
|
||||
case SLJIT_EQUAL:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_D_EQUAL:
|
||||
return 0x0;
|
||||
|
||||
case SLJIT_C_NOT_EQUAL:
|
||||
case SLJIT_C_MUL_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_NOT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
case SLJIT_D_NOT_EQUAL:
|
||||
return 0x1;
|
||||
|
||||
case SLJIT_C_LESS:
|
||||
case SLJIT_C_FLOAT_LESS:
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_LESS:
|
||||
return 0x3;
|
||||
|
||||
case SLJIT_C_GREATER_EQUAL:
|
||||
case SLJIT_C_FLOAT_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_GREATER_EQUAL:
|
||||
return 0x2;
|
||||
|
||||
case SLJIT_C_GREATER:
|
||||
case SLJIT_C_FLOAT_GREATER:
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER:
|
||||
return 0x8;
|
||||
|
||||
case SLJIT_C_LESS_EQUAL:
|
||||
case SLJIT_C_FLOAT_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
return 0x9;
|
||||
|
||||
case SLJIT_C_SIG_LESS:
|
||||
case SLJIT_SIG_LESS:
|
||||
return 0xb;
|
||||
|
||||
case SLJIT_C_SIG_GREATER_EQUAL:
|
||||
case SLJIT_SIG_GREATER_EQUAL:
|
||||
return 0xa;
|
||||
|
||||
case SLJIT_C_SIG_GREATER:
|
||||
case SLJIT_SIG_GREATER:
|
||||
return 0xc;
|
||||
|
||||
case SLJIT_C_SIG_LESS_EQUAL:
|
||||
case SLJIT_SIG_LESS_EQUAL:
|
||||
return 0xd;
|
||||
|
||||
case SLJIT_C_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_UNORDERED:
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_D_UNORDERED:
|
||||
return 0x6;
|
||||
|
||||
case SLJIT_C_NOT_OVERFLOW:
|
||||
case SLJIT_C_FLOAT_ORDERED:
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_D_ORDERED:
|
||||
return 0x7;
|
||||
|
||||
default: /* SLJIT_JUMP */
|
||||
SLJIT_ASSERT_STOP();
|
||||
return 0xe;
|
||||
}
|
||||
}
|
||||
|
|
@ -1817,7 +1868,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
struct sljit_label *label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_label(compiler);
|
||||
CHECK_PTR(check_sljit_emit_label(compiler));
|
||||
|
||||
if (compiler->last_label && compiler->last_label->size == compiler->size)
|
||||
return compiler->last_label;
|
||||
|
|
@ -1834,7 +1885,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
sljit_ins cc;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_jump(compiler, type);
|
||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF(!jump);
|
||||
|
|
@ -1866,7 +1917,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
|||
struct sljit_jump *jump;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_ijump(compiler, type, src, srcw);
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
/* In ARM, we don't need to touch the arguments. */
|
||||
|
|
@ -1898,7 +1949,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
sljit_ins cc, ins;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
|
||||
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
|
|
@ -1906,7 +1957,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
return SLJIT_SUCCESS;
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
cc = get_cc(type);
|
||||
cc = get_cc(type & 0xff);
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
|
||||
|
||||
if (op < SLJIT_ADD) {
|
||||
|
|
@ -1977,7 +2028,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
|||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_const(compiler, dst, dstw, init_value);
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB) {
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
|
||||
|
|
@ -102,7 +102,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH) {
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
|
||||
|
|
@ -125,7 +125,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (CHECK_FLAGS(SLJIT_SET_E))
|
||||
|
|
@ -154,9 +154,9 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
if (flags & SRC2_IMM) {
|
||||
if (op & SLJIT_SET_O) {
|
||||
if (src2 >= 0)
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
}
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
|
||||
|
|
@ -174,7 +174,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
}
|
||||
else {
|
||||
if (op & SLJIT_SET_O)
|
||||
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (op & (SLJIT_SET_C | SLJIT_SET_O))
|
||||
|
|
@ -189,8 +189,8 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
|
||||
if (!(op & SLJIT_SET_O))
|
||||
return SLJIT_SUCCESS;
|
||||
FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
return push_inst(compiler, SLL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
|
||||
|
||||
|
|
@ -198,21 +198,21 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
if (flags & SRC2_IMM) {
|
||||
if (op & SLJIT_SET_C) {
|
||||
if (src2 >= 0)
|
||||
FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
|
||||
else {
|
||||
FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
}
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
|
||||
} else {
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
/* dst may be the same as src1 or src2. */
|
||||
FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
|
||||
}
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
|
||||
FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
|
||||
if (!(op & SLJIT_SET_C))
|
||||
|
|
@ -221,7 +221,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
/* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
|
||||
/* Set carry flag. */
|
||||
return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG);
|
||||
return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG);
|
||||
|
||||
case SLJIT_SUB:
|
||||
if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) {
|
||||
|
|
@ -233,9 +233,9 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
if (flags & SRC2_IMM) {
|
||||
if (op & SLJIT_SET_O) {
|
||||
if (src2 >= 0)
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
}
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
|
||||
|
|
@ -247,7 +247,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
}
|
||||
else {
|
||||
if (op & SLJIT_SET_O)
|
||||
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O))
|
||||
|
|
@ -265,8 +265,8 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
|
||||
if (!(op & SLJIT_SET_O))
|
||||
return SLJIT_SUCCESS;
|
||||
FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
return push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
|
||||
|
||||
|
|
@ -279,27 +279,27 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
|
||||
if (flags & SRC2_IMM) {
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
|
||||
/* dst may be the same as src1 or src2. */
|
||||
FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
|
||||
}
|
||||
else {
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
/* dst may be the same as src1 or src2. */
|
||||
FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
|
||||
}
|
||||
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2));
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG));
|
||||
|
||||
FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
|
||||
return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
|
||||
return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MUL:
|
||||
SLJIT_ASSERT(!(flags & SRC2_IMM));
|
||||
if (!(op & SLJIT_SET_O)) {
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
|
|
@ -307,10 +307,10 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
#endif
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG));
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
|
||||
FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2));
|
||||
return push_inst(compiler, SUBU | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
|
||||
FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG));
|
||||
return push_inst(compiler, SUBU | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
|
||||
|
||||
case SLJIT_AND:
|
||||
EMIT_LOGICAL(ANDI, AND);
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (CHECK_FLAGS(SLJIT_SET_E))
|
||||
|
|
@ -246,9 +246,9 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
if (flags & SRC2_IMM) {
|
||||
if (op & SLJIT_SET_O) {
|
||||
if (src2 >= 0)
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
}
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
|
||||
|
|
@ -266,7 +266,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
}
|
||||
else {
|
||||
if (op & SLJIT_SET_O)
|
||||
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (op & (SLJIT_SET_C | SLJIT_SET_O))
|
||||
|
|
@ -281,8 +281,8 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
|
||||
if (!(op & SLJIT_SET_O))
|
||||
return SLJIT_SUCCESS;
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
return push_inst(compiler, SELECT_OP(DSRL32, SLL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
|
||||
|
||||
|
|
@ -290,21 +290,21 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
if (flags & SRC2_IMM) {
|
||||
if (op & SLJIT_SET_C) {
|
||||
if (src2 >= 0)
|
||||
FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
|
||||
else {
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
}
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
|
||||
} else {
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
/* dst may be the same as src1 or src2. */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
|
||||
}
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
|
||||
if (!(op & SLJIT_SET_C))
|
||||
|
|
@ -313,7 +313,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
/* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
|
||||
/* Set carry flag. */
|
||||
return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG);
|
||||
return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG);
|
||||
|
||||
case SLJIT_SUB:
|
||||
if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) {
|
||||
|
|
@ -325,9 +325,9 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
if (flags & SRC2_IMM) {
|
||||
if (op & SLJIT_SET_O) {
|
||||
if (src2 >= 0)
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
}
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
|
||||
|
|
@ -339,7 +339,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
}
|
||||
else {
|
||||
if (op & SLJIT_SET_O)
|
||||
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O))
|
||||
|
|
@ -357,8 +357,8 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
|
||||
if (!(op & SLJIT_SET_O))
|
||||
return SLJIT_SUCCESS;
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
|
||||
|
||||
|
|
@ -371,27 +371,27 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
|
||||
if (flags & SRC2_IMM) {
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
|
||||
/* dst may be the same as src1 or src2. */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
|
||||
}
|
||||
else {
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
|
||||
/* dst may be the same as src1 or src2. */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
|
||||
}
|
||||
|
||||
if (op & SLJIT_SET_C)
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2));
|
||||
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG));
|
||||
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
|
||||
return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
|
||||
return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MUL:
|
||||
SLJIT_ASSERT(!(flags & SRC2_IMM));
|
||||
if (!(op & SLJIT_SET_O)) {
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
if (op & SLJIT_INT_OP)
|
||||
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
|
|
@ -402,10 +402,10 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
#endif
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1));
|
||||
FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG));
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2));
|
||||
return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG));
|
||||
return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
|
||||
|
||||
case SLJIT_AND:
|
||||
EMIT_LOGICAL(ANDI, AND);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -87,22 +87,22 @@ static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
|
|||
#endif /* _AIX */
|
||||
}
|
||||
|
||||
#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
|
||||
#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
|
||||
#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
|
||||
#define TMP_ZERO (SLJIT_NO_REGISTERS + 4)
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
|
||||
#define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 5)
|
||||
|
||||
#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
|
||||
#define TMP_CALL_REG (SLJIT_NO_REGISTERS + 5)
|
||||
#define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 6)
|
||||
#else
|
||||
#define TMP_CALL_REG TMP_REG2
|
||||
#endif
|
||||
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = {
|
||||
0, 3, 4, 5, 6, 7, 30, 29, 28, 27, 26, 1, 8, 9, 10, 31, 12
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
|
||||
0, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 8, 9, 10, 31, 12
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
|
@ -114,6 +114,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = {
|
|||
#define B(b) (reg_map[b] << 11)
|
||||
#define C(c) (reg_map[c] << 6)
|
||||
#define FD(fd) ((fd) << 21)
|
||||
#define FS(fs) ((fs) << 21)
|
||||
#define FA(fa) ((fa) << 16)
|
||||
#define FB(fb) ((fb) << 11)
|
||||
#define FC(fc) ((fc) << 6)
|
||||
|
|
@ -159,13 +160,17 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = {
|
|||
#define FABS (HI(63) | LO(264))
|
||||
#define FADD (HI(63) | LO(21))
|
||||
#define FADDS (HI(59) | LO(21))
|
||||
#define FCFID (HI(63) | LO(846))
|
||||
#define FCMPU (HI(63) | LO(0))
|
||||
#define FCTIDZ (HI(63) | LO(815))
|
||||
#define FCTIWZ (HI(63) | LO(15))
|
||||
#define FDIV (HI(63) | LO(18))
|
||||
#define FDIVS (HI(59) | LO(18))
|
||||
#define FMR (HI(63) | LO(72))
|
||||
#define FMUL (HI(63) | LO(25))
|
||||
#define FMULS (HI(59) | LO(25))
|
||||
#define FNEG (HI(63) | LO(40))
|
||||
#define FRSP (HI(63) | LO(12))
|
||||
#define FSUB (HI(63) | LO(20))
|
||||
#define FSUBS (HI(59) | LO(20))
|
||||
#define LD (HI(58) | 0)
|
||||
|
|
@ -202,6 +207,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = {
|
|||
#define STD (HI(62) | 0)
|
||||
#define STDU (HI(62) | 1)
|
||||
#define STDUX (HI(31) | LO(181))
|
||||
#define STFIWX (HI(31) | LO(983))
|
||||
#define STW (HI(36))
|
||||
#define STWU (HI(37))
|
||||
#define STWUX (HI(31) | LO(183))
|
||||
|
|
@ -323,7 +329,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
struct sljit_const *const_;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_generate_code(compiler);
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||
|
|
@ -565,118 +571,121 @@ ALT_FORM6 0x200000 */
|
|||
#define STACK_LOAD LD
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
sljit_si i, tmp, offs;
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
FAIL_IF(push_inst(compiler, MFLR | D(0)));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) ));
|
||||
if (saveds >= 1)
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
if (saveds >= 2)
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
if (saveds >= 3)
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
if (saveds >= 4)
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
if (saveds >= 5)
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
offs = -(sljit_si)(sizeof(sljit_sw));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
|
||||
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
offs -= (sljit_si)(sizeof(sljit_sw));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
|
||||
}
|
||||
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
offs -= (sljit_si)(sizeof(sljit_sw));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
|
||||
}
|
||||
|
||||
SLJIT_ASSERT(offs == -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1));
|
||||
|
||||
#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(2 * sizeof(sljit_sw)) ));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_sw)) ));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
|
||||
#endif
|
||||
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));
|
||||
if (args >= 1)
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_SCRATCH_REG1)));
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0)));
|
||||
if (args >= 2)
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1)));
|
||||
if (args >= 3)
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_SCRATCH_REG3)));
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2)));
|
||||
|
||||
#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
|
||||
compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size;
|
||||
#else
|
||||
compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + local_size;
|
||||
#endif
|
||||
compiler->local_size = (compiler->local_size + 15) & ~0xf;
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
|
||||
local_size = (local_size + 15) & ~0xf;
|
||||
compiler->local_size = local_size;
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
||||
if (compiler->local_size <= SIMM_MAX)
|
||||
FAIL_IF(push_inst(compiler, STWU | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(-compiler->local_size)));
|
||||
if (local_size <= SIMM_MAX)
|
||||
FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
|
||||
else {
|
||||
FAIL_IF(load_immediate(compiler, 0, -compiler->local_size));
|
||||
FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0)));
|
||||
FAIL_IF(load_immediate(compiler, 0, -local_size));
|
||||
FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
|
||||
}
|
||||
#else
|
||||
if (compiler->local_size <= SIMM_MAX)
|
||||
FAIL_IF(push_inst(compiler, STDU | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(-compiler->local_size)));
|
||||
if (local_size <= SIMM_MAX)
|
||||
FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
|
||||
else {
|
||||
FAIL_IF(load_immediate(compiler, 0, -compiler->local_size));
|
||||
FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0)));
|
||||
FAIL_IF(load_immediate(compiler, 0, -local_size));
|
||||
FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
|
||||
}
|
||||
#endif
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
|
||||
compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size;
|
||||
#else
|
||||
compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + local_size;
|
||||
#endif
|
||||
compiler->local_size = (compiler->local_size + 15) & ~0xf;
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
|
||||
compiler->local_size = (local_size + 15) & ~0xf;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si i, tmp, offs;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
|
||||
if (compiler->local_size <= SIMM_MAX)
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(compiler->local_size)));
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size)));
|
||||
else {
|
||||
FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
|
||||
FAIL_IF(push_inst(compiler, ADD | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0)));
|
||||
FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0)));
|
||||
}
|
||||
|
||||
#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_LOCALS_REG) | IMM(2 * sizeof(sljit_sw))));
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_sw))));
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
|
||||
#endif
|
||||
if (compiler->saveds >= 5)
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
if (compiler->saveds >= 4)
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
if (compiler->saveds >= 3)
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
if (compiler->saveds >= 2)
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
if (compiler->saveds >= 1)
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) ));
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) ));
|
||||
|
||||
offs = -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);
|
||||
|
||||
tmp = compiler->scratches;
|
||||
for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
|
||||
offs += (sljit_si)(sizeof(sljit_sw));
|
||||
}
|
||||
|
||||
tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = tmp; i <= SLJIT_S0; i++) {
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
|
||||
offs += (sljit_si)(sizeof(sljit_sw));
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
|
||||
SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw)));
|
||||
|
||||
FAIL_IF(push_inst(compiler, MTLR | S(0)));
|
||||
FAIL_IF(push_inst(compiler, BLR));
|
||||
|
|
@ -999,12 +1008,12 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags,
|
|||
tmp_r = arg;
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(arg) | A(arg) | IMM(high_short >> 16)));
|
||||
}
|
||||
else if (compiler->cache_arg != arg || high_short != compiler->cache_argw) {
|
||||
else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) {
|
||||
if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) {
|
||||
next_high_short = (sljit_si)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
|
||||
if (high_short == next_high_short) {
|
||||
compiler->cache_arg = SLJIT_IMM | arg;
|
||||
compiler->cache_argw = next_high_short;
|
||||
compiler->cache_arg = SLJIT_MEM | arg;
|
||||
compiler->cache_argw = high_short;
|
||||
tmp_r = TMP_REG3;
|
||||
}
|
||||
}
|
||||
|
|
@ -1241,39 +1250,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op0(compiler, op);
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
switch (op) {
|
||||
case SLJIT_BREAKPOINT:
|
||||
case SLJIT_NOP:
|
||||
return push_inst(compiler, NOP);
|
||||
case SLJIT_UMUL:
|
||||
case SLJIT_SMUL:
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1)));
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
|
||||
return push_inst(compiler, (op == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2));
|
||||
FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
||||
return push_inst(compiler, (op == SLJIT_LUMUL ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
|
||||
return push_inst(compiler, (op == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2));
|
||||
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
||||
return push_inst(compiler, (op == SLJIT_LUMUL ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
|
||||
#endif
|
||||
case SLJIT_UDIV:
|
||||
case SLJIT_SDIV:
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1)));
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
if (int_op) {
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVWU : DIVW) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
||||
} else {
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVDU : DIVD) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
||||
}
|
||||
return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1));
|
||||
return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2)));
|
||||
return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVWU : DIVW) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
||||
return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1291,7 +1300,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
sljit_si op_flags = GET_ALL_FLAGS(op);
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
|
|
@ -1446,7 +1455,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
|
@ -1648,13 +1657,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
return reg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_float_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
|
@ -1662,8 +1671,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co
|
|||
void *instruction, sljit_si size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_custom(compiler, instruction, size);
|
||||
SLJIT_ASSERT(size == 4);
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
|
||||
return push_inst(compiler, *(sljit_ins*)instruction);
|
||||
}
|
||||
|
|
@ -1685,59 +1693,233 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
|
|||
#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6))
|
||||
#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double)
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
#define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
|
||||
#else
|
||||
#define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
|
||||
|
||||
#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
|
||||
#define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
|
||||
#define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
|
||||
#else
|
||||
#define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
|
||||
#define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
|
||||
#endif
|
||||
|
||||
#endif /* SLJIT_CONFIG_PPC_64 */
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
if (src & SLJIT_MEM) {
|
||||
/* We can ignore the temporary data store on the stack from caching point of view. */
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
|
||||
src = TMP_FREG1;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
op = GET_OPCODE(op);
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_CONVI_FROMD ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
if (op == SLJIT_CONVW_FROMD) {
|
||||
if (FAST_IS_REG(dst)) {
|
||||
FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0));
|
||||
return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
|
||||
}
|
||||
return emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
#endif
|
||||
|
||||
if (FAST_IS_REG(dst)) {
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
|
||||
FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
|
||||
return emit_op_mem2(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
|
||||
}
|
||||
|
||||
SLJIT_ASSERT(dst & SLJIT_MEM);
|
||||
|
||||
if (dst & OFFS_REG_MASK) {
|
||||
dstw &= 0x3;
|
||||
if (dstw) {
|
||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
||||
FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1)));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1)));
|
||||
#endif
|
||||
dstw = TMP_REG1;
|
||||
}
|
||||
else
|
||||
dstw = OFFS_REG(dst);
|
||||
}
|
||||
else {
|
||||
if ((dst & REG_MASK) && !dstw) {
|
||||
dstw = dst & REG_MASK;
|
||||
dst = 0;
|
||||
}
|
||||
else {
|
||||
/* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));
|
||||
dstw = TMP_REG1;
|
||||
}
|
||||
}
|
||||
|
||||
return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
|
||||
srcw = (sljit_si)srcw;
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
|
||||
src = TMP_REG1;
|
||||
}
|
||||
else if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) {
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
|
||||
else
|
||||
FAIL_IF(emit_op_mem2(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
|
||||
src = TMP_REG1;
|
||||
}
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
|
||||
FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, dst, dstw));
|
||||
}
|
||||
else
|
||||
FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
|
||||
|
||||
FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
|
||||
if (op & SLJIT_SINGLE_OP)
|
||||
return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
#else
|
||||
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
sljit_si invert_sign = 1;
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000));
|
||||
src = TMP_REG1;
|
||||
invert_sign = 0;
|
||||
}
|
||||
else if (!FAST_IS_REG(src)) {
|
||||
FAIL_IF(emit_op_mem2(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
|
||||
src = TMP_REG1;
|
||||
}
|
||||
|
||||
/* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
|
||||
The double precision format has exactly 53 bit precision, so the lower 32 bit represents
|
||||
the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
|
||||
to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
|
||||
point value, we need to substract 2^53 + 2^31 from the constructed value. */
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
|
||||
if (invert_sign)
|
||||
FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
|
||||
FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
|
||||
FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI));
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
|
||||
FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
|
||||
FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
|
||||
FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
|
||||
|
||||
FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
|
||||
if (op & SLJIT_SINGLE_OP)
|
||||
return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
if (src1 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
|
||||
src1 = TMP_FREG1;
|
||||
}
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
|
||||
src2 = TMP_FREG2;
|
||||
}
|
||||
|
||||
return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2));
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_fr;
|
||||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CMPD) {
|
||||
if (dst & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw));
|
||||
dst = TMP_FREG1;
|
||||
}
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0));
|
||||
src = TMP_FREG2;
|
||||
}
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMS)
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
|
||||
return push_inst(compiler, FCMPU | CRD(4) | FA(dst) | FB(src));
|
||||
}
|
||||
|
||||
dst_fr = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw));
|
||||
src = dst_fr;
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
|
||||
src = dst_r;
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOVD:
|
||||
if (src != dst_fr && dst_fr != TMP_FREG1)
|
||||
FAIL_IF(push_inst(compiler, FMR | FD(dst_fr) | FB(src)));
|
||||
break;
|
||||
case SLJIT_NEGD:
|
||||
FAIL_IF(push_inst(compiler, FNEG | FD(dst_fr) | FB(src)));
|
||||
break;
|
||||
case SLJIT_ABSD:
|
||||
FAIL_IF(push_inst(compiler, FABS | FD(dst_fr) | FB(src)));
|
||||
case SLJIT_CONVD_FROMS:
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
if (op & SLJIT_SINGLE_OP) {
|
||||
FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
|
||||
break;
|
||||
}
|
||||
/* Fall through. */
|
||||
case SLJIT_DMOV:
|
||||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1)
|
||||
FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
|
||||
else
|
||||
dst_r = src;
|
||||
}
|
||||
break;
|
||||
case SLJIT_DNEG:
|
||||
FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));
|
||||
break;
|
||||
case SLJIT_DABS:
|
||||
FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst_fr == TMP_FREG1) {
|
||||
if (GET_OPCODE(op) == SLJIT_MOVD)
|
||||
dst_fr = src;
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_fr, dst, dstw, 0, 0));
|
||||
}
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -1746,15 +1928,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si dst_fr, flags = 0;
|
||||
sljit_si dst_r, flags = 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
dst_fr = FAST_IS_REG(dst) ? dst : TMP_FREG2;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
|
||||
|
||||
if (src1 & SLJIT_MEM) {
|
||||
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
|
||||
|
|
@ -1793,24 +1978,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
src2 = TMP_FREG2;
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_ADDD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_fr) | FA(src1) | FB(src2)));
|
||||
case SLJIT_DADD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));
|
||||
break;
|
||||
|
||||
case SLJIT_SUBD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_fr) | FA(src1) | FB(src2)));
|
||||
case SLJIT_DSUB:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));
|
||||
break;
|
||||
|
||||
case SLJIT_MULD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_fr) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
|
||||
case SLJIT_DMUL:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
|
||||
break;
|
||||
|
||||
case SLJIT_DIVD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_fr) | FA(src1) | FB(src2)));
|
||||
case SLJIT_DDIV:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst_fr == TMP_FREG2)
|
||||
if (dst_r == TMP_FREG2)
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
|
@ -1826,7 +2011,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
/* For UNUSED dst. Uncommon, but possible. */
|
||||
|
|
@ -1844,7 +2029,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
|
|
@ -1868,7 +2053,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
struct sljit_label *label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_label(compiler);
|
||||
CHECK_PTR(check_sljit_emit_label(compiler));
|
||||
|
||||
if (compiler->last_label && compiler->last_label->size == compiler->size)
|
||||
return compiler->last_label;
|
||||
|
|
@ -1882,58 +2067,58 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
static sljit_ins get_bo_bi_flags(sljit_si type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_C_EQUAL:
|
||||
case SLJIT_EQUAL:
|
||||
return (12 << 21) | (2 << 16);
|
||||
|
||||
case SLJIT_C_NOT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL:
|
||||
return (4 << 21) | (2 << 16);
|
||||
|
||||
case SLJIT_C_LESS:
|
||||
case SLJIT_C_FLOAT_LESS:
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_LESS:
|
||||
return (12 << 21) | ((4 + 0) << 16);
|
||||
|
||||
case SLJIT_C_GREATER_EQUAL:
|
||||
case SLJIT_C_FLOAT_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_GREATER_EQUAL:
|
||||
return (4 << 21) | ((4 + 0) << 16);
|
||||
|
||||
case SLJIT_C_GREATER:
|
||||
case SLJIT_C_FLOAT_GREATER:
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER:
|
||||
return (12 << 21) | ((4 + 1) << 16);
|
||||
|
||||
case SLJIT_C_LESS_EQUAL:
|
||||
case SLJIT_C_FLOAT_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
return (4 << 21) | ((4 + 1) << 16);
|
||||
|
||||
case SLJIT_C_SIG_LESS:
|
||||
case SLJIT_SIG_LESS:
|
||||
return (12 << 21) | (0 << 16);
|
||||
|
||||
case SLJIT_C_SIG_GREATER_EQUAL:
|
||||
case SLJIT_SIG_GREATER_EQUAL:
|
||||
return (4 << 21) | (0 << 16);
|
||||
|
||||
case SLJIT_C_SIG_GREATER:
|
||||
case SLJIT_SIG_GREATER:
|
||||
return (12 << 21) | (1 << 16);
|
||||
|
||||
case SLJIT_C_SIG_LESS_EQUAL:
|
||||
case SLJIT_SIG_LESS_EQUAL:
|
||||
return (4 << 21) | (1 << 16);
|
||||
|
||||
case SLJIT_C_OVERFLOW:
|
||||
case SLJIT_C_MUL_OVERFLOW:
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
return (12 << 21) | (3 << 16);
|
||||
|
||||
case SLJIT_C_NOT_OVERFLOW:
|
||||
case SLJIT_C_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
return (4 << 21) | (3 << 16);
|
||||
|
||||
case SLJIT_C_FLOAT_EQUAL:
|
||||
case SLJIT_D_EQUAL:
|
||||
return (12 << 21) | ((4 + 2) << 16);
|
||||
|
||||
case SLJIT_C_FLOAT_NOT_EQUAL:
|
||||
case SLJIT_D_NOT_EQUAL:
|
||||
return (4 << 21) | ((4 + 2) << 16);
|
||||
|
||||
case SLJIT_C_FLOAT_UNORDERED:
|
||||
case SLJIT_D_UNORDERED:
|
||||
return (12 << 21) | ((4 + 3) << 16);
|
||||
|
||||
case SLJIT_C_FLOAT_ORDERED:
|
||||
case SLJIT_D_ORDERED:
|
||||
return (4 << 21) | ((4 + 3) << 16);
|
||||
|
||||
default:
|
||||
|
|
@ -1948,7 +2133,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
sljit_ins bo_bi_flags;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_jump(compiler, type);
|
||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||
|
||||
bo_bi_flags = get_bo_bi_flags(type & 0xff);
|
||||
if (!bo_bi_flags)
|
||||
|
|
@ -1980,7 +2165,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
|||
sljit_si src_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_ijump(compiler, type, src, srcw);
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
|
|
@ -2035,7 +2220,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
sljit_sw original_dstw = dstw;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
|
||||
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
|
|
@ -2058,81 +2243,81 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
srcw = 0;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SLJIT_C_EQUAL:
|
||||
switch (type & 0xff) {
|
||||
case SLJIT_EQUAL:
|
||||
GET_CR_BIT(2, reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_NOT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL:
|
||||
GET_CR_BIT(2, reg);
|
||||
INVERT_BIT(reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_LESS:
|
||||
case SLJIT_C_FLOAT_LESS:
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_LESS:
|
||||
GET_CR_BIT(4 + 0, reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_GREATER_EQUAL:
|
||||
case SLJIT_C_FLOAT_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_GREATER_EQUAL:
|
||||
GET_CR_BIT(4 + 0, reg);
|
||||
INVERT_BIT(reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_GREATER:
|
||||
case SLJIT_C_FLOAT_GREATER:
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER:
|
||||
GET_CR_BIT(4 + 1, reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_LESS_EQUAL:
|
||||
case SLJIT_C_FLOAT_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
GET_CR_BIT(4 + 1, reg);
|
||||
INVERT_BIT(reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_SIG_LESS:
|
||||
case SLJIT_SIG_LESS:
|
||||
GET_CR_BIT(0, reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_SIG_GREATER_EQUAL:
|
||||
case SLJIT_SIG_GREATER_EQUAL:
|
||||
GET_CR_BIT(0, reg);
|
||||
INVERT_BIT(reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_SIG_GREATER:
|
||||
case SLJIT_SIG_GREATER:
|
||||
GET_CR_BIT(1, reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_SIG_LESS_EQUAL:
|
||||
case SLJIT_SIG_LESS_EQUAL:
|
||||
GET_CR_BIT(1, reg);
|
||||
INVERT_BIT(reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_OVERFLOW:
|
||||
case SLJIT_C_MUL_OVERFLOW:
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
GET_CR_BIT(3, reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_NOT_OVERFLOW:
|
||||
case SLJIT_C_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
GET_CR_BIT(3, reg);
|
||||
INVERT_BIT(reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_FLOAT_EQUAL:
|
||||
case SLJIT_D_EQUAL:
|
||||
GET_CR_BIT(4 + 2, reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_FLOAT_NOT_EQUAL:
|
||||
case SLJIT_D_NOT_EQUAL:
|
||||
GET_CR_BIT(4 + 2, reg);
|
||||
INVERT_BIT(reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_FLOAT_UNORDERED:
|
||||
case SLJIT_D_UNORDERED:
|
||||
GET_CR_BIT(4 + 3, reg);
|
||||
break;
|
||||
|
||||
case SLJIT_C_FLOAT_ORDERED:
|
||||
case SLJIT_D_ORDERED:
|
||||
GET_CR_BIT(4 + 3, reg);
|
||||
INVERT_BIT(reg);
|
||||
break;
|
||||
|
|
@ -2159,7 +2344,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
return emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
|
||||
}
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0);
|
||||
|
|
@ -2171,7 +2357,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
|||
sljit_si reg;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_const(compiler, dst, dstw, init_value);
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
|||
if (!(flags & SET_FLAGS))
|
||||
return SLJIT_SUCCESS;
|
||||
FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(dst) | IMM(31), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, RDY | D(TMP_REG4), DR(TMP_REG4)));
|
||||
return push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(TMP_REG4), MOVABLE_INS | SET_FLAGS);
|
||||
FAIL_IF(push_inst(compiler, RDY | D(TMP_LINK), DR(TMP_LINK)));
|
||||
return push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(TMP_LINK), MOVABLE_INS | SET_FLAGS);
|
||||
|
||||
case SLJIT_AND:
|
||||
return push_inst(compiler, AND | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
|
||||
|
|
|
|||
|
|
@ -83,17 +83,16 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
|
|||
}
|
||||
|
||||
/* TMP_REG2 is not used by getput_arg */
|
||||
#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
|
||||
#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
|
||||
#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
|
||||
#define TMP_REG4 (SLJIT_NO_REGISTERS + 4)
|
||||
#define TMP_LINK (SLJIT_NO_REGISTERS + 5)
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
|
||||
#define TMP_LINK (SLJIT_NUMBER_OF_REGISTERS + 5)
|
||||
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 ((SLJIT_FLOAT_REG6 + 1) << 1)
|
||||
#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
|
||||
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = {
|
||||
0, 8, 9, 10, 11, 12, 16, 17, 18, 19, 20, 14, 1, 24, 25, 26, 15
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
|
@ -128,10 +127,16 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = {
|
|||
#define FCMPS (OPC1(0x2) | OPC3(0x35) | DOP(0x51))
|
||||
#define FDIVD (OPC1(0x2) | OPC3(0x34) | DOP(0x4e))
|
||||
#define FDIVS (OPC1(0x2) | OPC3(0x34) | DOP(0x4d))
|
||||
#define FDTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd2))
|
||||
#define FDTOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc6))
|
||||
#define FITOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc8))
|
||||
#define FITOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc4))
|
||||
#define FMOVS (OPC1(0x2) | OPC3(0x34) | DOP(0x01))
|
||||
#define FMULD (OPC1(0x2) | OPC3(0x34) | DOP(0x4a))
|
||||
#define FMULS (OPC1(0x2) | OPC3(0x34) | DOP(0x49))
|
||||
#define FNEGS (OPC1(0x2) | OPC3(0x34) | DOP(0x05))
|
||||
#define FSTOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc9))
|
||||
#define FSTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd1))
|
||||
#define FSUBD (OPC1(0x2) | OPC3(0x34) | DOP(0x46))
|
||||
#define FSUBS (OPC1(0x2) | OPC3(0x34) | DOP(0x45))
|
||||
#define JMPL (OPC1(0x2) | OPC3(0x38))
|
||||
|
|
@ -278,7 +283,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
struct sljit_const *const_;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_generate_code(compiler);
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
|
||||
|
|
@ -388,6 +393,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
/* Separates integer and floating point registers */
|
||||
#define GPR_REG 0x0f
|
||||
#define DOUBLE_DATA 0x10
|
||||
#define SINGLE_DATA 0x12
|
||||
|
||||
#define MEM_MASK 0x1f
|
||||
|
||||
|
|
@ -412,66 +418,54 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
#include "sljitNativeSPARC_64.c"
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
local_size += 23 * sizeof(sljit_sw);
|
||||
local_size = (local_size + 7) & ~0x7;
|
||||
local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
|
||||
compiler->local_size = local_size;
|
||||
|
||||
if (local_size <= SIMM_MAX) {
|
||||
FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_LOCALS_REG) | S1(SLJIT_LOCALS_REG) | IMM(-local_size), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | IMM(-local_size), UNMOVABLE_INS));
|
||||
}
|
||||
else {
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size));
|
||||
FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_LOCALS_REG) | S1(SLJIT_LOCALS_REG) | S2(TMP_REG1), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | S2(TMP_REG1), UNMOVABLE_INS));
|
||||
}
|
||||
|
||||
if (args >= 1)
|
||||
FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG1) | S1(0) | S2A(24), DR(SLJIT_SAVED_REG1)));
|
||||
if (args >= 2)
|
||||
FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG2) | S1(0) | S2A(25), DR(SLJIT_SAVED_REG2)));
|
||||
if (args >= 3)
|
||||
FAIL_IF(push_inst(compiler, OR | D(SLJIT_SAVED_REG3) | S1(0) | S2A(26), DR(SLJIT_SAVED_REG3)));
|
||||
/* Arguments are in their appropriate registers. */
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
local_size += 23 * sizeof(sljit_sw);
|
||||
compiler->local_size = (local_size + 7) & ~0x7;
|
||||
compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
|
||||
if (op != SLJIT_MOV || !FAST_IS_REG(src)) {
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
src = SLJIT_SCRATCH_REG1;
|
||||
src = SLJIT_R0;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS));
|
||||
return push_inst(compiler, RESTORE | D(SLJIT_SCRATCH_REG1) | S1(src) | S2(0), UNMOVABLE_INS);
|
||||
return push_inst(compiler, RESTORE | D(SLJIT_R0) | S1(src) | S2(0), UNMOVABLE_INS);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
|
@ -767,7 +761,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op0(compiler, op);
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
switch (op) {
|
||||
|
|
@ -775,27 +769,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
return push_inst(compiler, TA, UNMOVABLE_INS);
|
||||
case SLJIT_NOP:
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
case SLJIT_UMUL:
|
||||
case SLJIT_SMUL:
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? UMUL : SMUL) | D(SLJIT_SCRATCH_REG1) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG1)));
|
||||
return push_inst(compiler, RDY | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#else
|
||||
#error "Implementation required"
|
||||
#endif
|
||||
case SLJIT_UDIV:
|
||||
case SLJIT_SDIV:
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
if (op == SLJIT_UDIV)
|
||||
if (op == SLJIT_LUDIV)
|
||||
FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));
|
||||
else {
|
||||
FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_SCRATCH_REG1) | IMM(31), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_SCRATCH_REG1), DR(TMP_REG2)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? UDIV : SDIV) | D(SLJIT_SCRATCH_REG1) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG1)));
|
||||
FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_SCRATCH_REG2) | S1(SLJIT_SCRATCH_REG1) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, SUB | D(SLJIT_SCRATCH_REG2) | S1(TMP_REG2) | S2(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)));
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1)));
|
||||
return SLJIT_SUCCESS;
|
||||
#else
|
||||
#error "Implementation required"
|
||||
|
|
@ -812,7 +806,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
|
|
@ -881,7 +875,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
|
@ -917,13 +911,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
return reg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_float_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg << 1;
|
||||
}
|
||||
|
||||
|
|
@ -931,8 +925,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co
|
|||
void *instruction, sljit_si size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_custom(compiler, instruction, size);
|
||||
SLJIT_ASSERT(size == 4);
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
|
||||
return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
|
||||
}
|
||||
|
|
@ -953,73 +946,139 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
|
|||
|
||||
#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7))
|
||||
#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double)
|
||||
#define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw))
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
|
||||
src = TMP_FREG1;
|
||||
}
|
||||
else
|
||||
src <<= 1;
|
||||
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | DA(TMP_FREG1) | S2A(src), MOVABLE_INS));
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
if (FAST_IS_REG(dst)) {
|
||||
FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
|
||||
return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET);
|
||||
}
|
||||
|
||||
/* Store the integer value from a VFP register. */
|
||||
return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
|
||||
srcw = (sljit_si)srcw;
|
||||
#endif
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
|
||||
src = TMP_REG1;
|
||||
srcw = 0;
|
||||
}
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
|
||||
src = SLJIT_MEM1(SLJIT_SP);
|
||||
srcw = FLOAT_TMP_MEM_OFFSET;
|
||||
}
|
||||
|
||||
FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | DA(dst_r) | S2A(TMP_FREG1), MOVABLE_INS));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
if (src1 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
|
||||
src1 = TMP_FREG1;
|
||||
}
|
||||
else
|
||||
src1 <<= 1;
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
|
||||
src2 = TMP_FREG2;
|
||||
}
|
||||
else
|
||||
src2 <<= 1;
|
||||
|
||||
return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_fr;
|
||||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CMPD) {
|
||||
if (dst & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw));
|
||||
dst = TMP_FREG1;
|
||||
}
|
||||
else
|
||||
dst <<= 1;
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0));
|
||||
src = TMP_FREG2;
|
||||
}
|
||||
else
|
||||
src <<= 1;
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMS)
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
|
||||
return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(dst) | S2A(src), FCC_IS_SET | MOVABLE_INS);
|
||||
}
|
||||
|
||||
dst_fr = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw));
|
||||
src = dst_fr;
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
|
||||
src = dst_r;
|
||||
}
|
||||
else
|
||||
src <<= 1;
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOVD:
|
||||
if (src != dst_fr && dst_fr != TMP_FREG1) {
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr) | S2A(src), MOVABLE_INS));
|
||||
case SLJIT_DMOV:
|
||||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1) {
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
if (!(op & SLJIT_SINGLE_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
}
|
||||
break;
|
||||
case SLJIT_NEGD:
|
||||
FAIL_IF(push_inst(compiler, FNEGS | DA(dst_fr) | S2A(src), MOVABLE_INS));
|
||||
if (dst_fr != src && !(op & SLJIT_SINGLE_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_ABSD:
|
||||
FAIL_IF(push_inst(compiler, FABSS | DA(dst_fr) | S2A(src), MOVABLE_INS));
|
||||
if (dst_fr != src && !(op & SLJIT_SINGLE_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_fr | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst_fr == TMP_FREG1) {
|
||||
if (GET_OPCODE(op) == SLJIT_MOVD)
|
||||
dst_fr = src;
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_fr, dst, dstw, 0, 0));
|
||||
else
|
||||
dst_r = src;
|
||||
}
|
||||
break;
|
||||
case SLJIT_DNEG:
|
||||
FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
if (dst_r != src && !(op & SLJIT_SINGLE_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_DABS:
|
||||
FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
if (dst_r != src && !(op & SLJIT_SINGLE_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_CONVD_FROMS:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -1028,15 +1087,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si dst_fr, flags = 0;
|
||||
sljit_si dst_r, flags = 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
dst_fr = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
|
||||
dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
|
||||
|
||||
if (src1 & SLJIT_MEM) {
|
||||
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
|
||||
|
|
@ -1079,24 +1141,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
src2 = TMP_FREG2;
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_ADDD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
case SLJIT_DADD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
break;
|
||||
|
||||
case SLJIT_SUBD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
case SLJIT_DSUB:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
break;
|
||||
|
||||
case SLJIT_MULD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
case SLJIT_DMUL:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
break;
|
||||
|
||||
case SLJIT_DIVD:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_fr) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
case SLJIT_DDIV:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst_fr == TMP_FREG2)
|
||||
if (dst_r == TMP_FREG2)
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
|
@ -1112,7 +1174,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
/* For UNUSED dst. Uncommon, but possible. */
|
||||
|
|
@ -1129,7 +1191,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
|
|
@ -1152,7 +1214,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
struct sljit_label *label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_label(compiler);
|
||||
CHECK_PTR(check_sljit_emit_label(compiler));
|
||||
|
||||
if (compiler->last_label && compiler->last_label->size == compiler->size)
|
||||
return compiler->last_label;
|
||||
|
|
@ -1167,66 +1229,50 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
static sljit_ins get_cc(sljit_si type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_C_EQUAL:
|
||||
case SLJIT_C_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_EQUAL:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_D_NOT_EQUAL: /* Unordered. */
|
||||
return DA(0x1);
|
||||
|
||||
case SLJIT_C_NOT_EQUAL:
|
||||
case SLJIT_C_MUL_OVERFLOW:
|
||||
case SLJIT_NOT_EQUAL:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
case SLJIT_D_EQUAL:
|
||||
return DA(0x9);
|
||||
|
||||
case SLJIT_C_LESS:
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_GREATER: /* Unordered. */
|
||||
return DA(0x5);
|
||||
|
||||
case SLJIT_C_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
return DA(0xd);
|
||||
|
||||
case SLJIT_C_GREATER:
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER_EQUAL: /* Unordered. */
|
||||
return DA(0xc);
|
||||
|
||||
case SLJIT_C_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS:
|
||||
return DA(0x4);
|
||||
|
||||
case SLJIT_C_SIG_LESS:
|
||||
case SLJIT_SIG_LESS:
|
||||
return DA(0x3);
|
||||
|
||||
case SLJIT_C_SIG_GREATER_EQUAL:
|
||||
case SLJIT_SIG_GREATER_EQUAL:
|
||||
return DA(0xb);
|
||||
|
||||
case SLJIT_C_SIG_GREATER:
|
||||
case SLJIT_SIG_GREATER:
|
||||
return DA(0xa);
|
||||
|
||||
case SLJIT_C_SIG_LESS_EQUAL:
|
||||
case SLJIT_SIG_LESS_EQUAL:
|
||||
return DA(0x2);
|
||||
|
||||
case SLJIT_C_OVERFLOW:
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_D_UNORDERED:
|
||||
return DA(0x7);
|
||||
|
||||
case SLJIT_C_NOT_OVERFLOW:
|
||||
return DA(0xf);
|
||||
|
||||
case SLJIT_C_FLOAT_EQUAL:
|
||||
return DA(0x9);
|
||||
|
||||
case SLJIT_C_FLOAT_NOT_EQUAL: /* Unordered. */
|
||||
return DA(0x1);
|
||||
|
||||
case SLJIT_C_FLOAT_LESS:
|
||||
return DA(0x4);
|
||||
|
||||
case SLJIT_C_FLOAT_GREATER_EQUAL: /* Unordered. */
|
||||
return DA(0xc);
|
||||
|
||||
case SLJIT_C_FLOAT_LESS_EQUAL:
|
||||
return DA(0xd);
|
||||
|
||||
case SLJIT_C_FLOAT_GREATER: /* Unordered. */
|
||||
return DA(0x5);
|
||||
|
||||
case SLJIT_C_FLOAT_UNORDERED:
|
||||
return DA(0x7);
|
||||
|
||||
case SLJIT_C_FLOAT_ORDERED:
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_D_ORDERED:
|
||||
return DA(0xf);
|
||||
|
||||
default:
|
||||
|
|
@ -1240,14 +1286,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
struct sljit_jump *jump;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_jump(compiler, type);
|
||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF(!jump);
|
||||
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
|
||||
type &= 0xff;
|
||||
|
||||
if (type < SLJIT_C_FLOAT_EQUAL) {
|
||||
if (type < SLJIT_D_EQUAL) {
|
||||
jump->flags |= IS_COND;
|
||||
if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET))
|
||||
jump->flags |= IS_MOVABLE;
|
||||
|
|
@ -1287,7 +1333,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
|||
sljit_si src_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_ijump(compiler, type, src, srcw);
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
|
|
@ -1324,7 +1370,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0);
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
|
||||
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
|
|
@ -1343,7 +1389,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
srcw = 0;
|
||||
}
|
||||
|
||||
if (type < SLJIT_C_FLOAT_EQUAL)
|
||||
type &= 0xff;
|
||||
if (type < SLJIT_D_EQUAL)
|
||||
FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS));
|
||||
|
|
@ -1366,7 +1413,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
|||
struct sljit_const *const_;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_const(compiler, dst, dstw, init_value);
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
|
||||
|
|
|
|||
|
|
@ -1173,19 +1173,16 @@ static sljit_si emit_const_64(struct sljit_compiler *compiler, sljit_si dst_ar,
|
|||
return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_ins base;
|
||||
sljit_ins bundle = 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
local_size += (saveds + 1) * sizeof(sljit_sw);
|
||||
local_size = (local_size + 7) & ~7;
|
||||
|
|
@ -1233,16 +1230,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
|||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
local_size += (saveds + 1) * sizeof(sljit_sw);
|
||||
compiler->local_size = (local_size + 7) & ~7;
|
||||
|
|
@ -2370,7 +2364,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
|||
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
|
||||
}
|
||||
|
||||
FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_SCRATCH_REG1], ZERO));
|
||||
FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
|
||||
|
||||
FAIL_IF(ADDI_SOLO(54, 54, -16));
|
||||
|
||||
|
|
@ -2381,7 +2375,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
|||
|
||||
/* Register input. */
|
||||
if (type >= SLJIT_CALL1)
|
||||
FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_SCRATCH_REG1], ZERO));
|
||||
FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
|
||||
|
||||
FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO));
|
||||
|
||||
|
|
@ -2511,7 +2505,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compil
|
|||
SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);
|
||||
/* Cannot be optimized out if type is >= CALL0. */
|
||||
jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0);
|
||||
PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_SCRATCH_REG1], ZERO));
|
||||
PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
|
||||
jump->addr = compiler->size;
|
||||
PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,27 +63,25 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_
|
|||
return code_ptr;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_si size;
|
||||
sljit_si locals_offset;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
compiler->args = args;
|
||||
compiler->flags_saved = 0;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
size = 1 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3);
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);
|
||||
size += (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);
|
||||
#else
|
||||
size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0);
|
||||
size += (args > 0 ? (2 + args * 3) : 0);
|
||||
#endif
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
|
@ -96,76 +94,85 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
|||
*inst++ = MOD_REG | (reg_map[TMP_REG1] << 3) | 0x4 /* esp */;
|
||||
}
|
||||
#endif
|
||||
if (saveds > 2)
|
||||
PUSH_REG(reg_map[SLJIT_SAVED_REG3]);
|
||||
if (saveds > 1)
|
||||
PUSH_REG(reg_map[SLJIT_SAVED_REG2]);
|
||||
if (saveds > 0)
|
||||
PUSH_REG(reg_map[SLJIT_SAVED_REG1]);
|
||||
if (saveds > 2 || scratches > 7)
|
||||
PUSH_REG(reg_map[SLJIT_S2]);
|
||||
if (saveds > 1 || scratches > 8)
|
||||
PUSH_REG(reg_map[SLJIT_S1]);
|
||||
if (saveds > 0 || scratches > 9)
|
||||
PUSH_REG(reg_map[SLJIT_S0]);
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (args > 0) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_SCRATCH_REG3];
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2];
|
||||
}
|
||||
if (args > 1) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_SCRATCH_REG2];
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1];
|
||||
}
|
||||
if (args > 2) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x4 /* esp */;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */;
|
||||
*inst++ = 0x24;
|
||||
*inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */
|
||||
}
|
||||
#else
|
||||
if (args > 0) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = sizeof(sljit_sw) * 2;
|
||||
}
|
||||
if (args > 1) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = sizeof(sljit_sw) * 3;
|
||||
}
|
||||
if (args > 2) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = sizeof(sljit_sw) * 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
locals_offset = 2 * sizeof(sljit_uw);
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(FIXED_LOCALS_OFFSET >= 2 * sizeof(sljit_uw), require_at_least_two_words);
|
||||
locals_offset = FIXED_LOCALS_OFFSET;
|
||||
#endif
|
||||
compiler->scratches_start = locals_offset;
|
||||
if (scratches > 3)
|
||||
locals_offset += (scratches - 3) * sizeof(sljit_uw);
|
||||
compiler->saveds_start = locals_offset;
|
||||
if (saveds > 3)
|
||||
locals_offset += (saveds - 3) * sizeof(sljit_uw);
|
||||
compiler->locals_offset = locals_offset;
|
||||
SLJIT_COMPILE_ASSERT(SLJIT_LOCALS_OFFSET >= (2 + 4) * sizeof(sljit_uw), require_at_least_two_words);
|
||||
#if defined(__APPLE__)
|
||||
saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
|
||||
local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
|
||||
/* Ignore pushed registers and SLJIT_LOCALS_OFFSET when computing the aligned local size. */
|
||||
saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
|
||||
local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds;
|
||||
#else
|
||||
local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
|
||||
if (options & SLJIT_DOUBLE_ALIGNMENT) {
|
||||
local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7);
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 17);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(17);
|
||||
inst[0] = MOV_r_rm;
|
||||
inst[1] = MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[SLJIT_SP];
|
||||
inst[2] = GROUP_F7;
|
||||
inst[3] = MOD_REG | (0 << 3) | reg_map[SLJIT_SP];
|
||||
*(sljit_sw*)(inst + 4) = 0x4;
|
||||
inst[8] = JNE_i8;
|
||||
inst[9] = 6;
|
||||
inst[10] = GROUP_BINARY_81;
|
||||
inst[11] = MOD_REG | (5 << 3) | reg_map[SLJIT_SP];
|
||||
*(sljit_sw*)(inst + 12) = 0x4;
|
||||
inst[16] = PUSH_r + reg_map[TMP_REG1];
|
||||
}
|
||||
else
|
||||
local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3);
|
||||
#endif
|
||||
|
||||
compiler->local_size = local_size;
|
||||
#ifdef _WIN32
|
||||
if (local_size > 1024) {
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
|
||||
FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
|
||||
#else
|
||||
local_size -= FIXED_LOCALS_OFFSET;
|
||||
FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
|
||||
local_size -= SLJIT_LOCALS_OFFSET;
|
||||
FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
|
||||
FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
|
||||
SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, FIXED_LOCALS_OFFSET));
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, SLJIT_LOCALS_OFFSET));
|
||||
#endif
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
|
||||
}
|
||||
|
|
@ -173,41 +180,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
|||
|
||||
SLJIT_ASSERT(local_size > 0);
|
||||
return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
|
||||
SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_si locals_offset;
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
compiler->args = args;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
locals_offset = 2 * sizeof(sljit_uw);
|
||||
#else
|
||||
locals_offset = FIXED_LOCALS_OFFSET;
|
||||
#endif
|
||||
compiler->scratches_start = locals_offset;
|
||||
if (scratches > 3)
|
||||
locals_offset += (scratches - 3) * sizeof(sljit_uw);
|
||||
compiler->saveds_start = locals_offset;
|
||||
if (saveds > 3)
|
||||
locals_offset += (saveds - 3) * sizeof(sljit_uw);
|
||||
compiler->locals_offset = locals_offset;
|
||||
#if defined(__APPLE__)
|
||||
saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
|
||||
compiler->local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
|
||||
saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
|
||||
compiler->local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds;
|
||||
#else
|
||||
compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
|
||||
if (options & SLJIT_DOUBLE_ALIGNMENT)
|
||||
compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7);
|
||||
else
|
||||
compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3);
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
|
|
@ -216,7 +211,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
|||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
SLJIT_ASSERT(compiler->args >= 0);
|
||||
|
||||
compiler->flags_saved = 0;
|
||||
|
|
@ -224,9 +219,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
|||
|
||||
SLJIT_ASSERT(compiler->local_size > 0);
|
||||
FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
|
||||
|
||||
size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
|
||||
#if !defined(__APPLE__)
|
||||
if (compiler->options & SLJIT_DOUBLE_ALIGNMENT) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 3);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(3);
|
||||
inst[0] = MOV_r_rm;
|
||||
inst[1] = (reg_map[SLJIT_SP] << 3) | 0x4 /* SIB */;
|
||||
inst[2] = (4 << 3) | reg_map[SLJIT_SP];
|
||||
}
|
||||
#endif
|
||||
|
||||
size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) +
|
||||
(compiler->saveds <= 3 ? compiler->saveds : 3);
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (compiler->args > 2)
|
||||
size += 2;
|
||||
|
|
@ -239,12 +247,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
|||
|
||||
INC_SIZE(size);
|
||||
|
||||
if (compiler->saveds > 0)
|
||||
POP_REG(reg_map[SLJIT_SAVED_REG1]);
|
||||
if (compiler->saveds > 1)
|
||||
POP_REG(reg_map[SLJIT_SAVED_REG2]);
|
||||
if (compiler->saveds > 2)
|
||||
POP_REG(reg_map[SLJIT_SAVED_REG3]);
|
||||
if (compiler->saveds > 0 || compiler->scratches > 9)
|
||||
POP_REG(reg_map[SLJIT_S0]);
|
||||
if (compiler->saveds > 1 || compiler->scratches > 8)
|
||||
POP_REG(reg_map[SLJIT_S1]);
|
||||
if (compiler->saveds > 2 || compiler->scratches > 7)
|
||||
POP_REG(reg_map[SLJIT_S2]);
|
||||
POP_REG(reg_map[TMP_REG1]);
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (compiler->args > 2)
|
||||
|
|
@ -280,21 +288,17 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
|
||||
/* Both size flags cannot be switched on. */
|
||||
SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
/* SSE2 and immediate is not possible. */
|
||||
SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
|
||||
SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
|
||||
&& (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
|
||||
&& (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
|
||||
#endif
|
||||
|
||||
size &= 0xf;
|
||||
inst_size = size;
|
||||
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
|
||||
inst_size++;
|
||||
#endif
|
||||
if (flags & EX86_PREF_66)
|
||||
inst_size++;
|
||||
|
||||
|
|
@ -311,8 +315,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
inst_size += sizeof(sljit_sw);
|
||||
}
|
||||
|
||||
if ((b & REG_MASK) == SLJIT_LOCALS_REG && !(b & OFFS_REG_MASK))
|
||||
b |= TO_OFFS_REG(SLJIT_LOCALS_REG);
|
||||
if ((b & REG_MASK) == SLJIT_SP && !(b & OFFS_REG_MASK))
|
||||
b |= TO_OFFS_REG(SLJIT_SP);
|
||||
|
||||
if ((b & OFFS_REG_MASK) != SLJIT_UNUSED)
|
||||
inst_size += 1; /* SIB byte. */
|
||||
|
|
@ -348,12 +352,10 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
|
||||
/* Encoding the byte. */
|
||||
INC_SIZE(inst_size);
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
if (flags & EX86_PREF_F2)
|
||||
*inst++ = 0xf2;
|
||||
if (flags & EX86_PREF_F3)
|
||||
*inst++ = 0xf3;
|
||||
#endif
|
||||
if (flags & EX86_PREF_66)
|
||||
*inst++ = 0x66;
|
||||
|
||||
|
|
@ -366,15 +368,10 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
|
||||
if ((a & SLJIT_IMM) || (a == 0))
|
||||
*buf_ptr = 0;
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
else if (!(flags & EX86_SSE2))
|
||||
else if (!(flags & EX86_SSE2_OP1))
|
||||
*buf_ptr = reg_map[a] << 3;
|
||||
else
|
||||
*buf_ptr = a << 3;
|
||||
#else
|
||||
else
|
||||
*buf_ptr = reg_map[a] << 3;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (a & SLJIT_IMM) {
|
||||
|
|
@ -388,13 +385,9 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
}
|
||||
|
||||
if (!(b & SLJIT_MEM))
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_map[b] : b);
|
||||
#else
|
||||
*buf_ptr++ |= MOD_REG + reg_map[b];
|
||||
#endif
|
||||
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_map[b] : b);
|
||||
else if ((b & REG_MASK) != SLJIT_UNUSED) {
|
||||
if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_LOCALS_REG)) {
|
||||
if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
|
||||
if (immb != 0) {
|
||||
if (immb <= 127 && immb >= -128)
|
||||
*buf_ptr |= 0x40;
|
||||
|
|
@ -455,28 +448,28 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj
|
|||
INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
|
||||
|
||||
if (type >= SLJIT_CALL3)
|
||||
PUSH_REG(reg_map[SLJIT_SCRATCH_REG3]);
|
||||
PUSH_REG(reg_map[SLJIT_R2]);
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SCRATCH_REG3] << 3) | reg_map[SLJIT_SCRATCH_REG1];
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0];
|
||||
#else
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4 * (type - SLJIT_CALL0));
|
||||
|
||||
*inst++ = MOV_rm_r;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG1] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_R0] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
|
||||
*inst++ = 0;
|
||||
if (type >= SLJIT_CALL2) {
|
||||
*inst++ = MOV_rm_r;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG2] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_R1] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
|
||||
*inst++ = sizeof(sljit_sw);
|
||||
}
|
||||
if (type >= SLJIT_CALL3) {
|
||||
*inst++ = MOV_rm_r;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG3] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_R2] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
|
||||
*inst++ = 2 * sizeof(sljit_sw);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -488,7 +481,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
|||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
CHECK_EXTRA_REGS(dst, dstw, (void)0);
|
||||
|
|
@ -519,7 +512,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
|||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
|
|
|
|||
|
|
@ -87,118 +87,88 @@ static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si
|
|||
return code_ptr;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_si size, pushed_size;
|
||||
sljit_si i, tmp, size, saved_register_size;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
compiler->flags_saved = 0;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
size = saveds;
|
||||
/* Including the return address saved by the call instruction. */
|
||||
pushed_size = (saveds + 1) * sizeof(sljit_sw);
|
||||
#ifndef _WIN64
|
||||
if (saveds >= 2)
|
||||
size += saveds - 1;
|
||||
#else
|
||||
if (saveds >= 4)
|
||||
size += saveds - 3;
|
||||
if (scratches >= 5) {
|
||||
size += (5 - 4) * 2;
|
||||
pushed_size += sizeof(sljit_sw);
|
||||
saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
size = reg_map[i] >= 8 ? 2 : 1;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
if (reg_map[i] >= 8)
|
||||
*inst++ = REX_B;
|
||||
PUSH_REG(reg_lmap[i]);
|
||||
}
|
||||
#endif
|
||||
size += args * 3;
|
||||
if (size > 0) {
|
||||
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
size = reg_map[i] >= 8 ? 2 : 1;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
if (reg_map[i] >= 8)
|
||||
*inst++ = REX_B;
|
||||
PUSH_REG(reg_lmap[i]);
|
||||
}
|
||||
|
||||
if (args > 0) {
|
||||
size = args * 3;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(size);
|
||||
if (saveds >= 5) {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg);
|
||||
*inst++ = REX_B;
|
||||
PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]);
|
||||
}
|
||||
if (saveds >= 4) {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg);
|
||||
*inst++ = REX_B;
|
||||
PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]);
|
||||
}
|
||||
if (saveds >= 3) {
|
||||
#ifndef _WIN64
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg);
|
||||
*inst++ = REX_B;
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg);
|
||||
#endif
|
||||
PUSH_REG(reg_lmap[SLJIT_SAVED_REG3]);
|
||||
}
|
||||
if (saveds >= 2) {
|
||||
#ifndef _WIN64
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg);
|
||||
*inst++ = REX_B;
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg);
|
||||
#endif
|
||||
PUSH_REG(reg_lmap[SLJIT_SAVED_REG2]);
|
||||
}
|
||||
if (saveds >= 1) {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG1] < 8, saved_reg1_is_loreg);
|
||||
PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]);
|
||||
}
|
||||
#ifdef _WIN64
|
||||
if (scratches >= 5) {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);
|
||||
*inst++ = REX_B;
|
||||
PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN64
|
||||
if (args > 0) {
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7 /* rdi */;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */;
|
||||
}
|
||||
if (args > 1) {
|
||||
*inst++ = REX_W | REX_R;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6 /* rsi */;
|
||||
*inst++ = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */;
|
||||
}
|
||||
if (args > 2) {
|
||||
*inst++ = REX_W | REX_R;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2 /* rdx */;
|
||||
*inst++ = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */;
|
||||
}
|
||||
#else
|
||||
if (args > 0) {
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1 /* rcx */;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */;
|
||||
}
|
||||
if (args > 1) {
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2 /* rdx */;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */;
|
||||
}
|
||||
if (args > 2) {
|
||||
*inst++ = REX_W | REX_B;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0 /* r8 */;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
|
||||
local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size;
|
||||
compiler->local_size = local_size;
|
||||
|
||||
#ifdef _WIN64
|
||||
if (local_size > 1024) {
|
||||
/* Allocate stack for the callback, which grows the stack. */
|
||||
|
|
@ -208,9 +178,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
|||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_83;
|
||||
*inst++ = MOD_REG | SUB | 4;
|
||||
/* Pushed size must be divisible by 8. */
|
||||
SLJIT_ASSERT(!(pushed_size & 0x7));
|
||||
if (pushed_size & 0x8) {
|
||||
/* Allocated size for registers must be divisible by 8. */
|
||||
SLJIT_ASSERT(!(saved_register_size & 0x7));
|
||||
/* Aligned to 16 byte. */
|
||||
if (saved_register_size & 0x8) {
|
||||
*inst++ = 5 * sizeof(sljit_sw);
|
||||
local_size -= 5 * sizeof(sljit_sw);
|
||||
} else {
|
||||
|
|
@ -218,17 +189,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
|||
local_size -= 4 * sizeof(sljit_sw);
|
||||
}
|
||||
/* Second instruction */
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] < 8, temporary_reg1_is_loreg);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] < 8, temporary_reg1_is_loreg);
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_rm_i32;
|
||||
*inst++ = MOD_REG | reg_lmap[SLJIT_SCRATCH_REG1];
|
||||
*inst++ = MOD_REG | reg_lmap[SLJIT_R0];
|
||||
*(sljit_si*)inst = local_size;
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
|
||||
}
|
||||
#endif
|
||||
|
||||
SLJIT_ASSERT(local_size > 0);
|
||||
if (local_size <= 127) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
|
||||
|
|
@ -249,59 +222,59 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
|||
*(sljit_si*)inst = local_size;
|
||||
inst += sizeof(sljit_si);
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
/* Save xmm6 with MOVAPS instruction. */
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(5);
|
||||
*inst++ = GROUP_0F;
|
||||
*(sljit_si*)inst = 0x20247429;
|
||||
/* Save xmm6 register: movaps [rsp + 0x20], xmm6 */
|
||||
if (fscratches >= 6 || fsaveds >= 1) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(5);
|
||||
*inst++ = GROUP_0F;
|
||||
*(sljit_si*)inst = 0x20247429;
|
||||
}
|
||||
#endif
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_si pushed_size;
|
||||
sljit_si saved_register_size;
|
||||
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
/* Including the return address saved by the call instruction. */
|
||||
pushed_size = (saveds + 1) * sizeof(sljit_sw);
|
||||
#ifdef _WIN64
|
||||
if (scratches >= 5)
|
||||
pushed_size += sizeof(sljit_sw);
|
||||
#endif
|
||||
compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
|
||||
saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
compiler->local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si size;
|
||||
sljit_si i, tmp, size;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
|
||||
compiler->flags_saved = 0;
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
|
||||
#ifdef _WIN64
|
||||
/* Restore xmm6 with MOVAPS instruction. */
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(5);
|
||||
*inst++ = GROUP_0F;
|
||||
*(sljit_si*)inst = 0x20247428;
|
||||
/* Restore xmm6 register: movaps xmm6, [rsp + 0x20] */
|
||||
if (compiler->fscratches >= 6 || compiler->fsaveds >= 1) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(5);
|
||||
*inst++ = GROUP_0F;
|
||||
*(sljit_si*)inst = 0x20247428;
|
||||
}
|
||||
#endif
|
||||
|
||||
SLJIT_ASSERT(compiler->local_size > 0);
|
||||
if (compiler->local_size <= 127) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
|
||||
|
|
@ -322,50 +295,31 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
|||
*(sljit_si*)inst = compiler->local_size;
|
||||
}
|
||||
|
||||
size = 1 + compiler->saveds;
|
||||
#ifndef _WIN64
|
||||
if (compiler->saveds >= 2)
|
||||
size += compiler->saveds - 1;
|
||||
#else
|
||||
if (compiler->saveds >= 4)
|
||||
size += compiler->saveds - 3;
|
||||
if (compiler->scratches >= 5)
|
||||
size += (5 - 4) * 2;
|
||||
#endif
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
tmp = compiler->scratches;
|
||||
for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
|
||||
size = reg_map[i] >= 8 ? 2 : 1;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
if (reg_map[i] >= 8)
|
||||
*inst++ = REX_B;
|
||||
POP_REG(reg_lmap[i]);
|
||||
}
|
||||
|
||||
tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = tmp; i <= SLJIT_S0; i++) {
|
||||
size = reg_map[i] >= 8 ? 2 : 1;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
if (reg_map[i] >= 8)
|
||||
*inst++ = REX_B;
|
||||
POP_REG(reg_lmap[i]);
|
||||
}
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(size);
|
||||
|
||||
#ifdef _WIN64
|
||||
if (compiler->scratches >= 5) {
|
||||
*inst++ = REX_B;
|
||||
POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
|
||||
}
|
||||
#endif
|
||||
if (compiler->saveds >= 1)
|
||||
POP_REG(reg_map[SLJIT_SAVED_REG1]);
|
||||
if (compiler->saveds >= 2) {
|
||||
#ifndef _WIN64
|
||||
*inst++ = REX_B;
|
||||
#endif
|
||||
POP_REG(reg_lmap[SLJIT_SAVED_REG2]);
|
||||
}
|
||||
if (compiler->saveds >= 3) {
|
||||
#ifndef _WIN64
|
||||
*inst++ = REX_B;
|
||||
#endif
|
||||
POP_REG(reg_lmap[SLJIT_SAVED_REG3]);
|
||||
}
|
||||
if (compiler->saveds >= 4) {
|
||||
*inst++ = REX_B;
|
||||
POP_REG(reg_lmap[SLJIT_SAVED_EREG1]);
|
||||
}
|
||||
if (compiler->saveds >= 5) {
|
||||
*inst++ = REX_B;
|
||||
POP_REG(reg_lmap[SLJIT_SAVED_EREG2]);
|
||||
}
|
||||
|
||||
INC_SIZE(1);
|
||||
RET();
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -409,72 +363,67 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
|
||||
/* Both size flags cannot be switched on. */
|
||||
SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
/* SSE2 and immediate is not possible. */
|
||||
SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
|
||||
SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
|
||||
&& (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
|
||||
&& (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
|
||||
#endif
|
||||
|
||||
size &= 0xf;
|
||||
inst_size = size;
|
||||
|
||||
if ((b & SLJIT_MEM) && !(b & OFFS_REG_MASK) && NOT_HALFWORD(immb)) {
|
||||
if (emit_load_imm64(compiler, TMP_REG3, immb))
|
||||
return NULL;
|
||||
immb = 0;
|
||||
if (b & REG_MASK)
|
||||
b |= TO_OFFS_REG(TMP_REG3);
|
||||
else
|
||||
b |= TMP_REG3;
|
||||
}
|
||||
|
||||
if (!compiler->mode32 && !(flags & EX86_NO_REXW))
|
||||
rex |= REX_W;
|
||||
else if (flags & EX86_REX)
|
||||
rex |= REX;
|
||||
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
|
||||
inst_size++;
|
||||
#endif
|
||||
if (flags & EX86_PREF_66)
|
||||
inst_size++;
|
||||
|
||||
/* Calculate size of b. */
|
||||
inst_size += 1; /* mod r/m byte. */
|
||||
if (b & SLJIT_MEM) {
|
||||
if (!(b & OFFS_REG_MASK)) {
|
||||
if (NOT_HALFWORD(immb)) {
|
||||
if (emit_load_imm64(compiler, TMP_REG3, immb))
|
||||
return NULL;
|
||||
immb = 0;
|
||||
if (b & REG_MASK)
|
||||
b |= TO_OFFS_REG(TMP_REG3);
|
||||
else
|
||||
b |= TMP_REG3;
|
||||
}
|
||||
else if (reg_lmap[b & REG_MASK] == 4)
|
||||
b |= TO_OFFS_REG(SLJIT_SP);
|
||||
}
|
||||
|
||||
if ((b & REG_MASK) == SLJIT_UNUSED)
|
||||
inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */
|
||||
else {
|
||||
if (reg_map[b & REG_MASK] >= 8)
|
||||
rex |= REX_B;
|
||||
if (immb != 0 && !(b & OFFS_REG_MASK)) {
|
||||
|
||||
if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) {
|
||||
/* Immediate operand. */
|
||||
if (immb <= 127 && immb >= -128)
|
||||
inst_size += sizeof(sljit_sb);
|
||||
else
|
||||
inst_size += sizeof(sljit_si);
|
||||
}
|
||||
}
|
||||
else if (reg_lmap[b & REG_MASK] == 5)
|
||||
inst_size += sizeof(sljit_sb);
|
||||
|
||||
if ((b & REG_MASK) == SLJIT_LOCALS_REG && !(b & OFFS_REG_MASK))
|
||||
b |= TO_OFFS_REG(SLJIT_LOCALS_REG);
|
||||
|
||||
if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) {
|
||||
inst_size += 1; /* SIB byte. */
|
||||
if (reg_map[OFFS_REG(b)] >= 8)
|
||||
rex |= REX_X;
|
||||
if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) {
|
||||
inst_size += 1; /* SIB byte. */
|
||||
if (reg_map[OFFS_REG(b)] >= 8)
|
||||
rex |= REX_X;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
else if (!(flags & EX86_SSE2) && reg_map[b] >= 8)
|
||||
else if (!(flags & EX86_SSE2_OP2) && reg_map[b] >= 8)
|
||||
rex |= REX_B;
|
||||
#else
|
||||
else if (reg_map[b] >= 8)
|
||||
rex |= REX_B;
|
||||
#endif
|
||||
|
||||
if (a & SLJIT_IMM) {
|
||||
if (flags & EX86_BIN_INS) {
|
||||
|
|
@ -500,13 +449,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
else {
|
||||
SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
|
||||
/* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
if (!(flags & EX86_SSE2) && reg_map[a] >= 8)
|
||||
if (!(flags & EX86_SSE2_OP1) && reg_map[a] >= 8)
|
||||
rex |= REX_R;
|
||||
#else
|
||||
if (reg_map[a] >= 8)
|
||||
rex |= REX_R;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (rex)
|
||||
|
|
@ -517,12 +461,10 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
|
||||
/* Encoding the byte. */
|
||||
INC_SIZE(inst_size);
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
if (flags & EX86_PREF_F2)
|
||||
*inst++ = 0xf2;
|
||||
if (flags & EX86_PREF_F3)
|
||||
*inst++ = 0xf3;
|
||||
#endif
|
||||
if (flags & EX86_PREF_66)
|
||||
*inst++ = 0x66;
|
||||
if (rex)
|
||||
|
|
@ -536,15 +478,10 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
|
||||
if ((a & SLJIT_IMM) || (a == 0))
|
||||
*buf_ptr = 0;
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
else if (!(flags & EX86_SSE2))
|
||||
else if (!(flags & EX86_SSE2_OP1))
|
||||
*buf_ptr = reg_lmap[a] << 3;
|
||||
else
|
||||
*buf_ptr = a << 3;
|
||||
#else
|
||||
else
|
||||
*buf_ptr = reg_lmap[a] << 3;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (a & SLJIT_IMM) {
|
||||
|
|
@ -558,14 +495,10 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
}
|
||||
|
||||
if (!(b & SLJIT_MEM))
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
|
||||
#else
|
||||
*buf_ptr++ |= MOD_REG + reg_lmap[b];
|
||||
#endif
|
||||
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : b);
|
||||
else if ((b & REG_MASK) != SLJIT_UNUSED) {
|
||||
if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_LOCALS_REG)) {
|
||||
if (immb != 0) {
|
||||
if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
|
||||
if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
|
||||
if (immb <= 127 && immb >= -128)
|
||||
*buf_ptr |= 0x40;
|
||||
else
|
||||
|
|
@ -579,7 +512,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
*buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3);
|
||||
}
|
||||
|
||||
if (immb != 0) {
|
||||
if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
|
||||
if (immb <= 127 && immb >= -128)
|
||||
*buf_ptr++ = immb; /* 8 bit displacement. */
|
||||
else {
|
||||
|
|
@ -589,8 +522,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (reg_lmap[b & REG_MASK] == 5)
|
||||
*buf_ptr |= 0x40;
|
||||
*buf_ptr++ |= 0x04;
|
||||
*buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6);
|
||||
if (reg_lmap[b & REG_MASK] == 5)
|
||||
*buf_ptr++ = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -621,7 +558,7 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj
|
|||
sljit_ub *inst;
|
||||
|
||||
#ifndef _WIN64
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 6 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!inst);
|
||||
|
|
@ -629,13 +566,13 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj
|
|||
if (type >= SLJIT_CALL3) {
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3];
|
||||
*inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_R2];
|
||||
}
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1];
|
||||
*inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_R0];
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 2 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!inst);
|
||||
|
|
@ -643,11 +580,11 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj
|
|||
if (type >= SLJIT_CALL3) {
|
||||
*inst++ = REX_W | REX_R;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3];
|
||||
*inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_R2];
|
||||
}
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1];
|
||||
*inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_R0];
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -657,7 +594,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
|||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
/* For UNUSED dst. Uncommon, but possible. */
|
||||
|
|
@ -694,7 +631,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
|||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
|
||||
|
|
|
|||
|
|
@ -64,51 +64,46 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
|
|||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
/* Last register + 1. */
|
||||
#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = {
|
||||
0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = {
|
||||
0, 0, 2, 1, 0, 0, 0, 0, 7, 6, 3, 4, 5
|
||||
};
|
||||
|
||||
#define CHECK_EXTRA_REGS(p, w, do) \
|
||||
if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \
|
||||
w = compiler->scratches_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_sw); \
|
||||
p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
|
||||
do; \
|
||||
} \
|
||||
else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \
|
||||
w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_sw); \
|
||||
p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
|
||||
if (p >= SLJIT_R3 && p <= SLJIT_R6) { \
|
||||
w = SLJIT_LOCALS_OFFSET + ((p) - (SLJIT_R3 + 4)) * sizeof(sljit_sw); \
|
||||
p = SLJIT_MEM1(SLJIT_SP); \
|
||||
do; \
|
||||
}
|
||||
|
||||
#else /* SLJIT_CONFIG_X86_32 */
|
||||
|
||||
/* Last register + 1. */
|
||||
#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
|
||||
#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
|
||||
#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
|
||||
|
||||
/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
|
||||
Note: avoid to use r12 and r13 for memory addessing
|
||||
therefore r12 is better for SAVED_EREG than SAVED_REG. */
|
||||
#ifndef _WIN64
|
||||
/* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
|
||||
0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
0, 0, 6, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 7, 9
|
||||
};
|
||||
/* low-map. reg_map & 0x7. */
|
||||
static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
|
||||
0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1
|
||||
static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
0, 0, 6, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 7, 1
|
||||
};
|
||||
#else
|
||||
/* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
|
||||
0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 15, 4, 10, 8, 9
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
0, 0, 2, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 10, 8, 9
|
||||
};
|
||||
/* low-map. reg_map & 0x7. */
|
||||
static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
|
||||
0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 7, 4, 2, 0, 1
|
||||
static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
0, 0, 2, 1, 3, 4, 5, 5, 6, 7, 7, 6, 3, 4, 2, 0, 1
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -133,9 +128,7 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
|
|||
|
||||
#endif /* SLJIT_CONFIG_X86_32 */
|
||||
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
#define TMP_FREG (0)
|
||||
#endif
|
||||
|
||||
/* Size flags for emit_x86_instruction: */
|
||||
#define EX86_BIN_INS 0x0010
|
||||
|
|
@ -145,12 +138,11 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
|
|||
#define EX86_BYTE_ARG 0x0100
|
||||
#define EX86_HALF_ARG 0x0200
|
||||
#define EX86_PREF_66 0x0400
|
||||
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
#define EX86_SSE2 0x0800
|
||||
#define EX86_PREF_F2 0x1000
|
||||
#define EX86_PREF_F3 0x2000
|
||||
#endif
|
||||
#define EX86_PREF_F2 0x0800
|
||||
#define EX86_PREF_F3 0x1000
|
||||
#define EX86_SSE2_OP1 0x2000
|
||||
#define EX86_SSE2_OP2 0x4000
|
||||
#define EX86_SSE2 (EX86_SSE2_OP1 | EX86_SSE2_OP2)
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Instrucion forms */
|
||||
|
|
@ -179,6 +171,9 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
|
|||
#define CMP_EAX_i32 0x3d
|
||||
#define CMP_r_rm 0x3b
|
||||
#define CMP_rm_r 0x39
|
||||
#define CVTPD2PS_x_xm 0x5a
|
||||
#define CVTSI2SD_x_rm 0x2a
|
||||
#define CVTTSD2SI_r_xm 0x2c
|
||||
#define DIV (/* GROUP_F7 */ 6 << 3)
|
||||
#define DIVSD_x_xm 0x5e
|
||||
#define INT3 0xcc
|
||||
|
|
@ -188,6 +183,7 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
|
|||
#define IMUL_r_rm_i8 0x6b
|
||||
#define IMUL_r_rm_i32 0x69
|
||||
#define JE_i8 0x74
|
||||
#define JNE_i8 0x75
|
||||
#define JMP_i8 0xeb
|
||||
#define JMP_i32 0xe9
|
||||
#define JMP_rm (/* GROUP_FF */ 4 << 3)
|
||||
|
|
@ -239,6 +235,7 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
|
|||
#define TEST_EAX_i32 0xa9
|
||||
#define TEST_rm_r 0x85
|
||||
#define UCOMISD_x_xm 0x2e
|
||||
#define UNPCKLPD_x_xm 0x14
|
||||
#define XCHG_EAX_r 0x90
|
||||
#define XCHG_r_rm 0x87
|
||||
#define XOR (/* BINARY */ 6 << 3)
|
||||
|
|
@ -271,14 +268,12 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
|
|||
/* Multithreading does not affect these static variables, since they store
|
||||
built-in CPU features. Therefore they can be overwritten by different threads
|
||||
if they detect the CPU features in the same time. */
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2) && (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
|
||||
#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
|
||||
static sljit_si cpu_has_sse2 = -1;
|
||||
#endif
|
||||
static sljit_si cpu_has_cmov = -1;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#include <cmnintrin.h>
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -327,7 +322,7 @@ static void get_cpu_features(void)
|
|||
|
||||
#endif /* _MSC_VER && _MSC_VER >= 1400 */
|
||||
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2) && (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
|
||||
#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
|
||||
cpu_has_sse2 = (features >> 26) & 0x1;
|
||||
#endif
|
||||
cpu_has_cmov = (features >> 15) & 0x1;
|
||||
|
|
@ -336,54 +331,54 @@ static void get_cpu_features(void)
|
|||
static sljit_ub get_jump_code(sljit_si type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_C_EQUAL:
|
||||
case SLJIT_C_FLOAT_EQUAL:
|
||||
case SLJIT_EQUAL:
|
||||
case SLJIT_D_EQUAL:
|
||||
return 0x84 /* je */;
|
||||
|
||||
case SLJIT_C_NOT_EQUAL:
|
||||
case SLJIT_C_FLOAT_NOT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL:
|
||||
case SLJIT_D_NOT_EQUAL:
|
||||
return 0x85 /* jne */;
|
||||
|
||||
case SLJIT_C_LESS:
|
||||
case SLJIT_C_FLOAT_LESS:
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_LESS:
|
||||
return 0x82 /* jc */;
|
||||
|
||||
case SLJIT_C_GREATER_EQUAL:
|
||||
case SLJIT_C_FLOAT_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_GREATER_EQUAL:
|
||||
return 0x83 /* jae */;
|
||||
|
||||
case SLJIT_C_GREATER:
|
||||
case SLJIT_C_FLOAT_GREATER:
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER:
|
||||
return 0x87 /* jnbe */;
|
||||
|
||||
case SLJIT_C_LESS_EQUAL:
|
||||
case SLJIT_C_FLOAT_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
return 0x86 /* jbe */;
|
||||
|
||||
case SLJIT_C_SIG_LESS:
|
||||
case SLJIT_SIG_LESS:
|
||||
return 0x8c /* jl */;
|
||||
|
||||
case SLJIT_C_SIG_GREATER_EQUAL:
|
||||
case SLJIT_SIG_GREATER_EQUAL:
|
||||
return 0x8d /* jnl */;
|
||||
|
||||
case SLJIT_C_SIG_GREATER:
|
||||
case SLJIT_SIG_GREATER:
|
||||
return 0x8f /* jnle */;
|
||||
|
||||
case SLJIT_C_SIG_LESS_EQUAL:
|
||||
case SLJIT_SIG_LESS_EQUAL:
|
||||
return 0x8e /* jle */;
|
||||
|
||||
case SLJIT_C_OVERFLOW:
|
||||
case SLJIT_C_MUL_OVERFLOW:
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
return 0x80 /* jo */;
|
||||
|
||||
case SLJIT_C_NOT_OVERFLOW:
|
||||
case SLJIT_C_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
return 0x81 /* jno */;
|
||||
|
||||
case SLJIT_C_FLOAT_UNORDERED:
|
||||
case SLJIT_D_UNORDERED:
|
||||
return 0x8a /* jp */;
|
||||
|
||||
case SLJIT_C_FLOAT_ORDERED:
|
||||
case SLJIT_D_ORDERED:
|
||||
return 0x8b /* jpo */;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -462,7 +457,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
struct sljit_const *const_;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_generate_code(compiler);
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
/* Second code generation pass. */
|
||||
|
|
@ -730,7 +725,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op0(compiler, op);
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_BREAKPOINT:
|
||||
|
|
@ -745,22 +740,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
INC_SIZE(1);
|
||||
*inst = NOP;
|
||||
break;
|
||||
case SLJIT_UMUL:
|
||||
case SLJIT_SMUL:
|
||||
case SLJIT_UDIV:
|
||||
case SLJIT_SDIV:
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
compiler->flags_saved = 0;
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
#ifdef _WIN64
|
||||
SLJIT_COMPILE_ASSERT(
|
||||
reg_map[SLJIT_SCRATCH_REG1] == 0
|
||||
&& reg_map[SLJIT_SCRATCH_REG2] == 2
|
||||
reg_map[SLJIT_R0] == 0
|
||||
&& reg_map[SLJIT_R1] == 2
|
||||
&& reg_map[TMP_REG1] > 7,
|
||||
invalid_register_assignment_for_div_mul);
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(
|
||||
reg_map[SLJIT_SCRATCH_REG1] == 0
|
||||
&& reg_map[SLJIT_SCRATCH_REG2] < 7
|
||||
reg_map[SLJIT_R0] == 0
|
||||
&& reg_map[SLJIT_R1] < 7
|
||||
&& reg_map[TMP_REG1] == 2,
|
||||
invalid_register_assignment_for_div_mul);
|
||||
#endif
|
||||
|
|
@ -768,10 +763,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
#endif
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
if (op == SLJIT_UDIV) {
|
||||
if (op == SLJIT_LUDIV) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_SCRATCH_REG2, 0);
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0);
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0);
|
||||
#else
|
||||
inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0);
|
||||
#endif
|
||||
|
|
@ -779,9 +774,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
*inst = XOR_r_rm;
|
||||
}
|
||||
|
||||
if (op == SLJIT_SDIV) {
|
||||
if (op == SLJIT_LSDIV) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_SCRATCH_REG2, 0);
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
|
@ -810,10 +805,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
FAIL_IF(!inst);
|
||||
INC_SIZE(2);
|
||||
*inst++ = GROUP_F7;
|
||||
*inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_map[TMP_REG1] : reg_map[SLJIT_SCRATCH_REG2]);
|
||||
*inst = MOD_REG | ((op >= SLJIT_LUDIV) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]);
|
||||
#else
|
||||
#ifdef _WIN64
|
||||
size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2;
|
||||
size = (!compiler->mode32 || op >= SLJIT_LUDIV) ? 3 : 2;
|
||||
#else
|
||||
size = (!compiler->mode32) ? 3 : 2;
|
||||
#endif
|
||||
|
|
@ -822,34 +817,34 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
|||
INC_SIZE(size);
|
||||
#ifdef _WIN64
|
||||
if (!compiler->mode32)
|
||||
*inst++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0);
|
||||
else if (op >= SLJIT_UDIV)
|
||||
*inst++ = REX_W | ((op >= SLJIT_LUDIV) ? REX_B : 0);
|
||||
else if (op >= SLJIT_LUDIV)
|
||||
*inst++ = REX_B;
|
||||
*inst++ = GROUP_F7;
|
||||
*inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_SCRATCH_REG2]);
|
||||
*inst = MOD_REG | ((op >= SLJIT_LUDIV) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]);
|
||||
#else
|
||||
if (!compiler->mode32)
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_F7;
|
||||
*inst = MOD_REG | reg_map[SLJIT_SCRATCH_REG2];
|
||||
*inst = MOD_REG | reg_map[SLJIT_R1];
|
||||
#endif
|
||||
#endif
|
||||
switch (op) {
|
||||
case SLJIT_UMUL:
|
||||
case SLJIT_LUMUL:
|
||||
*inst |= MUL;
|
||||
break;
|
||||
case SLJIT_SMUL:
|
||||
case SLJIT_LSMUL:
|
||||
*inst |= IMUL;
|
||||
break;
|
||||
case SLJIT_UDIV:
|
||||
case SLJIT_LUDIV:
|
||||
*inst |= DIV;
|
||||
break;
|
||||
case SLJIT_SDIV:
|
||||
case SLJIT_LSDIV:
|
||||
*inst |= IDIV;
|
||||
break;
|
||||
}
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
|
||||
EMIT_MOV(compiler, SLJIT_SCRATCH_REG2, 0, TMP_REG1, 0);
|
||||
EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
|
@ -958,22 +953,22 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign,
|
|||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
if (dst_r == TMP_REG1) {
|
||||
/* Find a non-used register, whose reg_map[src] < 4. */
|
||||
if ((dst & REG_MASK) == SLJIT_SCRATCH_REG1) {
|
||||
if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SCRATCH_REG2))
|
||||
work_r = SLJIT_SCRATCH_REG3;
|
||||
if ((dst & REG_MASK) == SLJIT_R0) {
|
||||
if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_R1))
|
||||
work_r = SLJIT_R2;
|
||||
else
|
||||
work_r = SLJIT_SCRATCH_REG2;
|
||||
work_r = SLJIT_R1;
|
||||
}
|
||||
else {
|
||||
if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SCRATCH_REG1))
|
||||
work_r = SLJIT_SCRATCH_REG1;
|
||||
else if ((dst & REG_MASK) == SLJIT_SCRATCH_REG2)
|
||||
work_r = SLJIT_SCRATCH_REG3;
|
||||
if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0))
|
||||
work_r = SLJIT_R0;
|
||||
else if ((dst & REG_MASK) == SLJIT_R1)
|
||||
work_r = SLJIT_R2;
|
||||
else
|
||||
work_r = SLJIT_SCRATCH_REG2;
|
||||
work_r = SLJIT_R1;
|
||||
}
|
||||
|
||||
if (work_r == SLJIT_SCRATCH_REG1) {
|
||||
if (work_r == SLJIT_R0) {
|
||||
ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]);
|
||||
}
|
||||
else {
|
||||
|
|
@ -986,7 +981,7 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign,
|
|||
FAIL_IF(!inst);
|
||||
*inst = MOV_rm8_r8;
|
||||
|
||||
if (work_r == SLJIT_SCRATCH_REG1) {
|
||||
if (work_r == SLJIT_R0) {
|
||||
ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]);
|
||||
}
|
||||
else {
|
||||
|
|
@ -1181,12 +1176,12 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags,
|
|||
dst_r = dst;
|
||||
else {
|
||||
/* Find an unused temporary register. */
|
||||
if ((dst & REG_MASK) != SLJIT_SCRATCH_REG1 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SCRATCH_REG1))
|
||||
dst_r = SLJIT_SCRATCH_REG1;
|
||||
else if ((dst & REG_MASK) != SLJIT_SCRATCH_REG2 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SCRATCH_REG2))
|
||||
dst_r = SLJIT_SCRATCH_REG2;
|
||||
if ((dst & REG_MASK) != SLJIT_R0 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0))
|
||||
dst_r = SLJIT_R0;
|
||||
else if ((dst & REG_MASK) != SLJIT_R1 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R1))
|
||||
dst_r = SLJIT_R1;
|
||||
else
|
||||
dst_r = SLJIT_SCRATCH_REG3;
|
||||
dst_r = SLJIT_R2;
|
||||
EMIT_MOV(compiler, dst, dstw, dst_r, 0);
|
||||
}
|
||||
EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31);
|
||||
|
|
@ -1264,7 +1259,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
|
|
@ -1342,7 +1337,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) {
|
||||
SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG));
|
||||
SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP));
|
||||
dst = TMP_REG1;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1380,7 +1375,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
|||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1)
|
||||
return emit_mov(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), dstw, TMP_REG1, 0);
|
||||
return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0);
|
||||
#endif
|
||||
|
||||
if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & REG_MASK) && (dstw != 0 || (dst & OFFS_REG_MASK) != 0)) {
|
||||
|
|
@ -1472,9 +1467,9 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler,
|
|||
if (dst == src1 && dstw == src1w) {
|
||||
if (src2 & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
|
||||
if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
|
||||
#else
|
||||
if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128)) {
|
||||
if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {
|
||||
#endif
|
||||
BINARY_EAX_IMM(op_eax_imm, src2w);
|
||||
}
|
||||
|
|
@ -1506,9 +1501,9 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler,
|
|||
if (dst == src2 && dstw == src2w) {
|
||||
if (src1 & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if ((dst == SLJIT_SCRATCH_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
|
||||
if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
|
||||
#else
|
||||
if ((dst == SLJIT_SCRATCH_REG1) && (src1w > 127 || src1w < -128)) {
|
||||
if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128)) {
|
||||
#endif
|
||||
BINARY_EAX_IMM(op_eax_imm, src1w);
|
||||
}
|
||||
|
|
@ -1588,9 +1583,9 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler,
|
|||
if (dst == src1 && dstw == src1w) {
|
||||
if (src2 & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
|
||||
if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
|
||||
#else
|
||||
if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128)) {
|
||||
if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {
|
||||
#endif
|
||||
BINARY_EAX_IMM(op_eax_imm, src2w);
|
||||
}
|
||||
|
|
@ -1749,7 +1744,7 @@ static sljit_si emit_mul(struct sljit_compiler *compiler,
|
|||
*(sljit_si*)inst = (sljit_si)src2w;
|
||||
}
|
||||
else {
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src2w);
|
||||
if (dst_r != src1)
|
||||
EMIT_MOV(compiler, dst_r, 0, src1, src1w);
|
||||
inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
|
||||
|
|
@ -1842,9 +1837,9 @@ static sljit_si emit_cmp_binary(struct sljit_compiler *compiler,
|
|||
sljit_ub* inst;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
|
||||
if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
|
||||
#else
|
||||
if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
|
||||
if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
|
||||
#endif
|
||||
BINARY_EAX_IMM(CMP_EAX_i32, src2w);
|
||||
return SLJIT_SUCCESS;
|
||||
|
|
@ -1893,18 +1888,18 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler,
|
|||
sljit_ub* inst;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
|
||||
if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
|
||||
#else
|
||||
if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
|
||||
if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
|
||||
#endif
|
||||
BINARY_EAX_IMM(TEST_EAX_i32, src2w);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (src2 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
|
||||
if (src2 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
|
||||
#else
|
||||
if (src2 == SLJIT_SCRATCH_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
|
||||
if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
|
||||
#endif
|
||||
BINARY_EAX_IMM(TEST_EAX_i32, src1w);
|
||||
return SLJIT_SUCCESS;
|
||||
|
|
@ -2066,7 +2061,7 @@ static sljit_si emit_shift(struct sljit_compiler *compiler,
|
|||
EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
|
||||
#else
|
||||
/* [esp+0] contains the flags. */
|
||||
EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_sw), SLJIT_PREF_SHIFT_REG, 0);
|
||||
EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw), SLJIT_PREF_SHIFT_REG, 0);
|
||||
#endif
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
|
||||
inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
|
||||
|
|
@ -2075,7 +2070,7 @@ static sljit_si emit_shift(struct sljit_compiler *compiler,
|
|||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
|
||||
#else
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_sw));
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw));
|
||||
#endif
|
||||
EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
|
||||
}
|
||||
|
|
@ -2124,7 +2119,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
|
@ -2215,10 +2210,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2
|
||||
|| reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2)
|
||||
if (reg >= SLJIT_R3 && reg <= SLJIT_R6)
|
||||
return -1;
|
||||
#endif
|
||||
return reg_map[reg];
|
||||
|
|
@ -2226,7 +2220,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
|
||||
{
|
||||
check_sljit_get_float_register_index(reg);
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
|
@ -2236,8 +2230,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co
|
|||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_custom(compiler, instruction, size);
|
||||
SLJIT_ASSERT(size > 0 && size < 16);
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
|
@ -2250,8 +2243,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co
|
|||
/* Floating point operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
|
||||
/* Alignment + 2 * 16 bytes. */
|
||||
static sljit_si sse2_data[3 + (4 + 4) * 2];
|
||||
static sljit_si *sse2_buffer;
|
||||
|
|
@ -2269,27 +2260,19 @@ static void init_compiler(void)
|
|||
sse2_buffer[13] = 0x7fffffff;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
|
||||
{
|
||||
#ifdef SLJIT_IS_FPU_AVAILABLE
|
||||
return SLJIT_IS_FPU_AVAILABLE;
|
||||
#elif (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
|
||||
#elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
|
||||
if (cpu_has_sse2 == -1)
|
||||
get_cpu_features();
|
||||
return cpu_has_sse2;
|
||||
#else /* SLJIT_DETECT_SSE2 */
|
||||
return 1;
|
||||
#endif /* SLJIT_DETECT_SSE2 */
|
||||
#else /* SLJIT_SSE2 */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
|
||||
static sljit_si emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode,
|
||||
sljit_si single, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w)
|
||||
{
|
||||
|
|
@ -2326,31 +2309,89 @@ static SLJIT_INLINE sljit_si emit_sse2_store(struct sljit_compiler *compiler,
|
|||
return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
|
||||
sljit_ub *inst;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (GET_OPCODE(op) == SLJIT_CONVW_FROMD)
|
||||
compiler->mode32 = 0;
|
||||
#endif
|
||||
|
||||
inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = GROUP_0F;
|
||||
*inst = CVTTSD2SI_r_xm;
|
||||
|
||||
if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED)
|
||||
return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;
|
||||
sljit_ub *inst;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMW)
|
||||
compiler->mode32 = 0;
|
||||
#endif
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
|
||||
srcw = (sljit_si)srcw;
|
||||
#endif
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
|
||||
src = TMP_REG1;
|
||||
srcw = 0;
|
||||
}
|
||||
|
||||
inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = GROUP_0F;
|
||||
*inst = CVTSI2SD_x_rm;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = 1;
|
||||
#endif
|
||||
if (dst_r == TMP_FREG)
|
||||
return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
compiler->flags_saved = 0;
|
||||
if (!FAST_IS_REG(src1)) {
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w));
|
||||
src1 = TMP_FREG;
|
||||
}
|
||||
return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_SINGLE_OP), src1, src2, src2w);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = 1;
|
||||
#endif
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CMPD) {
|
||||
compiler->flags_saved = 0;
|
||||
if (FAST_IS_REG(dst))
|
||||
dst_r = dst;
|
||||
else {
|
||||
dst_r = TMP_FREG;
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, dst, dstw));
|
||||
}
|
||||
return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_SINGLE_OP), dst_r, src, srcw);
|
||||
}
|
||||
CHECK_ERROR();
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
if (op == SLJIT_MOVD) {
|
||||
if (GET_OPCODE(op) == SLJIT_DMOV) {
|
||||
if (FAST_IS_REG(dst))
|
||||
return emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst, src, srcw);
|
||||
if (FAST_IS_REG(src))
|
||||
|
|
@ -2359,6 +2400,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
|
|||
return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG);
|
||||
}
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) {
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;
|
||||
if (FAST_IS_REG(src)) {
|
||||
/* We overwrite the high bits of source. From SLJIT point of view,
|
||||
this is not an issue.
|
||||
Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */
|
||||
FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_SINGLE_OP, src, src, 0));
|
||||
}
|
||||
else {
|
||||
FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_SINGLE_OP), TMP_FREG, src, srcw));
|
||||
src = TMP_FREG;
|
||||
}
|
||||
|
||||
FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_SINGLE_OP, dst_r, src, 0));
|
||||
if (dst_r == TMP_FREG)
|
||||
return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (SLOW_IS_REG(dst)) {
|
||||
dst_r = dst;
|
||||
if (dst != src)
|
||||
|
|
@ -2370,11 +2430,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
|
|||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_NEGD:
|
||||
case SLJIT_DNEG:
|
||||
FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer : sse2_buffer + 8)));
|
||||
break;
|
||||
|
||||
case SLJIT_ABSD:
|
||||
case SLJIT_DABS:
|
||||
FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer + 4 : sse2_buffer + 12)));
|
||||
break;
|
||||
}
|
||||
|
|
@ -2392,7 +2452,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
sljit_si dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = 1;
|
||||
|
|
@ -2402,7 +2465,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
dst_r = dst;
|
||||
if (dst == src1)
|
||||
; /* Do nothing here. */
|
||||
else if (dst == src2 && (op == SLJIT_ADDD || op == SLJIT_MULD)) {
|
||||
else if (dst == src2 && (op == SLJIT_DADD || op == SLJIT_DMUL)) {
|
||||
/* Swap arguments. */
|
||||
src2 = src1;
|
||||
src2w = src1w;
|
||||
|
|
@ -2420,19 +2483,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_ADDD:
|
||||
case SLJIT_DADD:
|
||||
FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w));
|
||||
break;
|
||||
|
||||
case SLJIT_SUBD:
|
||||
case SLJIT_DSUB:
|
||||
FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w));
|
||||
break;
|
||||
|
||||
case SLJIT_MULD:
|
||||
case SLJIT_DMUL:
|
||||
FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w));
|
||||
break;
|
||||
|
||||
case SLJIT_DIVD:
|
||||
case SLJIT_DDIV:
|
||||
FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w));
|
||||
break;
|
||||
}
|
||||
|
|
@ -2442,33 +2505,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
|||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
/* Should cause an assertion fail. */
|
||||
check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
|
||||
compiler->error = SLJIT_ERR_UNSUPPORTED;
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
/* Should cause an assertion fail. */
|
||||
check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
compiler->error = SLJIT_ERR_UNSUPPORTED;
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Conditional instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
|
@ -2479,7 +2515,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
struct sljit_label *label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_label(compiler);
|
||||
CHECK_PTR(check_sljit_emit_label(compiler));
|
||||
|
||||
/* We should restore the flags before the label,
|
||||
since other taken jumps has their own flags as well. */
|
||||
|
|
@ -2508,7 +2544,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
struct sljit_jump *jump;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_jump(compiler, type);
|
||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||
|
||||
if (SLJIT_UNLIKELY(compiler->flags_saved)) {
|
||||
if ((type & 0xff) <= SLJIT_JUMP)
|
||||
|
|
@ -2545,7 +2581,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
|||
struct sljit_jump *jump;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_ijump(compiler, type, src, srcw);
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
|
|
@ -2559,16 +2595,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
|||
if (type >= SLJIT_CALL1) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (src == SLJIT_SCRATCH_REG3) {
|
||||
if (src == SLJIT_R2) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src, 0);
|
||||
src = TMP_REG1;
|
||||
}
|
||||
if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3)
|
||||
if (src == SLJIT_MEM1(SLJIT_SP) && type >= SLJIT_CALL3)
|
||||
srcw += sizeof(sljit_sw);
|
||||
#endif
|
||||
#endif
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
|
||||
if (src == SLJIT_SCRATCH_REG3) {
|
||||
if (src == SLJIT_R2) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src, 0);
|
||||
src = TMP_REG1;
|
||||
}
|
||||
|
|
@ -2624,7 +2660,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
|
||||
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
|
||||
SLJIT_UNUSED_ARG(srcw);
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
|
|
@ -2634,6 +2671,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
if (SLJIT_UNLIKELY(compiler->flags_saved))
|
||||
FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS));
|
||||
|
||||
type &= 0xff;
|
||||
/* setcc = jcc + 0x10. */
|
||||
cond_set = get_jump_code(type) + 0x10;
|
||||
|
||||
|
|
@ -2675,7 +2713,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
compiler->mode32 = GET_OPCODE(op) != SLJIT_MOV;
|
||||
return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
|
||||
}
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG1, 0);
|
||||
|
|
@ -2734,8 +2773,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
}
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src && reg_map[dst] <= 4) {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] == 0, scratch_reg1_must_be_eax);
|
||||
if (dst != SLJIT_SCRATCH_REG1) {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] == 0, scratch_reg1_must_be_eax);
|
||||
if (dst != SLJIT_R0) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1 + 3 + 2 + 1);
|
||||
|
|
@ -2785,7 +2824,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
if (GET_OPCODE(op) < SLJIT_ADD)
|
||||
return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0);
|
||||
|
|
@ -2795,7 +2835,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_get_local_base(compiler, dst, dstw, offset);
|
||||
CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
CHECK_EXTRA_REGS(dst, dstw, (void)0);
|
||||
|
|
@ -2804,23 +2844,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co
|
|||
compiler->mode32 = 0;
|
||||
#endif
|
||||
|
||||
ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset);
|
||||
ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (NOT_HALFWORD(offset)) {
|
||||
FAIL_IF(emit_load_imm64(compiler, TMP_REG1, offset));
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
SLJIT_ASSERT(emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED);
|
||||
SLJIT_ASSERT(emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED);
|
||||
return compiler->error;
|
||||
#else
|
||||
return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REG1, 0);
|
||||
return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (offset != 0)
|
||||
return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
|
||||
return emit_mov(compiler, dst, dstw, SLJIT_LOCALS_REG, 0);
|
||||
return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
|
||||
return emit_mov(compiler, dst, dstw, SLJIT_SP, 0);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
|
||||
|
|
@ -2832,7 +2872,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
|||
#endif
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_const(compiler, dst, dstw, init_value);
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
CHECK_EXTRA_REGS(dst, dstw, (void)0);
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ static SLJIT_INLINE sljit_si open_dev_zero(void)
|
|||
/* Planning to make it even more clever in the future. */
|
||||
static sljit_sw sljit_page_align = 0;
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data)
|
||||
{
|
||||
struct sljit_stack *stack;
|
||||
union {
|
||||
|
|
@ -211,6 +211,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
|
|||
SYSTEM_INFO si;
|
||||
#endif
|
||||
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
if (limit > max_limit || limit < 1)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -232,21 +233,21 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
|
|||
/* Align limit and max_limit. */
|
||||
max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
|
||||
|
||||
stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack));
|
||||
stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
|
||||
if (!stack)
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
base.ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!base.ptr) {
|
||||
SLJIT_FREE(stack);
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
stack->base = base.uw;
|
||||
stack->limit = stack->base;
|
||||
stack->max_limit = stack->base + max_limit;
|
||||
if (sljit_stack_resize(stack, stack->base + limit)) {
|
||||
sljit_free_stack(stack);
|
||||
sljit_free_stack(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
|
|
@ -255,14 +256,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
|
|||
#else
|
||||
if (dev_zero < 0) {
|
||||
if (open_dev_zero()) {
|
||||
SLJIT_FREE(stack);
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
|
||||
#endif
|
||||
if (base.ptr == MAP_FAILED) {
|
||||
SLJIT_FREE(stack);
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
stack->base = base.uw;
|
||||
|
|
@ -275,14 +276,15 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
|
|||
|
||||
#undef PAGE_ALIGN
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack, void *allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
#ifdef _WIN32
|
||||
VirtualFree((void*)stack->base, 0, MEM_RELEASE);
|
||||
#else
|
||||
munmap((void*)stack->base, stack->max_limit - stack->base);
|
||||
#endif
|
||||
SLJIT_FREE(stack);
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
|
||||
|
|
|
|||
|
|
@ -192,7 +192,31 @@ enum {
|
|||
ucp_Miao,
|
||||
ucp_Sharada,
|
||||
ucp_Sora_Sompeng,
|
||||
ucp_Takri
|
||||
ucp_Takri,
|
||||
/* New for Unicode 7.0.0: */
|
||||
ucp_Bassa_Vah,
|
||||
ucp_Caucasian_Albanian,
|
||||
ucp_Duployan,
|
||||
ucp_Elbasan,
|
||||
ucp_Grantha,
|
||||
ucp_Khojki,
|
||||
ucp_Khudawadi,
|
||||
ucp_Linear_A,
|
||||
ucp_Mahajani,
|
||||
ucp_Manichaean,
|
||||
ucp_Mende_Kikakui,
|
||||
ucp_Modi,
|
||||
ucp_Mro,
|
||||
ucp_Nabataean,
|
||||
ucp_Old_North_Arabian,
|
||||
ucp_Old_Permic,
|
||||
ucp_Pahawh_Hmong,
|
||||
ucp_Palmyrene,
|
||||
ucp_Psalter_Pahlavi,
|
||||
ucp_Pau_Cin_Hau,
|
||||
ucp_Siddham,
|
||||
ucp_Tirhuta,
|
||||
ucp_Warang_Citi
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::Options)
|
|||
//! [1]
|
||||
|
||||
//! [meta-object flags]
|
||||
Q_FLAGS(Options)
|
||||
Q_FLAG(Options)
|
||||
//! [meta-object flags]
|
||||
|
||||
//! [2]
|
||||
|
|
|
|||
|
|
@ -51,11 +51,12 @@ public:
|
|||
};
|
||||
|
||||
//! [0]
|
||||
QDebug operator<<(QDebug dbg, const Coordinate &c)
|
||||
QDebug operator<<(QDebug debug, const Coordinate &c)
|
||||
{
|
||||
dbg.nospace() << "(" << c.x() << ", " << c.y() << ")";
|
||||
QDebugStateSaver saver(debug);
|
||||
debug.nospace() << '(' << c.x() << ", " << c.y() << ')';
|
||||
|
||||
return dbg.space();
|
||||
return debug;
|
||||
}
|
||||
//! [0]
|
||||
|
||||
|
|
|
|||
|
|
@ -59,10 +59,11 @@ struct UsbEntry {
|
|||
int classtype;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug &dbg, const UsbEntry &entry)
|
||||
QDebug operator<<(QDebug &debug, const UsbEntry &entry)
|
||||
{
|
||||
dbg.nospace() << "" << entry.id << " (" << entry.classtype << ")";
|
||||
return dbg.space();
|
||||
QDebugStateSaver saver(debug);
|
||||
debug.nospace() << "" << entry.id << " (" << entry.classtype << ')';
|
||||
return debug;
|
||||
}
|
||||
|
||||
QList<UsbEntry> usbEntries() {
|
||||
|
|
|
|||
|
|
@ -910,6 +910,9 @@
|
|||
# undef Q_COMPILER_UNICODE_STRINGS
|
||||
# undef Q_COMPILER_NOEXCEPT
|
||||
# endif
|
||||
# if defined(_HAS_DINKUM_CLIB) && !defined(_HAS_NULLPTR_T)
|
||||
# undef Q_COMPILER_NULLPTR
|
||||
# endif
|
||||
# if defined(_HAS_DINKUM_CLIB) && !defined(_HAS_CONSTEXPR)
|
||||
// The libcpp is missing constexpr keywords on important functions like std::numeric_limits<>::min()
|
||||
// Disable constexpr support on QNX even if the compiler supports it
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits");
|
|||
|
||||
The Q_DECLARE_FLAGS() macro does not expose the flags to the meta-object
|
||||
system, so they cannot be used by Qt Script or edited in Qt Designer.
|
||||
To make the flags available for these purposes, the Q_FLAGS() macro must
|
||||
To make the flags available for these purposes, the Q_FLAG() macro must
|
||||
be used:
|
||||
|
||||
\snippet code/src_corelib_global_qglobal.cpp meta-object flags
|
||||
|
|
@ -2991,7 +2991,7 @@ QString qt_error_string(int errorCode)
|
|||
// Retrieve the system error message for the last-error code.
|
||||
# ifndef Q_OS_WINRT
|
||||
wchar_t *string = 0;
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
||||
NULL,
|
||||
errorCode,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
|
|||
if (!QLibraryInfoPrivate::configuration())
|
||||
#endif
|
||||
{
|
||||
const char *path = 0;
|
||||
const char * volatile path = 0;
|
||||
if (loc == PrefixPath) {
|
||||
path =
|
||||
#ifdef QT_BUILD_QMAKE
|
||||
|
|
|
|||
|
|
@ -2126,7 +2126,8 @@
|
|||
regardless of whether the parent widget is embedded in a scene or
|
||||
not.
|
||||
|
||||
\value WindowShadeButtonHint
|
||||
\value WindowShadeButtonHint Adds a shade button in place of the minimize
|
||||
button if the underlying window manager supports it.
|
||||
|
||||
\value WindowStaysOnTopHint Informs the window system that the
|
||||
window should stay on top of all other windows. Note that
|
||||
|
|
@ -2448,8 +2449,9 @@
|
|||
|
||||
Flags that alter the behavior:
|
||||
|
||||
\value ImhHiddenText Characters should be hidden, as is typically used when entering passwords.
|
||||
\value ImhHiddenText The input method should not show the characters while typing.
|
||||
This is automatically set when setting QLineEdit::echoMode to \c Password.
|
||||
Note that setting \c ImhHiddenText does not change the echo mode.
|
||||
\value ImhSensitiveData Typed text should not be stored by the active input method
|
||||
in any persistent storage like predictive user dictionary.
|
||||
\value ImhNoAutoUppercase The input method should not try to automatically switch to upper case
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ HEADERS += \
|
|||
io/qdatastream_p.h \
|
||||
io/qdataurl_p.h \
|
||||
io/qdebug.h \
|
||||
io/qdebug_p.h \
|
||||
io/qdir.h \
|
||||
io/qdir_p.h \
|
||||
io/qdiriterator.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QDEBUG_P_H
|
||||
#define QDEBUG_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "QtCore/qdebug.h"
|
||||
#include "QtCore/qmetaobject.h"
|
||||
#include "QtCore/qflags.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtDebugUtils {
|
||||
|
||||
// inline helpers for formatting basic classes.
|
||||
|
||||
template <class Point>
|
||||
static inline void formatQPoint(QDebug &debug, const Point &point)
|
||||
{
|
||||
debug << point.x() << ',' << point.y();
|
||||
}
|
||||
|
||||
template <class Size>
|
||||
static inline void formatQSize(QDebug &debug, const Size &size)
|
||||
{
|
||||
debug << size.width() << ", " << size.height();
|
||||
}
|
||||
|
||||
template <class Rect>
|
||||
static inline void formatQRect(QDebug &debug, const Rect &rect)
|
||||
{
|
||||
debug << rect.x() << ',' << rect.y() << ' ' << rect.width() << 'x' << rect.height();
|
||||
}
|
||||
|
||||
template <class Margins>
|
||||
static inline void formatQMargins(QDebug &debug, const Margins &margins)
|
||||
{
|
||||
debug << margins.left() << ", " << margins.top() << ", " << margins.right()
|
||||
<< ", " << margins.bottom();
|
||||
}
|
||||
|
||||
#ifndef QT_NO_QOBJECT
|
||||
template <class QEnum>
|
||||
static inline void formatQEnum(QDebug &debug, QEnum value)
|
||||
{
|
||||
const QMetaObject *metaObject = qt_getEnumMetaObject(value);
|
||||
const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(value)));
|
||||
if (const char *key = me.valueToKey(value))
|
||||
debug << key;
|
||||
else
|
||||
debug << int(value);
|
||||
}
|
||||
|
||||
template <class QEnum>
|
||||
static inline void formatNonNullQEnum(QDebug &debug, const char *prefix, QEnum value)
|
||||
{
|
||||
if (value) {
|
||||
debug << prefix;
|
||||
formatQEnum(debug, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Enum>
|
||||
static inline void formatQFlags(QDebug &debug, const QFlags<Enum> &value)
|
||||
{
|
||||
const QMetaObject *metaObject = qt_getEnumMetaObject(Enum());
|
||||
const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(Enum())));
|
||||
const QDebugStateSaver saver(debug);
|
||||
debug.noquote();
|
||||
debug << me.valueToKeys(value);
|
||||
}
|
||||
|
||||
template <class Enum>
|
||||
static inline void formatNonNullQFlags(QDebug &debug, const char *prefix, const QFlags<Enum> &value)
|
||||
{
|
||||
if (value) {
|
||||
debug << prefix;
|
||||
formatQFlags(debug, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !QT_NO_QOBJECT
|
||||
|
||||
} // namespace QtDebugUtils
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDEBUG_P_H
|
||||
|
|
@ -545,7 +545,7 @@ bool QFSFileEngine::renameOverwrite(const QString &newName)
|
|||
(wchar_t*)d->fileEntry.nativeFilePath().utf16()) != 0;
|
||||
if (!ret) {
|
||||
ret = ::DeleteFile((wchar_t*)QFileSystemEntry(newName).nativeFilePath().utf16()) != 0;
|
||||
if (ret)
|
||||
if (ret || ::GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||
ret = ::MoveFile((wchar_t*)d->fileEntry.nativeFilePath().utf16(),
|
||||
(wchar_t*)QFileSystemEntry(newName).nativeFilePath().utf16()) != 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -972,6 +972,7 @@ QByteArray QIODevice::readAll()
|
|||
|
||||
QByteArray result;
|
||||
qint64 readBytes = 0;
|
||||
const bool sequential = d->isSequential();
|
||||
|
||||
// flush internal read buffer
|
||||
if (!(d->openMode & Text) && !d->buffer.isEmpty()) {
|
||||
|
|
@ -979,11 +980,12 @@ QByteArray QIODevice::readAll()
|
|||
return QByteArray();
|
||||
result = d->buffer.readAll();
|
||||
readBytes = result.size();
|
||||
d->pos += readBytes;
|
||||
if (!sequential)
|
||||
d->pos += readBytes;
|
||||
}
|
||||
|
||||
qint64 theSize;
|
||||
if (d->isSequential() || (theSize = size()) == 0) {
|
||||
if (sequential || (theSize = size()) == 0) {
|
||||
// Size is unknown, read incrementally.
|
||||
qint64 readResult;
|
||||
do {
|
||||
|
|
@ -1629,6 +1631,23 @@ QString QIODevice::errorString() const
|
|||
\sa read(), write()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\internal
|
||||
\fn int qt_subtract_from_timeout(int timeout, int elapsed)
|
||||
|
||||
Reduces the \a timeout by \a elapsed, taking into account that -1 is a
|
||||
special value for timeouts.
|
||||
*/
|
||||
|
||||
int qt_subtract_from_timeout(int timeout, int elapsed)
|
||||
{
|
||||
if (timeout == -1)
|
||||
return -1;
|
||||
|
||||
timeout = timeout - elapsed;
|
||||
return timeout < 0 ? 0 : timeout;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(QT_NO_DEBUG_STREAM)
|
||||
QDebug operator<<(QDebug debug, QIODevice::OpenMode modes)
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
|
|||
#define QIODEVICE_BUFFERSIZE Q_INT64_C(16384)
|
||||
#endif
|
||||
|
||||
Q_CORE_EXPORT int qt_subtract_from_timeout(int timeout, int elapsed);
|
||||
|
||||
// This is QIODevice's read buffer, optimized for read(), isEmpty() and getChar()
|
||||
class QIODevicePrivateLinearBuffer
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1806,8 +1806,7 @@ bool QProcess::waitForBytesWritten(int msecs)
|
|||
bool started = waitForStarted(msecs);
|
||||
if (!started)
|
||||
return false;
|
||||
if (msecs != -1)
|
||||
msecs -= stopWatch.elapsed();
|
||||
msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
|
||||
}
|
||||
|
||||
return d->waitForBytesWritten(msecs);
|
||||
|
|
@ -1843,8 +1842,7 @@ bool QProcess::waitForFinished(int msecs)
|
|||
bool started = waitForStarted(msecs);
|
||||
if (!started)
|
||||
return false;
|
||||
if (msecs != -1)
|
||||
msecs -= stopWatch.elapsed();
|
||||
msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
|
||||
}
|
||||
|
||||
return d->waitForFinished(msecs);
|
||||
|
|
|
|||
|
|
@ -822,19 +822,6 @@ void QProcessPrivate::killProcess()
|
|||
::kill(pid_t(pid), SIGKILL);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the difference between msecs and elapsed. If msecs is -1,
|
||||
however, -1 is returned.
|
||||
*/
|
||||
static int qt_timeout_value(int msecs, int elapsed)
|
||||
{
|
||||
if (msecs == -1)
|
||||
return -1;
|
||||
|
||||
int timeout = msecs - elapsed;
|
||||
return timeout < 0 ? 0 : timeout;
|
||||
}
|
||||
|
||||
bool QProcessPrivate::waitForStarted(int msecs)
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
|
|
@ -909,7 +896,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
|
|||
if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
|
||||
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
|
||||
|
||||
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
|
||||
int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
|
||||
#ifdef Q_OS_BLACKBERRY
|
||||
int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout);
|
||||
#else
|
||||
|
|
@ -990,7 +977,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
|
|||
if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
|
||||
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
|
||||
|
||||
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
|
||||
int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
|
||||
#ifdef Q_OS_BLACKBERRY
|
||||
int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout);
|
||||
#else
|
||||
|
|
@ -1065,7 +1052,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
|
|||
if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
|
||||
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
|
||||
|
||||
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
|
||||
int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
|
||||
#ifdef Q_OS_BLACKBERRY
|
||||
int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -113,6 +113,9 @@ QT_BEGIN_NAMESPACE
|
|||
\value GenericCacheLocation Returns a directory location where user-specific non-essential
|
||||
(cached) data, shared across applications, should be written. This is a generic value.
|
||||
Note that the returned path may be empty if the system has no concept of shared cache.
|
||||
\value GenericDataLocation Returns a directory location where persistent
|
||||
data shared across applications can be stored. This is a generic value. The returned
|
||||
path is never empty.
|
||||
\value RuntimeLocation Returns a directory location where runtime communication
|
||||
files should be written, like Unix local sockets. This is a generic value.
|
||||
The returned path may be empty on some systems.
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include <qthread.h>
|
||||
#include <qt_windows.h>
|
||||
#include <private/qobject_p.h>
|
||||
#include <private/qiodevice_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -332,11 +333,9 @@ bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped
|
|||
return false;
|
||||
if (triggeredOverlapped == overlapped)
|
||||
return true;
|
||||
if (msecs != -1) {
|
||||
t = msecs - stopWatch.elapsed();
|
||||
if (t < 0)
|
||||
return false;
|
||||
}
|
||||
msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
|
||||
if (t == 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,11 @@
|
|||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#ifdef Q_OS_WINRT
|
||||
|
||||
#include "qfunctions_winrt.h"
|
||||
|
||||
#ifdef Q_OS_WINRT
|
||||
|
||||
#include "qstring.h"
|
||||
#include "qbytearray.h"
|
||||
#include "qhash.h"
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@
|
|||
\snippet code/src_corelib_kernel_qmath.cpp 3
|
||||
|
||||
\sa qDegreesToRadians()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn quint32 qNextPowerOfTwo(quint32 value)
|
||||
|
|
|
|||
|
|
@ -1364,6 +1364,11 @@ namespace QtPrivate
|
|||
enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(void*) };
|
||||
};
|
||||
|
||||
|
||||
QT_WARNING_PUSH
|
||||
// In C++03 mode, clang consider local or unnamed type and throw a warning instead of ignoring them
|
||||
QT_WARNING_DISABLE_CLANG("-Wunnamed-type-template-args")
|
||||
QT_WARNING_DISABLE_CLANG("-Wlocal-type-template-args")
|
||||
template<typename T> char qt_getEnumMetaObject(const T&);
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -1375,6 +1380,7 @@ namespace QtPrivate
|
|||
// qt_getEnumMetaObject(T) which returns 'char'
|
||||
enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
|
||||
};
|
||||
QT_WARNING_POP
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct MetaObjectForType
|
||||
|
|
|
|||
|
|
@ -217,6 +217,8 @@ static inline QByteArray makePattern(const QByteArray &value)
|
|||
*data++ = '\n';
|
||||
} else if (*p == 'r') {
|
||||
*data++ = '\r';
|
||||
} else if (*p == 't') {
|
||||
*data++ = '\t';
|
||||
} else { // escaped
|
||||
*data++ = *p;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -721,7 +721,7 @@ QDataStream &operator>>(QDataStream &s, QUuid &id)
|
|||
Returns \c true if this is the null UUID
|
||||
{00000000-0000-0000-0000-000000000000}; otherwise returns \c false.
|
||||
*/
|
||||
bool QUuid::isNull() const
|
||||
bool QUuid::isNull() const Q_DECL_NOTHROW
|
||||
{
|
||||
return data4[0] == 0 && data4[1] == 0 && data4[2] == 0 && data4[3] == 0 &&
|
||||
data4[4] == 0 && data4[5] == 0 && data4[6] == 0 && data4[7] == 0 &&
|
||||
|
|
@ -770,7 +770,7 @@ bool QUuid::isNull() const
|
|||
|
||||
\sa version()
|
||||
*/
|
||||
QUuid::Variant QUuid::variant() const
|
||||
QUuid::Variant QUuid::variant() const Q_DECL_NOTHROW
|
||||
{
|
||||
if (isNull())
|
||||
return VarUnknown;
|
||||
|
|
@ -791,7 +791,7 @@ QUuid::Variant QUuid::variant() const
|
|||
|
||||
\sa variant()
|
||||
*/
|
||||
QUuid::Version QUuid::version() const
|
||||
QUuid::Version QUuid::version() const Q_DECL_NOTHROW
|
||||
{
|
||||
// Check the 4 MSB of data3
|
||||
Version ver = (Version)(data3>>12);
|
||||
|
|
@ -814,18 +814,19 @@ QUuid::Version QUuid::version() const
|
|||
|
||||
\sa variant()
|
||||
*/
|
||||
#define ISLESS(f1, f2) if (f1!=f2) return (f1<f2);
|
||||
bool QUuid::operator<(const QUuid &other) const
|
||||
bool QUuid::operator<(const QUuid &other) const Q_DECL_NOTHROW
|
||||
{
|
||||
if (variant() != other.variant())
|
||||
return variant() < other.variant();
|
||||
|
||||
#define ISLESS(f1, f2) if (f1!=f2) return (f1<f2);
|
||||
ISLESS(data1, other.data1);
|
||||
ISLESS(data2, other.data2);
|
||||
ISLESS(data3, other.data3);
|
||||
for (int n = 0; n < 8; n++) {
|
||||
ISLESS(data4[n], other.data4[n]);
|
||||
}
|
||||
#undef ISLESS
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -840,21 +841,39 @@ bool QUuid::operator<(const QUuid &other) const
|
|||
|
||||
\sa variant()
|
||||
*/
|
||||
#define ISMORE(f1, f2) if (f1!=f2) return (f1>f2);
|
||||
bool QUuid::operator>(const QUuid &other) const
|
||||
bool QUuid::operator>(const QUuid &other) const Q_DECL_NOTHROW
|
||||
{
|
||||
if (variant() != other.variant())
|
||||
return variant() > other.variant();
|
||||
|
||||
ISMORE(data1, other.data1);
|
||||
ISMORE(data2, other.data2);
|
||||
ISMORE(data3, other.data3);
|
||||
for (int n = 0; n < 8; n++) {
|
||||
ISMORE(data4[n], other.data4[n]);
|
||||
}
|
||||
return false;
|
||||
return other < *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool operator<=(const QUuid &lhs, const QUuid &rhs)
|
||||
\relates QUuid
|
||||
\since 5.5
|
||||
|
||||
Returns \c true if \a lhs has the same \l{Variant field}
|
||||
{variant field} as \a rhs and is lexicographically
|
||||
\e{not after} \a rhs. If \a rhs has a
|
||||
different variant field, the return value is determined by
|
||||
comparing the two \l{QUuid::Variant} {variants}.
|
||||
|
||||
\sa variant()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator>=(const QUuid &lhs, const QUuid &rhs)
|
||||
\relates QUuid
|
||||
\since 5.5
|
||||
|
||||
Returns \c true if \a lhs has the same \l{Variant field}
|
||||
{variant field} as \a rhs and is lexicographically
|
||||
\e{not before} \a rhs. If \a rhs has a
|
||||
different variant field, the return value is determined by
|
||||
comparing the two \l{QUuid::Variant} {variants}.
|
||||
|
||||
\sa variant()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QUuid QUuid::createUuid()
|
||||
|
||||
|
|
|
|||
|
|
@ -75,13 +75,13 @@ public:
|
|||
};
|
||||
|
||||
#if defined(Q_COMPILER_UNIFORM_INIT) && !defined(Q_QDOC)
|
||||
Q_DECL_CONSTEXPR QUuid() : data1(0), data2(0), data3(0), data4{0,0,0,0,0,0,0,0} {}
|
||||
Q_DECL_CONSTEXPR QUuid() Q_DECL_NOTHROW : data1(0), data2(0), data3(0), data4{0,0,0,0,0,0,0,0} {}
|
||||
|
||||
Q_DECL_CONSTEXPR QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3,
|
||||
uchar b4, uchar b5, uchar b6, uchar b7, uchar b8)
|
||||
uchar b4, uchar b5, uchar b6, uchar b7, uchar b8) Q_DECL_NOTHROW
|
||||
: data1(l), data2(w1), data3(w2), data4{b1, b2, b3, b4, b5, b6, b7, b8} {}
|
||||
#else
|
||||
QUuid()
|
||||
QUuid() Q_DECL_NOTHROW
|
||||
{
|
||||
data1 = 0;
|
||||
data2 = 0;
|
||||
|
|
@ -89,7 +89,7 @@ public:
|
|||
for(int i = 0; i < 8; i++)
|
||||
data4[i] = 0;
|
||||
}
|
||||
QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8)
|
||||
QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8) Q_DECL_NOTHROW
|
||||
{
|
||||
data1 = l;
|
||||
data2 = w1;
|
||||
|
|
@ -112,9 +112,9 @@ public:
|
|||
QByteArray toByteArray() const;
|
||||
QByteArray toRfc4122() const;
|
||||
static QUuid fromRfc4122(const QByteArray &);
|
||||
bool isNull() const;
|
||||
bool isNull() const Q_DECL_NOTHROW;
|
||||
|
||||
Q_DECL_RELAXED_CONSTEXPR bool operator==(const QUuid &orig) const
|
||||
Q_DECL_RELAXED_CONSTEXPR bool operator==(const QUuid &orig) const Q_DECL_NOTHROW
|
||||
{
|
||||
if (data1 != orig.data1 || data2 != orig.data2 ||
|
||||
data3 != orig.data3)
|
||||
|
|
@ -127,24 +127,24 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
Q_DECL_RELAXED_CONSTEXPR bool operator!=(const QUuid &orig) const
|
||||
Q_DECL_RELAXED_CONSTEXPR bool operator!=(const QUuid &orig) const Q_DECL_NOTHROW
|
||||
{
|
||||
return !(*this == orig);
|
||||
}
|
||||
|
||||
bool operator<(const QUuid &other) const;
|
||||
bool operator>(const QUuid &other) const;
|
||||
bool operator<(const QUuid &other) const Q_DECL_NOTHROW;
|
||||
bool operator>(const QUuid &other) const Q_DECL_NOTHROW;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
// On Windows we have a type GUID that is used by the platform API, so we
|
||||
// provide convenience operators to cast from and to this type.
|
||||
#if defined(Q_COMPILER_UNIFORM_INIT) && !defined(Q_QDOC)
|
||||
Q_DECL_CONSTEXPR QUuid(const GUID &guid)
|
||||
Q_DECL_CONSTEXPR QUuid(const GUID &guid) Q_DECL_NOTHROW
|
||||
: data1(guid.Data1), data2(guid.Data2), data3(guid.Data3),
|
||||
data4{guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
|
||||
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]} {}
|
||||
#else
|
||||
QUuid(const GUID &guid)
|
||||
QUuid(const GUID &guid) Q_DECL_NOTHROW
|
||||
{
|
||||
data1 = guid.Data1;
|
||||
data2 = guid.Data2;
|
||||
|
|
@ -154,24 +154,24 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
Q_DECL_RELAXED_CONSTEXPR QUuid &operator=(const GUID &guid)
|
||||
Q_DECL_RELAXED_CONSTEXPR QUuid &operator=(const GUID &guid) Q_DECL_NOTHROW
|
||||
{
|
||||
*this = QUuid(guid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Q_DECL_RELAXED_CONSTEXPR operator GUID() const
|
||||
Q_DECL_RELAXED_CONSTEXPR operator GUID() const Q_DECL_NOTHROW
|
||||
{
|
||||
GUID guid = { data1, data2, data3, { data4[0], data4[1], data4[2], data4[3], data4[4], data4[5], data4[6], data4[7] } };
|
||||
return guid;
|
||||
}
|
||||
|
||||
Q_DECL_RELAXED_CONSTEXPR bool operator==(const GUID &guid) const
|
||||
Q_DECL_RELAXED_CONSTEXPR bool operator==(const GUID &guid) const Q_DECL_NOTHROW
|
||||
{
|
||||
return *this == QUuid(guid);
|
||||
}
|
||||
|
||||
Q_DECL_RELAXED_CONSTEXPR bool operator!=(const GUID &guid) const
|
||||
Q_DECL_RELAXED_CONSTEXPR bool operator!=(const GUID &guid) const Q_DECL_NOTHROW
|
||||
{
|
||||
return !(*this == guid);
|
||||
}
|
||||
|
|
@ -192,8 +192,8 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
QUuid::Variant variant() const;
|
||||
QUuid::Version version() const;
|
||||
QUuid::Variant variant() const Q_DECL_NOTHROW;
|
||||
QUuid::Version version() const Q_DECL_NOTHROW;
|
||||
|
||||
uint data1;
|
||||
ushort data2;
|
||||
|
|
@ -214,6 +214,11 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QUuid &);
|
|||
|
||||
Q_CORE_EXPORT uint qHash(const QUuid &uuid, uint seed = 0) Q_DECL_NOTHROW;
|
||||
|
||||
inline bool operator<=(const QUuid &lhs, const QUuid &rhs) Q_DECL_NOTHROW
|
||||
{ return !(rhs < lhs); }
|
||||
inline bool operator>=(const QUuid &lhs, const QUuid &rhs) Q_DECL_NOTHROW
|
||||
{ return !(lhs < rhs); }
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QUUID_H
|
||||
|
|
|
|||
|
|
@ -52,8 +52,12 @@ void QCollatorPrivate::init()
|
|||
UErrorCode status = U_ZERO_ERROR;
|
||||
QByteArray name = locale.bcp47Name().replace(QLatin1Char('-'), QLatin1Char('_')).toLatin1();
|
||||
collator = ucol_open(name.constData(), &status);
|
||||
if (U_FAILURE(status))
|
||||
if (U_FAILURE(status)) {
|
||||
qWarning("Could not create collator: %d", status);
|
||||
collator = 0;
|
||||
dirty = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// enable normalization by default
|
||||
ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
|
||||
|
|
@ -97,17 +101,26 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con
|
|||
if (d->dirty)
|
||||
d->init();
|
||||
|
||||
return ucol_strcoll(d->collator, (const UChar *)s1, len1, (const UChar *)s2, len2);
|
||||
if (d->collator)
|
||||
return ucol_strcoll(d->collator, (const UChar *)s1, len1, (const UChar *)s2, len2);
|
||||
|
||||
return QString::compare(QString(s1, len1), QString(s2, len2), d->caseSensitivity);
|
||||
}
|
||||
|
||||
int QCollator::compare(const QString &s1, const QString &s2) const
|
||||
{
|
||||
return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
|
||||
if (d->collator)
|
||||
return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
|
||||
|
||||
return QString::compare(s1, s2, d->caseSensitivity);
|
||||
}
|
||||
|
||||
int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
|
||||
{
|
||||
return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
|
||||
if (d->collator)
|
||||
return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
|
||||
|
||||
return QStringRef::compare(s1, s2, d->caseSensitivity);
|
||||
}
|
||||
|
||||
QCollatorSortKey QCollator::sortKey(const QString &string) const
|
||||
|
|
@ -115,16 +128,20 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const
|
|||
if (d->dirty)
|
||||
d->init();
|
||||
|
||||
QByteArray result(16 + string.size() + (string.size() >> 2), Qt::Uninitialized);
|
||||
int size = ucol_getSortKey(d->collator, (const UChar *)string.constData(),
|
||||
string.size(), (uint8_t *)result.data(), result.size());
|
||||
if (size > result.size()) {
|
||||
result.resize(size);
|
||||
size = ucol_getSortKey(d->collator, (const UChar *)string.constData(),
|
||||
string.size(), (uint8_t *)result.data(), result.size());
|
||||
if (d->collator) {
|
||||
QByteArray result(16 + string.size() + (string.size() >> 2), Qt::Uninitialized);
|
||||
int size = ucol_getSortKey(d->collator, (const UChar *)string.constData(),
|
||||
string.size(), (uint8_t *)result.data(), result.size());
|
||||
if (size > result.size()) {
|
||||
result.resize(size);
|
||||
size = ucol_getSortKey(d->collator, (const UChar *)string.constData(),
|
||||
string.size(), (uint8_t *)result.data(), result.size());
|
||||
}
|
||||
result.truncate(size);
|
||||
return QCollatorSortKey(new QCollatorSortKeyPrivate(result));
|
||||
}
|
||||
result.truncate(size);
|
||||
return QCollatorSortKey(new QCollatorSortKeyPrivate(result));
|
||||
|
||||
return QCollatorSortKey(new QCollatorSortKeyPrivate(QByteArray()));
|
||||
}
|
||||
|
||||
int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
|
||||
|
|
|
|||
|
|
@ -52,19 +52,13 @@ static void resolveLibs()
|
|||
if (done)
|
||||
return;
|
||||
|
||||
#ifndef Q_OS_WINRT
|
||||
#if !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE)
|
||||
// try to get GetTickCount64 from the system
|
||||
HMODULE kernel32 = GetModuleHandleW(L"kernel32");
|
||||
if (!kernel32)
|
||||
return;
|
||||
|
||||
#if defined(Q_OS_WINCE)
|
||||
// does this function exist on WinCE, or will ever exist?
|
||||
ptrGetTickCount64 = (PtrGetTickCount64)GetProcAddress(kernel32, L"GetTickCount64");
|
||||
#else
|
||||
ptrGetTickCount64 = (PtrGetTickCount64)GetProcAddress(kernel32, "GetTickCount64");
|
||||
#endif
|
||||
#endif // !Q_OS_WINRT
|
||||
#endif // !Q_OS_WINRT && !Q_OS_WINCE
|
||||
|
||||
// Retrieve the number of high-resolution performance counter ticks per second
|
||||
LARGE_INTEGER frequency;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@
|
|||
|
||||
#include "qmargins.h"
|
||||
#include "qdatastream.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#include <private/qdebug_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -431,10 +432,13 @@ QDataStream &operator>>(QDataStream &s, QMargins &m)
|
|||
#endif // QT_NO_DATASTREAM
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug dbg, const QMargins &m) {
|
||||
QDebug operator<<(QDebug dbg, const QMargins &m)
|
||||
{
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace() << "QMargins(" << m.left() << ", "
|
||||
<< m.top() << ", " << m.right() << ", " << m.bottom() << ')';
|
||||
dbg.nospace();
|
||||
dbg << "QMargins" << '(';
|
||||
QtDebugUtils::formatQMargins(dbg, m);
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -764,10 +768,13 @@ QDataStream &operator>>(QDataStream &s, QMarginsF &m)
|
|||
#endif // QT_NO_DATASTREAM
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug dbg, const QMarginsF &m) {
|
||||
QDebug operator<<(QDebug dbg, const QMarginsF &m)
|
||||
{
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace() << "QMarginsF(" << m.left() << ", "
|
||||
<< m.top() << ", " << m.right() << ", " << m.bottom() << ')';
|
||||
dbg.nospace();
|
||||
dbg << "QMarginsF" << '(';
|
||||
QtDebugUtils::formatQMargins(dbg, m);
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@
|
|||
|
||||
#include "qpoint.h"
|
||||
#include "qdatastream.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#include <private/qdebug_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -447,14 +448,20 @@ QDataStream &operator>>(QDataStream &s, QPoint &p)
|
|||
QDebug operator<<(QDebug dbg, const QPoint &p)
|
||||
{
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace() << "QPoint(" << p.x() << ',' << p.y() << ')';
|
||||
dbg.nospace();
|
||||
dbg << "QPoint" << '(';
|
||||
QtDebugUtils::formatQPoint(dbg, p);
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const QPointF &p)
|
||||
{
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace() << "QPointF(" << p.x() << ',' << p.y() << ')';
|
||||
dbg.nospace();
|
||||
dbg << "QPointF" << '(';
|
||||
QtDebugUtils::formatQPoint(dbg, p);
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,9 +33,10 @@
|
|||
|
||||
#include "qrect.h"
|
||||
#include "qdatastream.h"
|
||||
#include "qdebug.h"
|
||||
#include "qmath.h"
|
||||
|
||||
#include <private/qdebug_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
|
|
@ -1279,8 +1280,10 @@ QDataStream &operator>>(QDataStream &s, QRect &r)
|
|||
QDebug operator<<(QDebug dbg, const QRect &r)
|
||||
{
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace() << "QRect(" << r.x() << ',' << r.y() << ' '
|
||||
<< r.width() << 'x' << r.height() << ')';
|
||||
dbg.nospace();
|
||||
dbg << "QRect" << '(';
|
||||
QtDebugUtils::formatQRect(dbg, r);
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2488,8 +2491,10 @@ QDataStream &operator>>(QDataStream &s, QRectF &r)
|
|||
QDebug operator<<(QDebug dbg, const QRectF &r)
|
||||
{
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace() << "QRectF(" << r.x() << ',' << r.y() << ' '
|
||||
<< r.width() << 'x' << r.height() << ')';
|
||||
dbg.nospace();
|
||||
dbg << "QRectF" << '(';
|
||||
QtDebugUtils::formatQRect(dbg, r);
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@
|
|||
|
||||
#include "qsize.h"
|
||||
#include "qdatastream.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#include <private/qdebug_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -440,7 +441,10 @@ QDataStream &operator>>(QDataStream &s, QSize &sz)
|
|||
QDebug operator<<(QDebug dbg, const QSize &s)
|
||||
{
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace() << "QSize(" << s.width() << ", " << s.height() << ')';
|
||||
dbg.nospace();
|
||||
dbg << "QSize(";
|
||||
QtDebugUtils::formatQSize(dbg, s);
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -867,7 +871,10 @@ QDataStream &operator>>(QDataStream &s, QSizeF &sz)
|
|||
QDebug operator<<(QDebug dbg, const QSizeF &s)
|
||||
{
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace() << "QSizeF(" << s.width() << ", " << s.height() << ')';
|
||||
dbg.nospace();
|
||||
dbg << "QSizeF(";
|
||||
QtDebugUtils::formatQSize(dbg, s);
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8507,12 +8507,6 @@ QDataStream &operator<<(QDataStream &out, const QString &str)
|
|||
|
||||
QDataStream &operator>>(QDataStream &in, QString &str)
|
||||
{
|
||||
#ifdef QT_QSTRING_UCS_4
|
||||
#if defined(Q_CC_GNU)
|
||||
#warning "operator>> not working properly"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (in.version() == 1) {
|
||||
QByteArray l;
|
||||
in >> l;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,15 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_INITIALIZER_LISTS
|
||||
QVarLengthArray<T, Prealloc> &operator=(std::initializer_list<T> list)
|
||||
{
|
||||
resize(list.size());
|
||||
std::copy(list.begin(), list.end(), this->begin());
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void removeLast() {
|
||||
Q_ASSERT(s > 0);
|
||||
realloc(s - 1, a);
|
||||
|
|
|
|||
|
|
@ -362,6 +362,15 @@
|
|||
Assigns \a other to this array and returns a reference to this array.
|
||||
*/
|
||||
|
||||
/*! \fn QVarLengthArray<T, Prealloc> &QVarLengthArray::operator=(std::initializer_list<T> list)
|
||||
\since 5.5
|
||||
|
||||
Assigns the values of \a list to this array, and returns a reference to this array.
|
||||
|
||||
This constructor is only enabled if the compiler supports C++11 initializer
|
||||
lists.
|
||||
*/
|
||||
|
||||
/*! \fn QVarLengthArray::QVarLengthArray(const QVarLengthArray<T, Prealloc> &other)
|
||||
Constructs a copy of \a other.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1713,6 +1713,7 @@ bool operator==(const QAccessible::State &first, const QAccessible::State &secon
|
|||
/*! \internal */
|
||||
Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface)
|
||||
{
|
||||
QDebugStateSaver saver(d);
|
||||
if (!iface) {
|
||||
d << "QAccessibleInterface(null)";
|
||||
return d;
|
||||
|
|
@ -1720,10 +1721,10 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface)
|
|||
d.nospace();
|
||||
d << "QAccessibleInterface(" << hex << (const void *) iface << dec;
|
||||
if (iface->isValid()) {
|
||||
d << " name=" << iface->text(QAccessible::Name) << " ";
|
||||
d << "role=" << qAccessibleRoleString(iface->role()) << " ";
|
||||
d << " name=" << iface->text(QAccessible::Name) << ' ';
|
||||
d << "role=" << qAccessibleRoleString(iface->role()) << ' ';
|
||||
if (iface->childCount())
|
||||
d << "childc=" << iface->childCount() << " ";
|
||||
d << "childc=" << iface->childCount() << ' ';
|
||||
if (iface->object()) {
|
||||
d << "obj=" << iface->object();
|
||||
}
|
||||
|
|
@ -1747,13 +1748,14 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface)
|
|||
} else {
|
||||
d << " invalid";
|
||||
}
|
||||
d << ")";
|
||||
return d.space();
|
||||
d << ')';
|
||||
return d;
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
QDebug operator<<(QDebug d, const QAccessibleEvent &ev)
|
||||
{
|
||||
QDebugStateSaver saver(d);
|
||||
d.nospace() << "QAccessibleEvent(";
|
||||
if (ev.object()) {
|
||||
d.nospace() << "object=" << hex << ev.object() << dec;
|
||||
|
|
@ -1806,8 +1808,8 @@ QDebug operator<<(QDebug d, const QAccessibleEvent &ev)
|
|||
if (changed.supportsAutoCompletion) d << "supportsAutoCompletion";
|
||||
|
||||
}
|
||||
d.nospace() << ")";
|
||||
return d.space();
|
||||
d << ')';
|
||||
return d;
|
||||
}
|
||||
#endif // QT_NO_DEBUGSTREAM
|
||||
|
||||
|
|
|
|||
|
|
@ -484,12 +484,6 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
|
|||
p = data + (h-y-1)*bpl;
|
||||
break;
|
||||
case 2: // delta (jump)
|
||||
// Protection
|
||||
if ((uint)x >= (uint)w)
|
||||
x = w-1;
|
||||
if ((uint)y >= (uint)h)
|
||||
y = h-1;
|
||||
|
||||
{
|
||||
quint8 tmp;
|
||||
d->getChar((char *)&tmp);
|
||||
|
|
@ -497,6 +491,13 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
|
|||
d->getChar((char *)&tmp);
|
||||
y += tmp;
|
||||
}
|
||||
|
||||
// Protection
|
||||
if ((uint)x >= (uint)w)
|
||||
x = w-1;
|
||||
if ((uint)y >= (uint)h)
|
||||
y = h-1;
|
||||
|
||||
p = data + (h-y-1)*bpl + x;
|
||||
break;
|
||||
default: // absolute mode
|
||||
|
|
|
|||
|
|
@ -936,6 +936,8 @@ void QGIFFormat::fillRect(QImage *image, int col, int row, int w, int h, QRgb co
|
|||
|
||||
void QGIFFormat::nextY(unsigned char *bits, int bpl)
|
||||
{
|
||||
if (out_of_bounds)
|
||||
return;
|
||||
int my;
|
||||
switch (interlace) {
|
||||
case 0: // Non-interlaced
|
||||
|
|
|
|||
|
|
@ -681,6 +681,8 @@ static bool convert_BGR30_to_RGB30_inplace(QImageData *data, Qt::ImageConversion
|
|||
static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
|
||||
{
|
||||
Q_ASSERT(data->format == QImage::Format_Indexed8);
|
||||
if (!data->own_data)
|
||||
return false;
|
||||
const int depth = 32;
|
||||
|
||||
const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
|
||||
|
|
@ -733,6 +735,8 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve
|
|||
static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags)
|
||||
{
|
||||
Q_ASSERT(data->format == QImage::Format_Indexed8);
|
||||
if (!data->own_data)
|
||||
return false;
|
||||
const int depth = 32;
|
||||
|
||||
const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
|
||||
|
|
@ -782,6 +786,8 @@ static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversio
|
|||
static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
|
||||
{
|
||||
Q_ASSERT(data->format == QImage::Format_Indexed8);
|
||||
if (!data->own_data)
|
||||
return false;
|
||||
const int depth = 16;
|
||||
|
||||
const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
|
||||
|
|
@ -837,6 +843,8 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers
|
|||
static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
|
||||
{
|
||||
Q_ASSERT(data->format == QImage::Format_RGB32);
|
||||
if (!data->own_data)
|
||||
return false;
|
||||
const int depth = 16;
|
||||
|
||||
const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
|
||||
|
|
|
|||
|
|
@ -37,13 +37,13 @@
|
|||
#include "qpa/qplatformintegration.h"
|
||||
#include "qpa/qplatformdrag.h"
|
||||
#include "private/qevent_p.h"
|
||||
#include "qdebug.h"
|
||||
#include "qmetaobject.h"
|
||||
#include "qmimedata.h"
|
||||
#include "private/qdnd_p.h"
|
||||
#include "qevent_p.h"
|
||||
#include "qmath.h"
|
||||
|
||||
#include <private/qdebug_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -3463,7 +3463,10 @@ QShortcutEvent::~QShortcutEvent()
|
|||
|
||||
static inline void formatTouchEvent(QDebug d, const QTouchEvent &t)
|
||||
{
|
||||
d << "QTouchEvent(" << t.type() << " states: " << t.touchPointStates();
|
||||
d << "QTouchEvent(";
|
||||
QtDebugUtils::formatQEnum(d, t.type());
|
||||
d << " states: ";
|
||||
QtDebugUtils::formatQFlags(d, t.touchPointStates());
|
||||
d << ", " << t.touchPoints().size() << " points: " << t.touchPoints() << ')';
|
||||
}
|
||||
|
||||
|
|
@ -3644,15 +3647,20 @@ static const char *eventClassName(QEvent::Type t)
|
|||
static void formatDropEvent(QDebug d, const QDropEvent *e)
|
||||
{
|
||||
const QEvent::Type type = e->type();
|
||||
d << eventClassName(type) << "(dropAction=" << e->dropAction() << ", proposedAction="
|
||||
<< e->proposedAction() << ", possibleActions=" << e->possibleActions()
|
||||
<< ", posF=" << e->posF();
|
||||
d << eventClassName(type) << "(dropAction=";
|
||||
QtDebugUtils::formatQEnum(d, e->dropAction());
|
||||
d << ", proposedAction=";
|
||||
QtDebugUtils::formatQEnum(d, e->proposedAction());
|
||||
d << ", possibleActions=";
|
||||
QtDebugUtils::formatQFlags(d, e->possibleActions());
|
||||
d << ", posF=";
|
||||
QtDebugUtils::formatQPoint(d, e->posF());
|
||||
if (type == QEvent::DragMove || type == QEvent::DragEnter)
|
||||
d << ", answerRect=" << static_cast<const QDragMoveEvent *>(e)->answerRect();
|
||||
d << ", formats=" << e->mimeData()->formats();
|
||||
if (const Qt::KeyboardModifiers mods = e->keyboardModifiers())
|
||||
d << ", keyboardModifiers=" << mods;
|
||||
d << ", " << e->mouseButtons();
|
||||
QtDebugUtils::formatNonNullQFlags(d, ", keyboardModifiers=", e->keyboardModifiers());
|
||||
d << ", ";
|
||||
QtDebugUtils::formatQFlags(d, e->mouseButtons());
|
||||
}
|
||||
|
||||
# endif // !QT_NO_DRAGANDDROP
|
||||
|
|
@ -3663,15 +3671,19 @@ static void formatTabletEvent(QDebug d, const QTabletEvent *e)
|
|||
{
|
||||
const QEvent::Type type = e->type();
|
||||
|
||||
d << eventClassName(type) << '(' << type
|
||||
<< ", device=" << e->device()
|
||||
<< ", pointerType=" << e->pointerType()
|
||||
<< ", uniqueId=" << e->uniqueId()
|
||||
d << eventClassName(type) << '(';
|
||||
QtDebugUtils::formatQEnum(d, type);
|
||||
d << ", device=";
|
||||
QtDebugUtils::formatQEnum(d, e->device());
|
||||
d << ", pointerType=";
|
||||
QtDebugUtils::formatQEnum(d, e->pointerType());
|
||||
d << ", uniqueId=" << e->uniqueId()
|
||||
<< ", pos=" << e->posF()
|
||||
<< ", z=" << e->z()
|
||||
<< ", xTilt=" << e->xTilt()
|
||||
<< ", yTilt=" << e->yTilt()
|
||||
<< ", " << e->buttons();
|
||||
<< ", ";
|
||||
QtDebugUtils::formatQFlags(d, e->buttons());
|
||||
if (type == QEvent::TabletPress || type == QEvent::TabletMove)
|
||||
d << ", pressure=" << e->pressure();
|
||||
if (e->device() == QTabletEvent::RotationStylus || e->device() == QTabletEvent::FourDMouse)
|
||||
|
|
@ -3685,8 +3697,19 @@ static void formatTabletEvent(QDebug d, const QTabletEvent *e)
|
|||
QDebug operator<<(QDebug dbg, const QTouchEvent::TouchPoint &tp)
|
||||
{
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace() << "TouchPoint(" << tp.id() << ' ' << tp.rect() << ' ' << tp.state() << " press " << tp.pressure()
|
||||
<< " vel " << tp.velocity() << " start " << tp.startPos() << " last " << tp.lastPos() << " delta " << tp.pos() - tp.lastPos() << ')';
|
||||
dbg.nospace();
|
||||
dbg << "TouchPoint(" << tp.id() << " (";
|
||||
QtDebugUtils::formatQRect(dbg, tp.rect());
|
||||
dbg << ") ";
|
||||
QtDebugUtils::formatQEnum(dbg, tp.state());
|
||||
dbg << " press " << tp.pressure() << " vel " << tp.velocity()
|
||||
<< " start (";
|
||||
QtDebugUtils::formatQPoint(dbg, tp.startPos());
|
||||
dbg << ") last (";
|
||||
QtDebugUtils::formatQPoint(dbg, tp.lastPos());
|
||||
dbg << ") delta (";
|
||||
QtDebugUtils::formatQPoint(dbg, tp.pos() - tp.lastPos());
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
|
||||
|
|
@ -3716,18 +3739,23 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
|
|||
const QMouseEvent *me = static_cast<const QMouseEvent*>(e);
|
||||
const Qt::MouseButton button = me->button();
|
||||
const Qt::MouseButtons buttons = me->buttons();
|
||||
dbg << "QMouseEvent(" << type;
|
||||
if (type != QEvent::MouseMove && type != QEvent::NonClientAreaMouseMove)
|
||||
dbg << ", " << button;
|
||||
if (buttons && button != buttons)
|
||||
dbg << ", buttons=" << buttons;
|
||||
if (me->modifiers())
|
||||
dbg << ", " << me->modifiers();
|
||||
dbg << ", localPos=" << me->localPos() << ", screenPos=" << me->screenPos();
|
||||
if (me->source())
|
||||
dbg << ", " << me->source();
|
||||
if (const Qt::MouseEventFlags flags = me->flags())
|
||||
dbg << ", flags = " << hex << int(flags) << dec;
|
||||
dbg << "QMouseEvent(";
|
||||
QtDebugUtils::formatQEnum(dbg, type);
|
||||
if (type != QEvent::MouseMove && type != QEvent::NonClientAreaMouseMove) {
|
||||
dbg << ", ";
|
||||
QtDebugUtils::formatQEnum(dbg, button);
|
||||
}
|
||||
if (buttons && button != buttons) {
|
||||
dbg << ", buttons=";
|
||||
QtDebugUtils::formatQFlags(dbg, buttons);
|
||||
}
|
||||
QtDebugUtils::formatNonNullQFlags(dbg, ", ", me->modifiers());
|
||||
dbg << ", localPos=";
|
||||
QtDebugUtils::formatQPoint(dbg, me->localPos());
|
||||
dbg << ", screenPos=";
|
||||
QtDebugUtils::formatQPoint(dbg, me->screenPos());
|
||||
QtDebugUtils::formatNonNullQEnum(dbg, ", ", me->source());
|
||||
QtDebugUtils::formatNonNullQFlags(dbg, ", flags=", me->flags());
|
||||
dbg << ')';
|
||||
}
|
||||
break;
|
||||
|
|
@ -3743,10 +3771,11 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
|
|||
case QEvent::ShortcutOverride:
|
||||
{
|
||||
const QKeyEvent *ke = static_cast<const QKeyEvent *>(e);
|
||||
dbg << "QKeyEvent(" << type
|
||||
<< ", " << static_cast<Qt::Key>(ke->key());
|
||||
if (ke->modifiers())
|
||||
dbg << ", " << ke->modifiers();
|
||||
dbg << "QKeyEvent(";
|
||||
QtDebugUtils::formatQEnum(dbg, type);
|
||||
dbg << ", ";
|
||||
QtDebugUtils::formatQEnum(dbg, static_cast<Qt::Key>(ke->key()));
|
||||
QtDebugUtils::formatNonNullQFlags(dbg, ", ", ke->modifiers());
|
||||
if (!ke->text().isEmpty())
|
||||
dbg << ", text=" << ke->text();
|
||||
if (ke->isAutoRepeat())
|
||||
|
|
@ -3765,11 +3794,16 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
|
|||
case QEvent::FocusAboutToChange:
|
||||
case QEvent::FocusIn:
|
||||
case QEvent::FocusOut:
|
||||
dbg << "QFocusEvent(" << type << ", " << static_cast<const QFocusEvent *>(e)->reason() << ')';
|
||||
dbg << "QFocusEvent(";
|
||||
QtDebugUtils::formatQEnum(dbg, type);
|
||||
dbg << ", ";
|
||||
QtDebugUtils::formatQEnum(dbg, static_cast<const QFocusEvent *>(e)->reason());
|
||||
dbg << ')';
|
||||
break;
|
||||
case QEvent::Move: {
|
||||
const QMoveEvent *me = static_cast<const QMoveEvent *>(e);
|
||||
dbg << "QMoveEvent(" << me->pos();
|
||||
dbg << "QMoveEvent(";
|
||||
QtDebugUtils::formatQPoint(dbg, me->pos());
|
||||
if (!me->spontaneous())
|
||||
dbg << ", non-spontaneous";
|
||||
dbg << ')';
|
||||
|
|
@ -3777,7 +3811,8 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
|
|||
break;
|
||||
case QEvent::Resize: {
|
||||
const QResizeEvent *re = static_cast<const QResizeEvent *>(e);
|
||||
dbg << "QResizeEvent(" << re->size();
|
||||
dbg << "QResizeEvent(";
|
||||
QtDebugUtils::formatQSize(dbg, re->size());
|
||||
if (!re->spontaneous())
|
||||
dbg << ", non-spontaneous";
|
||||
dbg << ')';
|
||||
|
|
@ -3804,19 +3839,25 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
|
|||
case QEvent::ChildAdded:
|
||||
case QEvent::ChildPolished:
|
||||
case QEvent::ChildRemoved:
|
||||
dbg << "QChildEvent(" << type << ", " << (static_cast<const QChildEvent*>(e))->child() << ')';
|
||||
dbg << "QChildEvent(";
|
||||
QtDebugUtils::formatQEnum(dbg, type);
|
||||
dbg << ", " << (static_cast<const QChildEvent*>(e))->child() << ')';
|
||||
break;
|
||||
# ifndef QT_NO_GESTURES
|
||||
case QEvent::NativeGesture: {
|
||||
const QNativeGestureEvent *ne = static_cast<const QNativeGestureEvent *>(e);
|
||||
dbg << "QNativeGestureEvent(" << ne->gestureType()
|
||||
<< "localPos=" << ne->localPos() << ", value=" << ne->value() << ')';
|
||||
dbg << "QNativeGestureEvent(";
|
||||
QtDebugUtils::formatQEnum(dbg, ne->gestureType());
|
||||
dbg << "localPos=";
|
||||
QtDebugUtils::formatQPoint(dbg, ne->localPos());
|
||||
dbg << ", value=" << ne->value() << ')';
|
||||
}
|
||||
break;
|
||||
# endif // !QT_NO_GESTURES
|
||||
case QEvent::ApplicationStateChange:
|
||||
dbg << "QApplicationStateChangeEvent("
|
||||
<< static_cast<const QApplicationStateChangeEvent *>(e)->applicationState() << ')';
|
||||
dbg << "QApplicationStateChangeEvent(";
|
||||
QtDebugUtils::formatQEnum(dbg, static_cast<const QApplicationStateChangeEvent *>(e)->applicationState());
|
||||
dbg << ')';
|
||||
break;
|
||||
case QEvent::ContextMenu:
|
||||
dbg << "QContextMenuEvent(" << static_cast<const QContextMenuEvent *>(e)->pos() << ')';
|
||||
|
|
@ -3849,8 +3890,9 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
|
|||
dbg << ')';
|
||||
break;
|
||||
default:
|
||||
dbg << eventClassName(type) << '(' << type << ", "
|
||||
<< (const void *)e << ", type = " << e->type() << ')';
|
||||
dbg << eventClassName(type) << '(';
|
||||
QtDebugUtils::formatQEnum(dbg, type);
|
||||
dbg << ", " << (const void *)e << ')';
|
||||
break;
|
||||
}
|
||||
return dbg;
|
||||
|
|
|
|||
|
|
@ -236,9 +236,7 @@ struct QWindowGeometrySpecification
|
|||
{
|
||||
QWindowGeometrySpecification() : corner(Qt::TopLeftCorner), xOffset(-1), yOffset(-1), width(-1), height(-1) {}
|
||||
static QWindowGeometrySpecification fromArgument(const QByteArray &a);
|
||||
QRect apply(const QRect &windowGeometry, const QSize &windowMinimumSize, const QSize &windowMaximumSize, const QRect &availableGeometry) const;
|
||||
inline QRect apply(const QRect &windowGeometry, const QWindow *window) const
|
||||
{ return apply(windowGeometry, window->minimumSize(), window->maximumSize(), window->screen()->virtualGeometry()); }
|
||||
void applyTo(QWindow *window) const;
|
||||
|
||||
Qt::Corner corner;
|
||||
int xOffset;
|
||||
|
|
@ -300,32 +298,34 @@ QWindowGeometrySpecification QWindowGeometrySpecification::fromArgument(const QB
|
|||
return result;
|
||||
}
|
||||
|
||||
QRect QWindowGeometrySpecification::apply(const QRect &windowGeometry, const QSize &windowMinimumSize, const QSize &windowMaximumSize, const QRect &availableGeometry) const
|
||||
void QWindowGeometrySpecification::applyTo(QWindow *window) const
|
||||
{
|
||||
QRect result = windowGeometry;
|
||||
QRect windowGeometry = window->frameGeometry();
|
||||
QSize size = windowGeometry.size();
|
||||
if (width >= 0 || height >= 0) {
|
||||
QSize size = windowGeometry.size();
|
||||
const QSize windowMinimumSize = window->minimumSize();
|
||||
const QSize windowMaximumSize = window->maximumSize();
|
||||
if (width >= 0)
|
||||
size.setWidth(qBound(windowMinimumSize.width(), width, windowMaximumSize.width()));
|
||||
if (height >= 0)
|
||||
size.setHeight(qBound(windowMinimumSize.height(), height, windowMaximumSize.height()));
|
||||
result.setSize(size);
|
||||
window->resize(size);
|
||||
}
|
||||
if (xOffset >= 0 || yOffset >= 0) {
|
||||
const QRect availableGeometry = window->screen()->virtualGeometry();
|
||||
QPoint topLeft = windowGeometry.topLeft();
|
||||
if (xOffset >= 0) {
|
||||
topLeft.setX(corner == Qt::TopLeftCorner || corner == Qt::BottomLeftCorner ?
|
||||
xOffset :
|
||||
qMax(availableGeometry.right() - result.width() - xOffset, availableGeometry.left()));
|
||||
qMax(availableGeometry.right() - size.width() - xOffset, availableGeometry.left()));
|
||||
}
|
||||
if (yOffset >= 0) {
|
||||
topLeft.setY(corner == Qt::TopLeftCorner || corner == Qt::TopRightCorner ?
|
||||
yOffset :
|
||||
qMax(availableGeometry.bottom() - result.height() - yOffset, availableGeometry.top()));
|
||||
qMax(availableGeometry.bottom() - size.height() - yOffset, availableGeometry.top()));
|
||||
}
|
||||
result.moveTopLeft(topLeft);
|
||||
window->setFramePosition(topLeft);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static QWindowGeometrySpecification windowGeometrySpecification;
|
||||
|
|
@ -2757,9 +2757,9 @@ void QGuiApplication::setPalette(const QPalette &pal)
|
|||
emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal);
|
||||
}
|
||||
|
||||
QRect QGuiApplicationPrivate::applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window)
|
||||
void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)
|
||||
{
|
||||
return windowGeometrySpecification.apply(windowGeometry, window);
|
||||
windowGeometrySpecification.applyTo(window);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ public:
|
|||
|
||||
virtual void notifyWindowIconChanged();
|
||||
|
||||
static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window);
|
||||
static void applyWindowGeometrySpecificationTo(QWindow *window);
|
||||
|
||||
static void setApplicationState(Qt::ApplicationState state, bool forcePropagate = false);
|
||||
|
||||
|
|
|
|||
|
|
@ -489,6 +489,13 @@ void QWindow::setVisible(bool visible)
|
|||
}
|
||||
if (!app_priv->forcedWindowIcon.isNull())
|
||||
setIcon(app_priv->forcedWindowIcon);
|
||||
|
||||
// Handling of the -qwindowgeometry, -geometry command line arguments
|
||||
static bool geometryApplied = false;
|
||||
if (!geometryApplied) {
|
||||
geometryApplied = true;
|
||||
QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(this);
|
||||
}
|
||||
}
|
||||
|
||||
QShowEvent showEvent;
|
||||
|
|
@ -1502,10 +1509,10 @@ void QWindow::setFramePosition(const QPoint &point)
|
|||
{
|
||||
Q_D(QWindow);
|
||||
d->positionPolicy = QWindowPrivate::WindowFrameInclusive;
|
||||
d->positionAutomatic = false;
|
||||
if (d->platformWindow) {
|
||||
d->platformWindow->setGeometry(QRect(point, size()));
|
||||
} else {
|
||||
d->positionAutomatic = false;
|
||||
d->geometry.moveTopLeft(point);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1039,10 +1039,11 @@ bool QOpenGLDebugMessage::operator==(const QOpenGLDebugMessage &debugMessage) co
|
|||
*/
|
||||
QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Source source)
|
||||
{
|
||||
QDebugStateSaver saver(debug);
|
||||
debug.nospace() << "QOpenGLDebugMessage::Source("
|
||||
<< qt_messageSourceToString(source)
|
||||
<< ")";
|
||||
return debug.space();
|
||||
<< ')';
|
||||
return debug;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1053,10 +1054,11 @@ QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Source source)
|
|||
*/
|
||||
QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Type type)
|
||||
{
|
||||
QDebugStateSaver saver(debug);
|
||||
debug.nospace() << "QOpenGLDebugMessage::Type("
|
||||
<< qt_messageTypeToString(type)
|
||||
<< ")";
|
||||
return debug.space();
|
||||
<< ')';
|
||||
return debug;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1067,10 +1069,11 @@ QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Type type)
|
|||
*/
|
||||
QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Severity severity)
|
||||
{
|
||||
QDebugStateSaver saver(debug);
|
||||
debug.nospace() << "QOpenGLDebugMessage::Severity("
|
||||
<< qt_messageSeverityToString(severity)
|
||||
<< ")";
|
||||
return debug.space();
|
||||
<< ')';
|
||||
return debug;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1081,13 +1084,14 @@ QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Severity severity)
|
|||
*/
|
||||
QDebug operator<<(QDebug debug, const QOpenGLDebugMessage &message)
|
||||
{
|
||||
QDebugStateSaver saver(debug);
|
||||
debug.nospace() << "QOpenGLDebugMessage("
|
||||
<< qt_messageSourceToString(message.source()) << ", "
|
||||
<< message.id() << ", "
|
||||
<< message.message() << ", "
|
||||
<< qt_messageSeverityToString(message.severity()) << ", "
|
||||
<< qt_messageTypeToString(message.type()) << ")";
|
||||
return debug.space();
|
||||
<< qt_messageTypeToString(message.type()) << ')';
|
||||
return debug;
|
||||
|
||||
}
|
||||
#endif // QT_NO_DEBUG_STREAM
|
||||
|
|
|
|||
|
|
@ -602,8 +602,7 @@ void QCosmeticStroker::drawPath(const QVectorPath &path)
|
|||
if (!closed && drawCaps && points == end - 2)
|
||||
caps |= CapEnd;
|
||||
|
||||
QCosmeticStroker::Point last = this->lastPixel;
|
||||
bool unclipped = stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);
|
||||
bool moveNextStart = stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);
|
||||
|
||||
/* fix for gaps in polylines with fastpen and aliased in a sequence
|
||||
of points with small distances: if current point p2 has been dropped
|
||||
|
|
@ -613,14 +612,8 @@ void QCosmeticStroker::drawPath(const QVectorPath &path)
|
|||
still need to update p to avoid drawing the line after this one from
|
||||
a bad starting position.
|
||||
*/
|
||||
if (fastPenAliased && unclipped) {
|
||||
if (last.x != lastPixel.x || last.y != lastPixel.y
|
||||
|| points == begin + 2 || points == end - 2) {
|
||||
p = p2;
|
||||
}
|
||||
} else {
|
||||
if (!fastPenAliased || moveNextStart || points == begin + 2 || points == end - 2)
|
||||
p = p2;
|
||||
}
|
||||
points += 2;
|
||||
caps = NoCaps;
|
||||
}
|
||||
|
|
@ -727,8 +720,9 @@ template<DrawPixel drawPixel, class Dasher>
|
|||
static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
|
||||
{
|
||||
if (stroker->clipLine(rx1, ry1, rx2, ry2))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
bool didDraw = false;
|
||||
const int half = stroker->legacyRounding ? 31 : 0;
|
||||
int x1 = toF26Dot6(rx1) + half;
|
||||
int y1 = toF26Dot6(ry1) + half;
|
||||
|
|
@ -814,6 +808,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
|||
dasher.adjust();
|
||||
x += xinc;
|
||||
} while (++y < ys);
|
||||
didDraw = true;
|
||||
}
|
||||
} else {
|
||||
// horizontal
|
||||
|
|
@ -889,10 +884,11 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
|||
dasher.adjust();
|
||||
y += yinc;
|
||||
} while (++x < xs);
|
||||
didDraw = true;
|
||||
}
|
||||
}
|
||||
stroker->lastPixel = last;
|
||||
return true;
|
||||
return didDraw;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -900,7 +896,7 @@ template<DrawPixel drawPixel, class Dasher>
|
|||
static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
|
||||
{
|
||||
if (stroker->clipLine(rx1, ry1, rx2, ry2))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
int x1 = toF26Dot6(rx1);
|
||||
int y1 = toF26Dot6(ry1);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue