sljitNativePPC_common.c 73 KB

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