1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027 |
- // [AsmJit]
- // Machine Code Generation for C++.
- //
- // [License]
- // Zlib - See LICENSE.md file in the package.
- #include <setjmp.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "./asmjit.h"
- #include "./asmjit_test_misc.h"
- using namespace asmjit;
- // ============================================================================
- // [CmdLine]
- // ============================================================================
- class CmdLine {
- public:
- CmdLine(int argc, const char* const* argv) noexcept
- : _argc(argc),
- _argv(argv) {}
- bool hasArg(const char* arg) noexcept {
- for (int i = 1; i < _argc; i++)
- if (strcmp(_argv[i], arg) == 0)
- return true;
- return false;
- }
- int _argc;
- const char* const* _argv;
- };
- // ============================================================================
- // [SimpleErrorHandler]
- // ============================================================================
- class SimpleErrorHandler : public ErrorHandler {
- public:
- SimpleErrorHandler() : _err(kErrorOk) {}
- virtual void handleError(Error err, const char* message, BaseEmitter* origin) {
- ASMJIT_UNUSED(origin);
- _err = err;
- _message.assignString(message);
- }
- Error _err;
- String _message;
- };
- // ============================================================================
- // [X86Test]
- // ============================================================================
- //! Base test interface for testing `x86::Compiler`.
- class X86Test {
- public:
- X86Test(const char* name = nullptr) { _name.assignString(name); }
- virtual ~X86Test() {}
- inline const char* name() const { return _name.data(); }
- virtual void compile(x86::Compiler& c) = 0;
- virtual bool run(void* func, String& result, String& expect) = 0;
- String _name;
- };
- // ============================================================================
- // [X86TestApp]
- // ============================================================================
- class X86TestApp {
- public:
- Zone _zone;
- ZoneAllocator _allocator;
- ZoneVector<X86Test*> _tests;
- unsigned _nFailed;
- size_t _outputSize;
- bool _verbose;
- bool _dumpAsm;
- X86TestApp() noexcept
- : _zone(8096 - Zone::kBlockOverhead),
- _allocator(&_zone),
- _nFailed(0),
- _outputSize(0),
- _verbose(false),
- _dumpAsm(false) {}
- ~X86TestApp() noexcept {
- for (X86Test* test : _tests)
- delete test;
- }
- Error add(X86Test* test) noexcept{
- return _tests.append(&_allocator, test);
- }
- template<class T>
- inline void addT() { T::add(*this); }
- int handleArgs(int argc, const char* const* argv);
- void showInfo();
- int run();
- };
- int X86TestApp::handleArgs(int argc, const char* const* argv) {
- CmdLine cmd(argc, argv);
- if (cmd.hasArg("--verbose")) _verbose = true;
- if (cmd.hasArg("--dump-asm")) _dumpAsm = true;
- return 0;
- }
- void X86TestApp::showInfo() {
- printf("AsmJit Compiler Test-Suite v%u.%u.%u [Arch=%s]:\n",
- unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
- unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
- unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF),
- sizeof(void*) == 8 ? "X64" : "X86");
- printf(" [%s] Verbose (use --verbose to turn verbose output ON)\n", _verbose ? "x" : " ");
- printf(" [%s] DumpAsm (use --dump-asm to turn assembler dumps ON)\n", _dumpAsm ? "x" : " ");
- printf("\n");
- }
- int X86TestApp::run() {
- #ifndef ASMJIT_NO_LOGGING
- uint32_t kFormatFlags = FormatOptions::kFlagMachineCode |
- FormatOptions::kFlagExplainImms |
- FormatOptions::kFlagRegCasts |
- FormatOptions::kFlagAnnotations |
- FormatOptions::kFlagDebugPasses |
- FormatOptions::kFlagDebugRA ;
- FileLogger fileLogger(stdout);
- fileLogger.addFlags(kFormatFlags);
- StringLogger stringLogger;
- stringLogger.addFlags(kFormatFlags);
- #endif
- for (X86Test* test : _tests) {
- JitRuntime runtime;
- CodeHolder code;
- SimpleErrorHandler errorHandler;
- code.init(runtime.codeInfo());
- code.setErrorHandler(&errorHandler);
- #ifndef ASMJIT_NO_LOGGING
- if (_verbose) {
- code.setLogger(&fileLogger);
- }
- else {
- stringLogger.clear();
- code.setLogger(&stringLogger);
- }
- #endif
- printf("[Test] %s", test->name());
- #ifndef ASMJIT_NO_LOGGING
- if (_verbose) printf("\n");
- #endif
- x86::Compiler cc(&code);
- test->compile(cc);
- Error err = errorHandler._err;
- if (!err)
- err = cc.finalize();
- void* func;
- #ifndef ASMJIT_NO_LOGGING
- if (_dumpAsm) {
- if (!_verbose) printf("\n");
- String sb;
- cc.dump(sb, kFormatFlags);
- printf("%s", sb.data());
- }
- #endif
- if (err == kErrorOk)
- err = runtime.add(&func, &code);
- if (_verbose)
- fflush(stdout);
- if (err == kErrorOk) {
- _outputSize += code.codeSize();
- StringTmp<128> result;
- StringTmp<128> expect;
- if (test->run(func, result, expect)) {
- if (!_verbose) printf(" [OK]\n");
- }
- else {
- if (!_verbose) printf(" [FAILED]\n");
- #ifndef ASMJIT_NO_LOGGING
- if (!_verbose) printf("%s", stringLogger.data());
- #endif
- printf("[Status]\n");
- printf(" Returned: %s\n", result.data());
- printf(" Expected: %s\n", expect.data());
- _nFailed++;
- }
- if (_dumpAsm)
- printf("\n");
- runtime.release(func);
- }
- else {
- if (!_verbose) printf(" [FAILED]\n");
- #ifndef ASMJIT_NO_LOGGING
- if (!_verbose) printf("%s", stringLogger.data());
- #endif
- printf("[Status]\n");
- printf(" ERROR 0x%08X: %s\n", unsigned(err), errorHandler._message.data());
- _nFailed++;
- }
- }
- if (_nFailed == 0)
- printf("\n[PASSED] All %u tests passed\n", unsigned(_tests.size()));
- else
- printf("\n[FAILED] %u %s of %u failed\n", _nFailed, _nFailed == 1 ? "test" : "tests", unsigned(_tests.size()));
- printf(" OutputSize=%zu\n", _outputSize);
- return _nFailed == 0 ? 0 : 1;
- }
- // ============================================================================
- // [X86Test_AlignBase]
- // ============================================================================
- class X86Test_AlignBase : public X86Test {
- public:
- X86Test_AlignBase(uint32_t argCount, uint32_t alignment, bool preserveFP)
- : _argCount(argCount),
- _alignment(alignment),
- _preserveFP(preserveFP) {
- _name.assignFormat("AlignBase {NumArgs=%u Alignment=%u PreserveFP=%c}", argCount, alignment, preserveFP ? 'Y' : 'N');
- }
- static void add(X86TestApp& app) {
- for (uint32_t i = 0; i <= 16; i++) {
- for (uint32_t a = 16; a <= 32; a += 16) {
- app.add(new X86Test_AlignBase(i, a, true));
- app.add(new X86Test_AlignBase(i, a, false));
- }
- }
- }
- virtual void compile(x86::Compiler& cc) {
- uint32_t i;
- uint32_t argCount = _argCount;
- FuncSignatureBuilder signature(CallConv::kIdHost);
- signature.setRetT<int>();
- for (i = 0; i < argCount; i++)
- signature.addArgT<int>();
- cc.addFunc(signature);
- if (_preserveFP)
- cc.func()->frame().setPreservedFP();
- x86::Gp gpVar = cc.newIntPtr("gpVar");
- x86::Gp gpSum;
- x86::Mem stack = cc.newStack(_alignment, _alignment);
- // Do a sum of arguments to verify a possible relocation when misaligned.
- if (argCount) {
- for (i = 0; i < argCount; i++) {
- x86::Gp gpArg = cc.newInt32("gpArg%u", i);
- cc.setArg(i, gpArg);
- if (i == 0)
- gpSum = gpArg;
- else
- cc.add(gpSum, gpArg);
- }
- }
- // Check alignment of xmmVar (has to be 16).
- cc.lea(gpVar, stack);
- cc.and_(gpVar, _alignment - 1);
- // Add a sum of all arguments to check if they are correct.
- if (argCount)
- cc.or_(gpVar.r32(), gpSum);
- cc.ret(gpVar);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef unsigned int U;
- typedef U (*Func0)();
- typedef U (*Func1)(U);
- typedef U (*Func2)(U, U);
- typedef U (*Func3)(U, U, U);
- typedef U (*Func4)(U, U, U, U);
- typedef U (*Func5)(U, U, U, U, U);
- typedef U (*Func6)(U, U, U, U, U, U);
- typedef U (*Func7)(U, U, U, U, U, U, U);
- typedef U (*Func8)(U, U, U, U, U, U, U, U);
- typedef U (*Func9)(U, U, U, U, U, U, U, U, U);
- typedef U (*Func10)(U, U, U, U, U, U, U, U, U, U);
- typedef U (*Func11)(U, U, U, U, U, U, U, U, U, U, U);
- typedef U (*Func12)(U, U, U, U, U, U, U, U, U, U, U, U);
- typedef U (*Func13)(U, U, U, U, U, U, U, U, U, U, U, U, U);
- typedef U (*Func14)(U, U, U, U, U, U, U, U, U, U, U, U, U, U);
- typedef U (*Func15)(U, U, U, U, U, U, U, U, U, U, U, U, U, U, U);
- typedef U (*Func16)(U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U);
- unsigned int resultRet = 0;
- unsigned int expectRet = 0;
- switch (_argCount) {
- case 0:
- resultRet = ptr_as_func<Func0>(_func)();
- expectRet = 0;
- break;
- case 1:
- resultRet = ptr_as_func<Func1>(_func)(1);
- expectRet = 1;
- break;
- case 2:
- resultRet = ptr_as_func<Func2>(_func)(1, 2);
- expectRet = 1 + 2;
- break;
- case 3:
- resultRet = ptr_as_func<Func3>(_func)(1, 2, 3);
- expectRet = 1 + 2 + 3;
- break;
- case 4:
- resultRet = ptr_as_func<Func4>(_func)(1, 2, 3, 4);
- expectRet = 1 + 2 + 3 + 4;
- break;
- case 5:
- resultRet = ptr_as_func<Func5>(_func)(1, 2, 3, 4, 5);
- expectRet = 1 + 2 + 3 + 4 + 5;
- break;
- case 6:
- resultRet = ptr_as_func<Func6>(_func)(1, 2, 3, 4, 5, 6);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6;
- break;
- case 7:
- resultRet = ptr_as_func<Func7>(_func)(1, 2, 3, 4, 5, 6, 7);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7;
- break;
- case 8:
- resultRet = ptr_as_func<Func8>(_func)(1, 2, 3, 4, 5, 6, 7, 8);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8;
- break;
- case 9:
- resultRet = ptr_as_func<Func9>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9;
- break;
- case 10:
- resultRet = ptr_as_func<Func10>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10;
- break;
- case 11:
- resultRet = ptr_as_func<Func11>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11;
- break;
- case 12:
- resultRet = ptr_as_func<Func12>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12;
- break;
- case 13:
- resultRet = ptr_as_func<Func13>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13;
- break;
- case 14:
- resultRet = ptr_as_func<Func14>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14;
- break;
- case 15:
- resultRet = ptr_as_func<Func15>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15;
- break;
- case 16:
- resultRet = ptr_as_func<Func16>(_func)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
- expectRet = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16;
- break;
- }
- result.assignFormat("ret={%u, %u}", resultRet >> 28, resultRet & 0x0FFFFFFFu);
- expect.assignFormat("ret={%u, %u}", expectRet >> 28, expectRet & 0x0FFFFFFFu);
- return resultRet == expectRet;
- }
- uint32_t _argCount;
- uint32_t _alignment;
- bool _preserveFP;
- };
- // ============================================================================
- // [X86Test_NoCode]
- // ============================================================================
- class X86Test_NoCode : public X86Test {
- public:
- X86Test_NoCode() : X86Test("NoCode") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_NoCode());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- ASMJIT_UNUSED(result);
- ASMJIT_UNUSED(expect);
- typedef void(*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- func();
- return true;
- }
- };
- // ============================================================================
- // [X86Test_AlignNone]
- // ============================================================================
- class X86Test_NoAlign : public X86Test {
- public:
- X86Test_NoAlign() : X86Test("NoAlign") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_NoAlign());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
- cc.align(kAlignCode, 0);
- cc.align(kAlignCode, 1);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- ASMJIT_UNUSED(result);
- ASMJIT_UNUSED(expect);
- typedef void (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- func();
- return true;
- }
- };
- // ============================================================================
- // [X86Test_JumpMerge]
- // ============================================================================
- class X86Test_JumpMerge : public X86Test {
- public:
- X86Test_JumpMerge() : X86Test("JumpMerge") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_JumpMerge());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, int>(CallConv::kIdHost));
- Label L0 = cc.newLabel();
- Label L1 = cc.newLabel();
- Label L2 = cc.newLabel();
- Label LEnd = cc.newLabel();
- x86::Gp dst = cc.newIntPtr("dst");
- x86::Gp val = cc.newInt32("val");
- cc.setArg(0, dst);
- cc.setArg(1, val);
- cc.cmp(val, 0);
- cc.je(L2);
- cc.cmp(val, 1);
- cc.je(L1);
- cc.cmp(val, 2);
- cc.je(L0);
- cc.mov(x86::dword_ptr(dst), val);
- cc.jmp(LEnd);
- // On purpose. This tests whether the CFG constructs a single basic-block
- // from multiple labels next to each other.
- cc.bind(L0);
- cc.bind(L1);
- cc.bind(L2);
- cc.mov(x86::dword_ptr(dst), 0);
- cc.bind(LEnd);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void(*Func)(int*, int);
- Func func = ptr_as_func<Func>(_func);
- int arr[5] = { -1, -1, -1, -1, -1 };
- int exp[5] = { 0, 0, 0, 3, 4 };
- for (int i = 0; i < 5; i++)
- func(&arr[i], i);
- result.assignFormat("ret={%d, %d, %d, %d, %d}", arr[0], arr[1], arr[2], arr[3], arr[4]);
- expect.assignFormat("ret={%d, %d, %d, %d, %d}", exp[0], exp[1], exp[2], exp[3], exp[4]);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_JumpCross]
- // ============================================================================
- class X86Test_JumpCross : public X86Test {
- public:
- X86Test_JumpCross() : X86Test("JumpCross") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_JumpCross());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
- Label L1 = cc.newLabel();
- Label L2 = cc.newLabel();
- Label L3 = cc.newLabel();
- cc.jmp(L2);
- cc.bind(L1);
- cc.jmp(L3);
- cc.bind(L2);
- cc.jmp(L1);
- cc.bind(L3);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- ASMJIT_UNUSED(result);
- ASMJIT_UNUSED(expect);
- typedef void (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- func();
- return true;
- }
- };
- // ============================================================================
- // [X86Test_JumpMany]
- // ============================================================================
- class X86Test_JumpMany : public X86Test {
- public:
- X86Test_JumpMany() : X86Test("JumpMany") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_JumpMany());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- for (uint32_t i = 0; i < 1000; i++) {
- Label L = cc.newLabel();
- cc.jmp(L);
- cc.bind(L);
- }
- x86::Gp ret = cc.newInt32("ret");
- cc.xor_(ret, ret);
- cc.ret(ret);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = 0;
- result.assignFormat("ret={%d}", resultRet);
- expect.assignFormat("ret={%d}", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_JumpUnreachable1]
- // ============================================================================
- class X86Test_JumpUnreachable1 : public X86Test {
- public:
- X86Test_JumpUnreachable1() : X86Test("JumpUnreachable1") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_JumpUnreachable1());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
- Label L_1 = cc.newLabel();
- Label L_2 = cc.newLabel();
- Label L_3 = cc.newLabel();
- Label L_4 = cc.newLabel();
- Label L_5 = cc.newLabel();
- Label L_6 = cc.newLabel();
- Label L_7 = cc.newLabel();
- x86::Gp v0 = cc.newUInt32("v0");
- x86::Gp v1 = cc.newUInt32("v1");
- cc.bind(L_2);
- cc.bind(L_3);
- cc.jmp(L_1);
- cc.bind(L_5);
- cc.mov(v0, 0);
- cc.bind(L_6);
- cc.jmp(L_3);
- cc.mov(v1, 1);
- cc.jmp(L_1);
- cc.bind(L_4);
- cc.jmp(L_2);
- cc.bind(L_7);
- cc.add(v0, v1);
- cc.align(kAlignCode, 16);
- cc.bind(L_1);
- cc.ret();
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- func();
- result.appendString("ret={}");
- expect.appendString("ret={}");
- return true;
- }
- };
- // ============================================================================
- // [X86Test_JumpUnreachable2]
- // ============================================================================
- class X86Test_JumpUnreachable2 : public X86Test {
- public:
- X86Test_JumpUnreachable2() : X86Test("JumpUnreachable2") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_JumpUnreachable2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
- Label L_1 = cc.newLabel();
- Label L_2 = cc.newLabel();
- x86::Gp v0 = cc.newUInt32("v0");
- x86::Gp v1 = cc.newUInt32("v1");
- cc.jmp(L_1);
- cc.bind(L_2);
- cc.mov(v0, 1);
- cc.mov(v1, 2);
- cc.cmp(v0, v1);
- cc.jz(L_2);
- cc.jmp(L_1);
- cc.bind(L_1);
- cc.ret();
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- func();
- result.appendString("ret={}");
- expect.appendString("ret={}");
- return true;
- }
- };
- // ============================================================================
- // [X86Test_AllocBase]
- // ============================================================================
- class X86Test_AllocBase : public X86Test {
- public:
- X86Test_AllocBase() : X86Test("AllocBase") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocBase());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- x86::Gp v0 = cc.newInt32("v0");
- x86::Gp v1 = cc.newInt32("v1");
- x86::Gp v2 = cc.newInt32("v2");
- x86::Gp v3 = cc.newInt32("v3");
- x86::Gp v4 = cc.newInt32("v4");
- cc.xor_(v0, v0);
- cc.mov(v1, 1);
- cc.mov(v2, 2);
- cc.mov(v3, 3);
- cc.mov(v4, 4);
- cc.add(v0, v1);
- cc.add(v0, v2);
- cc.add(v0, v3);
- cc.add(v0, v4);
- cc.ret(v0);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = 1 + 2 + 3 + 4;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocMany1]
- // ============================================================================
- class X86Test_AllocMany1 : public X86Test {
- public:
- X86Test_AllocMany1() : X86Test("AllocMany1") {}
- enum { kCount = 8 };
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocMany1());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, int*>(CallConv::kIdHost));
- x86::Gp a0 = cc.newIntPtr("a0");
- x86::Gp a1 = cc.newIntPtr("a1");
- cc.setArg(0, a0);
- cc.setArg(1, a1);
- // Create some variables.
- x86::Gp t = cc.newInt32("t");
- x86::Gp x[kCount];
- uint32_t i;
- // Setup variables (use mov with reg/imm to se if register allocator works).
- for (i = 0; i < kCount; i++) x[i] = cc.newInt32("x%u", i);
- for (i = 0; i < kCount; i++) cc.mov(x[i], int(i + 1));
- // Make sum (addition).
- cc.xor_(t, t);
- for (i = 0; i < kCount; i++) cc.add(t, x[i]);
- // Store result to a given pointer in first argument.
- cc.mov(x86::dword_ptr(a0), t);
- // Clear t.
- cc.xor_(t, t);
- // Make sum (subtraction).
- for (i = 0; i < kCount; i++) cc.sub(t, x[i]);
- // Store result to a given pointer in second argument.
- cc.mov(x86::dword_ptr(a1), t);
- // End of function.
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(int*, int*);
- Func func = ptr_as_func<Func>(_func);
- int resultX;
- int resultY;
- int expectX = 36;
- int expectY = -36;
- func(&resultX, &resultY);
- result.assignFormat("ret={x=%d, y=%d}", resultX, resultY);
- expect.assignFormat("ret={x=%d, y=%d}", expectX, expectY);
- return resultX == expectX && resultY == expectY;
- }
- };
- // ============================================================================
- // [X86Test_AllocMany2]
- // ============================================================================
- class X86Test_AllocMany2 : public X86Test {
- public:
- X86Test_AllocMany2() : X86Test("AllocMany2") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocMany2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, uint32_t*>(CallConv::kIdHost));
- x86::Gp a = cc.newIntPtr("a");
- x86::Gp v[32];
- uint32_t i;
- cc.setArg(0, a);
- for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) v[i] = cc.newInt32("v%d", i);
- for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.xor_(v[i], v[i]);
- x86::Gp x = cc.newInt32("x");
- Label L = cc.newLabel();
- cc.mov(x, 32);
- cc.bind(L);
- for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.add(v[i], i);
- cc.dec(x);
- cc.jnz(L);
- for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.mov(x86::dword_ptr(a, int(i * 4)), v[i]);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(uint32_t*);
- Func func = ptr_as_func<Func>(_func);
- uint32_t i;
- uint32_t resultBuf[32];
- uint32_t expectBuf[32];
- for (i = 0; i < ASMJIT_ARRAY_SIZE(resultBuf); i++)
- expectBuf[i] = i * 32;
- func(resultBuf);
- for (i = 0; i < ASMJIT_ARRAY_SIZE(resultBuf); i++) {
- if (i != 0) {
- result.appendChar(',');
- expect.appendChar(',');
- }
- result.appendFormat("%u", resultBuf[i]);
- expect.appendFormat("%u", expectBuf[i]);
- }
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocImul1]
- // ============================================================================
- class X86Test_AllocImul1 : public X86Test {
- public:
- X86Test_AllocImul1() : X86Test("AllocImul1") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocImul1());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, int*, int, int>(CallConv::kIdHost));
- x86::Gp dstHi = cc.newIntPtr("dstHi");
- x86::Gp dstLo = cc.newIntPtr("dstLo");
- x86::Gp vHi = cc.newInt32("vHi");
- x86::Gp vLo = cc.newInt32("vLo");
- x86::Gp src = cc.newInt32("src");
- cc.setArg(0, dstHi);
- cc.setArg(1, dstLo);
- cc.setArg(2, vLo);
- cc.setArg(3, src);
- cc.imul(vHi, vLo, src);
- cc.mov(x86::dword_ptr(dstHi), vHi);
- cc.mov(x86::dword_ptr(dstLo), vLo);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(int*, int*, int, int);
- Func func = ptr_as_func<Func>(_func);
- int v0 = 4;
- int v1 = 4;
- int resultHi;
- int resultLo;
- int expectHi = 0;
- int expectLo = v0 * v1;
- func(&resultHi, &resultLo, v0, v1);
- result.assignFormat("hi=%d, lo=%d", resultHi, resultLo);
- expect.assignFormat("hi=%d, lo=%d", expectHi, expectLo);
- return resultHi == expectHi && resultLo == expectLo;
- }
- };
- // ============================================================================
- // [X86Test_AllocImul2]
- // ============================================================================
- class X86Test_AllocImul2 : public X86Test {
- public:
- X86Test_AllocImul2() : X86Test("AllocImul2") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocImul2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, const int*>(CallConv::kIdHost));
- x86::Gp dst = cc.newIntPtr("dst");
- x86::Gp src = cc.newIntPtr("src");
- cc.setArg(0, dst);
- cc.setArg(1, src);
- for (unsigned int i = 0; i < 4; i++) {
- x86::Gp x = cc.newInt32("x");
- x86::Gp y = cc.newInt32("y");
- x86::Gp hi = cc.newInt32("hi");
- cc.mov(x, x86::dword_ptr(src, 0));
- cc.mov(y, x86::dword_ptr(src, 4));
- cc.imul(hi, x, y);
- cc.add(x86::dword_ptr(dst, 0), hi);
- cc.add(x86::dword_ptr(dst, 4), x);
- }
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(int*, const int*);
- Func func = ptr_as_func<Func>(_func);
- int src[2] = { 4, 9 };
- int resultRet[2] = { 0, 0 };
- int expectRet[2] = { 0, (4 * 9) * 4 };
- func(resultRet, src);
- result.assignFormat("ret={%d, %d}", resultRet[0], resultRet[1]);
- expect.assignFormat("ret={%d, %d}", expectRet[0], expectRet[1]);
- return resultRet[0] == expectRet[0] && resultRet[1] == expectRet[1];
- }
- };
- // ============================================================================
- // [X86Test_AllocIdiv1]
- // ============================================================================
- class X86Test_AllocIdiv1 : public X86Test {
- public:
- X86Test_AllocIdiv1() : X86Test("AllocIdiv1") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocIdiv1());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
- x86::Gp a = cc.newInt32("a");
- x86::Gp b = cc.newInt32("b");
- x86::Gp dummy = cc.newInt32("dummy");
- cc.setArg(0, a);
- cc.setArg(1, b);
- cc.xor_(dummy, dummy);
- cc.idiv(dummy, a, b);
- cc.ret(a);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int);
- Func func = ptr_as_func<Func>(_func);
- int v0 = 2999;
- int v1 = 245;
- int resultRet = func(v0, v1);
- int expectRet = 2999 / 245;
- result.assignFormat("result=%d", resultRet);
- expect.assignFormat("result=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocSetz]
- // ============================================================================
- class X86Test_AllocSetz : public X86Test {
- public:
- X86Test_AllocSetz() : X86Test("AllocSetz") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocSetz());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int, int, char*>(CallConv::kIdHost));
- x86::Gp src0 = cc.newInt32("src0");
- x86::Gp src1 = cc.newInt32("src1");
- x86::Gp dst0 = cc.newIntPtr("dst0");
- cc.setArg(0, src0);
- cc.setArg(1, src1);
- cc.setArg(2, dst0);
- cc.cmp(src0, src1);
- cc.setz(x86::byte_ptr(dst0));
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(int, int, char*);
- Func func = ptr_as_func<Func>(_func);
- char resultBuf[4];
- char expectBuf[4] = { 1, 0, 0, 1 };
- func(0, 0, &resultBuf[0]); // We are expecting 1 (0 == 0).
- func(0, 1, &resultBuf[1]); // We are expecting 0 (0 != 1).
- func(1, 0, &resultBuf[2]); // We are expecting 0 (1 != 0).
- func(1, 1, &resultBuf[3]); // We are expecting 1 (1 == 1).
- result.assignFormat("out={%d, %d, %d, %d}", resultBuf[0], resultBuf[1], resultBuf[2], resultBuf[3]);
- expect.assignFormat("out={%d, %d, %d, %d}", expectBuf[0], expectBuf[1], expectBuf[2], expectBuf[3]);
- return resultBuf[0] == expectBuf[0] &&
- resultBuf[1] == expectBuf[1] &&
- resultBuf[2] == expectBuf[2] &&
- resultBuf[3] == expectBuf[3] ;
- }
- };
- // ============================================================================
- // [X86Test_AllocShlRor]
- // ============================================================================
- class X86Test_AllocShlRor : public X86Test {
- public:
- X86Test_AllocShlRor() : X86Test("AllocShlRor") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocShlRor());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, int, int, int>(CallConv::kIdHost));
- x86::Gp dst = cc.newIntPtr("dst");
- x86::Gp var = cc.newInt32("var");
- x86::Gp vShlParam = cc.newInt32("vShlParam");
- x86::Gp vRorParam = cc.newInt32("vRorParam");
- cc.setArg(0, dst);
- cc.setArg(1, var);
- cc.setArg(2, vShlParam);
- cc.setArg(3, vRorParam);
- cc.shl(var, vShlParam);
- cc.ror(var, vRorParam);
- cc.mov(x86::dword_ptr(dst), var);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(int*, int, int, int);
- Func func = ptr_as_func<Func>(_func);
- int v0 = 0x000000FF;
- int resultRet;
- int expectRet = 0x0000FF00;
- func(&resultRet, v0, 16, 8);
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocGpbLo]
- // ============================================================================
- class X86Test_AllocGpbLo1 : public X86Test {
- public:
- X86Test_AllocGpbLo1() : X86Test("AllocGpbLo1") {}
- enum { kCount = 32 };
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocGpbLo1());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<uint32_t, uint32_t*>(CallConv::kIdHost));
- x86::Gp rPtr = cc.newUIntPtr("rPtr");
- x86::Gp rSum = cc.newUInt32("rSum");
- cc.setArg(0, rPtr);
- x86::Gp x[kCount];
- uint32_t i;
- for (i = 0; i < kCount; i++) {
- x[i] = cc.newUInt32("x%u", i);
- }
- // Init pseudo-regs with values from our array.
- for (i = 0; i < kCount; i++) {
- cc.mov(x[i], x86::dword_ptr(rPtr, int(i * 4)));
- }
- for (i = 2; i < kCount; i++) {
- // Add and truncate to 8 bit; no purpose, just mess with jit.
- cc.add (x[i ], x[i-1]);
- cc.movzx(x[i ], x[i ].r8());
- cc.movzx(x[i-2], x[i-1].r8());
- cc.movzx(x[i-1], x[i-2].r8());
- }
- // Sum up all computed values.
- cc.mov(rSum, 0);
- for (i = 0; i < kCount; i++) {
- cc.add(rSum, x[i]);
- }
- // Return the sum.
- cc.ret(rSum);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef uint32_t (*Func)(uint32_t*);
- Func func = ptr_as_func<Func>(_func);
- uint32_t i;
- uint32_t buf[kCount];
- uint32_t resultRet;
- uint32_t expectRet;
- expectRet = 0;
- for (i = 0; i < kCount; i++) {
- buf[i] = 1;
- }
- for (i = 2; i < kCount; i++) {
- buf[i ]+= buf[i-1];
- buf[i ] = buf[i ] & 0xFF;
- buf[i-2] = buf[i-1] & 0xFF;
- buf[i-1] = buf[i-2] & 0xFF;
- }
- for (i = 0; i < kCount; i++) {
- expectRet += buf[i];
- }
- for (i = 0; i < kCount; i++) {
- buf[i] = 1;
- }
- resultRet = func(buf);
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocGpbLo2]
- // ============================================================================
- class X86Test_AllocGpbLo2 : public X86Test {
- public:
- X86Test_AllocGpbLo2() : X86Test("AllocGpbLo2") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocGpbLo2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<uint32_t, uint32_t>(CallConv::kIdHost));
- x86::Gp v = cc.newUInt32("v");
- cc.setArg(0, v);
- cc.mov(v.r8(), 0xFF);
- cc.ret(v);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef uint32_t (*Func)(uint32_t);
- Func func = ptr_as_func<Func>(_func);
- uint32_t resultRet = func(0x12345678u);
- uint32_t expectRet = 0x123456FFu;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocRepMovsb]
- // ============================================================================
- class X86Test_AllocRepMovsb : public X86Test {
- public:
- X86Test_AllocRepMovsb() : X86Test("AllocRepMovsb") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocRepMovsb());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, void*, void*, size_t>(CallConv::kIdHost));
- x86::Gp dst = cc.newIntPtr("dst");
- x86::Gp src = cc.newIntPtr("src");
- x86::Gp cnt = cc.newIntPtr("cnt");
- cc.setArg(0, dst);
- cc.setArg(1, src);
- cc.setArg(2, cnt);
- cc.rep(cnt).movs(x86::byte_ptr(dst), x86::byte_ptr(src));
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(void*, void*, size_t);
- Func func = ptr_as_func<Func>(_func);
- char dst[20] = { 0 };
- char src[20] = "Hello AsmJit!";
- func(dst, src, strlen(src) + 1);
- result.assignFormat("ret=\"%s\"", dst);
- expect.assignFormat("ret=\"%s\"", src);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocIfElse1]
- // ============================================================================
- class X86Test_AllocIfElse1 : public X86Test {
- public:
- X86Test_AllocIfElse1() : X86Test("AllocIfElse1") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocIfElse1());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
- x86::Gp v1 = cc.newInt32("v1");
- x86::Gp v2 = cc.newInt32("v2");
- Label L_1 = cc.newLabel();
- Label L_2 = cc.newLabel();
- cc.setArg(0, v1);
- cc.setArg(1, v2);
- cc.cmp(v1, v2);
- cc.jg(L_1);
- cc.mov(v1, 1);
- cc.jmp(L_2);
- cc.bind(L_1);
- cc.mov(v1, 2);
- cc.bind(L_2);
- cc.ret(v1);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int);
- Func func = ptr_as_func<Func>(_func);
- int a = func(0, 1);
- int b = func(1, 0);
- result.appendFormat("ret={%d, %d}", a, b);
- expect.appendFormat("ret={%d, %d}", 1, 2);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocIfElse2]
- // ============================================================================
- class X86Test_AllocIfElse2 : public X86Test {
- public:
- X86Test_AllocIfElse2() : X86Test("AllocIfElse2") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocIfElse2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
- x86::Gp v1 = cc.newInt32("v1");
- x86::Gp v2 = cc.newInt32("v2");
- Label L_1 = cc.newLabel();
- Label L_2 = cc.newLabel();
- Label L_3 = cc.newLabel();
- Label L_4 = cc.newLabel();
- cc.setArg(0, v1);
- cc.setArg(1, v2);
- cc.jmp(L_1);
- cc.bind(L_2);
- cc.jmp(L_4);
- cc.bind(L_1);
- cc.cmp(v1, v2);
- cc.jg(L_3);
- cc.mov(v1, 1);
- cc.jmp(L_2);
- cc.bind(L_3);
- cc.mov(v1, 2);
- cc.jmp(L_2);
- cc.bind(L_4);
- cc.ret(v1);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int);
- Func func = ptr_as_func<Func>(_func);
- int a = func(0, 1);
- int b = func(1, 0);
- result.appendFormat("ret={%d, %d}", a, b);
- expect.appendFormat("ret={%d, %d}", 1, 2);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocIfElse3]
- // ============================================================================
- class X86Test_AllocIfElse3 : public X86Test {
- public:
- X86Test_AllocIfElse3() : X86Test("AllocIfElse3") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocIfElse3());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
- x86::Gp v1 = cc.newInt32("v1");
- x86::Gp v2 = cc.newInt32("v2");
- x86::Gp counter = cc.newInt32("counter");
- Label L_1 = cc.newLabel();
- Label L_Loop = cc.newLabel();
- Label L_Exit = cc.newLabel();
- cc.setArg(0, v1);
- cc.setArg(1, v2);
- cc.cmp(v1, v2);
- cc.jg(L_1);
- cc.mov(counter, 0);
- cc.bind(L_Loop);
- cc.mov(v1, counter);
- cc.inc(counter);
- cc.cmp(counter, 1);
- cc.jle(L_Loop);
- cc.jmp(L_Exit);
- cc.bind(L_1);
- cc.mov(v1, 2);
- cc.bind(L_Exit);
- cc.ret(v1);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int);
- Func func = ptr_as_func<Func>(_func);
- int a = func(0, 1);
- int b = func(1, 0);
- result.appendFormat("ret={%d, %d}", a, b);
- expect.appendFormat("ret={%d, %d}", 1, 2);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocIfElse4]
- // ============================================================================
- class X86Test_AllocIfElse4 : public X86Test {
- public:
- X86Test_AllocIfElse4() : X86Test("AllocIfElse4") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocIfElse4());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
- x86::Gp v1 = cc.newInt32("v1");
- x86::Gp v2 = cc.newInt32("v2");
- x86::Gp counter = cc.newInt32("counter");
- Label L_1 = cc.newLabel();
- Label L_Loop1 = cc.newLabel();
- Label L_Loop2 = cc.newLabel();
- Label L_Exit = cc.newLabel();
- cc.mov(counter, 0);
- cc.setArg(0, v1);
- cc.setArg(1, v2);
- cc.cmp(v1, v2);
- cc.jg(L_1);
- cc.bind(L_Loop1);
- cc.mov(v1, counter);
- cc.inc(counter);
- cc.cmp(counter, 1);
- cc.jle(L_Loop1);
- cc.jmp(L_Exit);
- cc.bind(L_1);
- cc.bind(L_Loop2);
- cc.mov(v1, counter);
- cc.inc(counter);
- cc.cmp(counter, 2);
- cc.jle(L_Loop2);
- cc.bind(L_Exit);
- cc.ret(v1);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int);
- Func func = ptr_as_func<Func>(_func);
- int a = func(0, 1);
- int b = func(1, 0);
- result.appendFormat("ret={%d, %d}", a, b);
- expect.appendFormat("ret={%d, %d}", 1, 2);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocInt8]
- // ============================================================================
- class X86Test_AllocInt8 : public X86Test {
- public:
- X86Test_AllocInt8() : X86Test("AllocInt8") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocInt8());
- }
- virtual void compile(x86::Compiler& cc) {
- x86::Gp x = cc.newInt8("x");
- x86::Gp y = cc.newInt32("y");
- cc.addFunc(FuncSignatureT<int, char>(CallConv::kIdHost));
- cc.setArg(0, x);
- cc.movsx(y, x);
- cc.ret(y);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(char);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func(-13);
- int expectRet = -13;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocUnhandledArg]
- // ============================================================================
- class X86Test_AllocUnhandledArg : public X86Test {
- public:
- X86Test_AllocUnhandledArg() : X86Test("AllocUnhandledArg") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocUnhandledArg());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- x86::Gp x = cc.newInt32("x");
- cc.setArg(2, x);
- cc.ret(x);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int, int);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func(42, 155, 199);
- int expectRet = 199;
- result.assignFormat("ret={%d}", resultRet);
- expect.assignFormat("ret={%d}", expectRet);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocArgsIntPtr]
- // ============================================================================
- class X86Test_AllocArgsIntPtr : public X86Test {
- public:
- X86Test_AllocArgsIntPtr() : X86Test("AllocArgsIntPtr") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocArgsIntPtr());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, void*, void*, void*, void*, void*, void*, void*, void*>(CallConv::kIdHost));
- uint32_t i;
- x86::Gp var[8];
- for (i = 0; i < 8; i++) {
- var[i] = cc.newIntPtr("var%u", i);
- cc.setArg(i, var[i]);
- }
- for (i = 0; i < 8; i++) {
- cc.add(var[i], int(i + 1));
- }
- // Move some data into buffer provided by arguments so we can verify if it
- // really works without looking into assembler output.
- for (i = 0; i < 8; i++) {
- cc.add(x86::byte_ptr(var[i]), int(i + 1));
- }
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(void*, void*, void*, void*, void*, void*, void*, void*);
- Func func = ptr_as_func<Func>(_func);
- uint8_t resultBuf[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- uint8_t expectBuf[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
- func(resultBuf, resultBuf, resultBuf, resultBuf,
- resultBuf, resultBuf, resultBuf, resultBuf);
- result.assignFormat("buf={%d, %d, %d, %d, %d, %d, %d, %d, %d}",
- resultBuf[0], resultBuf[1], resultBuf[2], resultBuf[3],
- resultBuf[4], resultBuf[5], resultBuf[6], resultBuf[7],
- resultBuf[8]);
- expect.assignFormat("buf={%d, %d, %d, %d, %d, %d, %d, %d, %d}",
- expectBuf[0], expectBuf[1], expectBuf[2], expectBuf[3],
- expectBuf[4], expectBuf[5], expectBuf[6], expectBuf[7],
- expectBuf[8]);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocArgsFloat]
- // ============================================================================
- class X86Test_AllocArgsFloat : public X86Test {
- public:
- X86Test_AllocArgsFloat() : X86Test("AllocArgsFloat") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocArgsFloat());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, float, float, float, float, float, float, float, void*>(CallConv::kIdHost));
- uint32_t i;
- x86::Gp p = cc.newIntPtr("p");
- x86::Xmm xv[7];
- for (i = 0; i < 7; i++) {
- xv[i] = cc.newXmmSs("xv%u", i);
- cc.setArg(i, xv[i]);
- }
- cc.setArg(7, p);
- cc.addss(xv[0], xv[1]);
- cc.addss(xv[0], xv[2]);
- cc.addss(xv[0], xv[3]);
- cc.addss(xv[0], xv[4]);
- cc.addss(xv[0], xv[5]);
- cc.addss(xv[0], xv[6]);
- cc.movss(x86::ptr(p), xv[0]);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(float, float, float, float, float, float, float, float*);
- Func func = ptr_as_func<Func>(_func);
- float resultRet;
- float expectRet = 1.0f + 2.0f + 3.0f + 4.0f + 5.0f + 6.0f + 7.0f;
- func(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, &resultRet);
- result.assignFormat("ret={%g}", resultRet);
- expect.assignFormat("ret={%g}", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocArgsDouble]
- // ============================================================================
- class X86Test_AllocArgsDouble : public X86Test {
- public:
- X86Test_AllocArgsDouble() : X86Test("AllocArgsDouble") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocArgsDouble());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, double, double, double, double, double, double, double, void*>(CallConv::kIdHost));
- uint32_t i;
- x86::Gp p = cc.newIntPtr("p");
- x86::Xmm xv[7];
- for (i = 0; i < 7; i++) {
- xv[i] = cc.newXmmSd("xv%u", i);
- cc.setArg(i, xv[i]);
- }
- cc.setArg(7, p);
- cc.addsd(xv[0], xv[1]);
- cc.addsd(xv[0], xv[2]);
- cc.addsd(xv[0], xv[3]);
- cc.addsd(xv[0], xv[4]);
- cc.addsd(xv[0], xv[5]);
- cc.addsd(xv[0], xv[6]);
- cc.movsd(x86::ptr(p), xv[0]);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(double, double, double, double, double, double, double, double*);
- Func func = ptr_as_func<Func>(_func);
- double resultRet;
- double expectRet = 1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0;
- func(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, &resultRet);
- result.assignFormat("ret={%g}", resultRet);
- expect.assignFormat("ret={%g}", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocRetFloat1]
- // ============================================================================
- class X86Test_AllocRetFloat1 : public X86Test {
- public:
- X86Test_AllocRetFloat1() : X86Test("AllocRetFloat1") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocRetFloat1());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<float, float>(CallConv::kIdHost));
- x86::Xmm x = cc.newXmmSs("x");
- cc.setArg(0, x);
- cc.ret(x);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef float (*Func)(float);
- Func func = ptr_as_func<Func>(_func);
- float resultRet = func(42.0f);
- float expectRet = 42.0f;
- result.assignFormat("ret={%g}", resultRet);
- expect.assignFormat("ret={%g}", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocRetFloat2]
- // ============================================================================
- class X86Test_AllocRetFloat2 : public X86Test {
- public:
- X86Test_AllocRetFloat2() : X86Test("AllocRetFloat2") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocRetFloat2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<float, float, float>(CallConv::kIdHost));
- x86::Xmm x = cc.newXmmSs("x");
- x86::Xmm y = cc.newXmmSs("y");
- cc.setArg(0, x);
- cc.setArg(1, y);
- cc.addss(x, y);
- cc.ret(x);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef float (*Func)(float, float);
- Func func = ptr_as_func<Func>(_func);
- float resultRet = func(1.0f, 2.0f);
- float expectRet = 1.0f + 2.0f;
- result.assignFormat("ret={%g}", resultRet);
- expect.assignFormat("ret={%g}", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocRetDouble1]
- // ============================================================================
- class X86Test_AllocRetDouble1 : public X86Test {
- public:
- X86Test_AllocRetDouble1() : X86Test("AllocRetDouble1") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocRetDouble1());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, double>(CallConv::kIdHost));
- x86::Xmm x = cc.newXmmSd("x");
- cc.setArg(0, x);
- cc.ret(x);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef double (*Func)(double);
- Func func = ptr_as_func<Func>(_func);
- double resultRet = func(42.0);
- double expectRet = 42.0;
- result.assignFormat("ret={%g}", resultRet);
- expect.assignFormat("ret={%g}", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocRetDouble2]
- // ============================================================================
- class X86Test_AllocRetDouble2 : public X86Test {
- public:
- X86Test_AllocRetDouble2() : X86Test("AllocRetDouble2") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocRetDouble2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, double, double>(CallConv::kIdHost));
- x86::Xmm x = cc.newXmmSd("x");
- x86::Xmm y = cc.newXmmSd("y");
- cc.setArg(0, x);
- cc.setArg(1, y);
- cc.addsd(x, y);
- cc.ret(x);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef double (*Func)(double, double);
- Func func = ptr_as_func<Func>(_func);
- double resultRet = func(1.0, 2.0);
- double expectRet = 1.0 + 2.0;
- result.assignFormat("ret={%g}", resultRet);
- expect.assignFormat("ret={%g}", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocStack]
- // ============================================================================
- class X86Test_AllocStack : public X86Test {
- public:
- X86Test_AllocStack() : X86Test("AllocStack") {}
- enum { kSize = 256 };
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocStack());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- x86::Mem stack = cc.newStack(kSize, 1);
- stack.setSize(1);
- x86::Gp i = cc.newIntPtr("i");
- x86::Gp a = cc.newInt32("a");
- x86::Gp b = cc.newInt32("b");
- Label L_1 = cc.newLabel();
- Label L_2 = cc.newLabel();
- // Fill stack by sequence [0, 1, 2, 3 ... 255].
- cc.xor_(i, i);
- x86::Mem stackWithIndex = stack.clone();
- stackWithIndex.setIndex(i, 0);
- cc.bind(L_1);
- cc.mov(stackWithIndex, i.r8());
- cc.inc(i);
- cc.cmp(i, 255);
- cc.jle(L_1);
- // Sum sequence in stack.
- cc.xor_(i, i);
- cc.xor_(a, a);
- cc.bind(L_2);
- cc.movzx(b, stackWithIndex);
- cc.add(a, b);
- cc.inc(i);
- cc.cmp(i, 255);
- cc.jle(L_2);
- cc.ret(a);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = 32640;
- result.assignInt(resultRet);
- expect.assignInt(expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_AllocMemcpy]
- // ============================================================================
- class X86Test_AllocMemcpy : public X86Test {
- public:
- X86Test_AllocMemcpy() : X86Test("AllocMemcpy") {}
- enum { kCount = 32 };
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocMemcpy());
- }
- virtual void compile(x86::Compiler& cc) {
- x86::Gp dst = cc.newIntPtr("dst");
- x86::Gp src = cc.newIntPtr("src");
- x86::Gp cnt = cc.newUIntPtr("cnt");
- Label L_Loop = cc.newLabel(); // Create base labels we use
- Label L_Exit = cc.newLabel(); // in our function.
- cc.addFunc(FuncSignatureT<void, uint32_t*, const uint32_t*, size_t>(CallConv::kIdHost));
- cc.setArg(0, dst);
- cc.setArg(1, src);
- cc.setArg(2, cnt);
- cc.test(cnt, cnt); // Exit if the size is zero.
- cc.jz(L_Exit);
- cc.bind(L_Loop); // Bind the loop label here.
- x86::Gp tmp = cc.newInt32("tmp"); // Copy a single dword (4 bytes).
- cc.mov(tmp, x86::dword_ptr(src));
- cc.mov(x86::dword_ptr(dst), tmp);
- cc.add(src, 4); // Increment dst/src pointers.
- cc.add(dst, 4);
- cc.dec(cnt); // Loop until cnt isn't zero.
- cc.jnz(L_Loop);
- cc.bind(L_Exit); // Bind the exit label here.
- cc.endFunc(); // End of function.
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(uint32_t*, const uint32_t*, size_t);
- Func func = ptr_as_func<Func>(_func);
- uint32_t i;
- uint32_t dstBuffer[kCount];
- uint32_t srcBuffer[kCount];
- for (i = 0; i < kCount; i++) {
- dstBuffer[i] = 0;
- srcBuffer[i] = i;
- }
- func(dstBuffer, srcBuffer, kCount);
- result.assignString("buf={");
- expect.assignString("buf={");
- for (i = 0; i < kCount; i++) {
- if (i != 0) {
- result.appendString(", ");
- expect.appendString(", ");
- }
- result.appendFormat("%u", unsigned(dstBuffer[i]));
- expect.appendFormat("%u", unsigned(srcBuffer[i]));
- }
- result.appendString("}");
- expect.appendString("}");
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocExtraBlock]
- // ============================================================================
- class X86Test_AllocExtraBlock : public X86Test {
- public:
- X86Test_AllocExtraBlock() : X86Test("AllocExtraBlock") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocExtraBlock());
- }
- virtual void compile(x86::Compiler& cc) {
- x86::Gp cond = cc.newInt32("cond");
- x86::Gp ret = cc.newInt32("ret");
- x86::Gp a = cc.newInt32("a");
- x86::Gp b = cc.newInt32("b");
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- cc.setArg(0, cond);
- cc.setArg(1, a);
- cc.setArg(2, b);
- Label L_Ret = cc.newLabel();
- Label L_Extra = cc.newLabel();
- cc.test(cond, cond);
- cc.jnz(L_Extra);
- cc.mov(ret, a);
- cc.add(ret, b);
- cc.bind(L_Ret);
- cc.ret(ret);
- // Emit code sequence at the end of the function.
- BaseNode* prevCursor = cc.setCursor(cc.func()->endNode()->prev());
- cc.bind(L_Extra);
- cc.mov(ret, a);
- cc.sub(ret, b);
- cc.jmp(L_Ret);
- cc.setCursor(prevCursor);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int, int);
- Func func = ptr_as_func<Func>(_func);
- int ret1 = func(0, 4, 5);
- int ret2 = func(1, 4, 5);
- int exp1 = 4 + 5;
- int exp2 = 4 - 5;
- result.assignFormat("ret={%d, %d}", ret1, ret2);
- expect.assignFormat("ret={%d, %d}", exp1, exp2);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_AllocAlphaBlend]
- // ============================================================================
- class X86Test_AllocAlphaBlend : public X86Test {
- public:
- X86Test_AllocAlphaBlend() : X86Test("AllocAlphaBlend") {}
- enum { kCount = 17 };
- static void add(X86TestApp& app) {
- app.add(new X86Test_AllocAlphaBlend());
- }
- static uint32_t blendSrcOver(uint32_t d, uint32_t s) {
- uint32_t saInv = ~s >> 24;
- uint32_t d_20 = (d ) & 0x00FF00FF;
- uint32_t d_31 = (d >> 8) & 0x00FF00FF;
- d_20 *= saInv;
- d_31 *= saInv;
- d_20 = ((d_20 + ((d_20 >> 8) & 0x00FF00FFu) + 0x00800080u) & 0xFF00FF00u) >> 8;
- d_31 = ((d_31 + ((d_31 >> 8) & 0x00FF00FFu) + 0x00800080u) & 0xFF00FF00u);
- return d_20 + d_31 + s;
- }
- virtual void compile(x86::Compiler& cc) {
- asmtest::generateAlphaBlend(cc);
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(void*, const void*, size_t);
- Func func = ptr_as_func<Func>(_func);
- static const uint32_t dstConstData[] = { 0x00000000, 0x10101010, 0x20100804, 0x30200003, 0x40204040, 0x5000004D, 0x60302E2C, 0x706F6E6D, 0x807F4F2F, 0x90349001, 0xA0010203, 0xB03204AB, 0xC023AFBD, 0xD0D0D0C0, 0xE0AABBCC, 0xFFFFFFFF, 0xF8F4F2F1 };
- static const uint32_t srcConstData[] = { 0xE0E0E0E0, 0xA0008080, 0x341F1E1A, 0xFEFEFEFE, 0x80302010, 0x49490A0B, 0x998F7798, 0x00000000, 0x01010101, 0xA0264733, 0xBAB0B1B9, 0xFF000000, 0xDAB0A0C1, 0xE0BACFDA, 0x99887766, 0xFFFFFF80, 0xEE0A5FEC };
- uint32_t _dstBuffer[kCount + 3];
- uint32_t _srcBuffer[kCount + 3];
- // Has to be aligned.
- uint32_t* dstBuffer = (uint32_t*)Support::alignUp<intptr_t>((intptr_t)_dstBuffer, 16);
- uint32_t* srcBuffer = (uint32_t*)Support::alignUp<intptr_t>((intptr_t)_srcBuffer, 16);
- memcpy(dstBuffer, dstConstData, sizeof(dstConstData));
- memcpy(srcBuffer, srcConstData, sizeof(srcConstData));
- uint32_t i;
- uint32_t expBuffer[kCount];
- for (i = 0; i < kCount; i++) {
- expBuffer[i] = blendSrcOver(dstBuffer[i], srcBuffer[i]);
- }
- func(dstBuffer, srcBuffer, kCount);
- result.assignString("buf={");
- expect.assignString("buf={");
- for (i = 0; i < kCount; i++) {
- if (i != 0) {
- result.appendString(", ");
- expect.appendString(", ");
- }
- result.appendFormat("%08X", unsigned(dstBuffer[i]));
- expect.appendFormat("%08X", unsigned(expBuffer[i]));
- }
- result.appendString("}");
- expect.appendString("}");
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallBase1]
- // ============================================================================
- class X86Test_FuncCallBase1 : public X86Test {
- public:
- X86Test_FuncCallBase1() : X86Test("FuncCallBase1") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallBase1());
- }
- virtual void compile(x86::Compiler& cc) {
- x86::Gp v0 = cc.newInt32("v0");
- x86::Gp v1 = cc.newInt32("v1");
- x86::Gp v2 = cc.newInt32("v2");
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- cc.setArg(0, v0);
- cc.setArg(1, v1);
- cc.setArg(2, v2);
- // Just do something.
- cc.shl(v0, 1);
- cc.shl(v1, 1);
- cc.shl(v2, 1);
- // Call a function.
- FuncCallNode* call = cc.call(imm((void*)calledFunc), FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- call->setArg(0, v2);
- call->setArg(1, v1);
- call->setArg(2, v0);
- call->setRet(0, v0);
- cc.ret(v0);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int, int);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func(3, 2, 1);
- int expectRet = 36;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- static int calledFunc(int a, int b, int c) { return (a + b) * c; }
- };
- // ============================================================================
- // [X86Test_FuncCallBase2]
- // ============================================================================
- class X86Test_FuncCallBase2 : public X86Test {
- public:
- X86Test_FuncCallBase2() : X86Test("FuncCallBase2") {}
- enum { kSize = 256 };
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallBase2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- const int kTokenSize = 32;
- x86::Mem s1 = cc.newStack(kTokenSize, 32);
- x86::Mem s2 = cc.newStack(kTokenSize, 32);
- x86::Gp p1 = cc.newIntPtr("p1");
- x86::Gp p2 = cc.newIntPtr("p2");
- x86::Gp ret = cc.newInt32("ret");
- Label L_Exit = cc.newLabel();
- static const char token[kTokenSize] = "-+:|abcdefghijklmnopqrstuvwxyz|";
- FuncCallNode* call;
- cc.lea(p1, s1);
- cc.lea(p2, s2);
- // Try to corrupt the stack if wrongly allocated.
- call = cc.call(imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdHostCDecl));
- call->setArg(0, p1);
- call->setArg(1, imm(token));
- call->setArg(2, imm(kTokenSize));
- call->setRet(0, p1);
- call = cc.call(imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdHostCDecl));
- call->setArg(0, p2);
- call->setArg(1, imm(token));
- call->setArg(2, imm(kTokenSize));
- call->setRet(0, p2);
- call = cc.call(imm((void*)memcmp), FuncSignatureT<int, void*, void*, size_t>(CallConv::kIdHostCDecl));
- call->setArg(0, p1);
- call->setArg(1, p2);
- call->setArg(2, imm(kTokenSize));
- call->setRet(0, ret);
- // This should be 0 on success, however, if both `p1` and `p2` were
- // allocated in the same address this check will still pass.
- cc.cmp(ret, 0);
- cc.jnz(L_Exit);
- // Checks whether `p1` and `p2` are different (must be).
- cc.xor_(ret, ret);
- cc.cmp(p1, p2);
- cc.setz(ret.r8());
- cc.bind(L_Exit);
- cc.ret(ret);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = 0; // Must be zero, stack addresses must be different.
- result.assignInt(resultRet);
- expect.assignInt(expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallStd]
- // ============================================================================
- class X86Test_FuncCallStd : public X86Test {
- public:
- X86Test_FuncCallStd() : X86Test("FuncCallStd") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallStd());
- }
- virtual void compile(x86::Compiler& cc) {
- x86::Gp x = cc.newInt32("x");
- x86::Gp y = cc.newInt32("y");
- x86::Gp z = cc.newInt32("z");
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- cc.setArg(0, x);
- cc.setArg(1, y);
- cc.setArg(2, z);
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, int, int, int>(CallConv::kIdHostStdCall));
- call->setArg(0, x);
- call->setArg(1, y);
- call->setArg(2, z);
- call->setRet(0, x);
- cc.ret(x);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int, int);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func(1, 42, 3);
- int expectRet = calledFunc(1, 42, 3);
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- // STDCALL function that is called inside the generated one.
- static int ASMJIT_STDCALL calledFunc(int a, int b, int c) noexcept {
- return (a + b) * c;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallFast]
- // ============================================================================
- class X86Test_FuncCallFast : public X86Test {
- public:
- X86Test_FuncCallFast() : X86Test("FuncCallFast") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallFast());
- }
- virtual void compile(x86::Compiler& cc) {
- x86::Gp var = cc.newInt32("var");
- cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
- cc.setArg(0, var);
- FuncCallNode* call;
- call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, int>(CallConv::kIdHostFastCall));
- call->setArg(0, var);
- call->setRet(0, var);
- call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, int>(CallConv::kIdHostFastCall));
- call->setArg(0, var);
- call->setRet(0, var);
- cc.ret(var);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func(9);
- int expectRet = (9 * 9) * (9 * 9);
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- // FASTCALL function that is called inside the generated one.
- static int ASMJIT_FASTCALL calledFunc(int a) noexcept {
- return a * a;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallLight]
- // ============================================================================
- class X86Test_FuncCallLight : public X86Test {
- public:
- X86Test_FuncCallLight() : X86Test("FuncCallLight") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallLight());
- }
- virtual void compile(x86::Compiler& cc) {
- FuncSignatureT<void, const void*, const void*, const void*, const void*, void*> funcSig(CallConv::kIdHostCDecl);
- FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm> fastSig(CallConv::kIdHostLightCall2);
- FuncNode* func = cc.newFunc(funcSig);
- FuncNode* fast = cc.newFunc(fastSig);
- {
- x86::Gp aPtr = cc.newIntPtr("aPtr");
- x86::Gp bPtr = cc.newIntPtr("bPtr");
- x86::Gp cPtr = cc.newIntPtr("cPtr");
- x86::Gp dPtr = cc.newIntPtr("dPtr");
- x86::Gp pOut = cc.newIntPtr("pOut");
- x86::Xmm aXmm = cc.newXmm("aXmm");
- x86::Xmm bXmm = cc.newXmm("bXmm");
- x86::Xmm cXmm = cc.newXmm("cXmm");
- x86::Xmm dXmm = cc.newXmm("dXmm");
- cc.addFunc(func);
- cc.setArg(0, aPtr);
- cc.setArg(1, bPtr);
- cc.setArg(2, cPtr);
- cc.setArg(3, dPtr);
- cc.setArg(4, pOut);
- cc.movups(aXmm, x86::ptr(aPtr));
- cc.movups(bXmm, x86::ptr(bPtr));
- cc.movups(cXmm, x86::ptr(cPtr));
- cc.movups(dXmm, x86::ptr(dPtr));
- x86::Xmm xXmm = cc.newXmm("xXmm");
- x86::Xmm yXmm = cc.newXmm("yXmm");
- FuncCallNode* call1 = cc.call(fast->label(), fastSig);
- call1->setArg(0, aXmm);
- call1->setArg(1, bXmm);
- call1->setRet(0, xXmm);
- FuncCallNode* call2 = cc.call(fast->label(), fastSig);
- call2->setArg(0, cXmm);
- call2->setArg(1, dXmm);
- call2->setRet(0, yXmm);
- cc.pmullw(xXmm, yXmm);
- cc.movups(x86::ptr(pOut), xXmm);
- cc.endFunc();
- }
- {
- x86::Xmm aXmm = cc.newXmm("aXmm");
- x86::Xmm bXmm = cc.newXmm("bXmm");
- cc.addFunc(fast);
- cc.setArg(0, aXmm);
- cc.setArg(1, bXmm);
- cc.paddw(aXmm, bXmm);
- cc.ret(aXmm);
- cc.endFunc();
- }
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef void (*Func)(const void*, const void*, const void*, const void*, void*);
- Func func = ptr_as_func<Func>(_func);
- int16_t a[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
- int16_t b[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
- int16_t c[8] = { 1, 3, 9, 7, 5, 4, 2, 1 };
- int16_t d[8] = { 2, 0,-6,-4,-2,-1, 1, 2 };
- int16_t o[8];
- int oExp = 7 * 3;
- func(a, b, c, d, o);
- 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]);
- expect.assignFormat("ret={%02X %02X %02X %02X %02X %02X %02X %02X}", oExp, oExp, oExp, oExp, oExp, oExp, oExp, oExp);
- return result == expect;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallManyArgs]
- // ============================================================================
- class X86Test_FuncCallManyArgs : public X86Test {
- public:
- X86Test_FuncCallManyArgs() : X86Test("FuncCallManyArgs") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallManyArgs());
- }
- static int calledFunc(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
- return (a * b * c * d * e) + (f * g * h * i * j);
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- // Prepare.
- x86::Gp va = cc.newInt32("va");
- x86::Gp vb = cc.newInt32("vb");
- x86::Gp vc = cc.newInt32("vc");
- x86::Gp vd = cc.newInt32("vd");
- x86::Gp ve = cc.newInt32("ve");
- x86::Gp vf = cc.newInt32("vf");
- x86::Gp vg = cc.newInt32("vg");
- x86::Gp vh = cc.newInt32("vh");
- x86::Gp vi = cc.newInt32("vi");
- x86::Gp vj = cc.newInt32("vj");
- cc.mov(va, 0x03);
- cc.mov(vb, 0x12);
- cc.mov(vc, 0xA0);
- cc.mov(vd, 0x0B);
- cc.mov(ve, 0x2F);
- cc.mov(vf, 0x02);
- cc.mov(vg, 0x0C);
- cc.mov(vh, 0x12);
- cc.mov(vi, 0x18);
- cc.mov(vj, 0x1E);
- // Call function.
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
- call->setArg(0, va);
- call->setArg(1, vb);
- call->setArg(2, vc);
- call->setArg(3, vd);
- call->setArg(4, ve);
- call->setArg(5, vf);
- call->setArg(6, vg);
- call->setArg(7, vh);
- call->setArg(8, vi);
- call->setArg(9, vj);
- call->setRet(0, va);
- cc.ret(va);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = calledFunc(0x03, 0x12, 0xA0, 0x0B, 0x2F, 0x02, 0x0C, 0x12, 0x18, 0x1E);
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallDuplicateArgs]
- // ============================================================================
- class X86Test_FuncCallDuplicateArgs : public X86Test {
- public:
- X86Test_FuncCallDuplicateArgs() : X86Test("FuncCallDuplicateArgs") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallDuplicateArgs());
- }
- static int calledFunc(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
- return (a * b * c * d * e) + (f * g * h * i * j);
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- // Prepare.
- x86::Gp a = cc.newInt32("a");
- cc.mov(a, 3);
- // Call function.
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, a);
- call->setArg(2, a);
- call->setArg(3, a);
- call->setArg(4, a);
- call->setArg(5, a);
- call->setArg(6, a);
- call->setArg(7, a);
- call->setArg(8, a);
- call->setArg(9, a);
- call->setRet(0, a);
- cc.ret(a);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = calledFunc(3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallImmArgs]
- // ============================================================================
- class X86Test_FuncCallImmArgs : public X86Test {
- public:
- X86Test_FuncCallImmArgs() : X86Test("FuncCallImmArgs") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallImmArgs());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- // Prepare.
- x86::Gp rv = cc.newInt32("rv");
- // Call function.
- FuncCallNode* call = cc.call(
- imm((void*)X86Test_FuncCallManyArgs::calledFunc),
- FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
- call->setArg(0, imm(0x03));
- call->setArg(1, imm(0x12));
- call->setArg(2, imm(0xA0));
- call->setArg(3, imm(0x0B));
- call->setArg(4, imm(0x2F));
- call->setArg(5, imm(0x02));
- call->setArg(6, imm(0x0C));
- call->setArg(7, imm(0x12));
- call->setArg(8, imm(0x18));
- call->setArg(9, imm(0x1E));
- call->setRet(0, rv);
- cc.ret(rv);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = X86Test_FuncCallManyArgs::calledFunc(0x03, 0x12, 0xA0, 0x0B, 0x2F, 0x02, 0x0C, 0x12, 0x18, 0x1E);
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallPtrArgs]
- // ============================================================================
- class X86Test_FuncCallPtrArgs : public X86Test {
- public:
- X86Test_FuncCallPtrArgs() : X86Test("FuncCallPtrArgs") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallPtrArgs());
- }
- static int calledFunc(void* a, void* b, void* c, void* d, void* e, void* f, void* g, void* h, void* i, void* j) {
- return int((intptr_t)a) +
- int((intptr_t)b) +
- int((intptr_t)c) +
- int((intptr_t)d) +
- int((intptr_t)e) +
- int((intptr_t)f) +
- int((intptr_t)g) +
- int((intptr_t)h) +
- int((intptr_t)i) +
- int((intptr_t)j) ;
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- // Prepare.
- x86::Gp rv = cc.newInt32("rv");
- // Call function.
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>(CallConv::kIdHost));
- call->setArg(0, imm(0x01));
- call->setArg(1, imm(0x02));
- call->setArg(2, imm(0x03));
- call->setArg(3, imm(0x04));
- call->setArg(4, imm(0x05));
- call->setArg(5, imm(0x06));
- call->setArg(6, imm(0x07));
- call->setArg(7, imm(0x08));
- call->setArg(8, imm(0x09));
- call->setArg(9, imm(0x0A));
- call->setRet(0, rv);
- cc.ret(rv);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = 55;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallRefArgs]
- // ============================================================================
- class X86Test_FuncCallRefArgs : public X86Test {
- public:
- X86Test_FuncCallRefArgs() : X86Test("FuncCallRefArgs") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallRefArgs());
- }
- static int calledFunc(int& a, int& b, int& c, int& d) {
- a += a;
- b += b;
- c += c;
- d += d;
- return a + b + c + d;
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int&, int&, int&, int&>(CallConv::kIdHost));
- // Prepare.
- x86::Gp arg1 = cc.newInt32();
- x86::Gp arg2 = cc.newInt32();
- x86::Gp arg3 = cc.newInt32();
- x86::Gp arg4 = cc.newInt32();
- x86::Gp rv = cc.newInt32("rv");
- cc.setArg(0, arg1);
- cc.setArg(1, arg2);
- cc.setArg(2, arg3);
- cc.setArg(3, arg4);
- // Call function.
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, int&, int&, int&, int&>(CallConv::kIdHost));
- call->setArg(0, arg1);
- call->setArg(1, arg2);
- call->setArg(2, arg3);
- call->setArg(3, arg4);
- call->setRet(0, rv);
- cc.ret(rv);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int&, int&, int&, int&);
- Func func = ptr_as_func<Func>(_func);
- int inputs[4] = { 1, 2, 3, 4 };
- int outputs[4] = { 2, 4, 6, 8 };
- int resultRet = func(inputs[0], inputs[1], inputs[2], inputs[3]);
- int expectRet = 20;
- result.assignFormat("ret={%08X %08X %08X %08X %08X}", resultRet, inputs[0], inputs[1], inputs[2], inputs[3]);
- expect.assignFormat("ret={%08X %08X %08X %08X %08X}", expectRet, outputs[0], outputs[1], outputs[2], outputs[3]);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallFloatAsXmmRet]
- // ============================================================================
- class X86Test_FuncCallFloatAsXmmRet : public X86Test {
- public:
- X86Test_FuncCallFloatAsXmmRet() : X86Test("FuncCallFloatAsXmmRet") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallFloatAsXmmRet());
- }
- static float calledFunc(float a, float b) {
- return a * b;
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<float, float, float>(CallConv::kIdHost));
- x86::Xmm a = cc.newXmmSs("a");
- x86::Xmm b = cc.newXmmSs("b");
- x86::Xmm ret = cc.newXmmSs("ret");
- cc.setArg(0, a);
- cc.setArg(1, b);
- // Call function.
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<float, float, float>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, b);
- call->setRet(0, ret);
- cc.ret(ret);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef float (*Func)(float, float);
- Func func = ptr_as_func<Func>(_func);
- float resultRet = func(15.5f, 2.0f);
- float expectRet = calledFunc(15.5f, 2.0f);
- result.assignFormat("ret=%g", resultRet);
- expect.assignFormat("ret=%g", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallDoubleAsXmmRet]
- // ============================================================================
- class X86Test_FuncCallDoubleAsXmmRet : public X86Test {
- public:
- X86Test_FuncCallDoubleAsXmmRet() : X86Test("FuncCallDoubleAsXmmRet") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallDoubleAsXmmRet());
- }
- static double calledFunc(double a, double b) {
- return a * b;
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, double, double>(CallConv::kIdHost));
- x86::Xmm a = cc.newXmmSd("a");
- x86::Xmm b = cc.newXmmSd("b");
- x86::Xmm ret = cc.newXmmSd("ret");
- cc.setArg(0, a);
- cc.setArg(1, b);
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<double, double, double>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, b);
- call->setRet(0, ret);
- cc.ret(ret);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef double (*Func)(double, double);
- Func func = ptr_as_func<Func>(_func);
- double resultRet = func(15.5, 2.0);
- double expectRet = calledFunc(15.5, 2.0);
- result.assignFormat("ret=%g", resultRet);
- expect.assignFormat("ret=%g", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallConditional]
- // ============================================================================
- class X86Test_FuncCallConditional : public X86Test {
- public:
- X86Test_FuncCallConditional() : X86Test("FuncCallConditional") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallConditional());
- }
- virtual void compile(x86::Compiler& cc) {
- x86::Gp x = cc.newInt32("x");
- x86::Gp y = cc.newInt32("y");
- x86::Gp op = cc.newInt32("op");
- FuncCallNode* call;
- x86::Gp result;
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- cc.setArg(0, x);
- cc.setArg(1, y);
- cc.setArg(2, op);
- Label opAdd = cc.newLabel();
- Label opMul = cc.newLabel();
- cc.cmp(op, 0);
- cc.jz(opAdd);
- cc.cmp(op, 1);
- cc.jz(opMul);
- result = cc.newInt32("result_0");
- cc.mov(result, 0);
- cc.ret(result);
- cc.bind(opAdd);
- result = cc.newInt32("result_1");
- call = cc.call((uint64_t)calledFuncAdd, FuncSignatureT<int, int, int>(CallConv::kIdHost));
- call->setArg(0, x);
- call->setArg(1, y);
- call->setRet(0, result);
- cc.ret(result);
- cc.bind(opMul);
- result = cc.newInt32("result_2");
- call = cc.call((uint64_t)calledFuncMul, FuncSignatureT<int, int, int>(CallConv::kIdHost));
- call->setArg(0, x);
- call->setArg(1, y);
- call->setRet(0, result);
- cc.ret(result);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int, int);
- Func func = ptr_as_func<Func>(_func);
- int arg1 = 4;
- int arg2 = 8;
- int resultAdd = func(arg1, arg2, 0);
- int expectAdd = calledFuncAdd(arg1, arg2);
- int resultMul = func(arg1, arg2, 1);
- int expectMul = calledFuncMul(arg1, arg2);
- result.assignFormat("ret={add=%d, mul=%d}", resultAdd, resultMul);
- expect.assignFormat("ret={add=%d, mul=%d}", expectAdd, expectMul);
- return (resultAdd == expectAdd) && (resultMul == expectMul);
- }
- static int calledFuncAdd(int x, int y) { return x + y; }
- static int calledFuncMul(int x, int y) { return x * y; }
- };
- // ============================================================================
- // [X86Test_FuncCallMultiple]
- // ============================================================================
- class X86Test_FuncCallMultiple : public X86Test {
- public:
- X86Test_FuncCallMultiple() : X86Test("FuncCallMultiple") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallMultiple());
- }
- static int ASMJIT_FASTCALL calledFunc(int* pInt, int index) {
- return pInt[index];
- }
- virtual void compile(x86::Compiler& cc) {
- unsigned int i;
- x86::Gp buf = cc.newIntPtr("buf");
- x86::Gp acc0 = cc.newInt32("acc0");
- x86::Gp acc1 = cc.newInt32("acc1");
- cc.addFunc(FuncSignatureT<int, int*>(CallConv::kIdHost));
- cc.setArg(0, buf);
- cc.mov(acc0, 0);
- cc.mov(acc1, 0);
- for (i = 0; i < 4; i++) {
- x86::Gp ret = cc.newInt32("ret");
- x86::Gp ptr = cc.newIntPtr("ptr");
- x86::Gp idx = cc.newInt32("idx");
- FuncCallNode* call;
- cc.mov(ptr, buf);
- cc.mov(idx, int(i));
- call = cc.call((uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdHostFastCall));
- call->setArg(0, ptr);
- call->setArg(1, idx);
- call->setRet(0, ret);
- cc.add(acc0, ret);
- cc.mov(ptr, buf);
- cc.mov(idx, int(i));
- call = cc.call((uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdHostFastCall));
- call->setArg(0, ptr);
- call->setArg(1, idx);
- call->setRet(0, ret);
- cc.sub(acc1, ret);
- }
- cc.add(acc0, acc1);
- cc.ret(acc0);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int*);
- Func func = ptr_as_func<Func>(_func);
- int buffer[4] = { 127, 87, 23, 17 };
- int resultRet = func(buffer);
- int expectRet = 0;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallRecursive]
- // ============================================================================
- class X86Test_FuncCallRecursive : public X86Test {
- public:
- X86Test_FuncCallRecursive() : X86Test("FuncCallRecursive") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallRecursive());
- }
- virtual void compile(x86::Compiler& cc) {
- x86::Gp val = cc.newInt32("val");
- Label skip = cc.newLabel();
- FuncNode* func = cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
- cc.setArg(0, val);
- cc.cmp(val, 1);
- cc.jle(skip);
- x86::Gp tmp = cc.newInt32("tmp");
- cc.mov(tmp, val);
- cc.dec(tmp);
- FuncCallNode* call = cc.call(func->label(), FuncSignatureT<int, int>(CallConv::kIdHost));
- call->setArg(0, tmp);
- call->setRet(0, tmp);
- cc.mul(cc.newInt32(), val, tmp);
- cc.bind(skip);
- cc.ret(val);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func(5);
- int expectRet = 1 * 2 * 3 * 4 * 5;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallVarArg1]
- // ============================================================================
- class X86Test_FuncCallVarArg1 : public X86Test {
- public:
- X86Test_FuncCallVarArg1() : X86Test("FuncCallVarArg1") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallVarArg1());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int, int, int>(CallConv::kIdHost));
- x86::Gp a0 = cc.newInt32("a0");
- x86::Gp a1 = cc.newInt32("a1");
- x86::Gp a2 = cc.newInt32("a2");
- x86::Gp a3 = cc.newInt32("a3");
- cc.setArg(0, a0);
- cc.setArg(1, a1);
- cc.setArg(2, a2);
- cc.setArg(3, a3);
- // We call `int func(size_t, ...)`
- // - The `vaIndex` must be 1 (first argument after size_t).
- // - The full signature of varargs (int, int, int, int) must follow.
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, size_t, int, int, int, int>(CallConv::kIdHost, 1));
- call->setArg(0, imm(4));
- call->setArg(1, a0);
- call->setArg(2, a1);
- call->setArg(3, a2);
- call->setArg(4, a3);
- call->setRet(0, a0);
- cc.ret(a0);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int, int, int);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func(1, 2, 3, 4);
- int expectRet = 1 + 2 + 3 + 4;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- static int calledFunc(size_t n, ...) {
- int sum = 0;
- va_list ap;
- va_start(ap, n);
- for (size_t i = 0; i < n; i++) {
- int arg = va_arg(ap, int);
- sum += arg;
- }
- va_end(ap);
- return sum;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallVarArg2]
- // ============================================================================
- class X86Test_FuncCallVarArg2 : public X86Test {
- public:
- X86Test_FuncCallVarArg2() : X86Test("FuncCallVarArg2") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallVarArg2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, double, double, double, double>(CallConv::kIdHost));
- x86::Xmm a0 = cc.newXmmSd("a0");
- x86::Xmm a1 = cc.newXmmSd("a1");
- x86::Xmm a2 = cc.newXmmSd("a2");
- x86::Xmm a3 = cc.newXmmSd("a3");
- cc.setArg(0, a0);
- cc.setArg(1, a1);
- cc.setArg(2, a2);
- cc.setArg(3, a3);
- // We call `double func(size_t, ...)`
- // - The `vaIndex` must be 1 (first argument after size_t).
- // - The full signature of varargs (double, double, double, double) must follow.
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<double, size_t, double, double, double, double>(CallConv::kIdHost, 1));
- call->setArg(0, imm(4));
- call->setArg(1, a0);
- call->setArg(2, a1);
- call->setArg(3, a2);
- call->setArg(4, a3);
- call->setRet(0, a0);
- cc.ret(a0);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef double (*Func)(double, double, double, double);
- Func func = ptr_as_func<Func>(_func);
- double resultRet = func(1.0, 2.0, 3.0, 4.0);
- double expectRet = 1.0 + 2.0 + 3.0 + 4.0;
- result.assignFormat("ret=%f", resultRet);
- expect.assignFormat("ret=%f", expectRet);
- return resultRet == expectRet;
- }
- static double calledFunc(size_t n, ...) {
- double sum = 0;
- va_list ap;
- va_start(ap, n);
- for (size_t i = 0; i < n; i++) {
- double arg = va_arg(ap, double);
- sum += arg;
- }
- va_end(ap);
- return sum;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallMisc1]
- // ============================================================================
- class X86Test_FuncCallMisc1 : public X86Test {
- public:
- X86Test_FuncCallMisc1() : X86Test("FuncCallMisc1") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallMisc1());
- }
- static void dummy(int, int) {}
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
- x86::Gp a = cc.newInt32("a");
- x86::Gp b = cc.newInt32("b");
- x86::Gp r = cc.newInt32("r");
- cc.setArg(0, a);
- cc.setArg(1, b);
- FuncCallNode* call = cc.call(
- imm((void*)dummy),
- FuncSignatureT<void, int, int>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, b);
- cc.lea(r, x86::ptr(a, b));
- cc.ret(r);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func(44, 199);
- int expectRet = 243;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_FuncCallMisc2]
- // ============================================================================
- class X86Test_FuncCallMisc2 : public X86Test {
- public:
- X86Test_FuncCallMisc2() : X86Test("FuncCallMisc2") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallMisc2());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, const double*>(CallConv::kIdHost));
- x86::Gp p = cc.newIntPtr("p");
- x86::Xmm arg = cc.newXmmSd("arg");
- x86::Xmm ret = cc.newXmmSd("ret");
- cc.setArg(0, p);
- cc.movsd(arg, x86::ptr(p));
- FuncCallNode* call = cc.call(
- imm((void*)op),
- FuncSignatureT<double, double>(CallConv::kIdHost));
- call->setArg(0, arg);
- call->setRet(0, ret);
- cc.ret(ret);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef double (*Func)(const double*);
- Func func = ptr_as_func<Func>(_func);
- double arg = 2;
- double resultRet = func(&arg);
- double expectRet = op(arg);
- result.assignFormat("ret=%g", resultRet);
- expect.assignFormat("ret=%g", expectRet);
- return resultRet == expectRet;
- }
- static double op(double a) { return a * a; }
- };
- // ============================================================================
- // [X86Test_FuncCallMisc3]
- // ============================================================================
- class X86Test_FuncCallMisc3 : public X86Test {
- public:
- X86Test_FuncCallMisc3() : X86Test("FuncCallMisc3") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallMisc3());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, const double*>(CallConv::kIdHost));
- x86::Gp p = cc.newIntPtr("p");
- x86::Xmm arg = cc.newXmmSd("arg");
- x86::Xmm ret = cc.newXmmSd("ret");
- cc.setArg(0, p);
- cc.movsd(arg, x86::ptr(p));
- FuncCallNode* call = cc.call(
- imm((void*)op),
- FuncSignatureT<double, double>(CallConv::kIdHost));
- call->setArg(0, arg);
- call->setRet(0, ret);
- cc.xorps(arg, arg);
- cc.subsd(arg, ret);
- cc.ret(arg);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef double (*Func)(const double*);
- Func func = ptr_as_func<Func>(_func);
- double arg = 2;
- double resultRet = func(&arg);
- double expectRet = -op(arg);
- result.assignFormat("ret=%g", resultRet);
- expect.assignFormat("ret=%g", expectRet);
- return resultRet == expectRet;
- }
- static double op(double a) { return a * a; }
- };
- // ============================================================================
- // [X86Test_FuncCallMisc4]
- // ============================================================================
- class X86Test_FuncCallMisc4 : public X86Test {
- public:
- X86Test_FuncCallMisc4() : X86Test("FuncCallMisc4") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallMisc4());
- }
- virtual void compile(x86::Compiler& cc) {
- FuncSignatureBuilder funcPrototype;
- funcPrototype.setCallConv(CallConv::kIdHost);
- funcPrototype.setRet(Type::kIdF64);
- cc.addFunc(funcPrototype);
- FuncSignatureBuilder callPrototype;
- callPrototype.setCallConv(CallConv::kIdHost);
- callPrototype.setRet(Type::kIdF64);
- FuncCallNode* call = cc.call(imm((void*)calledFunc), callPrototype);
- x86::Xmm ret = cc.newXmmSd("ret");
- call->setRet(0, ret);
- cc.ret(ret);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef double (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- double resultRet = func();
- double expectRet = 3.14;
- result.assignFormat("ret=%g", resultRet);
- expect.assignFormat("ret=%g", expectRet);
- return resultRet == expectRet;
- }
- static double calledFunc() { return 3.14; }
- };
- // ============================================================================
- // [X86Test_FuncCallMisc5]
- // ============================================================================
- // The register allocator should clobber the register used by the `call` itself.
- class X86Test_FuncCallMisc5 : public X86Test {
- public:
- X86Test_FuncCallMisc5() : X86Test("FuncCallMisc5") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_FuncCallMisc5());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- x86::Gp pFn = cc.newIntPtr("pFn");
- x86::Gp vars[16];
- uint32_t i, regCount = cc.gpCount();
- ASMJIT_ASSERT(regCount <= ASMJIT_ARRAY_SIZE(vars));
- cc.mov(pFn, imm((void*)calledFunc));
- for (i = 0; i < regCount; i++) {
- if (i == x86::Gp::kIdBp || i == x86::Gp::kIdSp)
- continue;
- vars[i] = cc.newInt32("%%%u", unsigned(i));
- cc.mov(vars[i], 1);
- }
- cc.call(pFn, FuncSignatureT<void>(CallConv::kIdHost));
- for (i = 1; i < regCount; i++)
- if (vars[i].isValid())
- cc.add(vars[0], vars[i]);
- cc.ret(vars[0]);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = sizeof(void*) == 4 ? 6 : 14;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- static void calledFunc() {}
- };
- // ============================================================================
- // [X86Test_MiscLocalConstPool]
- // ============================================================================
- class X86Test_MiscLocalConstPool : public X86Test {
- public:
- X86Test_MiscLocalConstPool() : X86Test("MiscLocalConstPool") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_MiscLocalConstPool());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- x86::Gp v0 = cc.newInt32("v0");
- x86::Gp v1 = cc.newInt32("v1");
- x86::Mem c0 = cc.newInt32Const(ConstPool::kScopeLocal, 200);
- x86::Mem c1 = cc.newInt32Const(ConstPool::kScopeLocal, 33);
- cc.mov(v0, c0);
- cc.mov(v1, c1);
- cc.add(v0, v1);
- cc.ret(v0);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = 233;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_MiscGlobalConstPool]
- // ============================================================================
- class X86Test_MiscGlobalConstPool : public X86Test {
- public:
- X86Test_MiscGlobalConstPool() : X86Test("MiscGlobalConstPool") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_MiscGlobalConstPool());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
- x86::Gp v0 = cc.newInt32("v0");
- x86::Gp v1 = cc.newInt32("v1");
- x86::Mem c0 = cc.newInt32Const(ConstPool::kScopeGlobal, 200);
- x86::Mem c1 = cc.newInt32Const(ConstPool::kScopeGlobal, 33);
- cc.mov(v0, c0);
- cc.mov(v1, c1);
- cc.add(v0, v1);
- cc.ret(v0);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(void);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func();
- int expectRet = 233;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return resultRet == expectRet;
- }
- };
- // ============================================================================
- // [X86Test_MiscMultiRet]
- // ============================================================================
- struct X86Test_MiscMultiRet : public X86Test {
- X86Test_MiscMultiRet() : X86Test("MiscMultiRet") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_MiscMultiRet());
- }
- virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- x86::Gp op = cc.newInt32("op");
- x86::Gp a = cc.newInt32("a");
- x86::Gp b = cc.newInt32("b");
- Label L_Zero = cc.newLabel();
- Label L_Add = cc.newLabel();
- Label L_Sub = cc.newLabel();
- Label L_Mul = cc.newLabel();
- Label L_Div = cc.newLabel();
- cc.setArg(0, op);
- cc.setArg(1, a);
- cc.setArg(2, b);
- cc.cmp(op, 0);
- cc.jz(L_Add);
- cc.cmp(op, 1);
- cc.jz(L_Sub);
- cc.cmp(op, 2);
- cc.jz(L_Mul);
- cc.cmp(op, 3);
- cc.jz(L_Div);
- cc.bind(L_Zero);
- cc.xor_(a, a);
- cc.ret(a);
- cc.bind(L_Add);
- cc.add(a, b);
- cc.ret(a);
- cc.bind(L_Sub);
- cc.sub(a, b);
- cc.ret(a);
- cc.bind(L_Mul);
- cc.imul(a, b);
- cc.ret(a);
- cc.bind(L_Div);
- cc.cmp(b, 0);
- cc.jz(L_Zero);
- x86::Gp zero = cc.newInt32("zero");
- cc.xor_(zero, zero);
- cc.idiv(zero, a, b);
- cc.ret(a);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int, int);
- Func func = ptr_as_func<Func>(_func);
- int a = 44;
- int b = 3;
- int r0 = func(0, a, b);
- int r1 = func(1, a, b);
- int r2 = func(2, a, b);
- int r3 = func(3, a, b);
- int e0 = a + b;
- int e1 = a - b;
- int e2 = a * b;
- int e3 = a / b;
- result.assignFormat("ret={%d %d %d %d}", r0, r1, r2, r3);
- expect.assignFormat("ret={%d %d %d %d}", e0, e1, e2, e3);
- return result.eq(expect);
- }
- };
- // ============================================================================
- // [X86Test_MiscMultiFunc]
- // ============================================================================
- class X86Test_MiscMultiFunc : public X86Test {
- public:
- X86Test_MiscMultiFunc() : X86Test("MiscMultiFunc") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_MiscMultiFunc());
- }
- virtual void compile(x86::Compiler& cc) {
- FuncNode* f1 = cc.newFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
- FuncNode* f2 = cc.newFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
- {
- x86::Gp a = cc.newInt32("a");
- x86::Gp b = cc.newInt32("b");
- cc.addFunc(f1);
- cc.setArg(0, a);
- cc.setArg(1, b);
- FuncCallNode* call = cc.call(f2->label(), FuncSignatureT<int, int, int>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, b);
- call->setRet(0, a);
- cc.ret(a);
- cc.endFunc();
- }
- {
- x86::Gp a = cc.newInt32("a");
- x86::Gp b = cc.newInt32("b");
- cc.addFunc(f2);
- cc.setArg(0, a);
- cc.setArg(1, b);
- cc.add(a, b);
- cc.ret(a);
- cc.endFunc();
- }
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (*Func)(int, int);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = func(56, 22);
- int expectRet = 56 + 22;
- result.assignFormat("ret=%d", resultRet);
- expect.assignFormat("ret=%d", expectRet);
- return result.eq(expect);
- }
- };
- // ============================================================================
- // [X86Test_MiscUnfollow]
- // ============================================================================
- // Global (I didn't find a better way to test this).
- static jmp_buf globalJmpBuf;
- class X86Test_MiscUnfollow : public X86Test {
- public:
- X86Test_MiscUnfollow() : X86Test("MiscUnfollow") {}
- static void add(X86TestApp& app) {
- app.add(new X86Test_MiscUnfollow());
- }
- virtual void compile(x86::Compiler& cc) {
- // NOTE: Fastcall calling convention is the most appropriate here, as all
- // arguments will be passed by registers and there won't be any stack
- // misalignment when we call the `handler()`. This was failing on OSX
- // when targeting 32-bit.
- cc.addFunc(FuncSignatureT<int, int, void*>(CallConv::kIdHostFastCall));
- x86::Gp a = cc.newInt32("a");
- x86::Gp b = cc.newIntPtr("b");
- Label tramp = cc.newLabel();
- cc.setArg(0, a);
- cc.setArg(1, b);
- cc.cmp(a, 0);
- cc.jz(tramp);
- cc.ret(a);
- cc.bind(tramp);
- cc.unfollow().jmp(b);
- cc.endFunc();
- }
- virtual bool run(void* _func, String& result, String& expect) {
- typedef int (ASMJIT_FASTCALL *Func)(int, void*);
- Func func = ptr_as_func<Func>(_func);
- int resultRet = 0;
- int expectRet = 1;
- if (!setjmp(globalJmpBuf))
- resultRet = func(0, (void*)handler);
- else
- resultRet = 1;
- result.assignFormat("ret={%d}", resultRet);
- expect.assignFormat("ret={%d}", expectRet);
- return resultRet == expectRet;
- }
- static void ASMJIT_FASTCALL handler() { longjmp(globalJmpBuf, 1); }
- };
- // ============================================================================
- // [Main]
- // ============================================================================
- int main(int argc, char* argv[]) {
- X86TestApp app;
- app.handleArgs(argc, argv);
- app.showInfo();
- // Base tests.
- app.addT<X86Test_NoCode>();
- app.addT<X86Test_NoAlign>();
- app.addT<X86Test_AlignBase>();
- // Jump tests.
- app.addT<X86Test_JumpMerge>();
- app.addT<X86Test_JumpCross>();
- app.addT<X86Test_JumpMany>();
- app.addT<X86Test_JumpUnreachable1>();
- app.addT<X86Test_JumpUnreachable2>();
- // Alloc tests.
- app.addT<X86Test_AllocBase>();
- app.addT<X86Test_AllocMany1>();
- app.addT<X86Test_AllocMany2>();
- app.addT<X86Test_AllocImul1>();
- app.addT<X86Test_AllocImul2>();
- app.addT<X86Test_AllocIdiv1>();
- app.addT<X86Test_AllocSetz>();
- app.addT<X86Test_AllocShlRor>();
- app.addT<X86Test_AllocGpbLo1>();
- app.addT<X86Test_AllocGpbLo2>();
- app.addT<X86Test_AllocRepMovsb>();
- app.addT<X86Test_AllocIfElse1>();
- app.addT<X86Test_AllocIfElse2>();
- app.addT<X86Test_AllocIfElse3>();
- app.addT<X86Test_AllocIfElse4>();
- app.addT<X86Test_AllocInt8>();
- app.addT<X86Test_AllocUnhandledArg>();
- app.addT<X86Test_AllocArgsIntPtr>();
- app.addT<X86Test_AllocArgsFloat>();
- app.addT<X86Test_AllocArgsDouble>();
- app.addT<X86Test_AllocRetFloat1>();
- app.addT<X86Test_AllocRetFloat2>();
- app.addT<X86Test_AllocRetDouble1>();
- app.addT<X86Test_AllocRetDouble2>();
- app.addT<X86Test_AllocStack>();
- app.addT<X86Test_AllocMemcpy>();
- app.addT<X86Test_AllocExtraBlock>();
- app.addT<X86Test_AllocAlphaBlend>();
- // Function call tests.
- app.addT<X86Test_FuncCallBase1>();
- app.addT<X86Test_FuncCallBase2>();
- app.addT<X86Test_FuncCallStd>();
- app.addT<X86Test_FuncCallFast>();
- app.addT<X86Test_FuncCallLight>();
- app.addT<X86Test_FuncCallManyArgs>();
- app.addT<X86Test_FuncCallDuplicateArgs>();
- app.addT<X86Test_FuncCallImmArgs>();
- app.addT<X86Test_FuncCallPtrArgs>();
- app.addT<X86Test_FuncCallRefArgs>();
- app.addT<X86Test_FuncCallFloatAsXmmRet>();
- app.addT<X86Test_FuncCallDoubleAsXmmRet>();
- app.addT<X86Test_FuncCallConditional>();
- app.addT<X86Test_FuncCallMultiple>();
- app.addT<X86Test_FuncCallRecursive>();
- app.addT<X86Test_FuncCallVarArg1>();
- app.addT<X86Test_FuncCallVarArg2>();
- app.addT<X86Test_FuncCallMisc1>();
- app.addT<X86Test_FuncCallMisc2>();
- app.addT<X86Test_FuncCallMisc3>();
- app.addT<X86Test_FuncCallMisc4>();
- app.addT<X86Test_FuncCallMisc5>();
- // Miscellaneous tests.
- app.addT<X86Test_MiscLocalConstPool>();
- app.addT<X86Test_MiscGlobalConstPool>();
- app.addT<X86Test_MiscMultiRet>();
- app.addT<X86Test_MiscMultiFunc>();
- app.addT<X86Test_MiscUnfollow>();
- return app.run();
- }
|