1
0

asmjit_test_x86_cc.cpp 105 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027
  1. // [AsmJit]
  2. // Machine Code Generation for C++.
  3. //
  4. // [License]
  5. // Zlib - See LICENSE.md file in the package.
  6. #include <setjmp.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "./asmjit.h"
  11. #include "./asmjit_test_misc.h"
  12. using namespace asmjit;
  13. // ============================================================================
  14. // [CmdLine]
  15. // ============================================================================
  16. class CmdLine {
  17. public:
  18. CmdLine(int argc, const char* const* argv) noexcept
  19. : _argc(argc),
  20. _argv(argv) {}
  21. bool hasArg(const char* arg) noexcept {
  22. for (int i = 1; i < _argc; i++)
  23. if (strcmp(_argv[i], arg) == 0)
  24. return true;
  25. return false;
  26. }
  27. int _argc;
  28. const char* const* _argv;
  29. };
  30. // ============================================================================
  31. // [SimpleErrorHandler]
  32. // ============================================================================
  33. class SimpleErrorHandler : public ErrorHandler {
  34. public:
  35. SimpleErrorHandler() : _err(kErrorOk) {}
  36. virtual void handleError(Error err, const char* message, BaseEmitter* origin) {
  37. ASMJIT_UNUSED(origin);
  38. _err = err;
  39. _message.assignString(message);
  40. }
  41. Error _err;
  42. String _message;
  43. };
  44. // ============================================================================
  45. // [X86Test]
  46. // ============================================================================
  47. //! Base test interface for testing `x86::Compiler`.
  48. class X86Test {
  49. public:
  50. X86Test(const char* name = nullptr) { _name.assignString(name); }
  51. virtual ~X86Test() {}
  52. inline const char* name() const { return _name.data(); }
  53. virtual void compile(x86::Compiler& c) = 0;
  54. virtual bool run(void* func, String& result, String& expect) = 0;
  55. String _name;
  56. };
  57. // ============================================================================
  58. // [X86TestApp]
  59. // ============================================================================
  60. class X86TestApp {
  61. public:
  62. Zone _zone;
  63. ZoneAllocator _allocator;
  64. ZoneVector<X86Test*> _tests;
  65. unsigned _nFailed;
  66. size_t _outputSize;
  67. bool _verbose;
  68. bool _dumpAsm;
  69. X86TestApp() noexcept
  70. : _zone(8096 - Zone::kBlockOverhead),
  71. _allocator(&_zone),
  72. _nFailed(0),
  73. _outputSize(0),
  74. _verbose(false),
  75. _dumpAsm(false) {}
  76. ~X86TestApp() noexcept {
  77. for (X86Test* test : _tests)
  78. delete test;
  79. }
  80. Error add(X86Test* test) noexcept{
  81. return _tests.append(&_allocator, test);
  82. }
  83. template<class T>
  84. inline void addT() { T::add(*this); }
  85. int handleArgs(int argc, const char* const* argv);
  86. void showInfo();
  87. int run();
  88. };
  89. int X86TestApp::handleArgs(int argc, const char* const* argv) {
  90. CmdLine cmd(argc, argv);
  91. if (cmd.hasArg("--verbose")) _verbose = true;
  92. if (cmd.hasArg("--dump-asm")) _dumpAsm = true;
  93. return 0;
  94. }
  95. void X86TestApp::showInfo() {
  96. printf("AsmJit Compiler Test-Suite v%u.%u.%u [Arch=%s]:\n",
  97. unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
  98. unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
  99. unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF),
  100. sizeof(void*) == 8 ? "X64" : "X86");
  101. printf(" [%s] Verbose (use --verbose to turn verbose output ON)\n", _verbose ? "x" : " ");
  102. printf(" [%s] DumpAsm (use --dump-asm to turn assembler dumps ON)\n", _dumpAsm ? "x" : " ");
  103. printf("\n");
  104. }
  105. int X86TestApp::run() {
  106. #ifndef ASMJIT_NO_LOGGING
  107. uint32_t kFormatFlags = FormatOptions::kFlagMachineCode |
  108. FormatOptions::kFlagExplainImms |
  109. FormatOptions::kFlagRegCasts |
  110. FormatOptions::kFlagAnnotations |
  111. FormatOptions::kFlagDebugPasses |
  112. FormatOptions::kFlagDebugRA ;
  113. FileLogger fileLogger(stdout);
  114. fileLogger.addFlags(kFormatFlags);
  115. StringLogger stringLogger;
  116. stringLogger.addFlags(kFormatFlags);
  117. #endif
  118. for (X86Test* test : _tests) {
  119. JitRuntime runtime;
  120. CodeHolder code;
  121. SimpleErrorHandler errorHandler;
  122. code.init(runtime.codeInfo());
  123. code.setErrorHandler(&errorHandler);
  124. #ifndef ASMJIT_NO_LOGGING
  125. if (_verbose) {
  126. code.setLogger(&fileLogger);
  127. }
  128. else {
  129. stringLogger.clear();
  130. code.setLogger(&stringLogger);
  131. }
  132. #endif
  133. printf("[Test] %s", test->name());
  134. #ifndef ASMJIT_NO_LOGGING
  135. if (_verbose) printf("\n");
  136. #endif
  137. x86::Compiler cc(&code);
  138. test->compile(cc);
  139. Error err = errorHandler._err;
  140. if (!err)
  141. err = cc.finalize();
  142. void* func;
  143. #ifndef ASMJIT_NO_LOGGING
  144. if (_dumpAsm) {
  145. if (!_verbose) printf("\n");
  146. String sb;
  147. cc.dump(sb, kFormatFlags);
  148. printf("%s", sb.data());
  149. }
  150. #endif
  151. if (err == kErrorOk)
  152. err = runtime.add(&func, &code);
  153. if (_verbose)
  154. fflush(stdout);
  155. if (err == kErrorOk) {
  156. _outputSize += code.codeSize();
  157. StringTmp<128> result;
  158. StringTmp<128> expect;
  159. if (test->run(func, result, expect)) {
  160. if (!_verbose) printf(" [OK]\n");
  161. }
  162. else {
  163. if (!_verbose) printf(" [FAILED]\n");
  164. #ifndef ASMJIT_NO_LOGGING
  165. if (!_verbose) printf("%s", stringLogger.data());
  166. #endif
  167. printf("[Status]\n");
  168. printf(" Returned: %s\n", result.data());
  169. printf(" Expected: %s\n", expect.data());
  170. _nFailed++;
  171. }
  172. if (_dumpAsm)
  173. printf("\n");
  174. runtime.release(func);
  175. }
  176. else {
  177. if (!_verbose) printf(" [FAILED]\n");
  178. #ifndef ASMJIT_NO_LOGGING
  179. if (!_verbose) printf("%s", stringLogger.data());
  180. #endif
  181. printf("[Status]\n");
  182. printf(" ERROR 0x%08X: %s\n", unsigned(err), errorHandler._message.data());
  183. _nFailed++;
  184. }
  185. }
  186. if (_nFailed == 0)
  187. printf("\n[PASSED] All %u tests passed\n", unsigned(_tests.size()));
  188. else
  189. printf("\n[FAILED] %u %s of %u failed\n", _nFailed, _nFailed == 1 ? "test" : "tests", unsigned(_tests.size()));
  190. printf(" OutputSize=%zu\n", _outputSize);
  191. return _nFailed == 0 ? 0 : 1;
  192. }
  193. // ============================================================================
  194. // [X86Test_AlignBase]
  195. // ============================================================================
  196. class X86Test_AlignBase : public X86Test {
  197. public:
  198. X86Test_AlignBase(uint32_t argCount, uint32_t alignment, bool preserveFP)
  199. : _argCount(argCount),
  200. _alignment(alignment),
  201. _preserveFP(preserveFP) {
  202. _name.assignFormat("AlignBase {NumArgs=%u Alignment=%u PreserveFP=%c}", argCount, alignment, preserveFP ? 'Y' : 'N');
  203. }
  204. static void add(X86TestApp& app) {
  205. for (uint32_t i = 0; i <= 16; i++) {
  206. for (uint32_t a = 16; a <= 32; a += 16) {
  207. app.add(new X86Test_AlignBase(i, a, true));
  208. app.add(new X86Test_AlignBase(i, a, false));
  209. }
  210. }
  211. }
  212. virtual void compile(x86::Compiler& cc) {
  213. uint32_t i;
  214. uint32_t argCount = _argCount;
  215. FuncSignatureBuilder signature(CallConv::kIdHost);
  216. signature.setRetT<int>();
  217. for (i = 0; i < argCount; i++)
  218. signature.addArgT<int>();
  219. cc.addFunc(signature);
  220. if (_preserveFP)
  221. cc.func()->frame().setPreservedFP();
  222. x86::Gp gpVar = cc.newIntPtr("gpVar");
  223. x86::Gp gpSum;
  224. x86::Mem stack = cc.newStack(_alignment, _alignment);
  225. // Do a sum of arguments to verify a possible relocation when misaligned.
  226. if (argCount) {
  227. for (i = 0; i < argCount; i++) {
  228. x86::Gp gpArg = cc.newInt32("gpArg%u", i);
  229. cc.setArg(i, gpArg);
  230. if (i == 0)
  231. gpSum = gpArg;
  232. else
  233. cc.add(gpSum, gpArg);
  234. }
  235. }
  236. // Check alignment of xmmVar (has to be 16).
  237. cc.lea(gpVar, stack);
  238. cc.and_(gpVar, _alignment - 1);
  239. // Add a sum of all arguments to check if they are correct.
  240. if (argCount)
  241. cc.or_(gpVar.r32(), gpSum);
  242. cc.ret(gpVar);
  243. cc.endFunc();
  244. }
  245. virtual bool run(void* _func, String& result, String& expect) {
  246. typedef unsigned int U;
  247. typedef U (*Func0)();
  248. typedef U (*Func1)(U);
  249. typedef U (*Func2)(U, U);
  250. typedef U (*Func3)(U, U, U);
  251. typedef U (*Func4)(U, U, U, U);
  252. typedef U (*Func5)(U, U, U, U, U);
  253. typedef U (*Func6)(U, U, U, U, U, U);
  254. typedef U (*Func7)(U, U, U, U, U, U, U);
  255. typedef U (*Func8)(U, U, U, U, U, U, U, U);
  256. typedef U (*Func9)(U, U, U, U, U, U, U, U, U);
  257. typedef U (*Func10)(U, U, U, U, U, U, U, U, U, U);
  258. typedef U (*Func11)(U, U, U, U, U, U, U, U, U, U, U);
  259. typedef U (*Func12)(U, U, U, U, U, U, U, U, U, U, U, U);
  260. typedef U (*Func13)(U, U, U, U, U, U, U, U, U, U, U, U, U);
  261. typedef U (*Func14)(U, U, U, U, U, U, U, U, U, U, U, U, U, U);
  262. typedef U (*Func15)(U, U, U, U, U, U, U, U, U, U, U, U, U, U, U);
  263. typedef U (*Func16)(U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U);
  264. unsigned int resultRet = 0;
  265. unsigned int expectRet = 0;
  266. switch (_argCount) {
  267. case 0:
  268. resultRet = ptr_as_func<Func0>(_func)();
  269. expectRet = 0;
  270. break;
  271. case 1:
  272. resultRet = ptr_as_func<Func1>(_func)(1);
  273. expectRet = 1;
  274. break;
  275. case 2:
  276. resultRet = ptr_as_func<Func2>(_func)(1, 2);
  277. expectRet = 1 + 2;
  278. break;
  279. case 3:
  280. resultRet = ptr_as_func<Func3>(_func)(1, 2, 3);
  281. expectRet = 1 + 2 + 3;
  282. break;
  283. case 4:
  284. resultRet = ptr_as_func<Func4>(_func)(1, 2, 3, 4);
  285. expectRet = 1 + 2 + 3 + 4;
  286. break;
  287. case 5:
  288. resultRet = ptr_as_func<Func5>(_func)(1, 2, 3, 4, 5);
  289. expectRet = 1 + 2 + 3 + 4 + 5;
  290. break;
  291. case 6:
  292. resultRet = ptr_as_func<Func6>(_func)(1, 2, 3, 4, 5, 6);
  293. expectRet = 1 + 2 + 3 + 4 + 5 + 6;
  294. break;
  295. case 7:
  296. resultRet = ptr_as_func<Func7>(_func)(1, 2, 3, 4, 5, 6, 7);
  297. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7;
  298. break;
  299. case 8:
  300. resultRet = ptr_as_func<Func8>(_func)(1, 2, 3, 4, 5, 6, 7, 8);
  301. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8;
  302. break;
  303. case 9:
  304. resultRet = ptr_as_func<Func9>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9);
  305. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9;
  306. break;
  307. case 10:
  308. resultRet = ptr_as_func<Func10>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
  309. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10;
  310. break;
  311. case 11:
  312. resultRet = ptr_as_func<Func11>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
  313. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11;
  314. break;
  315. case 12:
  316. resultRet = ptr_as_func<Func12>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
  317. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12;
  318. break;
  319. case 13:
  320. resultRet = ptr_as_func<Func13>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
  321. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13;
  322. break;
  323. case 14:
  324. resultRet = ptr_as_func<Func14>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
  325. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14;
  326. break;
  327. case 15:
  328. resultRet = ptr_as_func<Func15>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
  329. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15;
  330. break;
  331. case 16:
  332. resultRet = ptr_as_func<Func16>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  333. expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16;
  334. break;
  335. }
  336. result.assignFormat("ret={%u, %u}", resultRet >> 28, resultRet & 0x0FFFFFFFu);
  337. expect.assignFormat("ret={%u, %u}", expectRet >> 28, expectRet & 0x0FFFFFFFu);
  338. return resultRet == expectRet;
  339. }
  340. uint32_t _argCount;
  341. uint32_t _alignment;
  342. bool _preserveFP;
  343. };
  344. // ============================================================================
  345. // [X86Test_NoCode]
  346. // ============================================================================
  347. class X86Test_NoCode : public X86Test {
  348. public:
  349. X86Test_NoCode() : X86Test("NoCode") {}
  350. static void add(X86TestApp& app) {
  351. app.add(new X86Test_NoCode());
  352. }
  353. virtual void compile(x86::Compiler& cc) {
  354. cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
  355. cc.endFunc();
  356. }
  357. virtual bool run(void* _func, String& result, String& expect) {
  358. ASMJIT_UNUSED(result);
  359. ASMJIT_UNUSED(expect);
  360. typedef void(*Func)(void);
  361. Func func = ptr_as_func<Func>(_func);
  362. func();
  363. return true;
  364. }
  365. };
  366. // ============================================================================
  367. // [X86Test_AlignNone]
  368. // ============================================================================
  369. class X86Test_NoAlign : public X86Test {
  370. public:
  371. X86Test_NoAlign() : X86Test("NoAlign") {}
  372. static void add(X86TestApp& app) {
  373. app.add(new X86Test_NoAlign());
  374. }
  375. virtual void compile(x86::Compiler& cc) {
  376. cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
  377. cc.align(kAlignCode, 0);
  378. cc.align(kAlignCode, 1);
  379. cc.endFunc();
  380. }
  381. virtual bool run(void* _func, String& result, String& expect) {
  382. ASMJIT_UNUSED(result);
  383. ASMJIT_UNUSED(expect);
  384. typedef void (*Func)(void);
  385. Func func = ptr_as_func<Func>(_func);
  386. func();
  387. return true;
  388. }
  389. };
  390. // ============================================================================
  391. // [X86Test_JumpMerge]
  392. // ============================================================================
  393. class X86Test_JumpMerge : public X86Test {
  394. public:
  395. X86Test_JumpMerge() : X86Test("JumpMerge") {}
  396. static void add(X86TestApp& app) {
  397. app.add(new X86Test_JumpMerge());
  398. }
  399. virtual void compile(x86::Compiler& cc) {
  400. cc.addFunc(FuncSignatureT<void, int*, int>(CallConv::kIdHost));
  401. Label L0 = cc.newLabel();
  402. Label L1 = cc.newLabel();
  403. Label L2 = cc.newLabel();
  404. Label LEnd = cc.newLabel();
  405. x86::Gp dst = cc.newIntPtr("dst");
  406. x86::Gp val = cc.newInt32("val");
  407. cc.setArg(0, dst);
  408. cc.setArg(1, val);
  409. cc.cmp(val, 0);
  410. cc.je(L2);
  411. cc.cmp(val, 1);
  412. cc.je(L1);
  413. cc.cmp(val, 2);
  414. cc.je(L0);
  415. cc.mov(x86::dword_ptr(dst), val);
  416. cc.jmp(LEnd);
  417. // On purpose. This tests whether the CFG constructs a single basic-block
  418. // from multiple labels next to each other.
  419. cc.bind(L0);
  420. cc.bind(L1);
  421. cc.bind(L2);
  422. cc.mov(x86::dword_ptr(dst), 0);
  423. cc.bind(LEnd);
  424. cc.endFunc();
  425. }
  426. virtual bool run(void* _func, String& result, String& expect) {
  427. typedef void(*Func)(int*, int);
  428. Func func = ptr_as_func<Func>(_func);
  429. int arr[5] = { -1, -1, -1, -1, -1 };
  430. int exp[5] = { 0, 0, 0, 3, 4 };
  431. for (int i = 0; i < 5; i++)
  432. func(&arr[i], i);
  433. result.assignFormat("ret={%d, %d, %d, %d, %d}", arr[0], arr[1], arr[2], arr[3], arr[4]);
  434. expect.assignFormat("ret={%d, %d, %d, %d, %d}", exp[0], exp[1], exp[2], exp[3], exp[4]);
  435. return result == expect;
  436. }
  437. };
  438. // ============================================================================
  439. // [X86Test_JumpCross]
  440. // ============================================================================
  441. class X86Test_JumpCross : public X86Test {
  442. public:
  443. X86Test_JumpCross() : X86Test("JumpCross") {}
  444. static void add(X86TestApp& app) {
  445. app.add(new X86Test_JumpCross());
  446. }
  447. virtual void compile(x86::Compiler& cc) {
  448. cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
  449. Label L1 = cc.newLabel();
  450. Label L2 = cc.newLabel();
  451. Label L3 = cc.newLabel();
  452. cc.jmp(L2);
  453. cc.bind(L1);
  454. cc.jmp(L3);
  455. cc.bind(L2);
  456. cc.jmp(L1);
  457. cc.bind(L3);
  458. cc.endFunc();
  459. }
  460. virtual bool run(void* _func, String& result, String& expect) {
  461. ASMJIT_UNUSED(result);
  462. ASMJIT_UNUSED(expect);
  463. typedef void (*Func)(void);
  464. Func func = ptr_as_func<Func>(_func);
  465. func();
  466. return true;
  467. }
  468. };
  469. // ============================================================================
  470. // [X86Test_JumpMany]
  471. // ============================================================================
  472. class X86Test_JumpMany : public X86Test {
  473. public:
  474. X86Test_JumpMany() : X86Test("JumpMany") {}
  475. static void add(X86TestApp& app) {
  476. app.add(new X86Test_JumpMany());
  477. }
  478. virtual void compile(x86::Compiler& cc) {
  479. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  480. for (uint32_t i = 0; i < 1000; i++) {
  481. Label L = cc.newLabel();
  482. cc.jmp(L);
  483. cc.bind(L);
  484. }
  485. x86::Gp ret = cc.newInt32("ret");
  486. cc.xor_(ret, ret);
  487. cc.ret(ret);
  488. cc.endFunc();
  489. }
  490. virtual bool run(void* _func, String& result, String& expect) {
  491. typedef int (*Func)(void);
  492. Func func = ptr_as_func<Func>(_func);
  493. int resultRet = func();
  494. int expectRet = 0;
  495. result.assignFormat("ret={%d}", resultRet);
  496. expect.assignFormat("ret={%d}", expectRet);
  497. return resultRet == expectRet;
  498. }
  499. };
  500. // ============================================================================
  501. // [X86Test_JumpUnreachable1]
  502. // ============================================================================
  503. class X86Test_JumpUnreachable1 : public X86Test {
  504. public:
  505. X86Test_JumpUnreachable1() : X86Test("JumpUnreachable1") {}
  506. static void add(X86TestApp& app) {
  507. app.add(new X86Test_JumpUnreachable1());
  508. }
  509. virtual void compile(x86::Compiler& cc) {
  510. cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
  511. Label L_1 = cc.newLabel();
  512. Label L_2 = cc.newLabel();
  513. Label L_3 = cc.newLabel();
  514. Label L_4 = cc.newLabel();
  515. Label L_5 = cc.newLabel();
  516. Label L_6 = cc.newLabel();
  517. Label L_7 = cc.newLabel();
  518. x86::Gp v0 = cc.newUInt32("v0");
  519. x86::Gp v1 = cc.newUInt32("v1");
  520. cc.bind(L_2);
  521. cc.bind(L_3);
  522. cc.jmp(L_1);
  523. cc.bind(L_5);
  524. cc.mov(v0, 0);
  525. cc.bind(L_6);
  526. cc.jmp(L_3);
  527. cc.mov(v1, 1);
  528. cc.jmp(L_1);
  529. cc.bind(L_4);
  530. cc.jmp(L_2);
  531. cc.bind(L_7);
  532. cc.add(v0, v1);
  533. cc.align(kAlignCode, 16);
  534. cc.bind(L_1);
  535. cc.ret();
  536. cc.endFunc();
  537. }
  538. virtual bool run(void* _func, String& result, String& expect) {
  539. typedef void (*Func)(void);
  540. Func func = ptr_as_func<Func>(_func);
  541. func();
  542. result.appendString("ret={}");
  543. expect.appendString("ret={}");
  544. return true;
  545. }
  546. };
  547. // ============================================================================
  548. // [X86Test_JumpUnreachable2]
  549. // ============================================================================
  550. class X86Test_JumpUnreachable2 : public X86Test {
  551. public:
  552. X86Test_JumpUnreachable2() : X86Test("JumpUnreachable2") {}
  553. static void add(X86TestApp& app) {
  554. app.add(new X86Test_JumpUnreachable2());
  555. }
  556. virtual void compile(x86::Compiler& cc) {
  557. cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
  558. Label L_1 = cc.newLabel();
  559. Label L_2 = cc.newLabel();
  560. x86::Gp v0 = cc.newUInt32("v0");
  561. x86::Gp v1 = cc.newUInt32("v1");
  562. cc.jmp(L_1);
  563. cc.bind(L_2);
  564. cc.mov(v0, 1);
  565. cc.mov(v1, 2);
  566. cc.cmp(v0, v1);
  567. cc.jz(L_2);
  568. cc.jmp(L_1);
  569. cc.bind(L_1);
  570. cc.ret();
  571. cc.endFunc();
  572. }
  573. virtual bool run(void* _func, String& result, String& expect) {
  574. typedef void (*Func)(void);
  575. Func func = ptr_as_func<Func>(_func);
  576. func();
  577. result.appendString("ret={}");
  578. expect.appendString("ret={}");
  579. return true;
  580. }
  581. };
  582. // ============================================================================
  583. // [X86Test_AllocBase]
  584. // ============================================================================
  585. class X86Test_AllocBase : public X86Test {
  586. public:
  587. X86Test_AllocBase() : X86Test("AllocBase") {}
  588. static void add(X86TestApp& app) {
  589. app.add(new X86Test_AllocBase());
  590. }
  591. virtual void compile(x86::Compiler& cc) {
  592. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  593. x86::Gp v0 = cc.newInt32("v0");
  594. x86::Gp v1 = cc.newInt32("v1");
  595. x86::Gp v2 = cc.newInt32("v2");
  596. x86::Gp v3 = cc.newInt32("v3");
  597. x86::Gp v4 = cc.newInt32("v4");
  598. cc.xor_(v0, v0);
  599. cc.mov(v1, 1);
  600. cc.mov(v2, 2);
  601. cc.mov(v3, 3);
  602. cc.mov(v4, 4);
  603. cc.add(v0, v1);
  604. cc.add(v0, v2);
  605. cc.add(v0, v3);
  606. cc.add(v0, v4);
  607. cc.ret(v0);
  608. cc.endFunc();
  609. }
  610. virtual bool run(void* _func, String& result, String& expect) {
  611. typedef int (*Func)(void);
  612. Func func = ptr_as_func<Func>(_func);
  613. int resultRet = func();
  614. int expectRet = 1 + 2 + 3 + 4;
  615. result.assignFormat("ret=%d", resultRet);
  616. expect.assignFormat("ret=%d", expectRet);
  617. return resultRet == expectRet;
  618. }
  619. };
  620. // ============================================================================
  621. // [X86Test_AllocMany1]
  622. // ============================================================================
  623. class X86Test_AllocMany1 : public X86Test {
  624. public:
  625. X86Test_AllocMany1() : X86Test("AllocMany1") {}
  626. enum { kCount = 8 };
  627. static void add(X86TestApp& app) {
  628. app.add(new X86Test_AllocMany1());
  629. }
  630. virtual void compile(x86::Compiler& cc) {
  631. cc.addFunc(FuncSignatureT<void, int*, int*>(CallConv::kIdHost));
  632. x86::Gp a0 = cc.newIntPtr("a0");
  633. x86::Gp a1 = cc.newIntPtr("a1");
  634. cc.setArg(0, a0);
  635. cc.setArg(1, a1);
  636. // Create some variables.
  637. x86::Gp t = cc.newInt32("t");
  638. x86::Gp x[kCount];
  639. uint32_t i;
  640. // Setup variables (use mov with reg/imm to se if register allocator works).
  641. for (i = 0; i < kCount; i++) x[i] = cc.newInt32("x%u", i);
  642. for (i = 0; i < kCount; i++) cc.mov(x[i], int(i + 1));
  643. // Make sum (addition).
  644. cc.xor_(t, t);
  645. for (i = 0; i < kCount; i++) cc.add(t, x[i]);
  646. // Store result to a given pointer in first argument.
  647. cc.mov(x86::dword_ptr(a0), t);
  648. // Clear t.
  649. cc.xor_(t, t);
  650. // Make sum (subtraction).
  651. for (i = 0; i < kCount; i++) cc.sub(t, x[i]);
  652. // Store result to a given pointer in second argument.
  653. cc.mov(x86::dword_ptr(a1), t);
  654. // End of function.
  655. cc.endFunc();
  656. }
  657. virtual bool run(void* _func, String& result, String& expect) {
  658. typedef void (*Func)(int*, int*);
  659. Func func = ptr_as_func<Func>(_func);
  660. int resultX;
  661. int resultY;
  662. int expectX = 36;
  663. int expectY = -36;
  664. func(&resultX, &resultY);
  665. result.assignFormat("ret={x=%d, y=%d}", resultX, resultY);
  666. expect.assignFormat("ret={x=%d, y=%d}", expectX, expectY);
  667. return resultX == expectX && resultY == expectY;
  668. }
  669. };
  670. // ============================================================================
  671. // [X86Test_AllocMany2]
  672. // ============================================================================
  673. class X86Test_AllocMany2 : public X86Test {
  674. public:
  675. X86Test_AllocMany2() : X86Test("AllocMany2") {}
  676. static void add(X86TestApp& app) {
  677. app.add(new X86Test_AllocMany2());
  678. }
  679. virtual void compile(x86::Compiler& cc) {
  680. cc.addFunc(FuncSignatureT<void, uint32_t*>(CallConv::kIdHost));
  681. x86::Gp a = cc.newIntPtr("a");
  682. x86::Gp v[32];
  683. uint32_t i;
  684. cc.setArg(0, a);
  685. for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) v[i] = cc.newInt32("v%d", i);
  686. for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.xor_(v[i], v[i]);
  687. x86::Gp x = cc.newInt32("x");
  688. Label L = cc.newLabel();
  689. cc.mov(x, 32);
  690. cc.bind(L);
  691. for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.add(v[i], i);
  692. cc.dec(x);
  693. cc.jnz(L);
  694. for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.mov(x86::dword_ptr(a, int(i * 4)), v[i]);
  695. cc.endFunc();
  696. }
  697. virtual bool run(void* _func, String& result, String& expect) {
  698. typedef void (*Func)(uint32_t*);
  699. Func func = ptr_as_func<Func>(_func);
  700. uint32_t i;
  701. uint32_t resultBuf[32];
  702. uint32_t expectBuf[32];
  703. for (i = 0; i < ASMJIT_ARRAY_SIZE(resultBuf); i++)
  704. expectBuf[i] = i * 32;
  705. func(resultBuf);
  706. for (i = 0; i < ASMJIT_ARRAY_SIZE(resultBuf); i++) {
  707. if (i != 0) {
  708. result.appendChar(',');
  709. expect.appendChar(',');
  710. }
  711. result.appendFormat("%u", resultBuf[i]);
  712. expect.appendFormat("%u", expectBuf[i]);
  713. }
  714. return result == expect;
  715. }
  716. };
  717. // ============================================================================
  718. // [X86Test_AllocImul1]
  719. // ============================================================================
  720. class X86Test_AllocImul1 : public X86Test {
  721. public:
  722. X86Test_AllocImul1() : X86Test("AllocImul1") {}
  723. static void add(X86TestApp& app) {
  724. app.add(new X86Test_AllocImul1());
  725. }
  726. virtual void compile(x86::Compiler& cc) {
  727. cc.addFunc(FuncSignatureT<void, int*, int*, int, int>(CallConv::kIdHost));
  728. x86::Gp dstHi = cc.newIntPtr("dstHi");
  729. x86::Gp dstLo = cc.newIntPtr("dstLo");
  730. x86::Gp vHi = cc.newInt32("vHi");
  731. x86::Gp vLo = cc.newInt32("vLo");
  732. x86::Gp src = cc.newInt32("src");
  733. cc.setArg(0, dstHi);
  734. cc.setArg(1, dstLo);
  735. cc.setArg(2, vLo);
  736. cc.setArg(3, src);
  737. cc.imul(vHi, vLo, src);
  738. cc.mov(x86::dword_ptr(dstHi), vHi);
  739. cc.mov(x86::dword_ptr(dstLo), vLo);
  740. cc.endFunc();
  741. }
  742. virtual bool run(void* _func, String& result, String& expect) {
  743. typedef void (*Func)(int*, int*, int, int);
  744. Func func = ptr_as_func<Func>(_func);
  745. int v0 = 4;
  746. int v1 = 4;
  747. int resultHi;
  748. int resultLo;
  749. int expectHi = 0;
  750. int expectLo = v0 * v1;
  751. func(&resultHi, &resultLo, v0, v1);
  752. result.assignFormat("hi=%d, lo=%d", resultHi, resultLo);
  753. expect.assignFormat("hi=%d, lo=%d", expectHi, expectLo);
  754. return resultHi == expectHi && resultLo == expectLo;
  755. }
  756. };
  757. // ============================================================================
  758. // [X86Test_AllocImul2]
  759. // ============================================================================
  760. class X86Test_AllocImul2 : public X86Test {
  761. public:
  762. X86Test_AllocImul2() : X86Test("AllocImul2") {}
  763. static void add(X86TestApp& app) {
  764. app.add(new X86Test_AllocImul2());
  765. }
  766. virtual void compile(x86::Compiler& cc) {
  767. cc.addFunc(FuncSignatureT<void, int*, const int*>(CallConv::kIdHost));
  768. x86::Gp dst = cc.newIntPtr("dst");
  769. x86::Gp src = cc.newIntPtr("src");
  770. cc.setArg(0, dst);
  771. cc.setArg(1, src);
  772. for (unsigned int i = 0; i < 4; i++) {
  773. x86::Gp x = cc.newInt32("x");
  774. x86::Gp y = cc.newInt32("y");
  775. x86::Gp hi = cc.newInt32("hi");
  776. cc.mov(x, x86::dword_ptr(src, 0));
  777. cc.mov(y, x86::dword_ptr(src, 4));
  778. cc.imul(hi, x, y);
  779. cc.add(x86::dword_ptr(dst, 0), hi);
  780. cc.add(x86::dword_ptr(dst, 4), x);
  781. }
  782. cc.endFunc();
  783. }
  784. virtual bool run(void* _func, String& result, String& expect) {
  785. typedef void (*Func)(int*, const int*);
  786. Func func = ptr_as_func<Func>(_func);
  787. int src[2] = { 4, 9 };
  788. int resultRet[2] = { 0, 0 };
  789. int expectRet[2] = { 0, (4 * 9) * 4 };
  790. func(resultRet, src);
  791. result.assignFormat("ret={%d, %d}", resultRet[0], resultRet[1]);
  792. expect.assignFormat("ret={%d, %d}", expectRet[0], expectRet[1]);
  793. return resultRet[0] == expectRet[0] && resultRet[1] == expectRet[1];
  794. }
  795. };
  796. // ============================================================================
  797. // [X86Test_AllocIdiv1]
  798. // ============================================================================
  799. class X86Test_AllocIdiv1 : public X86Test {
  800. public:
  801. X86Test_AllocIdiv1() : X86Test("AllocIdiv1") {}
  802. static void add(X86TestApp& app) {
  803. app.add(new X86Test_AllocIdiv1());
  804. }
  805. virtual void compile(x86::Compiler& cc) {
  806. cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
  807. x86::Gp a = cc.newInt32("a");
  808. x86::Gp b = cc.newInt32("b");
  809. x86::Gp dummy = cc.newInt32("dummy");
  810. cc.setArg(0, a);
  811. cc.setArg(1, b);
  812. cc.xor_(dummy, dummy);
  813. cc.idiv(dummy, a, b);
  814. cc.ret(a);
  815. cc.endFunc();
  816. }
  817. virtual bool run(void* _func, String& result, String& expect) {
  818. typedef int (*Func)(int, int);
  819. Func func = ptr_as_func<Func>(_func);
  820. int v0 = 2999;
  821. int v1 = 245;
  822. int resultRet = func(v0, v1);
  823. int expectRet = 2999 / 245;
  824. result.assignFormat("result=%d", resultRet);
  825. expect.assignFormat("result=%d", expectRet);
  826. return resultRet == expectRet;
  827. }
  828. };
  829. // ============================================================================
  830. // [X86Test_AllocSetz]
  831. // ============================================================================
  832. class X86Test_AllocSetz : public X86Test {
  833. public:
  834. X86Test_AllocSetz() : X86Test("AllocSetz") {}
  835. static void add(X86TestApp& app) {
  836. app.add(new X86Test_AllocSetz());
  837. }
  838. virtual void compile(x86::Compiler& cc) {
  839. cc.addFunc(FuncSignatureT<void, int, int, char*>(CallConv::kIdHost));
  840. x86::Gp src0 = cc.newInt32("src0");
  841. x86::Gp src1 = cc.newInt32("src1");
  842. x86::Gp dst0 = cc.newIntPtr("dst0");
  843. cc.setArg(0, src0);
  844. cc.setArg(1, src1);
  845. cc.setArg(2, dst0);
  846. cc.cmp(src0, src1);
  847. cc.setz(x86::byte_ptr(dst0));
  848. cc.endFunc();
  849. }
  850. virtual bool run(void* _func, String& result, String& expect) {
  851. typedef void (*Func)(int, int, char*);
  852. Func func = ptr_as_func<Func>(_func);
  853. char resultBuf[4];
  854. char expectBuf[4] = { 1, 0, 0, 1 };
  855. func(0, 0, &resultBuf[0]); // We are expecting 1 (0 == 0).
  856. func(0, 1, &resultBuf[1]); // We are expecting 0 (0 != 1).
  857. func(1, 0, &resultBuf[2]); // We are expecting 0 (1 != 0).
  858. func(1, 1, &resultBuf[3]); // We are expecting 1 (1 == 1).
  859. result.assignFormat("out={%d, %d, %d, %d}", resultBuf[0], resultBuf[1], resultBuf[2], resultBuf[3]);
  860. expect.assignFormat("out={%d, %d, %d, %d}", expectBuf[0], expectBuf[1], expectBuf[2], expectBuf[3]);
  861. return resultBuf[0] == expectBuf[0] &&
  862. resultBuf[1] == expectBuf[1] &&
  863. resultBuf[2] == expectBuf[2] &&
  864. resultBuf[3] == expectBuf[3] ;
  865. }
  866. };
  867. // ============================================================================
  868. // [X86Test_AllocShlRor]
  869. // ============================================================================
  870. class X86Test_AllocShlRor : public X86Test {
  871. public:
  872. X86Test_AllocShlRor() : X86Test("AllocShlRor") {}
  873. static void add(X86TestApp& app) {
  874. app.add(new X86Test_AllocShlRor());
  875. }
  876. virtual void compile(x86::Compiler& cc) {
  877. cc.addFunc(FuncSignatureT<void, int*, int, int, int>(CallConv::kIdHost));
  878. x86::Gp dst = cc.newIntPtr("dst");
  879. x86::Gp var = cc.newInt32("var");
  880. x86::Gp vShlParam = cc.newInt32("vShlParam");
  881. x86::Gp vRorParam = cc.newInt32("vRorParam");
  882. cc.setArg(0, dst);
  883. cc.setArg(1, var);
  884. cc.setArg(2, vShlParam);
  885. cc.setArg(3, vRorParam);
  886. cc.shl(var, vShlParam);
  887. cc.ror(var, vRorParam);
  888. cc.mov(x86::dword_ptr(dst), var);
  889. cc.endFunc();
  890. }
  891. virtual bool run(void* _func, String& result, String& expect) {
  892. typedef void (*Func)(int*, int, int, int);
  893. Func func = ptr_as_func<Func>(_func);
  894. int v0 = 0x000000FF;
  895. int resultRet;
  896. int expectRet = 0x0000FF00;
  897. func(&resultRet, v0, 16, 8);
  898. result.assignFormat("ret=%d", resultRet);
  899. expect.assignFormat("ret=%d", expectRet);
  900. return resultRet == expectRet;
  901. }
  902. };
  903. // ============================================================================
  904. // [X86Test_AllocGpbLo]
  905. // ============================================================================
  906. class X86Test_AllocGpbLo1 : public X86Test {
  907. public:
  908. X86Test_AllocGpbLo1() : X86Test("AllocGpbLo1") {}
  909. enum { kCount = 32 };
  910. static void add(X86TestApp& app) {
  911. app.add(new X86Test_AllocGpbLo1());
  912. }
  913. virtual void compile(x86::Compiler& cc) {
  914. cc.addFunc(FuncSignatureT<uint32_t, uint32_t*>(CallConv::kIdHost));
  915. x86::Gp rPtr = cc.newUIntPtr("rPtr");
  916. x86::Gp rSum = cc.newUInt32("rSum");
  917. cc.setArg(0, rPtr);
  918. x86::Gp x[kCount];
  919. uint32_t i;
  920. for (i = 0; i < kCount; i++) {
  921. x[i] = cc.newUInt32("x%u", i);
  922. }
  923. // Init pseudo-regs with values from our array.
  924. for (i = 0; i < kCount; i++) {
  925. cc.mov(x[i], x86::dword_ptr(rPtr, int(i * 4)));
  926. }
  927. for (i = 2; i < kCount; i++) {
  928. // Add and truncate to 8 bit; no purpose, just mess with jit.
  929. cc.add (x[i ], x[i-1]);
  930. cc.movzx(x[i ], x[i ].r8());
  931. cc.movzx(x[i-2], x[i-1].r8());
  932. cc.movzx(x[i-1], x[i-2].r8());
  933. }
  934. // Sum up all computed values.
  935. cc.mov(rSum, 0);
  936. for (i = 0; i < kCount; i++) {
  937. cc.add(rSum, x[i]);
  938. }
  939. // Return the sum.
  940. cc.ret(rSum);
  941. cc.endFunc();
  942. }
  943. virtual bool run(void* _func, String& result, String& expect) {
  944. typedef uint32_t (*Func)(uint32_t*);
  945. Func func = ptr_as_func<Func>(_func);
  946. uint32_t i;
  947. uint32_t buf[kCount];
  948. uint32_t resultRet;
  949. uint32_t expectRet;
  950. expectRet = 0;
  951. for (i = 0; i < kCount; i++) {
  952. buf[i] = 1;
  953. }
  954. for (i = 2; i < kCount; i++) {
  955. buf[i ]+= buf[i-1];
  956. buf[i ] = buf[i ] & 0xFF;
  957. buf[i-2] = buf[i-1] & 0xFF;
  958. buf[i-1] = buf[i-2] & 0xFF;
  959. }
  960. for (i = 0; i < kCount; i++) {
  961. expectRet += buf[i];
  962. }
  963. for (i = 0; i < kCount; i++) {
  964. buf[i] = 1;
  965. }
  966. resultRet = func(buf);
  967. result.assignFormat("ret=%d", resultRet);
  968. expect.assignFormat("ret=%d", expectRet);
  969. return resultRet == expectRet;
  970. }
  971. };
  972. // ============================================================================
  973. // [X86Test_AllocGpbLo2]
  974. // ============================================================================
  975. class X86Test_AllocGpbLo2 : public X86Test {
  976. public:
  977. X86Test_AllocGpbLo2() : X86Test("AllocGpbLo2") {}
  978. static void add(X86TestApp& app) {
  979. app.add(new X86Test_AllocGpbLo2());
  980. }
  981. virtual void compile(x86::Compiler& cc) {
  982. cc.addFunc(FuncSignatureT<uint32_t, uint32_t>(CallConv::kIdHost));
  983. x86::Gp v = cc.newUInt32("v");
  984. cc.setArg(0, v);
  985. cc.mov(v.r8(), 0xFF);
  986. cc.ret(v);
  987. cc.endFunc();
  988. }
  989. virtual bool run(void* _func, String& result, String& expect) {
  990. typedef uint32_t (*Func)(uint32_t);
  991. Func func = ptr_as_func<Func>(_func);
  992. uint32_t resultRet = func(0x12345678u);
  993. uint32_t expectRet = 0x123456FFu;
  994. result.assignFormat("ret=%d", resultRet);
  995. expect.assignFormat("ret=%d", expectRet);
  996. return resultRet == expectRet;
  997. }
  998. };
  999. // ============================================================================
  1000. // [X86Test_AllocRepMovsb]
  1001. // ============================================================================
  1002. class X86Test_AllocRepMovsb : public X86Test {
  1003. public:
  1004. X86Test_AllocRepMovsb() : X86Test("AllocRepMovsb") {}
  1005. static void add(X86TestApp& app) {
  1006. app.add(new X86Test_AllocRepMovsb());
  1007. }
  1008. virtual void compile(x86::Compiler& cc) {
  1009. cc.addFunc(FuncSignatureT<void, void*, void*, size_t>(CallConv::kIdHost));
  1010. x86::Gp dst = cc.newIntPtr("dst");
  1011. x86::Gp src = cc.newIntPtr("src");
  1012. x86::Gp cnt = cc.newIntPtr("cnt");
  1013. cc.setArg(0, dst);
  1014. cc.setArg(1, src);
  1015. cc.setArg(2, cnt);
  1016. cc.rep(cnt).movs(x86::byte_ptr(dst), x86::byte_ptr(src));
  1017. cc.endFunc();
  1018. }
  1019. virtual bool run(void* _func, String& result, String& expect) {
  1020. typedef void (*Func)(void*, void*, size_t);
  1021. Func func = ptr_as_func<Func>(_func);
  1022. char dst[20] = { 0 };
  1023. char src[20] = "Hello AsmJit!";
  1024. func(dst, src, strlen(src) + 1);
  1025. result.assignFormat("ret=\"%s\"", dst);
  1026. expect.assignFormat("ret=\"%s\"", src);
  1027. return result == expect;
  1028. }
  1029. };
  1030. // ============================================================================
  1031. // [X86Test_AllocIfElse1]
  1032. // ============================================================================
  1033. class X86Test_AllocIfElse1 : public X86Test {
  1034. public:
  1035. X86Test_AllocIfElse1() : X86Test("AllocIfElse1") {}
  1036. static void add(X86TestApp& app) {
  1037. app.add(new X86Test_AllocIfElse1());
  1038. }
  1039. virtual void compile(x86::Compiler& cc) {
  1040. cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
  1041. x86::Gp v1 = cc.newInt32("v1");
  1042. x86::Gp v2 = cc.newInt32("v2");
  1043. Label L_1 = cc.newLabel();
  1044. Label L_2 = cc.newLabel();
  1045. cc.setArg(0, v1);
  1046. cc.setArg(1, v2);
  1047. cc.cmp(v1, v2);
  1048. cc.jg(L_1);
  1049. cc.mov(v1, 1);
  1050. cc.jmp(L_2);
  1051. cc.bind(L_1);
  1052. cc.mov(v1, 2);
  1053. cc.bind(L_2);
  1054. cc.ret(v1);
  1055. cc.endFunc();
  1056. }
  1057. virtual bool run(void* _func, String& result, String& expect) {
  1058. typedef int (*Func)(int, int);
  1059. Func func = ptr_as_func<Func>(_func);
  1060. int a = func(0, 1);
  1061. int b = func(1, 0);
  1062. result.appendFormat("ret={%d, %d}", a, b);
  1063. expect.appendFormat("ret={%d, %d}", 1, 2);
  1064. return result == expect;
  1065. }
  1066. };
  1067. // ============================================================================
  1068. // [X86Test_AllocIfElse2]
  1069. // ============================================================================
  1070. class X86Test_AllocIfElse2 : public X86Test {
  1071. public:
  1072. X86Test_AllocIfElse2() : X86Test("AllocIfElse2") {}
  1073. static void add(X86TestApp& app) {
  1074. app.add(new X86Test_AllocIfElse2());
  1075. }
  1076. virtual void compile(x86::Compiler& cc) {
  1077. cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
  1078. x86::Gp v1 = cc.newInt32("v1");
  1079. x86::Gp v2 = cc.newInt32("v2");
  1080. Label L_1 = cc.newLabel();
  1081. Label L_2 = cc.newLabel();
  1082. Label L_3 = cc.newLabel();
  1083. Label L_4 = cc.newLabel();
  1084. cc.setArg(0, v1);
  1085. cc.setArg(1, v2);
  1086. cc.jmp(L_1);
  1087. cc.bind(L_2);
  1088. cc.jmp(L_4);
  1089. cc.bind(L_1);
  1090. cc.cmp(v1, v2);
  1091. cc.jg(L_3);
  1092. cc.mov(v1, 1);
  1093. cc.jmp(L_2);
  1094. cc.bind(L_3);
  1095. cc.mov(v1, 2);
  1096. cc.jmp(L_2);
  1097. cc.bind(L_4);
  1098. cc.ret(v1);
  1099. cc.endFunc();
  1100. }
  1101. virtual bool run(void* _func, String& result, String& expect) {
  1102. typedef int (*Func)(int, int);
  1103. Func func = ptr_as_func<Func>(_func);
  1104. int a = func(0, 1);
  1105. int b = func(1, 0);
  1106. result.appendFormat("ret={%d, %d}", a, b);
  1107. expect.appendFormat("ret={%d, %d}", 1, 2);
  1108. return result == expect;
  1109. }
  1110. };
  1111. // ============================================================================
  1112. // [X86Test_AllocIfElse3]
  1113. // ============================================================================
  1114. class X86Test_AllocIfElse3 : public X86Test {
  1115. public:
  1116. X86Test_AllocIfElse3() : X86Test("AllocIfElse3") {}
  1117. static void add(X86TestApp& app) {
  1118. app.add(new X86Test_AllocIfElse3());
  1119. }
  1120. virtual void compile(x86::Compiler& cc) {
  1121. cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
  1122. x86::Gp v1 = cc.newInt32("v1");
  1123. x86::Gp v2 = cc.newInt32("v2");
  1124. x86::Gp counter = cc.newInt32("counter");
  1125. Label L_1 = cc.newLabel();
  1126. Label L_Loop = cc.newLabel();
  1127. Label L_Exit = cc.newLabel();
  1128. cc.setArg(0, v1);
  1129. cc.setArg(1, v2);
  1130. cc.cmp(v1, v2);
  1131. cc.jg(L_1);
  1132. cc.mov(counter, 0);
  1133. cc.bind(L_Loop);
  1134. cc.mov(v1, counter);
  1135. cc.inc(counter);
  1136. cc.cmp(counter, 1);
  1137. cc.jle(L_Loop);
  1138. cc.jmp(L_Exit);
  1139. cc.bind(L_1);
  1140. cc.mov(v1, 2);
  1141. cc.bind(L_Exit);
  1142. cc.ret(v1);
  1143. cc.endFunc();
  1144. }
  1145. virtual bool run(void* _func, String& result, String& expect) {
  1146. typedef int (*Func)(int, int);
  1147. Func func = ptr_as_func<Func>(_func);
  1148. int a = func(0, 1);
  1149. int b = func(1, 0);
  1150. result.appendFormat("ret={%d, %d}", a, b);
  1151. expect.appendFormat("ret={%d, %d}", 1, 2);
  1152. return result == expect;
  1153. }
  1154. };
  1155. // ============================================================================
  1156. // [X86Test_AllocIfElse4]
  1157. // ============================================================================
  1158. class X86Test_AllocIfElse4 : public X86Test {
  1159. public:
  1160. X86Test_AllocIfElse4() : X86Test("AllocIfElse4") {}
  1161. static void add(X86TestApp& app) {
  1162. app.add(new X86Test_AllocIfElse4());
  1163. }
  1164. virtual void compile(x86::Compiler& cc) {
  1165. cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
  1166. x86::Gp v1 = cc.newInt32("v1");
  1167. x86::Gp v2 = cc.newInt32("v2");
  1168. x86::Gp counter = cc.newInt32("counter");
  1169. Label L_1 = cc.newLabel();
  1170. Label L_Loop1 = cc.newLabel();
  1171. Label L_Loop2 = cc.newLabel();
  1172. Label L_Exit = cc.newLabel();
  1173. cc.mov(counter, 0);
  1174. cc.setArg(0, v1);
  1175. cc.setArg(1, v2);
  1176. cc.cmp(v1, v2);
  1177. cc.jg(L_1);
  1178. cc.bind(L_Loop1);
  1179. cc.mov(v1, counter);
  1180. cc.inc(counter);
  1181. cc.cmp(counter, 1);
  1182. cc.jle(L_Loop1);
  1183. cc.jmp(L_Exit);
  1184. cc.bind(L_1);
  1185. cc.bind(L_Loop2);
  1186. cc.mov(v1, counter);
  1187. cc.inc(counter);
  1188. cc.cmp(counter, 2);
  1189. cc.jle(L_Loop2);
  1190. cc.bind(L_Exit);
  1191. cc.ret(v1);
  1192. cc.endFunc();
  1193. }
  1194. virtual bool run(void* _func, String& result, String& expect) {
  1195. typedef int (*Func)(int, int);
  1196. Func func = ptr_as_func<Func>(_func);
  1197. int a = func(0, 1);
  1198. int b = func(1, 0);
  1199. result.appendFormat("ret={%d, %d}", a, b);
  1200. expect.appendFormat("ret={%d, %d}", 1, 2);
  1201. return result == expect;
  1202. }
  1203. };
  1204. // ============================================================================
  1205. // [X86Test_AllocInt8]
  1206. // ============================================================================
  1207. class X86Test_AllocInt8 : public X86Test {
  1208. public:
  1209. X86Test_AllocInt8() : X86Test("AllocInt8") {}
  1210. static void add(X86TestApp& app) {
  1211. app.add(new X86Test_AllocInt8());
  1212. }
  1213. virtual void compile(x86::Compiler& cc) {
  1214. x86::Gp x = cc.newInt8("x");
  1215. x86::Gp y = cc.newInt32("y");
  1216. cc.addFunc(FuncSignatureT<int, char>(CallConv::kIdHost));
  1217. cc.setArg(0, x);
  1218. cc.movsx(y, x);
  1219. cc.ret(y);
  1220. cc.endFunc();
  1221. }
  1222. virtual bool run(void* _func, String& result, String& expect) {
  1223. typedef int (*Func)(char);
  1224. Func func = ptr_as_func<Func>(_func);
  1225. int resultRet = func(-13);
  1226. int expectRet = -13;
  1227. result.assignFormat("ret=%d", resultRet);
  1228. expect.assignFormat("ret=%d", expectRet);
  1229. return result == expect;
  1230. }
  1231. };
  1232. // ============================================================================
  1233. // [X86Test_AllocUnhandledArg]
  1234. // ============================================================================
  1235. class X86Test_AllocUnhandledArg : public X86Test {
  1236. public:
  1237. X86Test_AllocUnhandledArg() : X86Test("AllocUnhandledArg") {}
  1238. static void add(X86TestApp& app) {
  1239. app.add(new X86Test_AllocUnhandledArg());
  1240. }
  1241. virtual void compile(x86::Compiler& cc) {
  1242. cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
  1243. x86::Gp x = cc.newInt32("x");
  1244. cc.setArg(2, x);
  1245. cc.ret(x);
  1246. cc.endFunc();
  1247. }
  1248. virtual bool run(void* _func, String& result, String& expect) {
  1249. typedef int (*Func)(int, int, int);
  1250. Func func = ptr_as_func<Func>(_func);
  1251. int resultRet = func(42, 155, 199);
  1252. int expectRet = 199;
  1253. result.assignFormat("ret={%d}", resultRet);
  1254. expect.assignFormat("ret={%d}", expectRet);
  1255. return result == expect;
  1256. }
  1257. };
  1258. // ============================================================================
  1259. // [X86Test_AllocArgsIntPtr]
  1260. // ============================================================================
  1261. class X86Test_AllocArgsIntPtr : public X86Test {
  1262. public:
  1263. X86Test_AllocArgsIntPtr() : X86Test("AllocArgsIntPtr") {}
  1264. static void add(X86TestApp& app) {
  1265. app.add(new X86Test_AllocArgsIntPtr());
  1266. }
  1267. virtual void compile(x86::Compiler& cc) {
  1268. cc.addFunc(FuncSignatureT<void, void*, void*, void*, void*, void*, void*, void*, void*>(CallConv::kIdHost));
  1269. uint32_t i;
  1270. x86::Gp var[8];
  1271. for (i = 0; i < 8; i++) {
  1272. var[i] = cc.newIntPtr("var%u", i);
  1273. cc.setArg(i, var[i]);
  1274. }
  1275. for (i = 0; i < 8; i++) {
  1276. cc.add(var[i], int(i + 1));
  1277. }
  1278. // Move some data into buffer provided by arguments so we can verify if it
  1279. // really works without looking into assembler output.
  1280. for (i = 0; i < 8; i++) {
  1281. cc.add(x86::byte_ptr(var[i]), int(i + 1));
  1282. }
  1283. cc.endFunc();
  1284. }
  1285. virtual bool run(void* _func, String& result, String& expect) {
  1286. typedef void (*Func)(void*, void*, void*, void*, void*, void*, void*, void*);
  1287. Func func = ptr_as_func<Func>(_func);
  1288. uint8_t resultBuf[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  1289. uint8_t expectBuf[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
  1290. func(resultBuf, resultBuf, resultBuf, resultBuf,
  1291. resultBuf, resultBuf, resultBuf, resultBuf);
  1292. result.assignFormat("buf={%d, %d, %d, %d, %d, %d, %d, %d, %d}",
  1293. resultBuf[0], resultBuf[1], resultBuf[2], resultBuf[3],
  1294. resultBuf[4], resultBuf[5], resultBuf[6], resultBuf[7],
  1295. resultBuf[8]);
  1296. expect.assignFormat("buf={%d, %d, %d, %d, %d, %d, %d, %d, %d}",
  1297. expectBuf[0], expectBuf[1], expectBuf[2], expectBuf[3],
  1298. expectBuf[4], expectBuf[5], expectBuf[6], expectBuf[7],
  1299. expectBuf[8]);
  1300. return result == expect;
  1301. }
  1302. };
  1303. // ============================================================================
  1304. // [X86Test_AllocArgsFloat]
  1305. // ============================================================================
  1306. class X86Test_AllocArgsFloat : public X86Test {
  1307. public:
  1308. X86Test_AllocArgsFloat() : X86Test("AllocArgsFloat") {}
  1309. static void add(X86TestApp& app) {
  1310. app.add(new X86Test_AllocArgsFloat());
  1311. }
  1312. virtual void compile(x86::Compiler& cc) {
  1313. cc.addFunc(FuncSignatureT<void, float, float, float, float, float, float, float, void*>(CallConv::kIdHost));
  1314. uint32_t i;
  1315. x86::Gp p = cc.newIntPtr("p");
  1316. x86::Xmm xv[7];
  1317. for (i = 0; i < 7; i++) {
  1318. xv[i] = cc.newXmmSs("xv%u", i);
  1319. cc.setArg(i, xv[i]);
  1320. }
  1321. cc.setArg(7, p);
  1322. cc.addss(xv[0], xv[1]);
  1323. cc.addss(xv[0], xv[2]);
  1324. cc.addss(xv[0], xv[3]);
  1325. cc.addss(xv[0], xv[4]);
  1326. cc.addss(xv[0], xv[5]);
  1327. cc.addss(xv[0], xv[6]);
  1328. cc.movss(x86::ptr(p), xv[0]);
  1329. cc.endFunc();
  1330. }
  1331. virtual bool run(void* _func, String& result, String& expect) {
  1332. typedef void (*Func)(float, float, float, float, float, float, float, float*);
  1333. Func func = ptr_as_func<Func>(_func);
  1334. float resultRet;
  1335. float expectRet = 1.0f + 2.0f + 3.0f + 4.0f + 5.0f + 6.0f + 7.0f;
  1336. func(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, &resultRet);
  1337. result.assignFormat("ret={%g}", resultRet);
  1338. expect.assignFormat("ret={%g}", expectRet);
  1339. return resultRet == expectRet;
  1340. }
  1341. };
  1342. // ============================================================================
  1343. // [X86Test_AllocArgsDouble]
  1344. // ============================================================================
  1345. class X86Test_AllocArgsDouble : public X86Test {
  1346. public:
  1347. X86Test_AllocArgsDouble() : X86Test("AllocArgsDouble") {}
  1348. static void add(X86TestApp& app) {
  1349. app.add(new X86Test_AllocArgsDouble());
  1350. }
  1351. virtual void compile(x86::Compiler& cc) {
  1352. cc.addFunc(FuncSignatureT<void, double, double, double, double, double, double, double, void*>(CallConv::kIdHost));
  1353. uint32_t i;
  1354. x86::Gp p = cc.newIntPtr("p");
  1355. x86::Xmm xv[7];
  1356. for (i = 0; i < 7; i++) {
  1357. xv[i] = cc.newXmmSd("xv%u", i);
  1358. cc.setArg(i, xv[i]);
  1359. }
  1360. cc.setArg(7, p);
  1361. cc.addsd(xv[0], xv[1]);
  1362. cc.addsd(xv[0], xv[2]);
  1363. cc.addsd(xv[0], xv[3]);
  1364. cc.addsd(xv[0], xv[4]);
  1365. cc.addsd(xv[0], xv[5]);
  1366. cc.addsd(xv[0], xv[6]);
  1367. cc.movsd(x86::ptr(p), xv[0]);
  1368. cc.endFunc();
  1369. }
  1370. virtual bool run(void* _func, String& result, String& expect) {
  1371. typedef void (*Func)(double, double, double, double, double, double, double, double*);
  1372. Func func = ptr_as_func<Func>(_func);
  1373. double resultRet;
  1374. double expectRet = 1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0;
  1375. func(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, &resultRet);
  1376. result.assignFormat("ret={%g}", resultRet);
  1377. expect.assignFormat("ret={%g}", expectRet);
  1378. return resultRet == expectRet;
  1379. }
  1380. };
  1381. // ============================================================================
  1382. // [X86Test_AllocRetFloat1]
  1383. // ============================================================================
  1384. class X86Test_AllocRetFloat1 : public X86Test {
  1385. public:
  1386. X86Test_AllocRetFloat1() : X86Test("AllocRetFloat1") {}
  1387. static void add(X86TestApp& app) {
  1388. app.add(new X86Test_AllocRetFloat1());
  1389. }
  1390. virtual void compile(x86::Compiler& cc) {
  1391. cc.addFunc(FuncSignatureT<float, float>(CallConv::kIdHost));
  1392. x86::Xmm x = cc.newXmmSs("x");
  1393. cc.setArg(0, x);
  1394. cc.ret(x);
  1395. cc.endFunc();
  1396. }
  1397. virtual bool run(void* _func, String& result, String& expect) {
  1398. typedef float (*Func)(float);
  1399. Func func = ptr_as_func<Func>(_func);
  1400. float resultRet = func(42.0f);
  1401. float expectRet = 42.0f;
  1402. result.assignFormat("ret={%g}", resultRet);
  1403. expect.assignFormat("ret={%g}", expectRet);
  1404. return resultRet == expectRet;
  1405. }
  1406. };
  1407. // ============================================================================
  1408. // [X86Test_AllocRetFloat2]
  1409. // ============================================================================
  1410. class X86Test_AllocRetFloat2 : public X86Test {
  1411. public:
  1412. X86Test_AllocRetFloat2() : X86Test("AllocRetFloat2") {}
  1413. static void add(X86TestApp& app) {
  1414. app.add(new X86Test_AllocRetFloat2());
  1415. }
  1416. virtual void compile(x86::Compiler& cc) {
  1417. cc.addFunc(FuncSignatureT<float, float, float>(CallConv::kIdHost));
  1418. x86::Xmm x = cc.newXmmSs("x");
  1419. x86::Xmm y = cc.newXmmSs("y");
  1420. cc.setArg(0, x);
  1421. cc.setArg(1, y);
  1422. cc.addss(x, y);
  1423. cc.ret(x);
  1424. cc.endFunc();
  1425. }
  1426. virtual bool run(void* _func, String& result, String& expect) {
  1427. typedef float (*Func)(float, float);
  1428. Func func = ptr_as_func<Func>(_func);
  1429. float resultRet = func(1.0f, 2.0f);
  1430. float expectRet = 1.0f + 2.0f;
  1431. result.assignFormat("ret={%g}", resultRet);
  1432. expect.assignFormat("ret={%g}", expectRet);
  1433. return resultRet == expectRet;
  1434. }
  1435. };
  1436. // ============================================================================
  1437. // [X86Test_AllocRetDouble1]
  1438. // ============================================================================
  1439. class X86Test_AllocRetDouble1 : public X86Test {
  1440. public:
  1441. X86Test_AllocRetDouble1() : X86Test("AllocRetDouble1") {}
  1442. static void add(X86TestApp& app) {
  1443. app.add(new X86Test_AllocRetDouble1());
  1444. }
  1445. virtual void compile(x86::Compiler& cc) {
  1446. cc.addFunc(FuncSignatureT<double, double>(CallConv::kIdHost));
  1447. x86::Xmm x = cc.newXmmSd("x");
  1448. cc.setArg(0, x);
  1449. cc.ret(x);
  1450. cc.endFunc();
  1451. }
  1452. virtual bool run(void* _func, String& result, String& expect) {
  1453. typedef double (*Func)(double);
  1454. Func func = ptr_as_func<Func>(_func);
  1455. double resultRet = func(42.0);
  1456. double expectRet = 42.0;
  1457. result.assignFormat("ret={%g}", resultRet);
  1458. expect.assignFormat("ret={%g}", expectRet);
  1459. return resultRet == expectRet;
  1460. }
  1461. };
  1462. // ============================================================================
  1463. // [X86Test_AllocRetDouble2]
  1464. // ============================================================================
  1465. class X86Test_AllocRetDouble2 : public X86Test {
  1466. public:
  1467. X86Test_AllocRetDouble2() : X86Test("AllocRetDouble2") {}
  1468. static void add(X86TestApp& app) {
  1469. app.add(new X86Test_AllocRetDouble2());
  1470. }
  1471. virtual void compile(x86::Compiler& cc) {
  1472. cc.addFunc(FuncSignatureT<double, double, double>(CallConv::kIdHost));
  1473. x86::Xmm x = cc.newXmmSd("x");
  1474. x86::Xmm y = cc.newXmmSd("y");
  1475. cc.setArg(0, x);
  1476. cc.setArg(1, y);
  1477. cc.addsd(x, y);
  1478. cc.ret(x);
  1479. cc.endFunc();
  1480. }
  1481. virtual bool run(void* _func, String& result, String& expect) {
  1482. typedef double (*Func)(double, double);
  1483. Func func = ptr_as_func<Func>(_func);
  1484. double resultRet = func(1.0, 2.0);
  1485. double expectRet = 1.0 + 2.0;
  1486. result.assignFormat("ret={%g}", resultRet);
  1487. expect.assignFormat("ret={%g}", expectRet);
  1488. return resultRet == expectRet;
  1489. }
  1490. };
  1491. // ============================================================================
  1492. // [X86Test_AllocStack]
  1493. // ============================================================================
  1494. class X86Test_AllocStack : public X86Test {
  1495. public:
  1496. X86Test_AllocStack() : X86Test("AllocStack") {}
  1497. enum { kSize = 256 };
  1498. static void add(X86TestApp& app) {
  1499. app.add(new X86Test_AllocStack());
  1500. }
  1501. virtual void compile(x86::Compiler& cc) {
  1502. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  1503. x86::Mem stack = cc.newStack(kSize, 1);
  1504. stack.setSize(1);
  1505. x86::Gp i = cc.newIntPtr("i");
  1506. x86::Gp a = cc.newInt32("a");
  1507. x86::Gp b = cc.newInt32("b");
  1508. Label L_1 = cc.newLabel();
  1509. Label L_2 = cc.newLabel();
  1510. // Fill stack by sequence [0, 1, 2, 3 ... 255].
  1511. cc.xor_(i, i);
  1512. x86::Mem stackWithIndex = stack.clone();
  1513. stackWithIndex.setIndex(i, 0);
  1514. cc.bind(L_1);
  1515. cc.mov(stackWithIndex, i.r8());
  1516. cc.inc(i);
  1517. cc.cmp(i, 255);
  1518. cc.jle(L_1);
  1519. // Sum sequence in stack.
  1520. cc.xor_(i, i);
  1521. cc.xor_(a, a);
  1522. cc.bind(L_2);
  1523. cc.movzx(b, stackWithIndex);
  1524. cc.add(a, b);
  1525. cc.inc(i);
  1526. cc.cmp(i, 255);
  1527. cc.jle(L_2);
  1528. cc.ret(a);
  1529. cc.endFunc();
  1530. }
  1531. virtual bool run(void* _func, String& result, String& expect) {
  1532. typedef int (*Func)(void);
  1533. Func func = ptr_as_func<Func>(_func);
  1534. int resultRet = func();
  1535. int expectRet = 32640;
  1536. result.assignInt(resultRet);
  1537. expect.assignInt(expectRet);
  1538. return resultRet == expectRet;
  1539. }
  1540. };
  1541. // ============================================================================
  1542. // [X86Test_AllocMemcpy]
  1543. // ============================================================================
  1544. class X86Test_AllocMemcpy : public X86Test {
  1545. public:
  1546. X86Test_AllocMemcpy() : X86Test("AllocMemcpy") {}
  1547. enum { kCount = 32 };
  1548. static void add(X86TestApp& app) {
  1549. app.add(new X86Test_AllocMemcpy());
  1550. }
  1551. virtual void compile(x86::Compiler& cc) {
  1552. x86::Gp dst = cc.newIntPtr("dst");
  1553. x86::Gp src = cc.newIntPtr("src");
  1554. x86::Gp cnt = cc.newUIntPtr("cnt");
  1555. Label L_Loop = cc.newLabel(); // Create base labels we use
  1556. Label L_Exit = cc.newLabel(); // in our function.
  1557. cc.addFunc(FuncSignatureT<void, uint32_t*, const uint32_t*, size_t>(CallConv::kIdHost));
  1558. cc.setArg(0, dst);
  1559. cc.setArg(1, src);
  1560. cc.setArg(2, cnt);
  1561. cc.test(cnt, cnt); // Exit if the size is zero.
  1562. cc.jz(L_Exit);
  1563. cc.bind(L_Loop); // Bind the loop label here.
  1564. x86::Gp tmp = cc.newInt32("tmp"); // Copy a single dword (4 bytes).
  1565. cc.mov(tmp, x86::dword_ptr(src));
  1566. cc.mov(x86::dword_ptr(dst), tmp);
  1567. cc.add(src, 4); // Increment dst/src pointers.
  1568. cc.add(dst, 4);
  1569. cc.dec(cnt); // Loop until cnt isn't zero.
  1570. cc.jnz(L_Loop);
  1571. cc.bind(L_Exit); // Bind the exit label here.
  1572. cc.endFunc(); // End of function.
  1573. }
  1574. virtual bool run(void* _func, String& result, String& expect) {
  1575. typedef void (*Func)(uint32_t*, const uint32_t*, size_t);
  1576. Func func = ptr_as_func<Func>(_func);
  1577. uint32_t i;
  1578. uint32_t dstBuffer[kCount];
  1579. uint32_t srcBuffer[kCount];
  1580. for (i = 0; i < kCount; i++) {
  1581. dstBuffer[i] = 0;
  1582. srcBuffer[i] = i;
  1583. }
  1584. func(dstBuffer, srcBuffer, kCount);
  1585. result.assignString("buf={");
  1586. expect.assignString("buf={");
  1587. for (i = 0; i < kCount; i++) {
  1588. if (i != 0) {
  1589. result.appendString(", ");
  1590. expect.appendString(", ");
  1591. }
  1592. result.appendFormat("%u", unsigned(dstBuffer[i]));
  1593. expect.appendFormat("%u", unsigned(srcBuffer[i]));
  1594. }
  1595. result.appendString("}");
  1596. expect.appendString("}");
  1597. return result == expect;
  1598. }
  1599. };
  1600. // ============================================================================
  1601. // [X86Test_AllocExtraBlock]
  1602. // ============================================================================
  1603. class X86Test_AllocExtraBlock : public X86Test {
  1604. public:
  1605. X86Test_AllocExtraBlock() : X86Test("AllocExtraBlock") {}
  1606. static void add(X86TestApp& app) {
  1607. app.add(new X86Test_AllocExtraBlock());
  1608. }
  1609. virtual void compile(x86::Compiler& cc) {
  1610. x86::Gp cond = cc.newInt32("cond");
  1611. x86::Gp ret = cc.newInt32("ret");
  1612. x86::Gp a = cc.newInt32("a");
  1613. x86::Gp b = cc.newInt32("b");
  1614. cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
  1615. cc.setArg(0, cond);
  1616. cc.setArg(1, a);
  1617. cc.setArg(2, b);
  1618. Label L_Ret = cc.newLabel();
  1619. Label L_Extra = cc.newLabel();
  1620. cc.test(cond, cond);
  1621. cc.jnz(L_Extra);
  1622. cc.mov(ret, a);
  1623. cc.add(ret, b);
  1624. cc.bind(L_Ret);
  1625. cc.ret(ret);
  1626. // Emit code sequence at the end of the function.
  1627. BaseNode* prevCursor = cc.setCursor(cc.func()->endNode()->prev());
  1628. cc.bind(L_Extra);
  1629. cc.mov(ret, a);
  1630. cc.sub(ret, b);
  1631. cc.jmp(L_Ret);
  1632. cc.setCursor(prevCursor);
  1633. cc.endFunc();
  1634. }
  1635. virtual bool run(void* _func, String& result, String& expect) {
  1636. typedef int (*Func)(int, int, int);
  1637. Func func = ptr_as_func<Func>(_func);
  1638. int ret1 = func(0, 4, 5);
  1639. int ret2 = func(1, 4, 5);
  1640. int exp1 = 4 + 5;
  1641. int exp2 = 4 - 5;
  1642. result.assignFormat("ret={%d, %d}", ret1, ret2);
  1643. expect.assignFormat("ret={%d, %d}", exp1, exp2);
  1644. return result == expect;
  1645. }
  1646. };
  1647. // ============================================================================
  1648. // [X86Test_AllocAlphaBlend]
  1649. // ============================================================================
  1650. class X86Test_AllocAlphaBlend : public X86Test {
  1651. public:
  1652. X86Test_AllocAlphaBlend() : X86Test("AllocAlphaBlend") {}
  1653. enum { kCount = 17 };
  1654. static void add(X86TestApp& app) {
  1655. app.add(new X86Test_AllocAlphaBlend());
  1656. }
  1657. static uint32_t blendSrcOver(uint32_t d, uint32_t s) {
  1658. uint32_t saInv = ~s >> 24;
  1659. uint32_t d_20 = (d ) & 0x00FF00FF;
  1660. uint32_t d_31 = (d >> 8) & 0x00FF00FF;
  1661. d_20 *= saInv;
  1662. d_31 *= saInv;
  1663. d_20 = ((d_20 + ((d_20 >> 8) & 0x00FF00FFu) + 0x00800080u) & 0xFF00FF00u) >> 8;
  1664. d_31 = ((d_31 + ((d_31 >> 8) & 0x00FF00FFu) + 0x00800080u) & 0xFF00FF00u);
  1665. return d_20 + d_31 + s;
  1666. }
  1667. virtual void compile(x86::Compiler& cc) {
  1668. asmtest::generateAlphaBlend(cc);
  1669. }
  1670. virtual bool run(void* _func, String& result, String& expect) {
  1671. typedef void (*Func)(void*, const void*, size_t);
  1672. Func func = ptr_as_func<Func>(_func);
  1673. static const uint32_t dstConstData[] = { 0x00000000, 0x10101010, 0x20100804, 0x30200003, 0x40204040, 0x5000004D, 0x60302E2C, 0x706F6E6D, 0x807F4F2F, 0x90349001, 0xA0010203, 0xB03204AB, 0xC023AFBD, 0xD0D0D0C0, 0xE0AABBCC, 0xFFFFFFFF, 0xF8F4F2F1 };
  1674. static const uint32_t srcConstData[] = { 0xE0E0E0E0, 0xA0008080, 0x341F1E1A, 0xFEFEFEFE, 0x80302010, 0x49490A0B, 0x998F7798, 0x00000000, 0x01010101, 0xA0264733, 0xBAB0B1B9, 0xFF000000, 0xDAB0A0C1, 0xE0BACFDA, 0x99887766, 0xFFFFFF80, 0xEE0A5FEC };
  1675. uint32_t _dstBuffer[kCount + 3];
  1676. uint32_t _srcBuffer[kCount + 3];
  1677. // Has to be aligned.
  1678. uint32_t* dstBuffer = (uint32_t*)Support::alignUp<intptr_t>((intptr_t)_dstBuffer, 16);
  1679. uint32_t* srcBuffer = (uint32_t*)Support::alignUp<intptr_t>((intptr_t)_srcBuffer, 16);
  1680. memcpy(dstBuffer, dstConstData, sizeof(dstConstData));
  1681. memcpy(srcBuffer, srcConstData, sizeof(srcConstData));
  1682. uint32_t i;
  1683. uint32_t expBuffer[kCount];
  1684. for (i = 0; i < kCount; i++) {
  1685. expBuffer[i] = blendSrcOver(dstBuffer[i], srcBuffer[i]);
  1686. }
  1687. func(dstBuffer, srcBuffer, kCount);
  1688. result.assignString("buf={");
  1689. expect.assignString("buf={");
  1690. for (i = 0; i < kCount; i++) {
  1691. if (i != 0) {
  1692. result.appendString(", ");
  1693. expect.appendString(", ");
  1694. }
  1695. result.appendFormat("%08X", unsigned(dstBuffer[i]));
  1696. expect.appendFormat("%08X", unsigned(expBuffer[i]));
  1697. }
  1698. result.appendString("}");
  1699. expect.appendString("}");
  1700. return result == expect;
  1701. }
  1702. };
  1703. // ============================================================================
  1704. // [X86Test_FuncCallBase1]
  1705. // ============================================================================
  1706. class X86Test_FuncCallBase1 : public X86Test {
  1707. public:
  1708. X86Test_FuncCallBase1() : X86Test("FuncCallBase1") {}
  1709. static void add(X86TestApp& app) {
  1710. app.add(new X86Test_FuncCallBase1());
  1711. }
  1712. virtual void compile(x86::Compiler& cc) {
  1713. x86::Gp v0 = cc.newInt32("v0");
  1714. x86::Gp v1 = cc.newInt32("v1");
  1715. x86::Gp v2 = cc.newInt32("v2");
  1716. cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
  1717. cc.setArg(0, v0);
  1718. cc.setArg(1, v1);
  1719. cc.setArg(2, v2);
  1720. // Just do something.
  1721. cc.shl(v0, 1);
  1722. cc.shl(v1, 1);
  1723. cc.shl(v2, 1);
  1724. // Call a function.
  1725. FuncCallNode* call = cc.call(imm((void*)calledFunc), FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
  1726. call->setArg(0, v2);
  1727. call->setArg(1, v1);
  1728. call->setArg(2, v0);
  1729. call->setRet(0, v0);
  1730. cc.ret(v0);
  1731. cc.endFunc();
  1732. }
  1733. virtual bool run(void* _func, String& result, String& expect) {
  1734. typedef int (*Func)(int, int, int);
  1735. Func func = ptr_as_func<Func>(_func);
  1736. int resultRet = func(3, 2, 1);
  1737. int expectRet = 36;
  1738. result.assignFormat("ret=%d", resultRet);
  1739. expect.assignFormat("ret=%d", expectRet);
  1740. return resultRet == expectRet;
  1741. }
  1742. static int calledFunc(int a, int b, int c) { return (a + b) * c; }
  1743. };
  1744. // ============================================================================
  1745. // [X86Test_FuncCallBase2]
  1746. // ============================================================================
  1747. class X86Test_FuncCallBase2 : public X86Test {
  1748. public:
  1749. X86Test_FuncCallBase2() : X86Test("FuncCallBase2") {}
  1750. enum { kSize = 256 };
  1751. static void add(X86TestApp& app) {
  1752. app.add(new X86Test_FuncCallBase2());
  1753. }
  1754. virtual void compile(x86::Compiler& cc) {
  1755. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  1756. const int kTokenSize = 32;
  1757. x86::Mem s1 = cc.newStack(kTokenSize, 32);
  1758. x86::Mem s2 = cc.newStack(kTokenSize, 32);
  1759. x86::Gp p1 = cc.newIntPtr("p1");
  1760. x86::Gp p2 = cc.newIntPtr("p2");
  1761. x86::Gp ret = cc.newInt32("ret");
  1762. Label L_Exit = cc.newLabel();
  1763. static const char token[kTokenSize] = "-+:|abcdefghijklmnopqrstuvwxyz|";
  1764. FuncCallNode* call;
  1765. cc.lea(p1, s1);
  1766. cc.lea(p2, s2);
  1767. // Try to corrupt the stack if wrongly allocated.
  1768. call = cc.call(imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdHostCDecl));
  1769. call->setArg(0, p1);
  1770. call->setArg(1, imm(token));
  1771. call->setArg(2, imm(kTokenSize));
  1772. call->setRet(0, p1);
  1773. call = cc.call(imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdHostCDecl));
  1774. call->setArg(0, p2);
  1775. call->setArg(1, imm(token));
  1776. call->setArg(2, imm(kTokenSize));
  1777. call->setRet(0, p2);
  1778. call = cc.call(imm((void*)memcmp), FuncSignatureT<int, void*, void*, size_t>(CallConv::kIdHostCDecl));
  1779. call->setArg(0, p1);
  1780. call->setArg(1, p2);
  1781. call->setArg(2, imm(kTokenSize));
  1782. call->setRet(0, ret);
  1783. // This should be 0 on success, however, if both `p1` and `p2` were
  1784. // allocated in the same address this check will still pass.
  1785. cc.cmp(ret, 0);
  1786. cc.jnz(L_Exit);
  1787. // Checks whether `p1` and `p2` are different (must be).
  1788. cc.xor_(ret, ret);
  1789. cc.cmp(p1, p2);
  1790. cc.setz(ret.r8());
  1791. cc.bind(L_Exit);
  1792. cc.ret(ret);
  1793. cc.endFunc();
  1794. }
  1795. virtual bool run(void* _func, String& result, String& expect) {
  1796. typedef int (*Func)(void);
  1797. Func func = ptr_as_func<Func>(_func);
  1798. int resultRet = func();
  1799. int expectRet = 0; // Must be zero, stack addresses must be different.
  1800. result.assignInt(resultRet);
  1801. expect.assignInt(expectRet);
  1802. return resultRet == expectRet;
  1803. }
  1804. };
  1805. // ============================================================================
  1806. // [X86Test_FuncCallStd]
  1807. // ============================================================================
  1808. class X86Test_FuncCallStd : public X86Test {
  1809. public:
  1810. X86Test_FuncCallStd() : X86Test("FuncCallStd") {}
  1811. static void add(X86TestApp& app) {
  1812. app.add(new X86Test_FuncCallStd());
  1813. }
  1814. virtual void compile(x86::Compiler& cc) {
  1815. x86::Gp x = cc.newInt32("x");
  1816. x86::Gp y = cc.newInt32("y");
  1817. x86::Gp z = cc.newInt32("z");
  1818. cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
  1819. cc.setArg(0, x);
  1820. cc.setArg(1, y);
  1821. cc.setArg(2, z);
  1822. FuncCallNode* call = cc.call(
  1823. imm((void*)calledFunc),
  1824. FuncSignatureT<int, int, int, int>(CallConv::kIdHostStdCall));
  1825. call->setArg(0, x);
  1826. call->setArg(1, y);
  1827. call->setArg(2, z);
  1828. call->setRet(0, x);
  1829. cc.ret(x);
  1830. cc.endFunc();
  1831. }
  1832. virtual bool run(void* _func, String& result, String& expect) {
  1833. typedef int (*Func)(int, int, int);
  1834. Func func = ptr_as_func<Func>(_func);
  1835. int resultRet = func(1, 42, 3);
  1836. int expectRet = calledFunc(1, 42, 3);
  1837. result.assignFormat("ret=%d", resultRet);
  1838. expect.assignFormat("ret=%d", expectRet);
  1839. return resultRet == expectRet;
  1840. }
  1841. // STDCALL function that is called inside the generated one.
  1842. static int ASMJIT_STDCALL calledFunc(int a, int b, int c) noexcept {
  1843. return (a + b) * c;
  1844. }
  1845. };
  1846. // ============================================================================
  1847. // [X86Test_FuncCallFast]
  1848. // ============================================================================
  1849. class X86Test_FuncCallFast : public X86Test {
  1850. public:
  1851. X86Test_FuncCallFast() : X86Test("FuncCallFast") {}
  1852. static void add(X86TestApp& app) {
  1853. app.add(new X86Test_FuncCallFast());
  1854. }
  1855. virtual void compile(x86::Compiler& cc) {
  1856. x86::Gp var = cc.newInt32("var");
  1857. cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
  1858. cc.setArg(0, var);
  1859. FuncCallNode* call;
  1860. call = cc.call(
  1861. imm((void*)calledFunc),
  1862. FuncSignatureT<int, int>(CallConv::kIdHostFastCall));
  1863. call->setArg(0, var);
  1864. call->setRet(0, var);
  1865. call = cc.call(
  1866. imm((void*)calledFunc),
  1867. FuncSignatureT<int, int>(CallConv::kIdHostFastCall));
  1868. call->setArg(0, var);
  1869. call->setRet(0, var);
  1870. cc.ret(var);
  1871. cc.endFunc();
  1872. }
  1873. virtual bool run(void* _func, String& result, String& expect) {
  1874. typedef int (*Func)(int);
  1875. Func func = ptr_as_func<Func>(_func);
  1876. int resultRet = func(9);
  1877. int expectRet = (9 * 9) * (9 * 9);
  1878. result.assignFormat("ret=%d", resultRet);
  1879. expect.assignFormat("ret=%d", expectRet);
  1880. return resultRet == expectRet;
  1881. }
  1882. // FASTCALL function that is called inside the generated one.
  1883. static int ASMJIT_FASTCALL calledFunc(int a) noexcept {
  1884. return a * a;
  1885. }
  1886. };
  1887. // ============================================================================
  1888. // [X86Test_FuncCallLight]
  1889. // ============================================================================
  1890. class X86Test_FuncCallLight : public X86Test {
  1891. public:
  1892. X86Test_FuncCallLight() : X86Test("FuncCallLight") {}
  1893. static void add(X86TestApp& app) {
  1894. app.add(new X86Test_FuncCallLight());
  1895. }
  1896. virtual void compile(x86::Compiler& cc) {
  1897. FuncSignatureT<void, const void*, const void*, const void*, const void*, void*> funcSig(CallConv::kIdHostCDecl);
  1898. FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm> fastSig(CallConv::kIdHostLightCall2);
  1899. FuncNode* func = cc.newFunc(funcSig);
  1900. FuncNode* fast = cc.newFunc(fastSig);
  1901. {
  1902. x86::Gp aPtr = cc.newIntPtr("aPtr");
  1903. x86::Gp bPtr = cc.newIntPtr("bPtr");
  1904. x86::Gp cPtr = cc.newIntPtr("cPtr");
  1905. x86::Gp dPtr = cc.newIntPtr("dPtr");
  1906. x86::Gp pOut = cc.newIntPtr("pOut");
  1907. x86::Xmm aXmm = cc.newXmm("aXmm");
  1908. x86::Xmm bXmm = cc.newXmm("bXmm");
  1909. x86::Xmm cXmm = cc.newXmm("cXmm");
  1910. x86::Xmm dXmm = cc.newXmm("dXmm");
  1911. cc.addFunc(func);
  1912. cc.setArg(0, aPtr);
  1913. cc.setArg(1, bPtr);
  1914. cc.setArg(2, cPtr);
  1915. cc.setArg(3, dPtr);
  1916. cc.setArg(4, pOut);
  1917. cc.movups(aXmm, x86::ptr(aPtr));
  1918. cc.movups(bXmm, x86::ptr(bPtr));
  1919. cc.movups(cXmm, x86::ptr(cPtr));
  1920. cc.movups(dXmm, x86::ptr(dPtr));
  1921. x86::Xmm xXmm = cc.newXmm("xXmm");
  1922. x86::Xmm yXmm = cc.newXmm("yXmm");
  1923. FuncCallNode* call1 = cc.call(fast->label(), fastSig);
  1924. call1->setArg(0, aXmm);
  1925. call1->setArg(1, bXmm);
  1926. call1->setRet(0, xXmm);
  1927. FuncCallNode* call2 = cc.call(fast->label(), fastSig);
  1928. call2->setArg(0, cXmm);
  1929. call2->setArg(1, dXmm);
  1930. call2->setRet(0, yXmm);
  1931. cc.pmullw(xXmm, yXmm);
  1932. cc.movups(x86::ptr(pOut), xXmm);
  1933. cc.endFunc();
  1934. }
  1935. {
  1936. x86::Xmm aXmm = cc.newXmm("aXmm");
  1937. x86::Xmm bXmm = cc.newXmm("bXmm");
  1938. cc.addFunc(fast);
  1939. cc.setArg(0, aXmm);
  1940. cc.setArg(1, bXmm);
  1941. cc.paddw(aXmm, bXmm);
  1942. cc.ret(aXmm);
  1943. cc.endFunc();
  1944. }
  1945. }
  1946. virtual bool run(void* _func, String& result, String& expect) {
  1947. typedef void (*Func)(const void*, const void*, const void*, const void*, void*);
  1948. Func func = ptr_as_func<Func>(_func);
  1949. int16_t a[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
  1950. int16_t b[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
  1951. int16_t c[8] = { 1, 3, 9, 7, 5, 4, 2, 1 };
  1952. int16_t d[8] = { 2, 0,-6,-4,-2,-1, 1, 2 };
  1953. int16_t o[8];
  1954. int oExp = 7 * 3;
  1955. func(a, b, c, d, o);
  1956. result.assignFormat("ret={%02X %02X %02X %02X %02X %02X %02X %02X}", o[0], o[1], o[2], o[3], o[4], o[5], o[6], o[7]);
  1957. expect.assignFormat("ret={%02X %02X %02X %02X %02X %02X %02X %02X}", oExp, oExp, oExp, oExp, oExp, oExp, oExp, oExp);
  1958. return result == expect;
  1959. }
  1960. };
  1961. // ============================================================================
  1962. // [X86Test_FuncCallManyArgs]
  1963. // ============================================================================
  1964. class X86Test_FuncCallManyArgs : public X86Test {
  1965. public:
  1966. X86Test_FuncCallManyArgs() : X86Test("FuncCallManyArgs") {}
  1967. static void add(X86TestApp& app) {
  1968. app.add(new X86Test_FuncCallManyArgs());
  1969. }
  1970. static int calledFunc(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
  1971. return (a * b * c * d * e) + (f * g * h * i * j);
  1972. }
  1973. virtual void compile(x86::Compiler& cc) {
  1974. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  1975. // Prepare.
  1976. x86::Gp va = cc.newInt32("va");
  1977. x86::Gp vb = cc.newInt32("vb");
  1978. x86::Gp vc = cc.newInt32("vc");
  1979. x86::Gp vd = cc.newInt32("vd");
  1980. x86::Gp ve = cc.newInt32("ve");
  1981. x86::Gp vf = cc.newInt32("vf");
  1982. x86::Gp vg = cc.newInt32("vg");
  1983. x86::Gp vh = cc.newInt32("vh");
  1984. x86::Gp vi = cc.newInt32("vi");
  1985. x86::Gp vj = cc.newInt32("vj");
  1986. cc.mov(va, 0x03);
  1987. cc.mov(vb, 0x12);
  1988. cc.mov(vc, 0xA0);
  1989. cc.mov(vd, 0x0B);
  1990. cc.mov(ve, 0x2F);
  1991. cc.mov(vf, 0x02);
  1992. cc.mov(vg, 0x0C);
  1993. cc.mov(vh, 0x12);
  1994. cc.mov(vi, 0x18);
  1995. cc.mov(vj, 0x1E);
  1996. // Call function.
  1997. FuncCallNode* call = cc.call(
  1998. imm((void*)calledFunc),
  1999. FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
  2000. call->setArg(0, va);
  2001. call->setArg(1, vb);
  2002. call->setArg(2, vc);
  2003. call->setArg(3, vd);
  2004. call->setArg(4, ve);
  2005. call->setArg(5, vf);
  2006. call->setArg(6, vg);
  2007. call->setArg(7, vh);
  2008. call->setArg(8, vi);
  2009. call->setArg(9, vj);
  2010. call->setRet(0, va);
  2011. cc.ret(va);
  2012. cc.endFunc();
  2013. }
  2014. virtual bool run(void* _func, String& result, String& expect) {
  2015. typedef int (*Func)(void);
  2016. Func func = ptr_as_func<Func>(_func);
  2017. int resultRet = func();
  2018. int expectRet = calledFunc(0x03, 0x12, 0xA0, 0x0B, 0x2F, 0x02, 0x0C, 0x12, 0x18, 0x1E);
  2019. result.assignFormat("ret=%d", resultRet);
  2020. expect.assignFormat("ret=%d", expectRet);
  2021. return resultRet == expectRet;
  2022. }
  2023. };
  2024. // ============================================================================
  2025. // [X86Test_FuncCallDuplicateArgs]
  2026. // ============================================================================
  2027. class X86Test_FuncCallDuplicateArgs : public X86Test {
  2028. public:
  2029. X86Test_FuncCallDuplicateArgs() : X86Test("FuncCallDuplicateArgs") {}
  2030. static void add(X86TestApp& app) {
  2031. app.add(new X86Test_FuncCallDuplicateArgs());
  2032. }
  2033. static int calledFunc(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
  2034. return (a * b * c * d * e) + (f * g * h * i * j);
  2035. }
  2036. virtual void compile(x86::Compiler& cc) {
  2037. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  2038. // Prepare.
  2039. x86::Gp a = cc.newInt32("a");
  2040. cc.mov(a, 3);
  2041. // Call function.
  2042. FuncCallNode* call = cc.call(
  2043. imm((void*)calledFunc),
  2044. FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
  2045. call->setArg(0, a);
  2046. call->setArg(1, a);
  2047. call->setArg(2, a);
  2048. call->setArg(3, a);
  2049. call->setArg(4, a);
  2050. call->setArg(5, a);
  2051. call->setArg(6, a);
  2052. call->setArg(7, a);
  2053. call->setArg(8, a);
  2054. call->setArg(9, a);
  2055. call->setRet(0, a);
  2056. cc.ret(a);
  2057. cc.endFunc();
  2058. }
  2059. virtual bool run(void* _func, String& result, String& expect) {
  2060. typedef int (*Func)(void);
  2061. Func func = ptr_as_func<Func>(_func);
  2062. int resultRet = func();
  2063. int expectRet = calledFunc(3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
  2064. result.assignFormat("ret=%d", resultRet);
  2065. expect.assignFormat("ret=%d", expectRet);
  2066. return resultRet == expectRet;
  2067. }
  2068. };
  2069. // ============================================================================
  2070. // [X86Test_FuncCallImmArgs]
  2071. // ============================================================================
  2072. class X86Test_FuncCallImmArgs : public X86Test {
  2073. public:
  2074. X86Test_FuncCallImmArgs() : X86Test("FuncCallImmArgs") {}
  2075. static void add(X86TestApp& app) {
  2076. app.add(new X86Test_FuncCallImmArgs());
  2077. }
  2078. virtual void compile(x86::Compiler& cc) {
  2079. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  2080. // Prepare.
  2081. x86::Gp rv = cc.newInt32("rv");
  2082. // Call function.
  2083. FuncCallNode* call = cc.call(
  2084. imm((void*)X86Test_FuncCallManyArgs::calledFunc),
  2085. FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
  2086. call->setArg(0, imm(0x03));
  2087. call->setArg(1, imm(0x12));
  2088. call->setArg(2, imm(0xA0));
  2089. call->setArg(3, imm(0x0B));
  2090. call->setArg(4, imm(0x2F));
  2091. call->setArg(5, imm(0x02));
  2092. call->setArg(6, imm(0x0C));
  2093. call->setArg(7, imm(0x12));
  2094. call->setArg(8, imm(0x18));
  2095. call->setArg(9, imm(0x1E));
  2096. call->setRet(0, rv);
  2097. cc.ret(rv);
  2098. cc.endFunc();
  2099. }
  2100. virtual bool run(void* _func, String& result, String& expect) {
  2101. typedef int (*Func)(void);
  2102. Func func = ptr_as_func<Func>(_func);
  2103. int resultRet = func();
  2104. int expectRet = X86Test_FuncCallManyArgs::calledFunc(0x03, 0x12, 0xA0, 0x0B, 0x2F, 0x02, 0x0C, 0x12, 0x18, 0x1E);
  2105. result.assignFormat("ret=%d", resultRet);
  2106. expect.assignFormat("ret=%d", expectRet);
  2107. return resultRet == expectRet;
  2108. }
  2109. };
  2110. // ============================================================================
  2111. // [X86Test_FuncCallPtrArgs]
  2112. // ============================================================================
  2113. class X86Test_FuncCallPtrArgs : public X86Test {
  2114. public:
  2115. X86Test_FuncCallPtrArgs() : X86Test("FuncCallPtrArgs") {}
  2116. static void add(X86TestApp& app) {
  2117. app.add(new X86Test_FuncCallPtrArgs());
  2118. }
  2119. static int calledFunc(void* a, void* b, void* c, void* d, void* e, void* f, void* g, void* h, void* i, void* j) {
  2120. return int((intptr_t)a) +
  2121. int((intptr_t)b) +
  2122. int((intptr_t)c) +
  2123. int((intptr_t)d) +
  2124. int((intptr_t)e) +
  2125. int((intptr_t)f) +
  2126. int((intptr_t)g) +
  2127. int((intptr_t)h) +
  2128. int((intptr_t)i) +
  2129. int((intptr_t)j) ;
  2130. }
  2131. virtual void compile(x86::Compiler& cc) {
  2132. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  2133. // Prepare.
  2134. x86::Gp rv = cc.newInt32("rv");
  2135. // Call function.
  2136. FuncCallNode* call = cc.call(
  2137. imm((void*)calledFunc),
  2138. FuncSignatureT<int, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>(CallConv::kIdHost));
  2139. call->setArg(0, imm(0x01));
  2140. call->setArg(1, imm(0x02));
  2141. call->setArg(2, imm(0x03));
  2142. call->setArg(3, imm(0x04));
  2143. call->setArg(4, imm(0x05));
  2144. call->setArg(5, imm(0x06));
  2145. call->setArg(6, imm(0x07));
  2146. call->setArg(7, imm(0x08));
  2147. call->setArg(8, imm(0x09));
  2148. call->setArg(9, imm(0x0A));
  2149. call->setRet(0, rv);
  2150. cc.ret(rv);
  2151. cc.endFunc();
  2152. }
  2153. virtual bool run(void* _func, String& result, String& expect) {
  2154. typedef int (*Func)(void);
  2155. Func func = ptr_as_func<Func>(_func);
  2156. int resultRet = func();
  2157. int expectRet = 55;
  2158. result.assignFormat("ret=%d", resultRet);
  2159. expect.assignFormat("ret=%d", expectRet);
  2160. return resultRet == expectRet;
  2161. }
  2162. };
  2163. // ============================================================================
  2164. // [X86Test_FuncCallRefArgs]
  2165. // ============================================================================
  2166. class X86Test_FuncCallRefArgs : public X86Test {
  2167. public:
  2168. X86Test_FuncCallRefArgs() : X86Test("FuncCallRefArgs") {}
  2169. static void add(X86TestApp& app) {
  2170. app.add(new X86Test_FuncCallRefArgs());
  2171. }
  2172. static int calledFunc(int& a, int& b, int& c, int& d) {
  2173. a += a;
  2174. b += b;
  2175. c += c;
  2176. d += d;
  2177. return a + b + c + d;
  2178. }
  2179. virtual void compile(x86::Compiler& cc) {
  2180. cc.addFunc(FuncSignatureT<int, int&, int&, int&, int&>(CallConv::kIdHost));
  2181. // Prepare.
  2182. x86::Gp arg1 = cc.newInt32();
  2183. x86::Gp arg2 = cc.newInt32();
  2184. x86::Gp arg3 = cc.newInt32();
  2185. x86::Gp arg4 = cc.newInt32();
  2186. x86::Gp rv = cc.newInt32("rv");
  2187. cc.setArg(0, arg1);
  2188. cc.setArg(1, arg2);
  2189. cc.setArg(2, arg3);
  2190. cc.setArg(3, arg4);
  2191. // Call function.
  2192. FuncCallNode* call = cc.call(
  2193. imm((void*)calledFunc),
  2194. FuncSignatureT<int, int&, int&, int&, int&>(CallConv::kIdHost));
  2195. call->setArg(0, arg1);
  2196. call->setArg(1, arg2);
  2197. call->setArg(2, arg3);
  2198. call->setArg(3, arg4);
  2199. call->setRet(0, rv);
  2200. cc.ret(rv);
  2201. cc.endFunc();
  2202. }
  2203. virtual bool run(void* _func, String& result, String& expect) {
  2204. typedef int (*Func)(int&, int&, int&, int&);
  2205. Func func = ptr_as_func<Func>(_func);
  2206. int inputs[4] = { 1, 2, 3, 4 };
  2207. int outputs[4] = { 2, 4, 6, 8 };
  2208. int resultRet = func(inputs[0], inputs[1], inputs[2], inputs[3]);
  2209. int expectRet = 20;
  2210. result.assignFormat("ret={%08X %08X %08X %08X %08X}", resultRet, inputs[0], inputs[1], inputs[2], inputs[3]);
  2211. expect.assignFormat("ret={%08X %08X %08X %08X %08X}", expectRet, outputs[0], outputs[1], outputs[2], outputs[3]);
  2212. return resultRet == expectRet;
  2213. }
  2214. };
  2215. // ============================================================================
  2216. // [X86Test_FuncCallFloatAsXmmRet]
  2217. // ============================================================================
  2218. class X86Test_FuncCallFloatAsXmmRet : public X86Test {
  2219. public:
  2220. X86Test_FuncCallFloatAsXmmRet() : X86Test("FuncCallFloatAsXmmRet") {}
  2221. static void add(X86TestApp& app) {
  2222. app.add(new X86Test_FuncCallFloatAsXmmRet());
  2223. }
  2224. static float calledFunc(float a, float b) {
  2225. return a * b;
  2226. }
  2227. virtual void compile(x86::Compiler& cc) {
  2228. cc.addFunc(FuncSignatureT<float, float, float>(CallConv::kIdHost));
  2229. x86::Xmm a = cc.newXmmSs("a");
  2230. x86::Xmm b = cc.newXmmSs("b");
  2231. x86::Xmm ret = cc.newXmmSs("ret");
  2232. cc.setArg(0, a);
  2233. cc.setArg(1, b);
  2234. // Call function.
  2235. FuncCallNode* call = cc.call(
  2236. imm((void*)calledFunc),
  2237. FuncSignatureT<float, float, float>(CallConv::kIdHost));
  2238. call->setArg(0, a);
  2239. call->setArg(1, b);
  2240. call->setRet(0, ret);
  2241. cc.ret(ret);
  2242. cc.endFunc();
  2243. }
  2244. virtual bool run(void* _func, String& result, String& expect) {
  2245. typedef float (*Func)(float, float);
  2246. Func func = ptr_as_func<Func>(_func);
  2247. float resultRet = func(15.5f, 2.0f);
  2248. float expectRet = calledFunc(15.5f, 2.0f);
  2249. result.assignFormat("ret=%g", resultRet);
  2250. expect.assignFormat("ret=%g", expectRet);
  2251. return resultRet == expectRet;
  2252. }
  2253. };
  2254. // ============================================================================
  2255. // [X86Test_FuncCallDoubleAsXmmRet]
  2256. // ============================================================================
  2257. class X86Test_FuncCallDoubleAsXmmRet : public X86Test {
  2258. public:
  2259. X86Test_FuncCallDoubleAsXmmRet() : X86Test("FuncCallDoubleAsXmmRet") {}
  2260. static void add(X86TestApp& app) {
  2261. app.add(new X86Test_FuncCallDoubleAsXmmRet());
  2262. }
  2263. static double calledFunc(double a, double b) {
  2264. return a * b;
  2265. }
  2266. virtual void compile(x86::Compiler& cc) {
  2267. cc.addFunc(FuncSignatureT<double, double, double>(CallConv::kIdHost));
  2268. x86::Xmm a = cc.newXmmSd("a");
  2269. x86::Xmm b = cc.newXmmSd("b");
  2270. x86::Xmm ret = cc.newXmmSd("ret");
  2271. cc.setArg(0, a);
  2272. cc.setArg(1, b);
  2273. FuncCallNode* call = cc.call(
  2274. imm((void*)calledFunc),
  2275. FuncSignatureT<double, double, double>(CallConv::kIdHost));
  2276. call->setArg(0, a);
  2277. call->setArg(1, b);
  2278. call->setRet(0, ret);
  2279. cc.ret(ret);
  2280. cc.endFunc();
  2281. }
  2282. virtual bool run(void* _func, String& result, String& expect) {
  2283. typedef double (*Func)(double, double);
  2284. Func func = ptr_as_func<Func>(_func);
  2285. double resultRet = func(15.5, 2.0);
  2286. double expectRet = calledFunc(15.5, 2.0);
  2287. result.assignFormat("ret=%g", resultRet);
  2288. expect.assignFormat("ret=%g", expectRet);
  2289. return resultRet == expectRet;
  2290. }
  2291. };
  2292. // ============================================================================
  2293. // [X86Test_FuncCallConditional]
  2294. // ============================================================================
  2295. class X86Test_FuncCallConditional : public X86Test {
  2296. public:
  2297. X86Test_FuncCallConditional() : X86Test("FuncCallConditional") {}
  2298. static void add(X86TestApp& app) {
  2299. app.add(new X86Test_FuncCallConditional());
  2300. }
  2301. virtual void compile(x86::Compiler& cc) {
  2302. x86::Gp x = cc.newInt32("x");
  2303. x86::Gp y = cc.newInt32("y");
  2304. x86::Gp op = cc.newInt32("op");
  2305. FuncCallNode* call;
  2306. x86::Gp result;
  2307. cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
  2308. cc.setArg(0, x);
  2309. cc.setArg(1, y);
  2310. cc.setArg(2, op);
  2311. Label opAdd = cc.newLabel();
  2312. Label opMul = cc.newLabel();
  2313. cc.cmp(op, 0);
  2314. cc.jz(opAdd);
  2315. cc.cmp(op, 1);
  2316. cc.jz(opMul);
  2317. result = cc.newInt32("result_0");
  2318. cc.mov(result, 0);
  2319. cc.ret(result);
  2320. cc.bind(opAdd);
  2321. result = cc.newInt32("result_1");
  2322. call = cc.call((uint64_t)calledFuncAdd, FuncSignatureT<int, int, int>(CallConv::kIdHost));
  2323. call->setArg(0, x);
  2324. call->setArg(1, y);
  2325. call->setRet(0, result);
  2326. cc.ret(result);
  2327. cc.bind(opMul);
  2328. result = cc.newInt32("result_2");
  2329. call = cc.call((uint64_t)calledFuncMul, FuncSignatureT<int, int, int>(CallConv::kIdHost));
  2330. call->setArg(0, x);
  2331. call->setArg(1, y);
  2332. call->setRet(0, result);
  2333. cc.ret(result);
  2334. cc.endFunc();
  2335. }
  2336. virtual bool run(void* _func, String& result, String& expect) {
  2337. typedef int (*Func)(int, int, int);
  2338. Func func = ptr_as_func<Func>(_func);
  2339. int arg1 = 4;
  2340. int arg2 = 8;
  2341. int resultAdd = func(arg1, arg2, 0);
  2342. int expectAdd = calledFuncAdd(arg1, arg2);
  2343. int resultMul = func(arg1, arg2, 1);
  2344. int expectMul = calledFuncMul(arg1, arg2);
  2345. result.assignFormat("ret={add=%d, mul=%d}", resultAdd, resultMul);
  2346. expect.assignFormat("ret={add=%d, mul=%d}", expectAdd, expectMul);
  2347. return (resultAdd == expectAdd) && (resultMul == expectMul);
  2348. }
  2349. static int calledFuncAdd(int x, int y) { return x + y; }
  2350. static int calledFuncMul(int x, int y) { return x * y; }
  2351. };
  2352. // ============================================================================
  2353. // [X86Test_FuncCallMultiple]
  2354. // ============================================================================
  2355. class X86Test_FuncCallMultiple : public X86Test {
  2356. public:
  2357. X86Test_FuncCallMultiple() : X86Test("FuncCallMultiple") {}
  2358. static void add(X86TestApp& app) {
  2359. app.add(new X86Test_FuncCallMultiple());
  2360. }
  2361. static int ASMJIT_FASTCALL calledFunc(int* pInt, int index) {
  2362. return pInt[index];
  2363. }
  2364. virtual void compile(x86::Compiler& cc) {
  2365. unsigned int i;
  2366. x86::Gp buf = cc.newIntPtr("buf");
  2367. x86::Gp acc0 = cc.newInt32("acc0");
  2368. x86::Gp acc1 = cc.newInt32("acc1");
  2369. cc.addFunc(FuncSignatureT<int, int*>(CallConv::kIdHost));
  2370. cc.setArg(0, buf);
  2371. cc.mov(acc0, 0);
  2372. cc.mov(acc1, 0);
  2373. for (i = 0; i < 4; i++) {
  2374. x86::Gp ret = cc.newInt32("ret");
  2375. x86::Gp ptr = cc.newIntPtr("ptr");
  2376. x86::Gp idx = cc.newInt32("idx");
  2377. FuncCallNode* call;
  2378. cc.mov(ptr, buf);
  2379. cc.mov(idx, int(i));
  2380. call = cc.call((uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdHostFastCall));
  2381. call->setArg(0, ptr);
  2382. call->setArg(1, idx);
  2383. call->setRet(0, ret);
  2384. cc.add(acc0, ret);
  2385. cc.mov(ptr, buf);
  2386. cc.mov(idx, int(i));
  2387. call = cc.call((uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdHostFastCall));
  2388. call->setArg(0, ptr);
  2389. call->setArg(1, idx);
  2390. call->setRet(0, ret);
  2391. cc.sub(acc1, ret);
  2392. }
  2393. cc.add(acc0, acc1);
  2394. cc.ret(acc0);
  2395. cc.endFunc();
  2396. }
  2397. virtual bool run(void* _func, String& result, String& expect) {
  2398. typedef int (*Func)(int*);
  2399. Func func = ptr_as_func<Func>(_func);
  2400. int buffer[4] = { 127, 87, 23, 17 };
  2401. int resultRet = func(buffer);
  2402. int expectRet = 0;
  2403. result.assignFormat("ret=%d", resultRet);
  2404. expect.assignFormat("ret=%d", expectRet);
  2405. return resultRet == expectRet;
  2406. }
  2407. };
  2408. // ============================================================================
  2409. // [X86Test_FuncCallRecursive]
  2410. // ============================================================================
  2411. class X86Test_FuncCallRecursive : public X86Test {
  2412. public:
  2413. X86Test_FuncCallRecursive() : X86Test("FuncCallRecursive") {}
  2414. static void add(X86TestApp& app) {
  2415. app.add(new X86Test_FuncCallRecursive());
  2416. }
  2417. virtual void compile(x86::Compiler& cc) {
  2418. x86::Gp val = cc.newInt32("val");
  2419. Label skip = cc.newLabel();
  2420. FuncNode* func = cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
  2421. cc.setArg(0, val);
  2422. cc.cmp(val, 1);
  2423. cc.jle(skip);
  2424. x86::Gp tmp = cc.newInt32("tmp");
  2425. cc.mov(tmp, val);
  2426. cc.dec(tmp);
  2427. FuncCallNode* call = cc.call(func->label(), FuncSignatureT<int, int>(CallConv::kIdHost));
  2428. call->setArg(0, tmp);
  2429. call->setRet(0, tmp);
  2430. cc.mul(cc.newInt32(), val, tmp);
  2431. cc.bind(skip);
  2432. cc.ret(val);
  2433. cc.endFunc();
  2434. }
  2435. virtual bool run(void* _func, String& result, String& expect) {
  2436. typedef int (*Func)(int);
  2437. Func func = ptr_as_func<Func>(_func);
  2438. int resultRet = func(5);
  2439. int expectRet = 1 * 2 * 3 * 4 * 5;
  2440. result.assignFormat("ret=%d", resultRet);
  2441. expect.assignFormat("ret=%d", expectRet);
  2442. return resultRet == expectRet;
  2443. }
  2444. };
  2445. // ============================================================================
  2446. // [X86Test_FuncCallVarArg1]
  2447. // ============================================================================
  2448. class X86Test_FuncCallVarArg1 : public X86Test {
  2449. public:
  2450. X86Test_FuncCallVarArg1() : X86Test("FuncCallVarArg1") {}
  2451. static void add(X86TestApp& app) {
  2452. app.add(new X86Test_FuncCallVarArg1());
  2453. }
  2454. virtual void compile(x86::Compiler& cc) {
  2455. cc.addFunc(FuncSignatureT<int, int, int, int, int>(CallConv::kIdHost));
  2456. x86::Gp a0 = cc.newInt32("a0");
  2457. x86::Gp a1 = cc.newInt32("a1");
  2458. x86::Gp a2 = cc.newInt32("a2");
  2459. x86::Gp a3 = cc.newInt32("a3");
  2460. cc.setArg(0, a0);
  2461. cc.setArg(1, a1);
  2462. cc.setArg(2, a2);
  2463. cc.setArg(3, a3);
  2464. // We call `int func(size_t, ...)`
  2465. // - The `vaIndex` must be 1 (first argument after size_t).
  2466. // - The full signature of varargs (int, int, int, int) must follow.
  2467. FuncCallNode* call = cc.call(
  2468. imm((void*)calledFunc),
  2469. FuncSignatureT<int, size_t, int, int, int, int>(CallConv::kIdHost, 1));
  2470. call->setArg(0, imm(4));
  2471. call->setArg(1, a0);
  2472. call->setArg(2, a1);
  2473. call->setArg(3, a2);
  2474. call->setArg(4, a3);
  2475. call->setRet(0, a0);
  2476. cc.ret(a0);
  2477. cc.endFunc();
  2478. }
  2479. virtual bool run(void* _func, String& result, String& expect) {
  2480. typedef int (*Func)(int, int, int, int);
  2481. Func func = ptr_as_func<Func>(_func);
  2482. int resultRet = func(1, 2, 3, 4);
  2483. int expectRet = 1 + 2 + 3 + 4;
  2484. result.assignFormat("ret=%d", resultRet);
  2485. expect.assignFormat("ret=%d", expectRet);
  2486. return resultRet == expectRet;
  2487. }
  2488. static int calledFunc(size_t n, ...) {
  2489. int sum = 0;
  2490. va_list ap;
  2491. va_start(ap, n);
  2492. for (size_t i = 0; i < n; i++) {
  2493. int arg = va_arg(ap, int);
  2494. sum += arg;
  2495. }
  2496. va_end(ap);
  2497. return sum;
  2498. }
  2499. };
  2500. // ============================================================================
  2501. // [X86Test_FuncCallVarArg2]
  2502. // ============================================================================
  2503. class X86Test_FuncCallVarArg2 : public X86Test {
  2504. public:
  2505. X86Test_FuncCallVarArg2() : X86Test("FuncCallVarArg2") {}
  2506. static void add(X86TestApp& app) {
  2507. app.add(new X86Test_FuncCallVarArg2());
  2508. }
  2509. virtual void compile(x86::Compiler& cc) {
  2510. cc.addFunc(FuncSignatureT<double, double, double, double, double>(CallConv::kIdHost));
  2511. x86::Xmm a0 = cc.newXmmSd("a0");
  2512. x86::Xmm a1 = cc.newXmmSd("a1");
  2513. x86::Xmm a2 = cc.newXmmSd("a2");
  2514. x86::Xmm a3 = cc.newXmmSd("a3");
  2515. cc.setArg(0, a0);
  2516. cc.setArg(1, a1);
  2517. cc.setArg(2, a2);
  2518. cc.setArg(3, a3);
  2519. // We call `double func(size_t, ...)`
  2520. // - The `vaIndex` must be 1 (first argument after size_t).
  2521. // - The full signature of varargs (double, double, double, double) must follow.
  2522. FuncCallNode* call = cc.call(
  2523. imm((void*)calledFunc),
  2524. FuncSignatureT<double, size_t, double, double, double, double>(CallConv::kIdHost, 1));
  2525. call->setArg(0, imm(4));
  2526. call->setArg(1, a0);
  2527. call->setArg(2, a1);
  2528. call->setArg(3, a2);
  2529. call->setArg(4, a3);
  2530. call->setRet(0, a0);
  2531. cc.ret(a0);
  2532. cc.endFunc();
  2533. }
  2534. virtual bool run(void* _func, String& result, String& expect) {
  2535. typedef double (*Func)(double, double, double, double);
  2536. Func func = ptr_as_func<Func>(_func);
  2537. double resultRet = func(1.0, 2.0, 3.0, 4.0);
  2538. double expectRet = 1.0 + 2.0 + 3.0 + 4.0;
  2539. result.assignFormat("ret=%f", resultRet);
  2540. expect.assignFormat("ret=%f", expectRet);
  2541. return resultRet == expectRet;
  2542. }
  2543. static double calledFunc(size_t n, ...) {
  2544. double sum = 0;
  2545. va_list ap;
  2546. va_start(ap, n);
  2547. for (size_t i = 0; i < n; i++) {
  2548. double arg = va_arg(ap, double);
  2549. sum += arg;
  2550. }
  2551. va_end(ap);
  2552. return sum;
  2553. }
  2554. };
  2555. // ============================================================================
  2556. // [X86Test_FuncCallMisc1]
  2557. // ============================================================================
  2558. class X86Test_FuncCallMisc1 : public X86Test {
  2559. public:
  2560. X86Test_FuncCallMisc1() : X86Test("FuncCallMisc1") {}
  2561. static void add(X86TestApp& app) {
  2562. app.add(new X86Test_FuncCallMisc1());
  2563. }
  2564. static void dummy(int, int) {}
  2565. virtual void compile(x86::Compiler& cc) {
  2566. cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
  2567. x86::Gp a = cc.newInt32("a");
  2568. x86::Gp b = cc.newInt32("b");
  2569. x86::Gp r = cc.newInt32("r");
  2570. cc.setArg(0, a);
  2571. cc.setArg(1, b);
  2572. FuncCallNode* call = cc.call(
  2573. imm((void*)dummy),
  2574. FuncSignatureT<void, int, int>(CallConv::kIdHost));
  2575. call->setArg(0, a);
  2576. call->setArg(1, b);
  2577. cc.lea(r, x86::ptr(a, b));
  2578. cc.ret(r);
  2579. cc.endFunc();
  2580. }
  2581. virtual bool run(void* _func, String& result, String& expect) {
  2582. typedef int (*Func)(int, int);
  2583. Func func = ptr_as_func<Func>(_func);
  2584. int resultRet = func(44, 199);
  2585. int expectRet = 243;
  2586. result.assignFormat("ret=%d", resultRet);
  2587. expect.assignFormat("ret=%d", expectRet);
  2588. return resultRet == expectRet;
  2589. }
  2590. };
  2591. // ============================================================================
  2592. // [X86Test_FuncCallMisc2]
  2593. // ============================================================================
  2594. class X86Test_FuncCallMisc2 : public X86Test {
  2595. public:
  2596. X86Test_FuncCallMisc2() : X86Test("FuncCallMisc2") {}
  2597. static void add(X86TestApp& app) {
  2598. app.add(new X86Test_FuncCallMisc2());
  2599. }
  2600. virtual void compile(x86::Compiler& cc) {
  2601. cc.addFunc(FuncSignatureT<double, const double*>(CallConv::kIdHost));
  2602. x86::Gp p = cc.newIntPtr("p");
  2603. x86::Xmm arg = cc.newXmmSd("arg");
  2604. x86::Xmm ret = cc.newXmmSd("ret");
  2605. cc.setArg(0, p);
  2606. cc.movsd(arg, x86::ptr(p));
  2607. FuncCallNode* call = cc.call(
  2608. imm((void*)op),
  2609. FuncSignatureT<double, double>(CallConv::kIdHost));
  2610. call->setArg(0, arg);
  2611. call->setRet(0, ret);
  2612. cc.ret(ret);
  2613. cc.endFunc();
  2614. }
  2615. virtual bool run(void* _func, String& result, String& expect) {
  2616. typedef double (*Func)(const double*);
  2617. Func func = ptr_as_func<Func>(_func);
  2618. double arg = 2;
  2619. double resultRet = func(&arg);
  2620. double expectRet = op(arg);
  2621. result.assignFormat("ret=%g", resultRet);
  2622. expect.assignFormat("ret=%g", expectRet);
  2623. return resultRet == expectRet;
  2624. }
  2625. static double op(double a) { return a * a; }
  2626. };
  2627. // ============================================================================
  2628. // [X86Test_FuncCallMisc3]
  2629. // ============================================================================
  2630. class X86Test_FuncCallMisc3 : public X86Test {
  2631. public:
  2632. X86Test_FuncCallMisc3() : X86Test("FuncCallMisc3") {}
  2633. static void add(X86TestApp& app) {
  2634. app.add(new X86Test_FuncCallMisc3());
  2635. }
  2636. virtual void compile(x86::Compiler& cc) {
  2637. cc.addFunc(FuncSignatureT<double, const double*>(CallConv::kIdHost));
  2638. x86::Gp p = cc.newIntPtr("p");
  2639. x86::Xmm arg = cc.newXmmSd("arg");
  2640. x86::Xmm ret = cc.newXmmSd("ret");
  2641. cc.setArg(0, p);
  2642. cc.movsd(arg, x86::ptr(p));
  2643. FuncCallNode* call = cc.call(
  2644. imm((void*)op),
  2645. FuncSignatureT<double, double>(CallConv::kIdHost));
  2646. call->setArg(0, arg);
  2647. call->setRet(0, ret);
  2648. cc.xorps(arg, arg);
  2649. cc.subsd(arg, ret);
  2650. cc.ret(arg);
  2651. cc.endFunc();
  2652. }
  2653. virtual bool run(void* _func, String& result, String& expect) {
  2654. typedef double (*Func)(const double*);
  2655. Func func = ptr_as_func<Func>(_func);
  2656. double arg = 2;
  2657. double resultRet = func(&arg);
  2658. double expectRet = -op(arg);
  2659. result.assignFormat("ret=%g", resultRet);
  2660. expect.assignFormat("ret=%g", expectRet);
  2661. return resultRet == expectRet;
  2662. }
  2663. static double op(double a) { return a * a; }
  2664. };
  2665. // ============================================================================
  2666. // [X86Test_FuncCallMisc4]
  2667. // ============================================================================
  2668. class X86Test_FuncCallMisc4 : public X86Test {
  2669. public:
  2670. X86Test_FuncCallMisc4() : X86Test("FuncCallMisc4") {}
  2671. static void add(X86TestApp& app) {
  2672. app.add(new X86Test_FuncCallMisc4());
  2673. }
  2674. virtual void compile(x86::Compiler& cc) {
  2675. FuncSignatureBuilder funcPrototype;
  2676. funcPrototype.setCallConv(CallConv::kIdHost);
  2677. funcPrototype.setRet(Type::kIdF64);
  2678. cc.addFunc(funcPrototype);
  2679. FuncSignatureBuilder callPrototype;
  2680. callPrototype.setCallConv(CallConv::kIdHost);
  2681. callPrototype.setRet(Type::kIdF64);
  2682. FuncCallNode* call = cc.call(imm((void*)calledFunc), callPrototype);
  2683. x86::Xmm ret = cc.newXmmSd("ret");
  2684. call->setRet(0, ret);
  2685. cc.ret(ret);
  2686. cc.endFunc();
  2687. }
  2688. virtual bool run(void* _func, String& result, String& expect) {
  2689. typedef double (*Func)(void);
  2690. Func func = ptr_as_func<Func>(_func);
  2691. double resultRet = func();
  2692. double expectRet = 3.14;
  2693. result.assignFormat("ret=%g", resultRet);
  2694. expect.assignFormat("ret=%g", expectRet);
  2695. return resultRet == expectRet;
  2696. }
  2697. static double calledFunc() { return 3.14; }
  2698. };
  2699. // ============================================================================
  2700. // [X86Test_FuncCallMisc5]
  2701. // ============================================================================
  2702. // The register allocator should clobber the register used by the `call` itself.
  2703. class X86Test_FuncCallMisc5 : public X86Test {
  2704. public:
  2705. X86Test_FuncCallMisc5() : X86Test("FuncCallMisc5") {}
  2706. static void add(X86TestApp& app) {
  2707. app.add(new X86Test_FuncCallMisc5());
  2708. }
  2709. virtual void compile(x86::Compiler& cc) {
  2710. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  2711. x86::Gp pFn = cc.newIntPtr("pFn");
  2712. x86::Gp vars[16];
  2713. uint32_t i, regCount = cc.gpCount();
  2714. ASMJIT_ASSERT(regCount <= ASMJIT_ARRAY_SIZE(vars));
  2715. cc.mov(pFn, imm((void*)calledFunc));
  2716. for (i = 0; i < regCount; i++) {
  2717. if (i == x86::Gp::kIdBp || i == x86::Gp::kIdSp)
  2718. continue;
  2719. vars[i] = cc.newInt32("%%%u", unsigned(i));
  2720. cc.mov(vars[i], 1);
  2721. }
  2722. cc.call(pFn, FuncSignatureT<void>(CallConv::kIdHost));
  2723. for (i = 1; i < regCount; i++)
  2724. if (vars[i].isValid())
  2725. cc.add(vars[0], vars[i]);
  2726. cc.ret(vars[0]);
  2727. cc.endFunc();
  2728. }
  2729. virtual bool run(void* _func, String& result, String& expect) {
  2730. typedef int (*Func)(void);
  2731. Func func = ptr_as_func<Func>(_func);
  2732. int resultRet = func();
  2733. int expectRet = sizeof(void*) == 4 ? 6 : 14;
  2734. result.assignFormat("ret=%d", resultRet);
  2735. expect.assignFormat("ret=%d", expectRet);
  2736. return resultRet == expectRet;
  2737. }
  2738. static void calledFunc() {}
  2739. };
  2740. // ============================================================================
  2741. // [X86Test_MiscLocalConstPool]
  2742. // ============================================================================
  2743. class X86Test_MiscLocalConstPool : public X86Test {
  2744. public:
  2745. X86Test_MiscLocalConstPool() : X86Test("MiscLocalConstPool") {}
  2746. static void add(X86TestApp& app) {
  2747. app.add(new X86Test_MiscLocalConstPool());
  2748. }
  2749. virtual void compile(x86::Compiler& cc) {
  2750. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  2751. x86::Gp v0 = cc.newInt32("v0");
  2752. x86::Gp v1 = cc.newInt32("v1");
  2753. x86::Mem c0 = cc.newInt32Const(ConstPool::kScopeLocal, 200);
  2754. x86::Mem c1 = cc.newInt32Const(ConstPool::kScopeLocal, 33);
  2755. cc.mov(v0, c0);
  2756. cc.mov(v1, c1);
  2757. cc.add(v0, v1);
  2758. cc.ret(v0);
  2759. cc.endFunc();
  2760. }
  2761. virtual bool run(void* _func, String& result, String& expect) {
  2762. typedef int (*Func)(void);
  2763. Func func = ptr_as_func<Func>(_func);
  2764. int resultRet = func();
  2765. int expectRet = 233;
  2766. result.assignFormat("ret=%d", resultRet);
  2767. expect.assignFormat("ret=%d", expectRet);
  2768. return resultRet == expectRet;
  2769. }
  2770. };
  2771. // ============================================================================
  2772. // [X86Test_MiscGlobalConstPool]
  2773. // ============================================================================
  2774. class X86Test_MiscGlobalConstPool : public X86Test {
  2775. public:
  2776. X86Test_MiscGlobalConstPool() : X86Test("MiscGlobalConstPool") {}
  2777. static void add(X86TestApp& app) {
  2778. app.add(new X86Test_MiscGlobalConstPool());
  2779. }
  2780. virtual void compile(x86::Compiler& cc) {
  2781. cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
  2782. x86::Gp v0 = cc.newInt32("v0");
  2783. x86::Gp v1 = cc.newInt32("v1");
  2784. x86::Mem c0 = cc.newInt32Const(ConstPool::kScopeGlobal, 200);
  2785. x86::Mem c1 = cc.newInt32Const(ConstPool::kScopeGlobal, 33);
  2786. cc.mov(v0, c0);
  2787. cc.mov(v1, c1);
  2788. cc.add(v0, v1);
  2789. cc.ret(v0);
  2790. cc.endFunc();
  2791. }
  2792. virtual bool run(void* _func, String& result, String& expect) {
  2793. typedef int (*Func)(void);
  2794. Func func = ptr_as_func<Func>(_func);
  2795. int resultRet = func();
  2796. int expectRet = 233;
  2797. result.assignFormat("ret=%d", resultRet);
  2798. expect.assignFormat("ret=%d", expectRet);
  2799. return resultRet == expectRet;
  2800. }
  2801. };
  2802. // ============================================================================
  2803. // [X86Test_MiscMultiRet]
  2804. // ============================================================================
  2805. struct X86Test_MiscMultiRet : public X86Test {
  2806. X86Test_MiscMultiRet() : X86Test("MiscMultiRet") {}
  2807. static void add(X86TestApp& app) {
  2808. app.add(new X86Test_MiscMultiRet());
  2809. }
  2810. virtual void compile(x86::Compiler& cc) {
  2811. cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
  2812. x86::Gp op = cc.newInt32("op");
  2813. x86::Gp a = cc.newInt32("a");
  2814. x86::Gp b = cc.newInt32("b");
  2815. Label L_Zero = cc.newLabel();
  2816. Label L_Add = cc.newLabel();
  2817. Label L_Sub = cc.newLabel();
  2818. Label L_Mul = cc.newLabel();
  2819. Label L_Div = cc.newLabel();
  2820. cc.setArg(0, op);
  2821. cc.setArg(1, a);
  2822. cc.setArg(2, b);
  2823. cc.cmp(op, 0);
  2824. cc.jz(L_Add);
  2825. cc.cmp(op, 1);
  2826. cc.jz(L_Sub);
  2827. cc.cmp(op, 2);
  2828. cc.jz(L_Mul);
  2829. cc.cmp(op, 3);
  2830. cc.jz(L_Div);
  2831. cc.bind(L_Zero);
  2832. cc.xor_(a, a);
  2833. cc.ret(a);
  2834. cc.bind(L_Add);
  2835. cc.add(a, b);
  2836. cc.ret(a);
  2837. cc.bind(L_Sub);
  2838. cc.sub(a, b);
  2839. cc.ret(a);
  2840. cc.bind(L_Mul);
  2841. cc.imul(a, b);
  2842. cc.ret(a);
  2843. cc.bind(L_Div);
  2844. cc.cmp(b, 0);
  2845. cc.jz(L_Zero);
  2846. x86::Gp zero = cc.newInt32("zero");
  2847. cc.xor_(zero, zero);
  2848. cc.idiv(zero, a, b);
  2849. cc.ret(a);
  2850. cc.endFunc();
  2851. }
  2852. virtual bool run(void* _func, String& result, String& expect) {
  2853. typedef int (*Func)(int, int, int);
  2854. Func func = ptr_as_func<Func>(_func);
  2855. int a = 44;
  2856. int b = 3;
  2857. int r0 = func(0, a, b);
  2858. int r1 = func(1, a, b);
  2859. int r2 = func(2, a, b);
  2860. int r3 = func(3, a, b);
  2861. int e0 = a + b;
  2862. int e1 = a - b;
  2863. int e2 = a * b;
  2864. int e3 = a / b;
  2865. result.assignFormat("ret={%d %d %d %d}", r0, r1, r2, r3);
  2866. expect.assignFormat("ret={%d %d %d %d}", e0, e1, e2, e3);
  2867. return result.eq(expect);
  2868. }
  2869. };
  2870. // ============================================================================
  2871. // [X86Test_MiscMultiFunc]
  2872. // ============================================================================
  2873. class X86Test_MiscMultiFunc : public X86Test {
  2874. public:
  2875. X86Test_MiscMultiFunc() : X86Test("MiscMultiFunc") {}
  2876. static void add(X86TestApp& app) {
  2877. app.add(new X86Test_MiscMultiFunc());
  2878. }
  2879. virtual void compile(x86::Compiler& cc) {
  2880. FuncNode* f1 = cc.newFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
  2881. FuncNode* f2 = cc.newFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
  2882. {
  2883. x86::Gp a = cc.newInt32("a");
  2884. x86::Gp b = cc.newInt32("b");
  2885. cc.addFunc(f1);
  2886. cc.setArg(0, a);
  2887. cc.setArg(1, b);
  2888. FuncCallNode* call = cc.call(f2->label(), FuncSignatureT<int, int, int>(CallConv::kIdHost));
  2889. call->setArg(0, a);
  2890. call->setArg(1, b);
  2891. call->setRet(0, a);
  2892. cc.ret(a);
  2893. cc.endFunc();
  2894. }
  2895. {
  2896. x86::Gp a = cc.newInt32("a");
  2897. x86::Gp b = cc.newInt32("b");
  2898. cc.addFunc(f2);
  2899. cc.setArg(0, a);
  2900. cc.setArg(1, b);
  2901. cc.add(a, b);
  2902. cc.ret(a);
  2903. cc.endFunc();
  2904. }
  2905. }
  2906. virtual bool run(void* _func, String& result, String& expect) {
  2907. typedef int (*Func)(int, int);
  2908. Func func = ptr_as_func<Func>(_func);
  2909. int resultRet = func(56, 22);
  2910. int expectRet = 56 + 22;
  2911. result.assignFormat("ret=%d", resultRet);
  2912. expect.assignFormat("ret=%d", expectRet);
  2913. return result.eq(expect);
  2914. }
  2915. };
  2916. // ============================================================================
  2917. // [X86Test_MiscUnfollow]
  2918. // ============================================================================
  2919. // Global (I didn't find a better way to test this).
  2920. static jmp_buf globalJmpBuf;
  2921. class X86Test_MiscUnfollow : public X86Test {
  2922. public:
  2923. X86Test_MiscUnfollow() : X86Test("MiscUnfollow") {}
  2924. static void add(X86TestApp& app) {
  2925. app.add(new X86Test_MiscUnfollow());
  2926. }
  2927. virtual void compile(x86::Compiler& cc) {
  2928. // NOTE: Fastcall calling convention is the most appropriate here, as all
  2929. // arguments will be passed by registers and there won't be any stack
  2930. // misalignment when we call the `handler()`. This was failing on OSX
  2931. // when targeting 32-bit.
  2932. cc.addFunc(FuncSignatureT<int, int, void*>(CallConv::kIdHostFastCall));
  2933. x86::Gp a = cc.newInt32("a");
  2934. x86::Gp b = cc.newIntPtr("b");
  2935. Label tramp = cc.newLabel();
  2936. cc.setArg(0, a);
  2937. cc.setArg(1, b);
  2938. cc.cmp(a, 0);
  2939. cc.jz(tramp);
  2940. cc.ret(a);
  2941. cc.bind(tramp);
  2942. cc.unfollow().jmp(b);
  2943. cc.endFunc();
  2944. }
  2945. virtual bool run(void* _func, String& result, String& expect) {
  2946. typedef int (ASMJIT_FASTCALL *Func)(int, void*);
  2947. Func func = ptr_as_func<Func>(_func);
  2948. int resultRet = 0;
  2949. int expectRet = 1;
  2950. if (!setjmp(globalJmpBuf))
  2951. resultRet = func(0, (void*)handler);
  2952. else
  2953. resultRet = 1;
  2954. result.assignFormat("ret={%d}", resultRet);
  2955. expect.assignFormat("ret={%d}", expectRet);
  2956. return resultRet == expectRet;
  2957. }
  2958. static void ASMJIT_FASTCALL handler() { longjmp(globalJmpBuf, 1); }
  2959. };
  2960. // ============================================================================
  2961. // [Main]
  2962. // ============================================================================
  2963. int main(int argc, char* argv[]) {
  2964. X86TestApp app;
  2965. app.handleArgs(argc, argv);
  2966. app.showInfo();
  2967. // Base tests.
  2968. app.addT<X86Test_NoCode>();
  2969. app.addT<X86Test_NoAlign>();
  2970. app.addT<X86Test_AlignBase>();
  2971. // Jump tests.
  2972. app.addT<X86Test_JumpMerge>();
  2973. app.addT<X86Test_JumpCross>();
  2974. app.addT<X86Test_JumpMany>();
  2975. app.addT<X86Test_JumpUnreachable1>();
  2976. app.addT<X86Test_JumpUnreachable2>();
  2977. // Alloc tests.
  2978. app.addT<X86Test_AllocBase>();
  2979. app.addT<X86Test_AllocMany1>();
  2980. app.addT<X86Test_AllocMany2>();
  2981. app.addT<X86Test_AllocImul1>();
  2982. app.addT<X86Test_AllocImul2>();
  2983. app.addT<X86Test_AllocIdiv1>();
  2984. app.addT<X86Test_AllocSetz>();
  2985. app.addT<X86Test_AllocShlRor>();
  2986. app.addT<X86Test_AllocGpbLo1>();
  2987. app.addT<X86Test_AllocGpbLo2>();
  2988. app.addT<X86Test_AllocRepMovsb>();
  2989. app.addT<X86Test_AllocIfElse1>();
  2990. app.addT<X86Test_AllocIfElse2>();
  2991. app.addT<X86Test_AllocIfElse3>();
  2992. app.addT<X86Test_AllocIfElse4>();
  2993. app.addT<X86Test_AllocInt8>();
  2994. app.addT<X86Test_AllocUnhandledArg>();
  2995. app.addT<X86Test_AllocArgsIntPtr>();
  2996. app.addT<X86Test_AllocArgsFloat>();
  2997. app.addT<X86Test_AllocArgsDouble>();
  2998. app.addT<X86Test_AllocRetFloat1>();
  2999. app.addT<X86Test_AllocRetFloat2>();
  3000. app.addT<X86Test_AllocRetDouble1>();
  3001. app.addT<X86Test_AllocRetDouble2>();
  3002. app.addT<X86Test_AllocStack>();
  3003. app.addT<X86Test_AllocMemcpy>();
  3004. app.addT<X86Test_AllocExtraBlock>();
  3005. app.addT<X86Test_AllocAlphaBlend>();
  3006. // Function call tests.
  3007. app.addT<X86Test_FuncCallBase1>();
  3008. app.addT<X86Test_FuncCallBase2>();
  3009. app.addT<X86Test_FuncCallStd>();
  3010. app.addT<X86Test_FuncCallFast>();
  3011. app.addT<X86Test_FuncCallLight>();
  3012. app.addT<X86Test_FuncCallManyArgs>();
  3013. app.addT<X86Test_FuncCallDuplicateArgs>();
  3014. app.addT<X86Test_FuncCallImmArgs>();
  3015. app.addT<X86Test_FuncCallPtrArgs>();
  3016. app.addT<X86Test_FuncCallRefArgs>();
  3017. app.addT<X86Test_FuncCallFloatAsXmmRet>();
  3018. app.addT<X86Test_FuncCallDoubleAsXmmRet>();
  3019. app.addT<X86Test_FuncCallConditional>();
  3020. app.addT<X86Test_FuncCallMultiple>();
  3021. app.addT<X86Test_FuncCallRecursive>();
  3022. app.addT<X86Test_FuncCallVarArg1>();
  3023. app.addT<X86Test_FuncCallVarArg2>();
  3024. app.addT<X86Test_FuncCallMisc1>();
  3025. app.addT<X86Test_FuncCallMisc2>();
  3026. app.addT<X86Test_FuncCallMisc3>();
  3027. app.addT<X86Test_FuncCallMisc4>();
  3028. app.addT<X86Test_FuncCallMisc5>();
  3029. // Miscellaneous tests.
  3030. app.addT<X86Test_MiscLocalConstPool>();
  3031. app.addT<X86Test_MiscGlobalConstPool>();
  3032. app.addT<X86Test_MiscMultiRet>();
  3033. app.addT<X86Test_MiscMultiFunc>();
  3034. app.addT<X86Test_MiscUnfollow>();
  3035. return app.run();
  3036. }