sljitNativePPC_common.c 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281
  1. /*
  2. * Stack-less Just-In-Time compiler
  3. *
  4. * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification, are
  7. * permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this list of
  10. * conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form must reproduce the above copyright notice, this list
  13. * of conditions and the following disclaimer in the documentation and/or other materials
  14. * provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  19. * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  21. * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  22. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  24. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
  27. {
  28. return "PowerPC" SLJIT_CPUINFO;
  29. }
  30. /* Length of an instruction word.
  31. Both for ppc-32 and ppc-64. */
  32. typedef sljit_u32 sljit_ins;
  33. #if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \
  34. || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  35. #define SLJIT_PPC_STACK_FRAME_V2 1
  36. #endif
  37. #ifdef _AIX
  38. #include <sys/cache.h>
  39. #endif
  40. #if (defined _CALL_ELF && _CALL_ELF == 2)
  41. #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1
  42. #endif
  43. #if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)
  44. static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
  45. {
  46. #ifdef _AIX
  47. _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from));
  48. #elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
  49. # if defined(_ARCH_PWR) || defined(_ARCH_PWR2)
  50. /* Cache flush for POWER architecture. */
  51. while (from < to) {
  52. __asm__ volatile (
  53. "clf 0, %0\n"
  54. "dcs\n"
  55. : : "r"(from)
  56. );
  57. from++;
  58. }
  59. __asm__ volatile ( "ics" );
  60. # elif defined(_ARCH_COM) && !defined(_ARCH_PPC)
  61. # error "Cache flush is not implemented for PowerPC/POWER common mode."
  62. # else
  63. /* Cache flush for PowerPC architecture. */
  64. while (from < to) {
  65. __asm__ volatile (
  66. "dcbf 0, %0\n"
  67. "sync\n"
  68. "icbi 0, %0\n"
  69. : : "r"(from)
  70. );
  71. from++;
  72. }
  73. __asm__ volatile ( "isync" );
  74. # endif
  75. # ifdef __xlc__
  76. # warning "This file may fail to compile if -qfuncsect is used"
  77. # endif
  78. #elif defined(__xlc__)
  79. #error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"
  80. #else
  81. #error "This platform requires a cache flush implementation."
  82. #endif /* _AIX */
  83. }
  84. #endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */
  85. #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
  86. #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
  87. #define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 4)
  88. #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
  89. #define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 5)
  90. #else
  91. #define TMP_CALL_REG TMP_REG2
  92. #endif
  93. #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
  94. #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
  95. static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
  96. 0, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 9, 10, 31, 12
  97. };
  98. static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
  99. 0, 1, 2, 3, 4, 5, 6, 0, 7
  100. };
  101. /* --------------------------------------------------------------------- */
  102. /* Instrucion forms */
  103. /* --------------------------------------------------------------------- */
  104. #define D(d) (reg_map[d] << 21)
  105. #define S(s) (reg_map[s] << 21)
  106. #define A(a) (reg_map[a] << 16)
  107. #define B(b) (reg_map[b] << 11)
  108. #define C(c) (reg_map[c] << 6)
  109. #define FD(fd) (freg_map[fd] << 21)
  110. #define FS(fs) (freg_map[fs] << 21)
  111. #define FA(fa) (freg_map[fa] << 16)
  112. #define FB(fb) (freg_map[fb] << 11)
  113. #define FC(fc) (freg_map[fc] << 6)
  114. #define IMM(imm) ((imm) & 0xffff)
  115. #define CRD(d) ((d) << 21)
  116. /* Instruction bit sections.
  117. OE and Rc flag (see ALT_SET_FLAGS). */
  118. #define OE(flags) ((flags) & ALT_SET_FLAGS)
  119. /* Rc flag (see ALT_SET_FLAGS). */
  120. #define RC(flags) (((flags) & ALT_SET_FLAGS) >> 10)
  121. #define HI(opcode) ((opcode) << 26)
  122. #define LO(opcode) ((opcode) << 1)
  123. #define ADD (HI(31) | LO(266))
  124. #define ADDC (HI(31) | LO(10))
  125. #define ADDE (HI(31) | LO(138))
  126. #define ADDI (HI(14))
  127. #define ADDIC (HI(13))
  128. #define ADDIS (HI(15))
  129. #define ADDME (HI(31) | LO(234))
  130. #define AND (HI(31) | LO(28))
  131. #define ANDI (HI(28))
  132. #define ANDIS (HI(29))
  133. #define Bx (HI(18))
  134. #define BCx (HI(16))
  135. #define BCCTR (HI(19) | LO(528) | (3 << 11))
  136. #define BLR (HI(19) | LO(16) | (0x14 << 21))
  137. #define CNTLZD (HI(31) | LO(58))
  138. #define CNTLZW (HI(31) | LO(26))
  139. #define CMP (HI(31) | LO(0))
  140. #define CMPI (HI(11))
  141. #define CMPL (HI(31) | LO(32))
  142. #define CMPLI (HI(10))
  143. #define CROR (HI(19) | LO(449))
  144. #define DCBT (HI(31) | LO(278))
  145. #define DIVD (HI(31) | LO(489))
  146. #define DIVDU (HI(31) | LO(457))
  147. #define DIVW (HI(31) | LO(491))
  148. #define DIVWU (HI(31) | LO(459))
  149. #define EXTSB (HI(31) | LO(954))
  150. #define EXTSH (HI(31) | LO(922))
  151. #define EXTSW (HI(31) | LO(986))
  152. #define FABS (HI(63) | LO(264))
  153. #define FADD (HI(63) | LO(21))
  154. #define FADDS (HI(59) | LO(21))
  155. #define FCFID (HI(63) | LO(846))
  156. #define FCMPU (HI(63) | LO(0))
  157. #define FCTIDZ (HI(63) | LO(815))
  158. #define FCTIWZ (HI(63) | LO(15))
  159. #define FDIV (HI(63) | LO(18))
  160. #define FDIVS (HI(59) | LO(18))
  161. #define FMR (HI(63) | LO(72))
  162. #define FMUL (HI(63) | LO(25))
  163. #define FMULS (HI(59) | LO(25))
  164. #define FNEG (HI(63) | LO(40))
  165. #define FRSP (HI(63) | LO(12))
  166. #define FSUB (HI(63) | LO(20))
  167. #define FSUBS (HI(59) | LO(20))
  168. #define LD (HI(58) | 0)
  169. #define LWZ (HI(32))
  170. #define MFCR (HI(31) | LO(19))
  171. #define MFLR (HI(31) | LO(339) | 0x80000)
  172. #define MFXER (HI(31) | LO(339) | 0x10000)
  173. #define MTCTR (HI(31) | LO(467) | 0x90000)
  174. #define MTLR (HI(31) | LO(467) | 0x80000)
  175. #define MTXER (HI(31) | LO(467) | 0x10000)
  176. #define MULHD (HI(31) | LO(73))
  177. #define MULHDU (HI(31) | LO(9))
  178. #define MULHW (HI(31) | LO(75))
  179. #define MULHWU (HI(31) | LO(11))
  180. #define MULLD (HI(31) | LO(233))
  181. #define MULLI (HI(7))
  182. #define MULLW (HI(31) | LO(235))
  183. #define NEG (HI(31) | LO(104))
  184. #define NOP (HI(24))
  185. #define NOR (HI(31) | LO(124))
  186. #define OR (HI(31) | LO(444))
  187. #define ORI (HI(24))
  188. #define ORIS (HI(25))
  189. #define RLDICL (HI(30))
  190. #define RLWINM (HI(21))
  191. #define SLD (HI(31) | LO(27))
  192. #define SLW (HI(31) | LO(24))
  193. #define SRAD (HI(31) | LO(794))
  194. #define SRADI (HI(31) | LO(413 << 1))
  195. #define SRAW (HI(31) | LO(792))
  196. #define SRAWI (HI(31) | LO(824))
  197. #define SRD (HI(31) | LO(539))
  198. #define SRW (HI(31) | LO(536))
  199. #define STD (HI(62) | 0)
  200. #define STDU (HI(62) | 1)
  201. #define STDUX (HI(31) | LO(181))
  202. #define STFIWX (HI(31) | LO(983))
  203. #define STW (HI(36))
  204. #define STWU (HI(37))
  205. #define STWUX (HI(31) | LO(183))
  206. #define SUBF (HI(31) | LO(40))
  207. #define SUBFC (HI(31) | LO(8))
  208. #define SUBFE (HI(31) | LO(136))
  209. #define SUBFIC (HI(8))
  210. #define XOR (HI(31) | LO(316))
  211. #define XORI (HI(26))
  212. #define XORIS (HI(27))
  213. #define SIMM_MAX (0x7fff)
  214. #define SIMM_MIN (-0x8000)
  215. #define UIMM_MAX (0xffff)
  216. #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
  217. SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func)
  218. {
  219. sljit_sw* ptrs;
  220. if (func_ptr)
  221. *func_ptr = (void*)context;
  222. ptrs = (sljit_sw*)func;
  223. context->addr = addr ? addr : ptrs[0];
  224. context->r2 = ptrs[1];
  225. context->r11 = ptrs[2];
  226. }
  227. #endif
  228. static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
  229. {
  230. sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
  231. FAIL_IF(!ptr);
  232. *ptr = ins;
  233. compiler->size++;
  234. return SLJIT_SUCCESS;
  235. }
  236. static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
  237. {
  238. sljit_sw diff;
  239. sljit_uw target_addr;
  240. sljit_sw extra_jump_flags;
  241. #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  242. if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
  243. return 0;
  244. #else
  245. if (jump->flags & SLJIT_REWRITABLE_JUMP)
  246. return 0;
  247. #endif
  248. if (jump->flags & JUMP_ADDR)
  249. target_addr = jump->u.target;
  250. else {
  251. SLJIT_ASSERT(jump->flags & JUMP_LABEL);
  252. target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
  253. }
  254. #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  255. if (jump->flags & IS_CALL)
  256. goto keep_address;
  257. #endif
  258. diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l;
  259. extra_jump_flags = 0;
  260. if (jump->flags & IS_COND) {
  261. if (diff <= 0x7fff && diff >= -0x8000) {
  262. jump->flags |= PATCH_B;
  263. return 1;
  264. }
  265. if (target_addr <= 0xffff) {
  266. jump->flags |= PATCH_B | PATCH_ABS_B;
  267. return 1;
  268. }
  269. extra_jump_flags = REMOVE_COND;
  270. diff -= sizeof(sljit_ins);
  271. }
  272. if (diff <= 0x01ffffff && diff >= -0x02000000) {
  273. jump->flags |= PATCH_B | extra_jump_flags;
  274. return 1;
  275. }
  276. if (target_addr <= 0x03ffffff) {
  277. jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags;
  278. return 1;
  279. }
  280. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  281. #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
  282. keep_address:
  283. #endif
  284. if (target_addr <= 0x7fffffff) {
  285. jump->flags |= PATCH_ABS32;
  286. return 1;
  287. }
  288. if (target_addr <= 0x7fffffffffffl) {
  289. jump->flags |= PATCH_ABS48;
  290. return 1;
  291. }
  292. #endif
  293. return 0;
  294. }
  295. SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
  296. {
  297. struct sljit_memory_fragment *buf;
  298. sljit_ins *code;
  299. sljit_ins *code_ptr;
  300. sljit_ins *buf_ptr;
  301. sljit_ins *buf_end;
  302. sljit_uw word_count;
  303. sljit_sw executable_offset;
  304. sljit_uw addr;
  305. struct sljit_label *label;
  306. struct sljit_jump *jump;
  307. struct sljit_const *const_;
  308. CHECK_ERROR_PTR();
  309. CHECK_PTR(check_sljit_generate_code(compiler));
  310. reverse_buf(compiler);
  311. #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
  312. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  313. compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
  314. #else
  315. compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
  316. #endif
  317. #endif
  318. code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
  319. PTR_FAIL_WITH_EXEC_IF(code);
  320. buf = compiler->buf;
  321. code_ptr = code;
  322. word_count = 0;
  323. executable_offset = SLJIT_EXEC_OFFSET(code);
  324. label = compiler->labels;
  325. jump = compiler->jumps;
  326. const_ = compiler->consts;
  327. do {
  328. buf_ptr = (sljit_ins*)buf->memory;
  329. buf_end = buf_ptr + (buf->used_size >> 2);
  330. do {
  331. *code_ptr = *buf_ptr++;
  332. SLJIT_ASSERT(!label || label->size >= word_count);
  333. SLJIT_ASSERT(!jump || jump->addr >= word_count);
  334. SLJIT_ASSERT(!const_ || const_->addr >= word_count);
  335. /* These structures are ordered by their address. */
  336. if (label && label->size == word_count) {
  337. /* Just recording the address. */
  338. label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
  339. label->size = code_ptr - code;
  340. label = label->next;
  341. }
  342. if (jump && jump->addr == word_count) {
  343. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  344. jump->addr = (sljit_uw)(code_ptr - 3);
  345. #else
  346. jump->addr = (sljit_uw)(code_ptr - 6);
  347. #endif
  348. if (detect_jump_type(jump, code_ptr, code, executable_offset)) {
  349. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  350. code_ptr[-3] = code_ptr[0];
  351. code_ptr -= 3;
  352. #else
  353. if (jump->flags & PATCH_ABS32) {
  354. code_ptr -= 3;
  355. code_ptr[-1] = code_ptr[2];
  356. code_ptr[0] = code_ptr[3];
  357. }
  358. else if (jump->flags & PATCH_ABS48) {
  359. code_ptr--;
  360. code_ptr[-1] = code_ptr[0];
  361. code_ptr[0] = code_ptr[1];
  362. /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
  363. SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6);
  364. code_ptr[-3] ^= 0x8422;
  365. /* oris -> ori */
  366. code_ptr[-2] ^= 0x4000000;
  367. }
  368. else {
  369. code_ptr[-6] = code_ptr[0];
  370. code_ptr -= 6;
  371. }
  372. #endif
  373. if (jump->flags & REMOVE_COND) {
  374. code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
  375. code_ptr++;
  376. jump->addr += sizeof(sljit_ins);
  377. code_ptr[0] = Bx;
  378. jump->flags -= IS_COND;
  379. }
  380. }
  381. jump = jump->next;
  382. }
  383. if (const_ && const_->addr == word_count) {
  384. const_->addr = (sljit_uw)code_ptr;
  385. const_ = const_->next;
  386. }
  387. code_ptr ++;
  388. word_count ++;
  389. } while (buf_ptr < buf_end);
  390. buf = buf->next;
  391. } while (buf);
  392. if (label && label->size == word_count) {
  393. label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
  394. label->size = code_ptr - code;
  395. label = label->next;
  396. }
  397. SLJIT_ASSERT(!label);
  398. SLJIT_ASSERT(!jump);
  399. SLJIT_ASSERT(!const_);
  400. #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
  401. SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)));
  402. #else
  403. SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
  404. #endif
  405. jump = compiler->jumps;
  406. while (jump) {
  407. do {
  408. addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
  409. buf_ptr = (sljit_ins *)jump->addr;
  410. if (jump->flags & PATCH_B) {
  411. if (jump->flags & IS_COND) {
  412. if (!(jump->flags & PATCH_ABS_B)) {
  413. addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
  414. SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
  415. *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
  416. }
  417. else {
  418. SLJIT_ASSERT(addr <= 0xffff);
  419. *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);
  420. }
  421. }
  422. else {
  423. if (!(jump->flags & PATCH_ABS_B)) {
  424. addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
  425. SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
  426. *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
  427. }
  428. else {
  429. SLJIT_ASSERT(addr <= 0x03ffffff);
  430. *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);
  431. }
  432. }
  433. break;
  434. }
  435. /* Set the fields of immediate loads. */
  436. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  437. buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
  438. buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
  439. #else
  440. if (jump->flags & PATCH_ABS32) {
  441. SLJIT_ASSERT(addr <= 0x7fffffff);
  442. buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
  443. buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
  444. break;
  445. }
  446. if (jump->flags & PATCH_ABS48) {
  447. SLJIT_ASSERT(addr <= 0x7fffffffffff);
  448. buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff);
  449. buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff);
  450. buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff);
  451. break;
  452. }
  453. buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
  454. buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
  455. buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
  456. buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);
  457. #endif
  458. } while (0);
  459. jump = jump->next;
  460. }
  461. compiler->error = SLJIT_ERR_COMPILED;
  462. compiler->executable_offset = executable_offset;
  463. compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
  464. code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
  465. #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
  466. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  467. if (((sljit_sw)code_ptr) & 0x4)
  468. code_ptr++;
  469. #endif
  470. sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
  471. #endif
  472. code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
  473. SLJIT_CACHE_FLUSH(code, code_ptr);
  474. #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
  475. return code_ptr;
  476. #else
  477. return code;
  478. #endif
  479. }
  480. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
  481. {
  482. switch (feature_type) {
  483. case SLJIT_HAS_FPU:
  484. #ifdef SLJIT_IS_FPU_AVAILABLE
  485. return SLJIT_IS_FPU_AVAILABLE;
  486. #else
  487. /* Available by default. */
  488. return 1;
  489. #endif
  490. case SLJIT_HAS_CLZ:
  491. return 1;
  492. default:
  493. return 0;
  494. }
  495. }
  496. /* --------------------------------------------------------------------- */
  497. /* Entry, exit */
  498. /* --------------------------------------------------------------------- */
  499. /* inp_flags: */
  500. /* Creates an index in data_transfer_insts array. */
  501. #define LOAD_DATA 0x01
  502. #define INDEXED 0x02
  503. #define SIGNED_DATA 0x04
  504. #define WORD_DATA 0x00
  505. #define BYTE_DATA 0x08
  506. #define HALF_DATA 0x10
  507. #define INT_DATA 0x18
  508. /* Separates integer and floating point registers */
  509. #define GPR_REG 0x1f
  510. #define DOUBLE_DATA 0x20
  511. #define MEM_MASK 0x7f
  512. /* Other inp_flags. */
  513. /* Integer opertion and set flags -> requires exts on 64 bit systems. */
  514. #define ALT_SIGN_EXT 0x000100
  515. /* This flag affects the RC() and OERC() macros. */
  516. #define ALT_SET_FLAGS 0x000400
  517. #define ALT_FORM1 0x001000
  518. #define ALT_FORM2 0x002000
  519. #define ALT_FORM3 0x004000
  520. #define ALT_FORM4 0x008000
  521. #define ALT_FORM5 0x010000
  522. /* Source and destination is register. */
  523. #define REG_DEST 0x000001
  524. #define REG1_SOURCE 0x000002
  525. #define REG2_SOURCE 0x000004
  526. /*
  527. ALT_SIGN_EXT 0x000100
  528. ALT_SET_FLAGS 0x000200
  529. ALT_FORM1 0x001000
  530. ...
  531. ALT_FORM5 0x010000 */
  532. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  533. #include "sljitNativePPC_32.c"
  534. #else
  535. #include "sljitNativePPC_64.c"
  536. #endif
  537. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  538. #define STACK_STORE STW
  539. #define STACK_LOAD LWZ
  540. #else
  541. #define STACK_STORE STD
  542. #define STACK_LOAD LD
  543. #endif
  544. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
  545. sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
  546. sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
  547. {
  548. sljit_s32 args, i, tmp, offs;
  549. CHECK_ERROR();
  550. CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
  551. set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
  552. FAIL_IF(push_inst(compiler, MFLR | D(0)));
  553. offs = -(sljit_s32)(sizeof(sljit_sw));
  554. FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
  555. tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
  556. for (i = SLJIT_S0; i >= tmp; i--) {
  557. offs -= (sljit_s32)(sizeof(sljit_sw));
  558. FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
  559. }
  560. for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
  561. offs -= (sljit_s32)(sizeof(sljit_sw));
  562. FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));
  563. }
  564. SLJIT_ASSERT(offs == -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1));
  565. #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
  566. FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
  567. #else
  568. FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
  569. #endif
  570. FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));
  571. args = get_arg_count(arg_types);
  572. if (args >= 1)
  573. FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0)));
  574. if (args >= 2)
  575. FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1)));
  576. if (args >= 3)
  577. FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2)));
  578. local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
  579. local_size = (local_size + 15) & ~0xf;
  580. compiler->local_size = local_size;
  581. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  582. if (local_size <= SIMM_MAX)
  583. FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
  584. else {
  585. FAIL_IF(load_immediate(compiler, 0, -local_size));
  586. FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
  587. }
  588. #else
  589. if (local_size <= SIMM_MAX)
  590. FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));
  591. else {
  592. FAIL_IF(load_immediate(compiler, 0, -local_size));
  593. FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));
  594. }
  595. #endif
  596. return SLJIT_SUCCESS;
  597. }
  598. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
  599. sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
  600. sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
  601. {
  602. CHECK_ERROR();
  603. CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
  604. set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
  605. local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
  606. compiler->local_size = (local_size + 15) & ~0xf;
  607. return SLJIT_SUCCESS;
  608. }
  609. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
  610. {
  611. sljit_s32 i, tmp, offs;
  612. CHECK_ERROR();
  613. CHECK(check_sljit_emit_return(compiler, op, src, srcw));
  614. FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
  615. if (compiler->local_size <= SIMM_MAX)
  616. FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size)));
  617. else {
  618. FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
  619. FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0)));
  620. }
  621. #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)
  622. FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));
  623. #else
  624. FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));
  625. #endif
  626. offs = -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);
  627. tmp = compiler->scratches;
  628. for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
  629. FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
  630. offs += (sljit_s32)(sizeof(sljit_sw));
  631. }
  632. tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
  633. for (i = tmp; i <= SLJIT_S0; i++) {
  634. FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));
  635. offs += (sljit_s32)(sizeof(sljit_sw));
  636. }
  637. FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));
  638. SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw)));
  639. FAIL_IF(push_inst(compiler, MTLR | S(0)));
  640. FAIL_IF(push_inst(compiler, BLR));
  641. return SLJIT_SUCCESS;
  642. }
  643. #undef STACK_STORE
  644. #undef STACK_LOAD
  645. /* --------------------------------------------------------------------- */
  646. /* Operators */
  647. /* --------------------------------------------------------------------- */
  648. /* s/l - store/load (1 bit)
  649. i/x - immediate/indexed form
  650. u/s - signed/unsigned (1 bit)
  651. w/b/h/i - word/byte/half/int allowed (2 bit)
  652. Some opcodes are repeated (e.g. store signed / unsigned byte is the same instruction). */
  653. /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
  654. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  655. #define INT_ALIGNED 0x10000
  656. #endif
  657. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  658. #define ARCH_32_64(a, b) a
  659. #define INST_CODE_AND_DST(inst, flags, reg) \
  660. ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
  661. #else
  662. #define ARCH_32_64(a, b) b
  663. #define INST_CODE_AND_DST(inst, flags, reg) \
  664. (((inst) & ~INT_ALIGNED) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
  665. #endif
  666. static const sljit_ins data_transfer_insts[64 + 16] = {
  667. /* -------- Integer -------- */
  668. /* Word. */
  669. /* w u i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
  670. /* w u i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
  671. /* w u x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
  672. /* w u x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
  673. /* w s i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
  674. /* w s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
  675. /* w s x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
  676. /* w s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
  677. /* Byte. */
  678. /* b u i s */ HI(38) /* stb */,
  679. /* b u i l */ HI(34) /* lbz */,
  680. /* b u x s */ HI(31) | LO(215) /* stbx */,
  681. /* b u x l */ HI(31) | LO(87) /* lbzx */,
  682. /* b s i s */ HI(38) /* stb */,
  683. /* b s i l */ HI(34) /* lbz */ /* EXTS_REQ */,
  684. /* b s x s */ HI(31) | LO(215) /* stbx */,
  685. /* b s x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
  686. /* Half. */
  687. /* h u i s */ HI(44) /* sth */,
  688. /* h u i l */ HI(40) /* lhz */,
  689. /* h u x s */ HI(31) | LO(407) /* sthx */,
  690. /* h u x l */ HI(31) | LO(279) /* lhzx */,
  691. /* h s i s */ HI(44) /* sth */,
  692. /* h s i l */ HI(42) /* lha */,
  693. /* h s x s */ HI(31) | LO(407) /* sthx */,
  694. /* h s x l */ HI(31) | LO(343) /* lhax */,
  695. /* Int. */
  696. /* i u i s */ HI(36) /* stw */,
  697. /* i u i l */ HI(32) /* lwz */,
  698. /* i u x s */ HI(31) | LO(151) /* stwx */,
  699. /* i u x l */ HI(31) | LO(23) /* lwzx */,
  700. /* i s i s */ HI(36) /* stw */,
  701. /* i s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),
  702. /* i s x s */ HI(31) | LO(151) /* stwx */,
  703. /* i s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
  704. /* -------- Floating point -------- */
  705. /* d i s */ HI(54) /* stfd */,
  706. /* d i l */ HI(50) /* lfd */,
  707. /* d x s */ HI(31) | LO(727) /* stfdx */,
  708. /* d x l */ HI(31) | LO(599) /* lfdx */,
  709. /* s i s */ HI(52) /* stfs */,
  710. /* s i l */ HI(48) /* lfs */,
  711. /* s x s */ HI(31) | LO(663) /* stfsx */,
  712. /* s x l */ HI(31) | LO(535) /* lfsx */,
  713. };
  714. static const sljit_ins updated_data_transfer_insts[64] = {
  715. /* -------- Integer -------- */
  716. /* Word. */
  717. /* w u i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
  718. /* w u i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
  719. /* w u x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
  720. /* w u x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
  721. /* w s i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
  722. /* w s i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
  723. /* w s x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
  724. /* w s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
  725. /* Byte. */
  726. /* b u i s */ HI(39) /* stbu */,
  727. /* b u i l */ HI(35) /* lbzu */,
  728. /* b u x s */ HI(31) | LO(247) /* stbux */,
  729. /* b u x l */ HI(31) | LO(119) /* lbzux */,
  730. /* b s i s */ HI(39) /* stbu */,
  731. /* b s i l */ 0 /* no such instruction */,
  732. /* b s x s */ HI(31) | LO(247) /* stbux */,
  733. /* b s x l */ 0 /* no such instruction */,
  734. /* Half. */
  735. /* h u i s */ HI(45) /* sthu */,
  736. /* h u i l */ HI(41) /* lhzu */,
  737. /* h u x s */ HI(31) | LO(439) /* sthux */,
  738. /* h u x l */ HI(31) | LO(311) /* lhzux */,
  739. /* h s i s */ HI(45) /* sthu */,
  740. /* h s i l */ HI(43) /* lhau */,
  741. /* h s x s */ HI(31) | LO(439) /* sthux */,
  742. /* h s x l */ HI(31) | LO(375) /* lhaux */,
  743. /* Int. */
  744. /* i u i s */ HI(37) /* stwu */,
  745. /* i u i l */ HI(33) /* lwzu */,
  746. /* i u x s */ HI(31) | LO(183) /* stwux */,
  747. /* i u x l */ HI(31) | LO(55) /* lwzux */,
  748. /* i s i s */ HI(37) /* stwu */,
  749. /* i s i l */ ARCH_32_64(HI(33) /* lwzu */, 0 /* no such instruction */),
  750. /* i s x s */ HI(31) | LO(183) /* stwux */,
  751. /* i s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
  752. /* -------- Floating point -------- */
  753. /* d i s */ HI(55) /* stfdu */,
  754. /* d i l */ HI(51) /* lfdu */,
  755. /* d x s */ HI(31) | LO(759) /* stfdux */,
  756. /* d x l */ HI(31) | LO(631) /* lfdux */,
  757. /* s i s */ HI(53) /* stfsu */,
  758. /* s i l */ HI(49) /* lfsu */,
  759. /* s x s */ HI(31) | LO(695) /* stfsux */,
  760. /* s x l */ HI(31) | LO(567) /* lfsux */,
  761. };
  762. #undef ARCH_32_64
  763. /* Simple cases, (no caching is required). */
  764. static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg,
  765. sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
  766. {
  767. sljit_ins inst;
  768. sljit_s32 offs_reg;
  769. sljit_sw high_short;
  770. /* Should work when (arg & REG_MASK) == 0. */
  771. SLJIT_ASSERT(A(0) == 0);
  772. SLJIT_ASSERT(arg & SLJIT_MEM);
  773. if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
  774. argw &= 0x3;
  775. offs_reg = OFFS_REG(arg);
  776. if (argw != 0) {
  777. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  778. FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_reg) | (argw << 11) | ((31 - argw) << 1)));
  779. #else
  780. FAIL_IF(push_inst(compiler, RLDI(tmp_reg, OFFS_REG(arg), argw, 63 - argw, 1)));
  781. #endif
  782. offs_reg = tmp_reg;
  783. }
  784. inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
  785. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  786. SLJIT_ASSERT(!(inst & INT_ALIGNED));
  787. #endif
  788. return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(offs_reg));
  789. }
  790. inst = data_transfer_insts[inp_flags & MEM_MASK];
  791. arg &= REG_MASK;
  792. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  793. if ((inst & INT_ALIGNED) && (argw & 0x3) != 0) {
  794. FAIL_IF(load_immediate(compiler, tmp_reg, argw));
  795. inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
  796. return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
  797. }
  798. #endif
  799. if (argw <= SIMM_MAX && argw >= SIMM_MIN)
  800. return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | IMM(argw));
  801. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  802. if (argw <= 0x7fff7fffl && argw >= -0x80000000l) {
  803. #endif
  804. high_short = (sljit_s32)(argw + ((argw & 0x8000) << 1)) & ~0xffff;
  805. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  806. SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l);
  807. #else
  808. SLJIT_ASSERT(high_short);
  809. #endif
  810. FAIL_IF(push_inst(compiler, ADDIS | D(tmp_reg) | A(arg) | IMM(high_short >> 16)));
  811. return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_reg) | IMM(argw));
  812. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  813. }
  814. /* The rest is PPC-64 only. */
  815. FAIL_IF(load_immediate(compiler, tmp_reg, argw));
  816. inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
  817. return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
  818. #endif
  819. }
  820. static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags,
  821. sljit_s32 dst, sljit_sw dstw,
  822. sljit_s32 src1, sljit_sw src1w,
  823. sljit_s32 src2, sljit_sw src2w)
  824. {
  825. /* arg1 goes to TMP_REG1 or src reg
  826. arg2 goes to TMP_REG2, imm or src reg
  827. result goes to TMP_REG2, so put result can use TMP_REG1. */
  828. sljit_s32 dst_r = TMP_REG2;
  829. sljit_s32 src1_r;
  830. sljit_s32 src2_r;
  831. sljit_s32 sugg_src2_r = TMP_REG2;
  832. sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_SIGN_EXT | ALT_SET_FLAGS);
  833. /* Destination check. */
  834. if (SLOW_IS_REG(dst)) {
  835. dst_r = dst;
  836. flags |= REG_DEST;
  837. if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
  838. sugg_src2_r = dst_r;
  839. }
  840. /* Source 1. */
  841. if (FAST_IS_REG(src1)) {
  842. src1_r = src1;
  843. flags |= REG1_SOURCE;
  844. }
  845. else if (src1 & SLJIT_IMM) {
  846. FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
  847. src1_r = TMP_REG1;
  848. }
  849. else {
  850. FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
  851. src1_r = TMP_REG1;
  852. }
  853. /* Source 2. */
  854. if (FAST_IS_REG(src2)) {
  855. src2_r = src2;
  856. flags |= REG2_SOURCE;
  857. if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
  858. dst_r = src2_r;
  859. }
  860. else if (src2 & SLJIT_IMM) {
  861. FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
  862. src2_r = sugg_src2_r;
  863. }
  864. else {
  865. FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, TMP_REG2));
  866. src2_r = sugg_src2_r;
  867. }
  868. FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
  869. if (!(dst & SLJIT_MEM))
  870. return SLJIT_SUCCESS;
  871. return emit_op_mem(compiler, input_flags, dst_r, dst, dstw, TMP_REG1);
  872. }
  873. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
  874. {
  875. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  876. sljit_s32 int_op = op & SLJIT_I32_OP;
  877. #endif
  878. CHECK_ERROR();
  879. CHECK(check_sljit_emit_op0(compiler, op));
  880. op = GET_OPCODE(op);
  881. switch (op) {
  882. case SLJIT_BREAKPOINT:
  883. case SLJIT_NOP:
  884. return push_inst(compiler, NOP);
  885. case SLJIT_LMUL_UW:
  886. case SLJIT_LMUL_SW:
  887. FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
  888. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  889. FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
  890. return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
  891. #else
  892. FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
  893. return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
  894. #endif
  895. case SLJIT_DIVMOD_UW:
  896. case SLJIT_DIVMOD_SW:
  897. FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
  898. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  899. FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) : (op == SLJIT_DIVMOD_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
  900. FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
  901. #else
  902. FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
  903. FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
  904. #endif
  905. return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
  906. case SLJIT_DIV_UW:
  907. case SLJIT_DIV_SW:
  908. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  909. return push_inst(compiler, (int_op ? (op == SLJIT_DIV_UW ? DIVWU : DIVW) : (op == SLJIT_DIV_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
  910. #else
  911. return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
  912. #endif
  913. }
  914. return SLJIT_SUCCESS;
  915. }
  916. static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
  917. sljit_s32 src, sljit_sw srcw)
  918. {
  919. if (!(src & OFFS_REG_MASK)) {
  920. if (srcw == 0 && (src & REG_MASK) != SLJIT_UNUSED)
  921. return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK));
  922. FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
  923. /* Works with SLJIT_MEM0() case as well. */
  924. return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
  925. }
  926. srcw &= 0x3;
  927. if (srcw == 0)
  928. return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src)));
  929. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  930. FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(src)) | A(TMP_REG1) | (srcw << 11) | ((31 - srcw) << 1)));
  931. #else
  932. FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(src), srcw, 63 - srcw, 1)));
  933. #endif
  934. return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
  935. }
  936. #define EMIT_MOV(type, type_flags, type_cast) \
  937. emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw)
  938. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
  939. sljit_s32 dst, sljit_sw dstw,
  940. sljit_s32 src, sljit_sw srcw)
  941. {
  942. sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
  943. sljit_s32 op_flags = GET_ALL_FLAGS(op);
  944. CHECK_ERROR();
  945. CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
  946. ADJUST_LOCAL_OFFSET(dst, dstw);
  947. ADJUST_LOCAL_OFFSET(src, srcw);
  948. if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
  949. if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
  950. return emit_prefetch(compiler, src, srcw);
  951. return SLJIT_SUCCESS;
  952. }
  953. op = GET_OPCODE(op);
  954. if ((src & SLJIT_IMM) && srcw == 0)
  955. src = TMP_ZERO;
  956. if (GET_FLAG_TYPE(op_flags) == SLJIT_OVERFLOW)
  957. FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
  958. if (op < SLJIT_NOT && FAST_IS_REG(src) && src == dst) {
  959. if (!TYPE_CAST_NEEDED(op))
  960. return SLJIT_SUCCESS;
  961. }
  962. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  963. if (op_flags & SLJIT_I32_OP) {
  964. if (op < SLJIT_NOT) {
  965. if (src & SLJIT_MEM) {
  966. if (op == SLJIT_MOV_S32)
  967. op = SLJIT_MOV_U32;
  968. }
  969. else if (src & SLJIT_IMM) {
  970. if (op == SLJIT_MOV_U32)
  971. op = SLJIT_MOV_S32;
  972. }
  973. }
  974. else {
  975. /* Most operations expect sign extended arguments. */
  976. flags |= INT_DATA | SIGNED_DATA;
  977. if (HAS_FLAGS(op_flags))
  978. flags |= ALT_SIGN_EXT;
  979. }
  980. }
  981. #endif
  982. switch (op) {
  983. case SLJIT_MOV:
  984. case SLJIT_MOV_P:
  985. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  986. case SLJIT_MOV_U32:
  987. case SLJIT_MOV_S32:
  988. #endif
  989. return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  990. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  991. case SLJIT_MOV_U32:
  992. return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32));
  993. case SLJIT_MOV_S32:
  994. return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32));
  995. #endif
  996. case SLJIT_MOV_U8:
  997. return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8));
  998. case SLJIT_MOV_S8:
  999. return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8));
  1000. case SLJIT_MOV_U16:
  1001. return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16));
  1002. case SLJIT_MOV_S16:
  1003. return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16));
  1004. case SLJIT_NOT:
  1005. return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw);
  1006. case SLJIT_NEG:
  1007. return emit_op(compiler, SLJIT_NEG, flags | (GET_FLAG_TYPE(op_flags) ? ALT_FORM1 : 0), dst, dstw, TMP_REG1, 0, src, srcw);
  1008. case SLJIT_CLZ:
  1009. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1010. return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_I32_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);
  1011. #else
  1012. return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw);
  1013. #endif
  1014. }
  1015. return SLJIT_SUCCESS;
  1016. }
  1017. #undef EMIT_MOV
  1018. #define TEST_SL_IMM(src, srcw) \
  1019. (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
  1020. #define TEST_UL_IMM(src, srcw) \
  1021. (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
  1022. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1023. #define TEST_SH_IMM(src, srcw) \
  1024. (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)
  1025. #else
  1026. #define TEST_SH_IMM(src, srcw) \
  1027. (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
  1028. #endif
  1029. #define TEST_UH_IMM(src, srcw) \
  1030. (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
  1031. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1032. #define TEST_ADD_IMM(src, srcw) \
  1033. (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)
  1034. #else
  1035. #define TEST_ADD_IMM(src, srcw) \
  1036. ((src) & SLJIT_IMM)
  1037. #endif
  1038. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1039. #define TEST_UI_IMM(src, srcw) \
  1040. (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
  1041. #else
  1042. #define TEST_UI_IMM(src, srcw) \
  1043. ((src) & SLJIT_IMM)
  1044. #endif
  1045. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
  1046. sljit_s32 dst, sljit_sw dstw,
  1047. sljit_s32 src1, sljit_sw src1w,
  1048. sljit_s32 src2, sljit_sw src2w)
  1049. {
  1050. sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
  1051. CHECK_ERROR();
  1052. CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
  1053. ADJUST_LOCAL_OFFSET(dst, dstw);
  1054. ADJUST_LOCAL_OFFSET(src1, src1w);
  1055. ADJUST_LOCAL_OFFSET(src2, src2w);
  1056. if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
  1057. return SLJIT_SUCCESS;
  1058. if ((src1 & SLJIT_IMM) && src1w == 0)
  1059. src1 = TMP_ZERO;
  1060. if ((src2 & SLJIT_IMM) && src2w == 0)
  1061. src2 = TMP_ZERO;
  1062. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1063. if (op & SLJIT_I32_OP) {
  1064. /* Most operations expect sign extended arguments. */
  1065. flags |= INT_DATA | SIGNED_DATA;
  1066. if (src1 & SLJIT_IMM)
  1067. src1w = (sljit_s32)(src1w);
  1068. if (src2 & SLJIT_IMM)
  1069. src2w = (sljit_s32)(src2w);
  1070. if (HAS_FLAGS(op))
  1071. flags |= ALT_SIGN_EXT;
  1072. }
  1073. #endif
  1074. if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
  1075. FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
  1076. switch (GET_OPCODE(op)) {
  1077. case SLJIT_ADD:
  1078. if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
  1079. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
  1080. if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
  1081. if (TEST_SL_IMM(src2, src2w)) {
  1082. compiler->imm = src2w & 0xffff;
  1083. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
  1084. }
  1085. if (TEST_SL_IMM(src1, src1w)) {
  1086. compiler->imm = src1w & 0xffff;
  1087. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
  1088. }
  1089. if (TEST_SH_IMM(src2, src2w)) {
  1090. compiler->imm = (src2w >> 16) & 0xffff;
  1091. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
  1092. }
  1093. if (TEST_SH_IMM(src1, src1w)) {
  1094. compiler->imm = (src1w >> 16) & 0xffff;
  1095. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
  1096. }
  1097. /* Range between -1 and -32768 is covered above. */
  1098. if (TEST_ADD_IMM(src2, src2w)) {
  1099. compiler->imm = src2w & 0xffffffff;
  1100. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
  1101. }
  1102. if (TEST_ADD_IMM(src1, src1w)) {
  1103. compiler->imm = src1w & 0xffffffff;
  1104. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
  1105. }
  1106. }
  1107. if (HAS_FLAGS(op)) {
  1108. if (TEST_SL_IMM(src2, src2w)) {
  1109. compiler->imm = src2w & 0xffff;
  1110. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
  1111. }
  1112. if (TEST_SL_IMM(src1, src1w)) {
  1113. compiler->imm = src1w & 0xffff;
  1114. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
  1115. }
  1116. }
  1117. return emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM4 : 0), dst, dstw, src1, src1w, src2, src2w);
  1118. case SLJIT_ADDC:
  1119. return emit_op(compiler, SLJIT_ADDC, flags, dst, dstw, src1, src1w, src2, src2w);
  1120. case SLJIT_SUB:
  1121. if (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_LESS_EQUAL) {
  1122. if (dst == SLJIT_UNUSED) {
  1123. if (TEST_UL_IMM(src2, src2w)) {
  1124. compiler->imm = src2w & 0xffff;
  1125. return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
  1126. }
  1127. return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
  1128. }
  1129. if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= (SIMM_MAX + 1)) {
  1130. compiler->imm = src2w;
  1131. return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
  1132. }
  1133. return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);
  1134. }
  1135. if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
  1136. return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, src2, src2w);
  1137. if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
  1138. if (TEST_SL_IMM(src2, -src2w)) {
  1139. compiler->imm = (-src2w) & 0xffff;
  1140. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
  1141. }
  1142. if (TEST_SL_IMM(src1, src1w)) {
  1143. compiler->imm = src1w & 0xffff;
  1144. return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
  1145. }
  1146. if (TEST_SH_IMM(src2, -src2w)) {
  1147. compiler->imm = ((-src2w) >> 16) & 0xffff;
  1148. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
  1149. }
  1150. /* Range between -1 and -32768 is covered above. */
  1151. if (TEST_ADD_IMM(src2, -src2w)) {
  1152. compiler->imm = -src2w & 0xffffffff;
  1153. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
  1154. }
  1155. }
  1156. if (dst == SLJIT_UNUSED && GET_FLAG_TYPE(op) != GET_FLAG_TYPE(SLJIT_SET_CARRY)) {
  1157. if (TEST_SL_IMM(src2, src2w)) {
  1158. compiler->imm = src2w & 0xffff;
  1159. return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4 | ALT_FORM5, dst, dstw, src1, src1w, TMP_REG2, 0);
  1160. }
  1161. return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
  1162. }
  1163. if (TEST_SL_IMM(src2, -src2w)) {
  1164. compiler->imm = (-src2w) & 0xffff;
  1165. return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
  1166. }
  1167. /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
  1168. return emit_op(compiler, SLJIT_SUB, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
  1169. case SLJIT_SUBC:
  1170. return emit_op(compiler, SLJIT_SUBC, flags, dst, dstw, src1, src1w, src2, src2w);
  1171. case SLJIT_MUL:
  1172. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1173. if (op & SLJIT_I32_OP)
  1174. flags |= ALT_FORM2;
  1175. #endif
  1176. if (!HAS_FLAGS(op)) {
  1177. if (TEST_SL_IMM(src2, src2w)) {
  1178. compiler->imm = src2w & 0xffff;
  1179. return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
  1180. }
  1181. if (TEST_SL_IMM(src1, src1w)) {
  1182. compiler->imm = src1w & 0xffff;
  1183. return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
  1184. }
  1185. }
  1186. else
  1187. FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
  1188. return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);
  1189. case SLJIT_AND:
  1190. case SLJIT_OR:
  1191. case SLJIT_XOR:
  1192. /* Commutative unsigned operations. */
  1193. if (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
  1194. if (TEST_UL_IMM(src2, src2w)) {
  1195. compiler->imm = src2w;
  1196. return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
  1197. }
  1198. if (TEST_UL_IMM(src1, src1w)) {
  1199. compiler->imm = src1w;
  1200. return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
  1201. }
  1202. if (TEST_UH_IMM(src2, src2w)) {
  1203. compiler->imm = (src2w >> 16) & 0xffff;
  1204. return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
  1205. }
  1206. if (TEST_UH_IMM(src1, src1w)) {
  1207. compiler->imm = (src1w >> 16) & 0xffff;
  1208. return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
  1209. }
  1210. }
  1211. if (GET_OPCODE(op) != SLJIT_AND && GET_OPCODE(op) != SLJIT_AND) {
  1212. /* Unlike or and xor, and resets unwanted bits as well. */
  1213. if (TEST_UI_IMM(src2, src2w)) {
  1214. compiler->imm = src2w;
  1215. return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
  1216. }
  1217. if (TEST_UI_IMM(src1, src1w)) {
  1218. compiler->imm = src1w;
  1219. return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
  1220. }
  1221. }
  1222. return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
  1223. case SLJIT_SHL:
  1224. case SLJIT_LSHR:
  1225. case SLJIT_ASHR:
  1226. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1227. if (op & SLJIT_I32_OP)
  1228. flags |= ALT_FORM2;
  1229. #endif
  1230. if (src2 & SLJIT_IMM) {
  1231. compiler->imm = src2w;
  1232. return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
  1233. }
  1234. return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
  1235. }
  1236. return SLJIT_SUCCESS;
  1237. }
  1238. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
  1239. {
  1240. CHECK_REG_INDEX(check_sljit_get_register_index(reg));
  1241. return reg_map[reg];
  1242. }
  1243. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
  1244. {
  1245. CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
  1246. return freg_map[reg];
  1247. }
  1248. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
  1249. void *instruction, sljit_s32 size)
  1250. {
  1251. CHECK_ERROR();
  1252. CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
  1253. return push_inst(compiler, *(sljit_ins*)instruction);
  1254. }
  1255. /* --------------------------------------------------------------------- */
  1256. /* Floating point operators */
  1257. /* --------------------------------------------------------------------- */
  1258. #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6))
  1259. #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
  1260. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1261. #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))
  1262. #else
  1263. #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))
  1264. #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
  1265. #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))
  1266. #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))
  1267. #else
  1268. #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))
  1269. #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))
  1270. #endif
  1271. #endif /* SLJIT_CONFIG_PPC_64 */
  1272. static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
  1273. sljit_s32 dst, sljit_sw dstw,
  1274. sljit_s32 src, sljit_sw srcw)
  1275. {
  1276. if (src & SLJIT_MEM) {
  1277. /* We can ignore the temporary data store on the stack from caching point of view. */
  1278. FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
  1279. src = TMP_FREG1;
  1280. }
  1281. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1282. op = GET_OPCODE(op);
  1283. FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
  1284. if (op == SLJIT_CONV_SW_FROM_F64) {
  1285. if (FAST_IS_REG(dst)) {
  1286. FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
  1287. return emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
  1288. }
  1289. return emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1);
  1290. }
  1291. #else
  1292. FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
  1293. #endif
  1294. if (FAST_IS_REG(dst)) {
  1295. FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
  1296. FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
  1297. return emit_op_mem(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
  1298. }
  1299. SLJIT_ASSERT(dst & SLJIT_MEM);
  1300. if (dst & OFFS_REG_MASK) {
  1301. dstw &= 0x3;
  1302. if (dstw) {
  1303. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  1304. FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1)));
  1305. #else
  1306. FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1)));
  1307. #endif
  1308. dstw = TMP_REG1;
  1309. }
  1310. else
  1311. dstw = OFFS_REG(dst);
  1312. }
  1313. else {
  1314. if ((dst & REG_MASK) && !dstw) {
  1315. dstw = dst & REG_MASK;
  1316. dst = 0;
  1317. }
  1318. else {
  1319. /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */
  1320. FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));
  1321. dstw = TMP_REG1;
  1322. }
  1323. }
  1324. return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));
  1325. }
  1326. static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
  1327. sljit_s32 dst, sljit_sw dstw,
  1328. sljit_s32 src, sljit_sw srcw)
  1329. {
  1330. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1331. sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
  1332. if (src & SLJIT_IMM) {
  1333. if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
  1334. srcw = (sljit_s32)srcw;
  1335. FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
  1336. src = TMP_REG1;
  1337. }
  1338. else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {
  1339. if (FAST_IS_REG(src))
  1340. FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
  1341. else
  1342. FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
  1343. src = TMP_REG1;
  1344. }
  1345. if (FAST_IS_REG(src)) {
  1346. FAIL_IF(emit_op_mem(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
  1347. FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
  1348. }
  1349. else
  1350. FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
  1351. FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
  1352. if (dst & SLJIT_MEM)
  1353. return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
  1354. if (op & SLJIT_F32_OP)
  1355. return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
  1356. return SLJIT_SUCCESS;
  1357. #else
  1358. sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
  1359. sljit_s32 invert_sign = 1;
  1360. if (src & SLJIT_IMM) {
  1361. FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000));
  1362. src = TMP_REG1;
  1363. invert_sign = 0;
  1364. }
  1365. else if (!FAST_IS_REG(src)) {
  1366. FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
  1367. src = TMP_REG1;
  1368. }
  1369. /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))
  1370. The double precision format has exactly 53 bit precision, so the lower 32 bit represents
  1371. the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000
  1372. to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating
  1373. point value, we need to substract 2^53 + 2^31 from the constructed value. */
  1374. FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
  1375. if (invert_sign)
  1376. FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
  1377. FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, TMP_REG1));
  1378. FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
  1379. FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
  1380. FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
  1381. FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
  1382. FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
  1383. FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
  1384. if (dst & SLJIT_MEM)
  1385. return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
  1386. if (op & SLJIT_F32_OP)
  1387. return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
  1388. return SLJIT_SUCCESS;
  1389. #endif
  1390. }
  1391. static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
  1392. sljit_s32 src1, sljit_sw src1w,
  1393. sljit_s32 src2, sljit_sw src2w)
  1394. {
  1395. if (src1 & SLJIT_MEM) {
  1396. FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
  1397. src1 = TMP_FREG1;
  1398. }
  1399. if (src2 & SLJIT_MEM) {
  1400. FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
  1401. src2 = TMP_FREG2;
  1402. }
  1403. return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2));
  1404. }
  1405. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
  1406. sljit_s32 dst, sljit_sw dstw,
  1407. sljit_s32 src, sljit_sw srcw)
  1408. {
  1409. sljit_s32 dst_r;
  1410. CHECK_ERROR();
  1411. SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
  1412. SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
  1413. if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
  1414. op ^= SLJIT_F32_OP;
  1415. dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
  1416. if (src & SLJIT_MEM) {
  1417. FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, TMP_REG1));
  1418. src = dst_r;
  1419. }
  1420. switch (GET_OPCODE(op)) {
  1421. case SLJIT_CONV_F64_FROM_F32:
  1422. op ^= SLJIT_F32_OP;
  1423. if (op & SLJIT_F32_OP) {
  1424. FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
  1425. break;
  1426. }
  1427. /* Fall through. */
  1428. case SLJIT_MOV_F64:
  1429. if (src != dst_r) {
  1430. if (dst_r != TMP_FREG1)
  1431. FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
  1432. else
  1433. dst_r = src;
  1434. }
  1435. break;
  1436. case SLJIT_NEG_F64:
  1437. FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));
  1438. break;
  1439. case SLJIT_ABS_F64:
  1440. FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));
  1441. break;
  1442. }
  1443. if (dst & SLJIT_MEM)
  1444. FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), dst_r, dst, dstw, TMP_REG1));
  1445. return SLJIT_SUCCESS;
  1446. }
  1447. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
  1448. sljit_s32 dst, sljit_sw dstw,
  1449. sljit_s32 src1, sljit_sw src1w,
  1450. sljit_s32 src2, sljit_sw src2w)
  1451. {
  1452. sljit_s32 dst_r;
  1453. CHECK_ERROR();
  1454. CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
  1455. ADJUST_LOCAL_OFFSET(dst, dstw);
  1456. ADJUST_LOCAL_OFFSET(src1, src1w);
  1457. ADJUST_LOCAL_OFFSET(src2, src2w);
  1458. dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
  1459. if (src1 & SLJIT_MEM) {
  1460. FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
  1461. src1 = TMP_FREG1;
  1462. }
  1463. if (src2 & SLJIT_MEM) {
  1464. FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
  1465. src2 = TMP_FREG2;
  1466. }
  1467. switch (GET_OPCODE(op)) {
  1468. case SLJIT_ADD_F64:
  1469. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));
  1470. break;
  1471. case SLJIT_SUB_F64:
  1472. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));
  1473. break;
  1474. case SLJIT_MUL_F64:
  1475. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
  1476. break;
  1477. case SLJIT_DIV_F64:
  1478. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));
  1479. break;
  1480. }
  1481. if (dst & SLJIT_MEM)
  1482. FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, TMP_REG1));
  1483. return SLJIT_SUCCESS;
  1484. }
  1485. #undef SELECT_FOP
  1486. /* --------------------------------------------------------------------- */
  1487. /* Other instructions */
  1488. /* --------------------------------------------------------------------- */
  1489. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
  1490. {
  1491. CHECK_ERROR();
  1492. CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
  1493. ADJUST_LOCAL_OFFSET(dst, dstw);
  1494. if (FAST_IS_REG(dst))
  1495. return push_inst(compiler, MFLR | D(dst));
  1496. /* Memory. */
  1497. FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
  1498. return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
  1499. }
  1500. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
  1501. {
  1502. CHECK_ERROR();
  1503. CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
  1504. ADJUST_LOCAL_OFFSET(src, srcw);
  1505. if (FAST_IS_REG(src))
  1506. FAIL_IF(push_inst(compiler, MTLR | S(src)));
  1507. else {
  1508. FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
  1509. FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
  1510. }
  1511. return push_inst(compiler, BLR);
  1512. }
  1513. /* --------------------------------------------------------------------- */
  1514. /* Conditional instructions */
  1515. /* --------------------------------------------------------------------- */
  1516. SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
  1517. {
  1518. struct sljit_label *label;
  1519. CHECK_ERROR_PTR();
  1520. CHECK_PTR(check_sljit_emit_label(compiler));
  1521. if (compiler->last_label && compiler->last_label->size == compiler->size)
  1522. return compiler->last_label;
  1523. label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
  1524. PTR_FAIL_IF(!label);
  1525. set_label(label, compiler);
  1526. return label;
  1527. }
  1528. static sljit_ins get_bo_bi_flags(sljit_s32 type)
  1529. {
  1530. switch (type) {
  1531. case SLJIT_EQUAL:
  1532. return (12 << 21) | (2 << 16);
  1533. case SLJIT_NOT_EQUAL:
  1534. return (4 << 21) | (2 << 16);
  1535. case SLJIT_LESS:
  1536. case SLJIT_SIG_LESS:
  1537. return (12 << 21) | (0 << 16);
  1538. case SLJIT_GREATER_EQUAL:
  1539. case SLJIT_SIG_GREATER_EQUAL:
  1540. return (4 << 21) | (0 << 16);
  1541. case SLJIT_GREATER:
  1542. case SLJIT_SIG_GREATER:
  1543. return (12 << 21) | (1 << 16);
  1544. case SLJIT_LESS_EQUAL:
  1545. case SLJIT_SIG_LESS_EQUAL:
  1546. return (4 << 21) | (1 << 16);
  1547. case SLJIT_LESS_F64:
  1548. return (12 << 21) | ((4 + 0) << 16);
  1549. case SLJIT_GREATER_EQUAL_F64:
  1550. return (4 << 21) | ((4 + 0) << 16);
  1551. case SLJIT_GREATER_F64:
  1552. return (12 << 21) | ((4 + 1) << 16);
  1553. case SLJIT_LESS_EQUAL_F64:
  1554. return (4 << 21) | ((4 + 1) << 16);
  1555. case SLJIT_OVERFLOW:
  1556. case SLJIT_MUL_OVERFLOW:
  1557. return (12 << 21) | (3 << 16);
  1558. case SLJIT_NOT_OVERFLOW:
  1559. case SLJIT_MUL_NOT_OVERFLOW:
  1560. return (4 << 21) | (3 << 16);
  1561. case SLJIT_EQUAL_F64:
  1562. return (12 << 21) | ((4 + 2) << 16);
  1563. case SLJIT_NOT_EQUAL_F64:
  1564. return (4 << 21) | ((4 + 2) << 16);
  1565. case SLJIT_UNORDERED_F64:
  1566. return (12 << 21) | ((4 + 3) << 16);
  1567. case SLJIT_ORDERED_F64:
  1568. return (4 << 21) | ((4 + 3) << 16);
  1569. default:
  1570. SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_CDECL);
  1571. return (20 << 21);
  1572. }
  1573. }
  1574. SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
  1575. {
  1576. struct sljit_jump *jump;
  1577. sljit_ins bo_bi_flags;
  1578. CHECK_ERROR_PTR();
  1579. CHECK_PTR(check_sljit_emit_jump(compiler, type));
  1580. bo_bi_flags = get_bo_bi_flags(type & 0xff);
  1581. if (!bo_bi_flags)
  1582. return NULL;
  1583. jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
  1584. PTR_FAIL_IF(!jump);
  1585. set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
  1586. type &= 0xff;
  1587. /* In PPC, we don't need to touch the arguments. */
  1588. if (type < SLJIT_JUMP)
  1589. jump->flags |= IS_COND;
  1590. #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
  1591. if (type >= SLJIT_CALL)
  1592. jump->flags |= IS_CALL;
  1593. #endif
  1594. PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
  1595. PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));
  1596. jump->addr = compiler->size;
  1597. PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
  1598. return jump;
  1599. }
  1600. SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
  1601. sljit_s32 arg_types)
  1602. {
  1603. CHECK_ERROR_PTR();
  1604. CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
  1605. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1606. PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
  1607. #endif
  1608. #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
  1609. || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
  1610. compiler->skip_checks = 1;
  1611. #endif
  1612. return sljit_emit_jump(compiler, type);
  1613. }
  1614. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
  1615. {
  1616. struct sljit_jump *jump = NULL;
  1617. sljit_s32 src_r;
  1618. CHECK_ERROR();
  1619. CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
  1620. ADJUST_LOCAL_OFFSET(src, srcw);
  1621. if (FAST_IS_REG(src)) {
  1622. #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
  1623. if (type >= SLJIT_CALL) {
  1624. FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
  1625. src_r = TMP_CALL_REG;
  1626. }
  1627. else
  1628. src_r = src;
  1629. #else
  1630. src_r = src;
  1631. #endif
  1632. } else if (src & SLJIT_IMM) {
  1633. /* These jumps are converted to jump/call instructions when possible. */
  1634. jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
  1635. FAIL_IF(!jump);
  1636. set_jump(jump, compiler, JUMP_ADDR);
  1637. jump->u.target = srcw;
  1638. #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
  1639. if (type >= SLJIT_CALL)
  1640. jump->flags |= IS_CALL;
  1641. #endif
  1642. FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
  1643. src_r = TMP_CALL_REG;
  1644. }
  1645. else {
  1646. FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
  1647. src_r = TMP_CALL_REG;
  1648. }
  1649. FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
  1650. if (jump)
  1651. jump->addr = compiler->size;
  1652. return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
  1653. }
  1654. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
  1655. sljit_s32 arg_types,
  1656. sljit_s32 src, sljit_sw srcw)
  1657. {
  1658. CHECK_ERROR();
  1659. CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
  1660. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1661. if (src & SLJIT_MEM) {
  1662. ADJUST_LOCAL_OFFSET(src, srcw);
  1663. FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
  1664. src = TMP_CALL_REG;
  1665. }
  1666. FAIL_IF(call_with_args(compiler, arg_types, &src));
  1667. #endif
  1668. #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
  1669. || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
  1670. compiler->skip_checks = 1;
  1671. #endif
  1672. return sljit_emit_ijump(compiler, type, src, srcw);
  1673. }
  1674. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
  1675. sljit_s32 dst, sljit_sw dstw,
  1676. sljit_s32 type)
  1677. {
  1678. sljit_s32 reg, input_flags, cr_bit, invert;
  1679. sljit_s32 saved_op = op;
  1680. sljit_sw saved_dstw = dstw;
  1681. CHECK_ERROR();
  1682. CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
  1683. ADJUST_LOCAL_OFFSET(dst, dstw);
  1684. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1685. input_flags = (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA;
  1686. #else
  1687. input_flags = WORD_DATA;
  1688. #endif
  1689. op = GET_OPCODE(op);
  1690. reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
  1691. if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
  1692. FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG1));
  1693. invert = 0;
  1694. cr_bit = 0;
  1695. switch (type & 0xff) {
  1696. case SLJIT_LESS:
  1697. case SLJIT_SIG_LESS:
  1698. break;
  1699. case SLJIT_GREATER_EQUAL:
  1700. case SLJIT_SIG_GREATER_EQUAL:
  1701. invert = 1;
  1702. break;
  1703. case SLJIT_GREATER:
  1704. case SLJIT_SIG_GREATER:
  1705. cr_bit = 1;
  1706. break;
  1707. case SLJIT_LESS_EQUAL:
  1708. case SLJIT_SIG_LESS_EQUAL:
  1709. cr_bit = 1;
  1710. invert = 1;
  1711. break;
  1712. case SLJIT_EQUAL:
  1713. cr_bit = 2;
  1714. break;
  1715. case SLJIT_NOT_EQUAL:
  1716. cr_bit = 2;
  1717. invert = 1;
  1718. break;
  1719. case SLJIT_OVERFLOW:
  1720. case SLJIT_MUL_OVERFLOW:
  1721. cr_bit = 3;
  1722. break;
  1723. case SLJIT_NOT_OVERFLOW:
  1724. case SLJIT_MUL_NOT_OVERFLOW:
  1725. cr_bit = 3;
  1726. invert = 1;
  1727. break;
  1728. case SLJIT_LESS_F64:
  1729. cr_bit = 4 + 0;
  1730. break;
  1731. case SLJIT_GREATER_EQUAL_F64:
  1732. cr_bit = 4 + 0;
  1733. invert = 1;
  1734. break;
  1735. case SLJIT_GREATER_F64:
  1736. cr_bit = 4 + 1;
  1737. break;
  1738. case SLJIT_LESS_EQUAL_F64:
  1739. cr_bit = 4 + 1;
  1740. invert = 1;
  1741. break;
  1742. case SLJIT_EQUAL_F64:
  1743. cr_bit = 4 + 2;
  1744. break;
  1745. case SLJIT_NOT_EQUAL_F64:
  1746. cr_bit = 4 + 2;
  1747. invert = 1;
  1748. break;
  1749. case SLJIT_UNORDERED_F64:
  1750. cr_bit = 4 + 3;
  1751. break;
  1752. case SLJIT_ORDERED_F64:
  1753. cr_bit = 4 + 3;
  1754. invert = 1;
  1755. break;
  1756. default:
  1757. SLJIT_UNREACHABLE();
  1758. break;
  1759. }
  1760. FAIL_IF(push_inst(compiler, MFCR | D(reg)));
  1761. FAIL_IF(push_inst(compiler, RLWINM | S(reg) | A(reg) | ((1 + (cr_bit)) << 11) | (31 << 6) | (31 << 1)));
  1762. if (invert)
  1763. FAIL_IF(push_inst(compiler, XORI | S(reg) | A(reg) | 0x1));
  1764. if (op < SLJIT_ADD) {
  1765. if (!(dst & SLJIT_MEM))
  1766. return SLJIT_SUCCESS;
  1767. return emit_op_mem(compiler, input_flags, reg, dst, dstw, TMP_REG1);
  1768. }
  1769. #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
  1770. || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
  1771. compiler->skip_checks = 1;
  1772. #endif
  1773. if (dst & SLJIT_MEM)
  1774. return sljit_emit_op2(compiler, saved_op, dst, saved_dstw, TMP_REG1, 0, TMP_REG2, 0);
  1775. return sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0);
  1776. }
  1777. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
  1778. sljit_s32 dst_reg,
  1779. sljit_s32 src, sljit_sw srcw)
  1780. {
  1781. CHECK_ERROR();
  1782. CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
  1783. return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
  1784. }
  1785. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
  1786. sljit_s32 reg,
  1787. sljit_s32 mem, sljit_sw memw)
  1788. {
  1789. sljit_s32 mem_flags;
  1790. sljit_ins inst;
  1791. CHECK_ERROR();
  1792. CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
  1793. if (type & SLJIT_MEM_POST)
  1794. return SLJIT_ERR_UNSUPPORTED;
  1795. switch (type & 0xff) {
  1796. case SLJIT_MOV:
  1797. case SLJIT_MOV_P:
  1798. #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
  1799. case SLJIT_MOV_U32:
  1800. case SLJIT_MOV_S32:
  1801. #endif
  1802. mem_flags = WORD_DATA;
  1803. break;
  1804. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1805. case SLJIT_MOV_U32:
  1806. mem_flags = INT_DATA;
  1807. break;
  1808. case SLJIT_MOV_S32:
  1809. mem_flags = INT_DATA;
  1810. if (!(type & SLJIT_MEM_STORE) && !(type & SLJIT_I32_OP)) {
  1811. if (mem & OFFS_REG_MASK)
  1812. mem_flags |= SIGNED_DATA;
  1813. else
  1814. return SLJIT_ERR_UNSUPPORTED;
  1815. }
  1816. break;
  1817. #endif
  1818. case SLJIT_MOV_U8:
  1819. case SLJIT_MOV_S8:
  1820. mem_flags = BYTE_DATA;
  1821. break;
  1822. case SLJIT_MOV_U16:
  1823. mem_flags = HALF_DATA;
  1824. break;
  1825. case SLJIT_MOV_S16:
  1826. mem_flags = HALF_DATA | SIGNED_DATA;
  1827. break;
  1828. default:
  1829. SLJIT_UNREACHABLE();
  1830. mem_flags = WORD_DATA;
  1831. break;
  1832. }
  1833. if (!(type & SLJIT_MEM_STORE))
  1834. mem_flags |= LOAD_DATA;
  1835. if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
  1836. if (memw != 0)
  1837. return SLJIT_ERR_UNSUPPORTED;
  1838. if (type & SLJIT_MEM_SUPP)
  1839. return SLJIT_SUCCESS;
  1840. inst = updated_data_transfer_insts[mem_flags | INDEXED];
  1841. FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | B(OFFS_REG(mem))));
  1842. }
  1843. else {
  1844. if (memw > SIMM_MAX || memw < SIMM_MIN)
  1845. return SLJIT_ERR_UNSUPPORTED;
  1846. inst = updated_data_transfer_insts[mem_flags];
  1847. #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
  1848. if ((inst & INT_ALIGNED) && (memw & 0x3) != 0)
  1849. return SLJIT_ERR_UNSUPPORTED;
  1850. #endif
  1851. if (type & SLJIT_MEM_SUPP)
  1852. return SLJIT_SUCCESS;
  1853. FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | IMM(memw)));
  1854. }
  1855. if ((mem_flags & LOAD_DATA) && (type & 0xff) == SLJIT_MOV_S8)
  1856. return push_inst(compiler, EXTSB | S(reg) | A(reg));
  1857. return SLJIT_SUCCESS;
  1858. }
  1859. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
  1860. sljit_s32 freg,
  1861. sljit_s32 mem, sljit_sw memw)
  1862. {
  1863. sljit_s32 mem_flags;
  1864. sljit_ins inst;
  1865. CHECK_ERROR();
  1866. CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
  1867. if (type & SLJIT_MEM_POST)
  1868. return SLJIT_ERR_UNSUPPORTED;
  1869. if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
  1870. if (memw != 0)
  1871. return SLJIT_ERR_UNSUPPORTED;
  1872. }
  1873. else {
  1874. if (memw > SIMM_MAX || memw < SIMM_MIN)
  1875. return SLJIT_ERR_UNSUPPORTED;
  1876. }
  1877. if (type & SLJIT_MEM_SUPP)
  1878. return SLJIT_SUCCESS;
  1879. mem_flags = FLOAT_DATA(type);
  1880. if (!(type & SLJIT_MEM_STORE))
  1881. mem_flags |= LOAD_DATA;
  1882. if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
  1883. inst = updated_data_transfer_insts[mem_flags | INDEXED];
  1884. return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | B(OFFS_REG(mem)));
  1885. }
  1886. inst = updated_data_transfer_insts[mem_flags];
  1887. return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | IMM(memw));
  1888. }
  1889. SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
  1890. {
  1891. struct sljit_const *const_;
  1892. sljit_s32 reg;
  1893. CHECK_ERROR_PTR();
  1894. CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
  1895. ADJUST_LOCAL_OFFSET(dst, dstw);
  1896. const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
  1897. PTR_FAIL_IF(!const_);
  1898. set_const(const_, compiler);
  1899. reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
  1900. PTR_FAIL_IF(emit_const(compiler, reg, init_value));
  1901. if (dst & SLJIT_MEM)
  1902. PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
  1903. return const_;
  1904. }