sljitNativeARM_64.c 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050
  1. /*
  2. * Stack-less Just-In-Time compiler
  3. *
  4. * Copyright 2009-2012 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 SLJIT_CONST char* sljit_get_platform_name(void)
  27. {
  28. return "ARM-64" SLJIT_CPUINFO;
  29. }
  30. /* Length of an instruction word */
  31. typedef sljit_ui sljit_ins;
  32. #define TMP_ZERO (0)
  33. #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
  34. #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
  35. #define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
  36. #define TMP_LR (SLJIT_NUMBER_OF_REGISTERS + 5)
  37. #define TMP_SP (SLJIT_NUMBER_OF_REGISTERS + 6)
  38. #define TMP_FREG1 (0)
  39. #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
  40. static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {
  41. 31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31
  42. };
  43. #define W_OP (1 << 31)
  44. #define RD(rd) (reg_map[rd])
  45. #define RT(rt) (reg_map[rt])
  46. #define RN(rn) (reg_map[rn] << 5)
  47. #define RT2(rt2) (reg_map[rt2] << 10)
  48. #define RM(rm) (reg_map[rm] << 16)
  49. #define VD(vd) (vd)
  50. #define VT(vt) (vt)
  51. #define VN(vn) ((vn) << 5)
  52. #define VM(vm) ((vm) << 16)
  53. /* --------------------------------------------------------------------- */
  54. /* Instrucion forms */
  55. /* --------------------------------------------------------------------- */
  56. #define ADC 0x9a000000
  57. #define ADD 0x8b000000
  58. #define ADDI 0x91000000
  59. #define AND 0x8a000000
  60. #define ANDI 0x92000000
  61. #define ASRV 0x9ac02800
  62. #define B 0x14000000
  63. #define B_CC 0x54000000
  64. #define BL 0x94000000
  65. #define BLR 0xd63f0000
  66. #define BR 0xd61f0000
  67. #define BRK 0xd4200000
  68. #define CBZ 0xb4000000
  69. #define CLZ 0xdac01000
  70. #define CSINC 0x9a800400
  71. #define EOR 0xca000000
  72. #define EORI 0xd2000000
  73. #define FABS 0x1e60c000
  74. #define FADD 0x1e602800
  75. #define FCMP 0x1e602000
  76. #define FCVT 0x1e224000
  77. #define FCVTZS 0x9e780000
  78. #define FDIV 0x1e601800
  79. #define FMOV 0x1e604000
  80. #define FMUL 0x1e600800
  81. #define FNEG 0x1e614000
  82. #define FSUB 0x1e603800
  83. #define LDRI 0xf9400000
  84. #define LDP 0xa9400000
  85. #define LDP_PST 0xa8c00000
  86. #define LSLV 0x9ac02000
  87. #define LSRV 0x9ac02400
  88. #define MADD 0x9b000000
  89. #define MOVK 0xf2800000
  90. #define MOVN 0x92800000
  91. #define MOVZ 0xd2800000
  92. #define NOP 0xd503201f
  93. #define ORN 0xaa200000
  94. #define ORR 0xaa000000
  95. #define ORRI 0xb2000000
  96. #define RET 0xd65f0000
  97. #define SBC 0xda000000
  98. #define SBFM 0x93000000
  99. #define SCVTF 0x9e620000
  100. #define SDIV 0x9ac00c00
  101. #define SMADDL 0x9b200000
  102. #define SMULH 0x9b403c00
  103. #define STP 0xa9000000
  104. #define STP_PRE 0xa9800000
  105. #define STRI 0xf9000000
  106. #define STR_FI 0x3d000000
  107. #define STR_FR 0x3c206800
  108. #define STUR_FI 0x3c000000
  109. #define SUB 0xcb000000
  110. #define SUBI 0xd1000000
  111. #define SUBS 0xeb000000
  112. #define UBFM 0xd3000000
  113. #define UDIV 0x9ac00800
  114. #define UMULH 0x9bc03c00
  115. /* dest_reg is the absolute name of the register
  116. Useful for reordering instructions in the delay slot. */
  117. static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins)
  118. {
  119. sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
  120. FAIL_IF(!ptr);
  121. *ptr = ins;
  122. compiler->size++;
  123. return SLJIT_SUCCESS;
  124. }
  125. static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm)
  126. {
  127. FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));
  128. FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21)));
  129. FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 32) & 0xffff) << 5) | (2 << 21)));
  130. return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21));
  131. }
  132. static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
  133. {
  134. sljit_si dst = inst[0] & 0x1f;
  135. SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
  136. inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5);
  137. inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21);
  138. inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21);
  139. inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
  140. }
  141. static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
  142. {
  143. sljit_sw diff;
  144. sljit_uw target_addr;
  145. if (jump->flags & SLJIT_REWRITABLE_JUMP) {
  146. jump->flags |= PATCH_ABS64;
  147. return 0;
  148. }
  149. if (jump->flags & JUMP_ADDR)
  150. target_addr = jump->u.target;
  151. else {
  152. SLJIT_ASSERT(jump->flags & JUMP_LABEL);
  153. target_addr = (sljit_uw)(code + jump->u.label->size);
  154. }
  155. diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4);
  156. if (jump->flags & IS_COND) {
  157. diff += sizeof(sljit_ins);
  158. if (diff <= 0xfffff && diff >= -0x100000) {
  159. code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1;
  160. jump->addr -= sizeof(sljit_ins);
  161. jump->flags |= PATCH_COND;
  162. return 5;
  163. }
  164. diff -= sizeof(sljit_ins);
  165. }
  166. if (diff <= 0x7ffffff && diff >= -0x8000000) {
  167. jump->flags |= PATCH_B;
  168. return 4;
  169. }
  170. if (target_addr <= 0xffffffffl) {
  171. if (jump->flags & IS_COND)
  172. code_ptr[-5] -= (2 << 5);
  173. code_ptr[-2] = code_ptr[0];
  174. return 2;
  175. }
  176. if (target_addr <= 0xffffffffffffl) {
  177. if (jump->flags & IS_COND)
  178. code_ptr[-5] -= (1 << 5);
  179. jump->flags |= PATCH_ABS48;
  180. code_ptr[-1] = code_ptr[0];
  181. return 1;
  182. }
  183. jump->flags |= PATCH_ABS64;
  184. return 0;
  185. }
  186. SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
  187. {
  188. struct sljit_memory_fragment *buf;
  189. sljit_ins *code;
  190. sljit_ins *code_ptr;
  191. sljit_ins *buf_ptr;
  192. sljit_ins *buf_end;
  193. sljit_uw word_count;
  194. sljit_uw addr;
  195. sljit_si dst;
  196. struct sljit_label *label;
  197. struct sljit_jump *jump;
  198. struct sljit_const *const_;
  199. CHECK_ERROR_PTR();
  200. CHECK_PTR(check_sljit_generate_code(compiler));
  201. reverse_buf(compiler);
  202. code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
  203. PTR_FAIL_WITH_EXEC_IF(code);
  204. buf = compiler->buf;
  205. code_ptr = code;
  206. word_count = 0;
  207. label = compiler->labels;
  208. jump = compiler->jumps;
  209. const_ = compiler->consts;
  210. do {
  211. buf_ptr = (sljit_ins*)buf->memory;
  212. buf_end = buf_ptr + (buf->used_size >> 2);
  213. do {
  214. *code_ptr = *buf_ptr++;
  215. /* These structures are ordered by their address. */
  216. SLJIT_ASSERT(!label || label->size >= word_count);
  217. SLJIT_ASSERT(!jump || jump->addr >= word_count);
  218. SLJIT_ASSERT(!const_ || const_->addr >= word_count);
  219. if (label && label->size == word_count) {
  220. label->addr = (sljit_uw)code_ptr;
  221. label->size = code_ptr - code;
  222. label = label->next;
  223. }
  224. if (jump && jump->addr == word_count) {
  225. jump->addr = (sljit_uw)(code_ptr - 4);
  226. code_ptr -= detect_jump_type(jump, code_ptr, code);
  227. jump = jump->next;
  228. }
  229. if (const_ && const_->addr == word_count) {
  230. const_->addr = (sljit_uw)code_ptr;
  231. const_ = const_->next;
  232. }
  233. code_ptr ++;
  234. word_count ++;
  235. } while (buf_ptr < buf_end);
  236. buf = buf->next;
  237. } while (buf);
  238. if (label && label->size == word_count) {
  239. label->addr = (sljit_uw)code_ptr;
  240. label->size = code_ptr - code;
  241. label = label->next;
  242. }
  243. SLJIT_ASSERT(!label);
  244. SLJIT_ASSERT(!jump);
  245. SLJIT_ASSERT(!const_);
  246. SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
  247. jump = compiler->jumps;
  248. while (jump) {
  249. do {
  250. addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
  251. buf_ptr = (sljit_ins*)jump->addr;
  252. if (jump->flags & PATCH_B) {
  253. addr = (sljit_sw)(addr - jump->addr) >> 2;
  254. SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000);
  255. buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff);
  256. if (jump->flags & IS_COND)
  257. buf_ptr[-1] -= (4 << 5);
  258. break;
  259. }
  260. if (jump->flags & PATCH_COND) {
  261. addr = (sljit_sw)(addr - jump->addr) >> 2;
  262. SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000);
  263. buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5);
  264. break;
  265. }
  266. SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || addr <= 0xffffffffl);
  267. SLJIT_ASSERT((jump->flags & PATCH_ABS64) || addr <= 0xffffffffffffl);
  268. dst = buf_ptr[0] & 0x1f;
  269. buf_ptr[0] = MOVZ | dst | ((addr & 0xffff) << 5);
  270. buf_ptr[1] = MOVK | dst | (((addr >> 16) & 0xffff) << 5) | (1 << 21);
  271. if (jump->flags & (PATCH_ABS48 | PATCH_ABS64))
  272. buf_ptr[2] = MOVK | dst | (((addr >> 32) & 0xffff) << 5) | (2 << 21);
  273. if (jump->flags & PATCH_ABS64)
  274. buf_ptr[3] = MOVK | dst | (((addr >> 48) & 0xffff) << 5) | (3 << 21);
  275. } while (0);
  276. jump = jump->next;
  277. }
  278. compiler->error = SLJIT_ERR_COMPILED;
  279. compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
  280. SLJIT_CACHE_FLUSH(code, code_ptr);
  281. return code;
  282. }
  283. /* --------------------------------------------------------------------- */
  284. /* Core code generator functions. */
  285. /* --------------------------------------------------------------------- */
  286. #define COUNT_TRAILING_ZERO(value, result) \
  287. result = 0; \
  288. if (!(value & 0xffffffff)) { \
  289. result += 32; \
  290. value >>= 32; \
  291. } \
  292. if (!(value & 0xffff)) { \
  293. result += 16; \
  294. value >>= 16; \
  295. } \
  296. if (!(value & 0xff)) { \
  297. result += 8; \
  298. value >>= 8; \
  299. } \
  300. if (!(value & 0xf)) { \
  301. result += 4; \
  302. value >>= 4; \
  303. } \
  304. if (!(value & 0x3)) { \
  305. result += 2; \
  306. value >>= 2; \
  307. } \
  308. if (!(value & 0x1)) { \
  309. result += 1; \
  310. value >>= 1; \
  311. }
  312. #define LOGICAL_IMM_CHECK 0x100
  313. static sljit_ins logical_imm(sljit_sw imm, sljit_si len)
  314. {
  315. sljit_si negated, ones, right;
  316. sljit_uw mask, uimm;
  317. sljit_ins ins;
  318. if (len & LOGICAL_IMM_CHECK) {
  319. len &= ~LOGICAL_IMM_CHECK;
  320. if (len == 32 && (imm == 0 || imm == -1))
  321. return 0;
  322. if (len == 16 && ((sljit_si)imm == 0 || (sljit_si)imm == -1))
  323. return 0;
  324. }
  325. SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1)
  326. || (len == 16 && (sljit_si)imm != 0 && (sljit_si)imm != -1));
  327. uimm = (sljit_uw)imm;
  328. while (1) {
  329. if (len <= 0) {
  330. SLJIT_ASSERT_STOP();
  331. return 0;
  332. }
  333. mask = ((sljit_uw)1 << len) - 1;
  334. if ((uimm & mask) != ((uimm >> len) & mask))
  335. break;
  336. len >>= 1;
  337. }
  338. len <<= 1;
  339. negated = 0;
  340. if (uimm & 0x1) {
  341. negated = 1;
  342. uimm = ~uimm;
  343. }
  344. if (len < 64)
  345. uimm &= ((sljit_uw)1 << len) - 1;
  346. /* Unsigned right shift. */
  347. COUNT_TRAILING_ZERO(uimm, right);
  348. /* Signed shift. We also know that the highest bit is set. */
  349. imm = (sljit_sw)~uimm;
  350. SLJIT_ASSERT(imm < 0);
  351. COUNT_TRAILING_ZERO(imm, ones);
  352. if (~imm)
  353. return 0;
  354. if (len == 64)
  355. ins = 1 << 22;
  356. else
  357. ins = (0x3f - ((len << 1) - 1)) << 10;
  358. if (negated)
  359. return ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16);
  360. return ins | ((ones - 1) << 10) | ((len - right) << 16);
  361. }
  362. #undef COUNT_TRAILING_ZERO
  363. static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw simm)
  364. {
  365. sljit_uw imm = (sljit_uw)simm;
  366. sljit_si i, zeros, ones, first;
  367. sljit_ins bitmask;
  368. if (imm <= 0xffff)
  369. return push_inst(compiler, MOVZ | RD(dst) | (imm << 5));
  370. if (simm >= -0x10000 && simm < 0)
  371. return push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5));
  372. if (imm <= 0xffffffffl) {
  373. if ((imm & 0xffff0000l) == 0xffff0000)
  374. return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff) << 5));
  375. if ((imm & 0xffff) == 0xffff)
  376. return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
  377. bitmask = logical_imm(simm, 16);
  378. if (bitmask != 0)
  379. return push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask);
  380. }
  381. else {
  382. bitmask = logical_imm(simm, 32);
  383. if (bitmask != 0)
  384. return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask);
  385. }
  386. if (imm <= 0xffffffffl) {
  387. FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));
  388. return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
  389. }
  390. if (simm >= -0x100000000l && simm < 0) {
  391. FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5)));
  392. return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
  393. }
  394. /* A large amount of number can be constructed from ORR and MOVx,
  395. but computing them is costly. We don't */
  396. zeros = 0;
  397. ones = 0;
  398. for (i = 4; i > 0; i--) {
  399. if ((simm & 0xffff) == 0)
  400. zeros++;
  401. if ((simm & 0xffff) == 0xffff)
  402. ones++;
  403. simm >>= 16;
  404. }
  405. simm = (sljit_sw)imm;
  406. first = 1;
  407. if (ones > zeros) {
  408. simm = ~simm;
  409. for (i = 0; i < 4; i++) {
  410. if (!(simm & 0xffff)) {
  411. simm >>= 16;
  412. continue;
  413. }
  414. if (first) {
  415. first = 0;
  416. FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));
  417. }
  418. else
  419. FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((~simm & 0xffff) << 5) | (i << 21)));
  420. simm >>= 16;
  421. }
  422. return SLJIT_SUCCESS;
  423. }
  424. for (i = 0; i < 4; i++) {
  425. if (!(simm & 0xffff)) {
  426. simm >>= 16;
  427. continue;
  428. }
  429. if (first) {
  430. first = 0;
  431. FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));
  432. }
  433. else
  434. FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));
  435. simm >>= 16;
  436. }
  437. return SLJIT_SUCCESS;
  438. }
  439. #define ARG1_IMM 0x0010000
  440. #define ARG2_IMM 0x0020000
  441. #define INT_OP 0x0040000
  442. #define SET_FLAGS 0x0080000
  443. #define UNUSED_RETURN 0x0100000
  444. #define SLOW_DEST 0x0200000
  445. #define SLOW_SRC1 0x0400000
  446. #define SLOW_SRC2 0x0800000
  447. #define CHECK_FLAGS(flag_bits) \
  448. if (flags & SET_FLAGS) { \
  449. inv_bits |= flag_bits; \
  450. if (flags & UNUSED_RETURN) \
  451. dst = TMP_ZERO; \
  452. }
  453. static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_sw arg1, sljit_sw arg2)
  454. {
  455. /* dst must be register, TMP_REG1
  456. arg1 must be register, TMP_REG1, imm
  457. arg2 must be register, TMP_REG2, imm */
  458. sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0;
  459. sljit_ins inst_bits;
  460. sljit_si op = (flags & 0xffff);
  461. sljit_si reg;
  462. sljit_sw imm, nimm;
  463. if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
  464. /* Both are immediates. */
  465. flags &= ~ARG1_IMM;
  466. if (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB)
  467. arg1 = TMP_ZERO;
  468. else {
  469. FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
  470. arg1 = TMP_REG1;
  471. }
  472. }
  473. if (flags & (ARG1_IMM | ARG2_IMM)) {
  474. reg = (flags & ARG2_IMM) ? arg1 : arg2;
  475. imm = (flags & ARG2_IMM) ? arg2 : arg1;
  476. switch (op) {
  477. case SLJIT_MUL:
  478. case SLJIT_NEG:
  479. case SLJIT_CLZ:
  480. case SLJIT_ADDC:
  481. case SLJIT_SUBC:
  482. /* No form with immediate operand (except imm 0, which
  483. is represented by a ZERO register). */
  484. break;
  485. case SLJIT_MOV:
  486. SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);
  487. return load_immediate(compiler, dst, imm);
  488. case SLJIT_NOT:
  489. SLJIT_ASSERT(flags & ARG2_IMM);
  490. FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm));
  491. goto set_flags;
  492. case SLJIT_SUB:
  493. if (flags & ARG1_IMM)
  494. break;
  495. imm = -imm;
  496. /* Fall through. */
  497. case SLJIT_ADD:
  498. if (imm == 0) {
  499. CHECK_FLAGS(1 << 29);
  500. return push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg));
  501. }
  502. if (imm > 0 && imm <= 0xfff) {
  503. CHECK_FLAGS(1 << 29);
  504. return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (imm << 10));
  505. }
  506. nimm = -imm;
  507. if (nimm > 0 && nimm <= 0xfff) {
  508. CHECK_FLAGS(1 << 29);
  509. return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (nimm << 10));
  510. }
  511. if (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) {
  512. CHECK_FLAGS(1 << 29);
  513. return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22));
  514. }
  515. if (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) {
  516. CHECK_FLAGS(1 << 29);
  517. return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22));
  518. }
  519. if (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) {
  520. FAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22)));
  521. return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | ((imm & 0xfff) << 10));
  522. }
  523. if (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) {
  524. FAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22)));
  525. return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | ((nimm & 0xfff) << 10));
  526. }
  527. break;
  528. case SLJIT_AND:
  529. inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));
  530. if (!inst_bits)
  531. break;
  532. CHECK_FLAGS(3 << 29);
  533. return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits);
  534. case SLJIT_OR:
  535. case SLJIT_XOR:
  536. inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));
  537. if (!inst_bits)
  538. break;
  539. if (op == SLJIT_OR)
  540. inst_bits |= ORRI;
  541. else
  542. inst_bits |= EORI;
  543. FAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg)));
  544. goto set_flags;
  545. case SLJIT_SHL:
  546. if (flags & ARG1_IMM)
  547. break;
  548. if (flags & INT_OP) {
  549. imm &= 0x1f;
  550. FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | ((-imm & 0x1f) << 16) | ((31 - imm) << 10)));
  551. }
  552. else {
  553. imm &= 0x3f;
  554. FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | ((-imm & 0x3f) << 16) | ((63 - imm) << 10)));
  555. }
  556. goto set_flags;
  557. case SLJIT_LSHR:
  558. case SLJIT_ASHR:
  559. if (flags & ARG1_IMM)
  560. break;
  561. if (op == SLJIT_ASHR)
  562. inv_bits |= 1 << 30;
  563. if (flags & INT_OP) {
  564. imm &= 0x1f;
  565. FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (imm << 16) | (31 << 10)));
  566. }
  567. else {
  568. imm &= 0x3f;
  569. FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | (imm << 16) | (63 << 10)));
  570. }
  571. goto set_flags;
  572. default:
  573. SLJIT_ASSERT_STOP();
  574. break;
  575. }
  576. if (flags & ARG2_IMM) {
  577. if (arg2 == 0)
  578. arg2 = TMP_ZERO;
  579. else {
  580. FAIL_IF(load_immediate(compiler, TMP_REG2, arg2));
  581. arg2 = TMP_REG2;
  582. }
  583. }
  584. else {
  585. if (arg1 == 0)
  586. arg1 = TMP_ZERO;
  587. else {
  588. FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
  589. arg1 = TMP_REG1;
  590. }
  591. }
  592. }
  593. /* Both arguments are registers. */
  594. switch (op) {
  595. case SLJIT_MOV:
  596. case SLJIT_MOV_P:
  597. case SLJIT_MOVU:
  598. case SLJIT_MOVU_P:
  599. SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
  600. if (dst == arg2)
  601. return SLJIT_SUCCESS;
  602. return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2));
  603. case SLJIT_MOV_UB:
  604. case SLJIT_MOVU_UB:
  605. SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
  606. return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10));
  607. case SLJIT_MOV_SB:
  608. case SLJIT_MOVU_SB:
  609. SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
  610. if (!(flags & INT_OP))
  611. inv_bits |= 1 << 22;
  612. return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10));
  613. case SLJIT_MOV_UH:
  614. case SLJIT_MOVU_UH:
  615. SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
  616. return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10));
  617. case SLJIT_MOV_SH:
  618. case SLJIT_MOVU_SH:
  619. SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
  620. if (!(flags & INT_OP))
  621. inv_bits |= 1 << 22;
  622. return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10));
  623. case SLJIT_MOV_UI:
  624. case SLJIT_MOVU_UI:
  625. SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
  626. if ((flags & INT_OP) && dst == arg2)
  627. return SLJIT_SUCCESS;
  628. return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
  629. case SLJIT_MOV_SI:
  630. case SLJIT_MOVU_SI:
  631. SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
  632. if ((flags & INT_OP) && dst == arg2)
  633. return SLJIT_SUCCESS;
  634. return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10));
  635. case SLJIT_NOT:
  636. SLJIT_ASSERT(arg1 == TMP_REG1);
  637. FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)));
  638. goto set_flags;
  639. case SLJIT_NEG:
  640. SLJIT_ASSERT(arg1 == TMP_REG1);
  641. if (flags & SET_FLAGS)
  642. inv_bits |= 1 << 29;
  643. return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
  644. case SLJIT_CLZ:
  645. SLJIT_ASSERT(arg1 == TMP_REG1);
  646. FAIL_IF(push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2)));
  647. goto set_flags;
  648. case SLJIT_ADD:
  649. CHECK_FLAGS(1 << 29);
  650. return push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
  651. case SLJIT_ADDC:
  652. CHECK_FLAGS(1 << 29);
  653. return push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
  654. case SLJIT_SUB:
  655. CHECK_FLAGS(1 << 29);
  656. return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
  657. case SLJIT_SUBC:
  658. CHECK_FLAGS(1 << 29);
  659. return push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
  660. case SLJIT_MUL:
  661. if (!(flags & SET_FLAGS))
  662. return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO));
  663. if (flags & INT_OP) {
  664. FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10)));
  665. FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10)));
  666. return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
  667. }
  668. FAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2)));
  669. FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)));
  670. return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));
  671. case SLJIT_AND:
  672. CHECK_FLAGS(3 << 29);
  673. return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
  674. case SLJIT_OR:
  675. FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
  676. goto set_flags;
  677. case SLJIT_XOR:
  678. FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
  679. goto set_flags;
  680. case SLJIT_SHL:
  681. FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
  682. goto set_flags;
  683. case SLJIT_LSHR:
  684. FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
  685. goto set_flags;
  686. case SLJIT_ASHR:
  687. FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
  688. goto set_flags;
  689. }
  690. SLJIT_ASSERT_STOP();
  691. return SLJIT_SUCCESS;
  692. set_flags:
  693. if (flags & SET_FLAGS)
  694. return push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO));
  695. return SLJIT_SUCCESS;
  696. }
  697. #define STORE 0x01
  698. #define SIGNED 0x02
  699. #define UPDATE 0x04
  700. #define ARG_TEST 0x08
  701. #define BYTE_SIZE 0x000
  702. #define HALF_SIZE 0x100
  703. #define INT_SIZE 0x200
  704. #define WORD_SIZE 0x300
  705. #define MEM_SIZE_SHIFT(flags) ((flags) >> 8)
  706. static SLJIT_CONST sljit_ins sljit_mem_imm[4] = {
  707. /* u l */ 0x39400000 /* ldrb [reg,imm] */,
  708. /* u s */ 0x39000000 /* strb [reg,imm] */,
  709. /* s l */ 0x39800000 /* ldrsb [reg,imm] */,
  710. /* s s */ 0x39000000 /* strb [reg,imm] */,
  711. };
  712. static SLJIT_CONST sljit_ins sljit_mem_simm[4] = {
  713. /* u l */ 0x38400000 /* ldurb [reg,imm] */,
  714. /* u s */ 0x38000000 /* sturb [reg,imm] */,
  715. /* s l */ 0x38800000 /* ldursb [reg,imm] */,
  716. /* s s */ 0x38000000 /* sturb [reg,imm] */,
  717. };
  718. static SLJIT_CONST sljit_ins sljit_mem_pre_simm[4] = {
  719. /* u l */ 0x38400c00 /* ldrb [reg,imm]! */,
  720. /* u s */ 0x38000c00 /* strb [reg,imm]! */,
  721. /* s l */ 0x38800c00 /* ldrsb [reg,imm]! */,
  722. /* s s */ 0x38000c00 /* strb [reg,imm]! */,
  723. };
  724. static SLJIT_CONST sljit_ins sljit_mem_reg[4] = {
  725. /* u l */ 0x38606800 /* ldrb [reg,reg] */,
  726. /* u s */ 0x38206800 /* strb [reg,reg] */,
  727. /* s l */ 0x38a06800 /* ldrsb [reg,reg] */,
  728. /* s s */ 0x38206800 /* strb [reg,reg] */,
  729. };
  730. /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
  731. static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value)
  732. {
  733. if (value >= 0) {
  734. if (value <= 0xfff)
  735. return push_inst(compiler, ADDI | RD(dst) | RN(reg) | (value << 10));
  736. if (value <= 0xffffff && !(value & 0xfff))
  737. return push_inst(compiler, ADDI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2));
  738. }
  739. else {
  740. value = -value;
  741. if (value <= 0xfff)
  742. return push_inst(compiler, SUBI | RD(dst) | RN(reg) | (value << 10));
  743. if (value <= 0xffffff && !(value & 0xfff))
  744. return push_inst(compiler, SUBI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2));
  745. }
  746. return SLJIT_ERR_UNSUPPORTED;
  747. }
  748. /* Can perform an operation using at most 1 instruction. */
  749. static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
  750. {
  751. sljit_ui shift = MEM_SIZE_SHIFT(flags);
  752. SLJIT_ASSERT(arg & SLJIT_MEM);
  753. if (SLJIT_UNLIKELY(flags & UPDATE)) {
  754. if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 255 && argw >= -256) {
  755. if (SLJIT_UNLIKELY(flags & ARG_TEST))
  756. return 1;
  757. arg &= REG_MASK;
  758. argw &= 0x1ff;
  759. FAIL_IF(push_inst(compiler, sljit_mem_pre_simm[flags & 0x3]
  760. | (shift << 30) | RT(reg) | RN(arg) | (argw << 12)));
  761. return -1;
  762. }
  763. return 0;
  764. }
  765. if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
  766. argw &= 0x3;
  767. if (argw && argw != shift)
  768. return 0;
  769. if (SLJIT_UNLIKELY(flags & ARG_TEST))
  770. return 1;
  771. FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg)
  772. | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0)));
  773. return -1;
  774. }
  775. arg &= REG_MASK;
  776. if (argw >= 0 && (argw >> shift) <= 0xfff && (argw & ((1 << shift) - 1)) == 0) {
  777. if (SLJIT_UNLIKELY(flags & ARG_TEST))
  778. return 1;
  779. FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30)
  780. | RT(reg) | RN(arg) | (argw << (10 - shift))));
  781. return -1;
  782. }
  783. if (argw > 255 || argw < -256)
  784. return 0;
  785. if (SLJIT_UNLIKELY(flags & ARG_TEST))
  786. return 1;
  787. FAIL_IF(push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30)
  788. | RT(reg) | RN(arg) | ((argw & 0x1ff) << 12)));
  789. return -1;
  790. }
  791. /* see getput_arg below.
  792. Note: can_cache is called only for binary operators. Those
  793. operators always uses word arguments without write back. */
  794. static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
  795. {
  796. sljit_sw diff;
  797. if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM))
  798. return 0;
  799. if (!(arg & REG_MASK)) {
  800. diff = argw - next_argw;
  801. if (diff <= 0xfff && diff >= -0xfff)
  802. return 1;
  803. return 0;
  804. }
  805. if (argw == next_argw)
  806. return 1;
  807. diff = argw - next_argw;
  808. if (arg == next_arg && diff <= 0xfff && diff >= -0xfff)
  809. return 1;
  810. return 0;
  811. }
  812. /* Emit the necessary instructions. See can_cache above. */
  813. static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg,
  814. sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
  815. {
  816. sljit_ui shift = MEM_SIZE_SHIFT(flags);
  817. sljit_si tmp_r, other_r;
  818. sljit_sw diff;
  819. SLJIT_ASSERT(arg & SLJIT_MEM);
  820. if (!(next_arg & SLJIT_MEM)) {
  821. next_arg = 0;
  822. next_argw = 0;
  823. }
  824. tmp_r = (flags & STORE) ? TMP_REG3 : reg;
  825. if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) {
  826. /* Update only applies if a base register exists. */
  827. other_r = OFFS_REG(arg);
  828. if (!other_r) {
  829. other_r = arg & REG_MASK;
  830. if (other_r != reg && argw >= 0 && argw <= 0xffffff) {
  831. if ((argw & 0xfff) != 0)
  832. FAIL_IF(push_inst(compiler, ADDI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10)));
  833. if (argw >> 12)
  834. FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10)));
  835. return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r));
  836. }
  837. else if (other_r != reg && argw < 0 && argw >= -0xffffff) {
  838. argw = -argw;
  839. if ((argw & 0xfff) != 0)
  840. FAIL_IF(push_inst(compiler, SUBI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10)));
  841. if (argw >> 12)
  842. FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10)));
  843. return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r));
  844. }
  845. if (compiler->cache_arg == SLJIT_MEM) {
  846. if (argw == compiler->cache_argw) {
  847. other_r = TMP_REG3;
  848. argw = 0;
  849. }
  850. else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
  851. FAIL_IF(compiler->error);
  852. compiler->cache_argw = argw;
  853. other_r = TMP_REG3;
  854. argw = 0;
  855. }
  856. }
  857. if (argw) {
  858. FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
  859. compiler->cache_arg = SLJIT_MEM;
  860. compiler->cache_argw = argw;
  861. other_r = TMP_REG3;
  862. argw = 0;
  863. }
  864. }
  865. /* No caching here. */
  866. arg &= REG_MASK;
  867. argw &= 0x3;
  868. if (!argw || argw == shift) {
  869. FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(other_r) | (argw ? (1 << 12) : 0)));
  870. return push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10));
  871. }
  872. if (arg != reg) {
  873. FAIL_IF(push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10)));
  874. return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg));
  875. }
  876. FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(arg) | RM(other_r) | (argw << 10)));
  877. FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_LR)));
  878. return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_LR));
  879. }
  880. if (arg & OFFS_REG_MASK) {
  881. other_r = OFFS_REG(arg);
  882. arg &= REG_MASK;
  883. FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RN(arg) | RM(other_r) | ((argw & 0x3) << 10)));
  884. return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(tmp_r));
  885. }
  886. if (compiler->cache_arg == arg) {
  887. diff = argw - compiler->cache_argw;
  888. if (diff <= 255 && diff >= -256)
  889. return push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30)
  890. | RT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12));
  891. if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) {
  892. FAIL_IF(compiler->error);
  893. return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg));
  894. }
  895. }
  896. if (argw >= 0 && argw <= 0xffffff && (argw & ((1 << shift) - 1)) == 0) {
  897. FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_r) | RN(arg & REG_MASK) | ((argw >> 12) << 10)));
  898. return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30)
  899. | RT(reg) | RN(tmp_r) | ((argw & 0xfff) << (10 - shift)));
  900. }
  901. diff = argw - next_argw;
  902. next_arg = (arg & REG_MASK) && (arg == next_arg) && diff <= 0xfff && diff >= -0xfff && diff != 0;
  903. arg &= REG_MASK;
  904. if (arg && compiler->cache_arg == SLJIT_MEM) {
  905. if (compiler->cache_argw == argw)
  906. return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
  907. if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
  908. FAIL_IF(compiler->error);
  909. compiler->cache_argw = argw;
  910. return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
  911. }
  912. }
  913. compiler->cache_argw = argw;
  914. if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) {
  915. FAIL_IF(compiler->error);
  916. compiler->cache_arg = SLJIT_MEM | arg;
  917. arg = 0;
  918. }
  919. else {
  920. FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
  921. compiler->cache_arg = SLJIT_MEM;
  922. if (next_arg) {
  923. FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RN(TMP_REG3) | RM(arg)));
  924. compiler->cache_arg = SLJIT_MEM | arg;
  925. arg = 0;
  926. }
  927. }
  928. if (arg)
  929. return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
  930. return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3));
  931. }
  932. static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
  933. {
  934. if (getput_arg_fast(compiler, flags, reg, arg, argw))
  935. return compiler->error;
  936. compiler->cache_arg = 0;
  937. compiler->cache_argw = 0;
  938. return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
  939. }
  940. static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w)
  941. {
  942. if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
  943. return compiler->error;
  944. return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
  945. }
  946. /* --------------------------------------------------------------------- */
  947. /* Entry, exit */
  948. /* --------------------------------------------------------------------- */
  949. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
  950. sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
  951. sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
  952. {
  953. sljit_si i, tmp, offs, prev, saved_regs_size;
  954. CHECK_ERROR();
  955. CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
  956. set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
  957. saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0);
  958. local_size += saved_regs_size + SLJIT_LOCALS_OFFSET;
  959. local_size = (local_size + 15) & ~0xf;
  960. compiler->local_size = local_size;
  961. if (local_size <= (63 * sizeof(sljit_sw))) {
  962. FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
  963. | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15)));
  964. FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
  965. offs = (local_size - saved_regs_size) << (15 - 3);
  966. } else {
  967. offs = 0 << 15;
  968. if (saved_regs_size & 0x8) {
  969. offs = 1 << 15;
  970. saved_regs_size += sizeof(sljit_sw);
  971. }
  972. local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
  973. if (saved_regs_size > 0)
  974. FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
  975. }
  976. tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
  977. prev = -1;
  978. for (i = SLJIT_S0; i >= tmp; i--) {
  979. if (prev == -1) {
  980. if (!(offs & (1 << 15))) {
  981. prev = i;
  982. continue;
  983. }
  984. FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
  985. offs += 1 << 15;
  986. continue;
  987. }
  988. FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
  989. offs += 2 << 15;
  990. prev = -1;
  991. }
  992. for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
  993. if (prev == -1) {
  994. if (!(offs & (1 << 15))) {
  995. prev = i;
  996. continue;
  997. }
  998. FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
  999. offs += 1 << 15;
  1000. continue;
  1001. }
  1002. FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
  1003. offs += 2 << 15;
  1004. prev = -1;
  1005. }
  1006. SLJIT_ASSERT(prev == -1);
  1007. if (compiler->local_size > (63 * sizeof(sljit_sw))) {
  1008. /* The local_size is already adjusted by the saved registers. */
  1009. if (local_size > 0xfff) {
  1010. FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22)));
  1011. local_size &= 0xfff;
  1012. }
  1013. if (local_size)
  1014. FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
  1015. FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
  1016. | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15)));
  1017. FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
  1018. }
  1019. if (args >= 1)
  1020. FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0) | RN(TMP_ZERO) | RM(SLJIT_R0)));
  1021. if (args >= 2)
  1022. FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S1) | RN(TMP_ZERO) | RM(SLJIT_R1)));
  1023. if (args >= 3)
  1024. FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S2) | RN(TMP_ZERO) | RM(SLJIT_R2)));
  1025. return SLJIT_SUCCESS;
  1026. }
  1027. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
  1028. sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
  1029. sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
  1030. {
  1031. CHECK_ERROR();
  1032. CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
  1033. set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
  1034. local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET;
  1035. local_size = (local_size + 15) & ~0xf;
  1036. compiler->local_size = local_size;
  1037. return SLJIT_SUCCESS;
  1038. }
  1039. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
  1040. {
  1041. sljit_si local_size;
  1042. sljit_si i, tmp, offs, prev, saved_regs_size;
  1043. CHECK_ERROR();
  1044. CHECK(check_sljit_emit_return(compiler, op, src, srcw));
  1045. FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
  1046. local_size = compiler->local_size;
  1047. saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0);
  1048. if (local_size <= (63 * sizeof(sljit_sw)))
  1049. offs = (local_size - saved_regs_size) << (15 - 3);
  1050. else {
  1051. FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
  1052. | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15)));
  1053. offs = 0 << 15;
  1054. if (saved_regs_size & 0x8) {
  1055. offs = 1 << 15;
  1056. saved_regs_size += sizeof(sljit_sw);
  1057. }
  1058. local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
  1059. if (local_size > 0xfff) {
  1060. FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22)));
  1061. local_size &= 0xfff;
  1062. }
  1063. if (local_size)
  1064. FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
  1065. }
  1066. tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
  1067. prev = -1;
  1068. for (i = SLJIT_S0; i >= tmp; i--) {
  1069. if (prev == -1) {
  1070. if (!(offs & (1 << 15))) {
  1071. prev = i;
  1072. continue;
  1073. }
  1074. FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
  1075. offs += 1 << 15;
  1076. continue;
  1077. }
  1078. FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
  1079. offs += 2 << 15;
  1080. prev = -1;
  1081. }
  1082. for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
  1083. if (prev == -1) {
  1084. if (!(offs & (1 << 15))) {
  1085. prev = i;
  1086. continue;
  1087. }
  1088. FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
  1089. offs += 1 << 15;
  1090. continue;
  1091. }
  1092. FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
  1093. offs += 2 << 15;
  1094. prev = -1;
  1095. }
  1096. SLJIT_ASSERT(prev == -1);
  1097. if (compiler->local_size <= (63 * sizeof(sljit_sw))) {
  1098. FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
  1099. | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
  1100. } else if (saved_regs_size > 0) {
  1101. FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
  1102. }
  1103. FAIL_IF(push_inst(compiler, RET | RN(TMP_LR)));
  1104. return SLJIT_SUCCESS;
  1105. }
  1106. /* --------------------------------------------------------------------- */
  1107. /* Operators */
  1108. /* --------------------------------------------------------------------- */
  1109. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
  1110. {
  1111. sljit_ins inv_bits = (op & SLJIT_INT_OP) ? (1 << 31) : 0;
  1112. CHECK_ERROR();
  1113. CHECK(check_sljit_emit_op0(compiler, op));
  1114. op = GET_OPCODE(op);
  1115. switch (op) {
  1116. case SLJIT_BREAKPOINT:
  1117. return push_inst(compiler, BRK);
  1118. case SLJIT_NOP:
  1119. return push_inst(compiler, NOP);
  1120. case SLJIT_LUMUL:
  1121. case SLJIT_LSMUL:
  1122. FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
  1123. FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
  1124. return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
  1125. case SLJIT_UDIVMOD:
  1126. case SLJIT_SDIVMOD:
  1127. FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
  1128. FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
  1129. FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
  1130. return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
  1131. case SLJIT_UDIVI:
  1132. case SLJIT_SDIVI:
  1133. return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
  1134. }
  1135. return SLJIT_SUCCESS;
  1136. }
  1137. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
  1138. sljit_si dst, sljit_sw dstw,
  1139. sljit_si src, sljit_sw srcw)
  1140. {
  1141. sljit_si dst_r, flags, mem_flags;
  1142. sljit_si op_flags = GET_ALL_FLAGS(op);
  1143. CHECK_ERROR();
  1144. CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
  1145. ADJUST_LOCAL_OFFSET(dst, dstw);
  1146. ADJUST_LOCAL_OFFSET(src, srcw);
  1147. compiler->cache_arg = 0;
  1148. compiler->cache_argw = 0;
  1149. dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
  1150. op = GET_OPCODE(op);
  1151. if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
  1152. switch (op) {
  1153. case SLJIT_MOV:
  1154. case SLJIT_MOV_P:
  1155. flags = WORD_SIZE;
  1156. break;
  1157. case SLJIT_MOV_UB:
  1158. flags = BYTE_SIZE;
  1159. if (src & SLJIT_IMM)
  1160. srcw = (sljit_ub)srcw;
  1161. break;
  1162. case SLJIT_MOV_SB:
  1163. flags = BYTE_SIZE | SIGNED;
  1164. if (src & SLJIT_IMM)
  1165. srcw = (sljit_sb)srcw;
  1166. break;
  1167. case SLJIT_MOV_UH:
  1168. flags = HALF_SIZE;
  1169. if (src & SLJIT_IMM)
  1170. srcw = (sljit_uh)srcw;
  1171. break;
  1172. case SLJIT_MOV_SH:
  1173. flags = HALF_SIZE | SIGNED;
  1174. if (src & SLJIT_IMM)
  1175. srcw = (sljit_sh)srcw;
  1176. break;
  1177. case SLJIT_MOV_UI:
  1178. flags = INT_SIZE;
  1179. if (src & SLJIT_IMM)
  1180. srcw = (sljit_ui)srcw;
  1181. break;
  1182. case SLJIT_MOV_SI:
  1183. flags = INT_SIZE | SIGNED;
  1184. if (src & SLJIT_IMM)
  1185. srcw = (sljit_si)srcw;
  1186. break;
  1187. case SLJIT_MOVU:
  1188. case SLJIT_MOVU_P:
  1189. flags = WORD_SIZE | UPDATE;
  1190. break;
  1191. case SLJIT_MOVU_UB:
  1192. flags = BYTE_SIZE | UPDATE;
  1193. if (src & SLJIT_IMM)
  1194. srcw = (sljit_ub)srcw;
  1195. break;
  1196. case SLJIT_MOVU_SB:
  1197. flags = BYTE_SIZE | SIGNED | UPDATE;
  1198. if (src & SLJIT_IMM)
  1199. srcw = (sljit_sb)srcw;
  1200. break;
  1201. case SLJIT_MOVU_UH:
  1202. flags = HALF_SIZE | UPDATE;
  1203. if (src & SLJIT_IMM)
  1204. srcw = (sljit_uh)srcw;
  1205. break;
  1206. case SLJIT_MOVU_SH:
  1207. flags = HALF_SIZE | SIGNED | UPDATE;
  1208. if (src & SLJIT_IMM)
  1209. srcw = (sljit_sh)srcw;
  1210. break;
  1211. case SLJIT_MOVU_UI:
  1212. flags = INT_SIZE | UPDATE;
  1213. if (src & SLJIT_IMM)
  1214. srcw = (sljit_ui)srcw;
  1215. break;
  1216. case SLJIT_MOVU_SI:
  1217. flags = INT_SIZE | SIGNED | UPDATE;
  1218. if (src & SLJIT_IMM)
  1219. srcw = (sljit_si)srcw;
  1220. break;
  1221. default:
  1222. SLJIT_ASSERT_STOP();
  1223. flags = 0;
  1224. break;
  1225. }
  1226. if (src & SLJIT_IMM)
  1227. FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
  1228. else if (src & SLJIT_MEM) {
  1229. if (getput_arg_fast(compiler, flags, dst_r, src, srcw))
  1230. FAIL_IF(compiler->error);
  1231. else
  1232. FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
  1233. } else {
  1234. if (dst_r != TMP_REG1)
  1235. return emit_op_imm(compiler, op | ((op_flags & SLJIT_INT_OP) ? INT_OP : 0), dst_r, TMP_REG1, src);
  1236. dst_r = src;
  1237. }
  1238. if (dst & SLJIT_MEM) {
  1239. if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
  1240. return compiler->error;
  1241. else
  1242. return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
  1243. }
  1244. return SLJIT_SUCCESS;
  1245. }
  1246. flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0;
  1247. mem_flags = WORD_SIZE;
  1248. if (op_flags & SLJIT_INT_OP) {
  1249. flags |= INT_OP;
  1250. mem_flags = INT_SIZE;
  1251. }
  1252. if (dst == SLJIT_UNUSED)
  1253. flags |= UNUSED_RETURN;
  1254. if (src & SLJIT_MEM) {
  1255. if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src, srcw))
  1256. FAIL_IF(compiler->error);
  1257. else
  1258. FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src, srcw, dst, dstw));
  1259. src = TMP_REG2;
  1260. }
  1261. if (src & SLJIT_IMM) {
  1262. flags |= ARG2_IMM;
  1263. if (op_flags & SLJIT_INT_OP)
  1264. srcw = (sljit_si)srcw;
  1265. } else
  1266. srcw = src;
  1267. emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw);
  1268. if (dst & SLJIT_MEM) {
  1269. if (getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw))
  1270. return compiler->error;
  1271. else
  1272. return getput_arg(compiler, mem_flags | STORE, dst_r, dst, dstw, 0, 0);
  1273. }
  1274. return SLJIT_SUCCESS;
  1275. }
  1276. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
  1277. sljit_si dst, sljit_sw dstw,
  1278. sljit_si src1, sljit_sw src1w,
  1279. sljit_si src2, sljit_sw src2w)
  1280. {
  1281. sljit_si dst_r, flags, mem_flags;
  1282. CHECK_ERROR();
  1283. CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
  1284. ADJUST_LOCAL_OFFSET(dst, dstw);
  1285. ADJUST_LOCAL_OFFSET(src1, src1w);
  1286. ADJUST_LOCAL_OFFSET(src2, src2w);
  1287. compiler->cache_arg = 0;
  1288. compiler->cache_argw = 0;
  1289. dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
  1290. flags = GET_FLAGS(op) ? SET_FLAGS : 0;
  1291. mem_flags = WORD_SIZE;
  1292. if (op & SLJIT_INT_OP) {
  1293. flags |= INT_OP;
  1294. mem_flags = INT_SIZE;
  1295. }
  1296. if (dst == SLJIT_UNUSED)
  1297. flags |= UNUSED_RETURN;
  1298. if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, mem_flags | STORE | ARG_TEST, TMP_REG1, dst, dstw))
  1299. flags |= SLOW_DEST;
  1300. if (src1 & SLJIT_MEM) {
  1301. if (getput_arg_fast(compiler, mem_flags, TMP_REG1, src1, src1w))
  1302. FAIL_IF(compiler->error);
  1303. else
  1304. flags |= SLOW_SRC1;
  1305. }
  1306. if (src2 & SLJIT_MEM) {
  1307. if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src2, src2w))
  1308. FAIL_IF(compiler->error);
  1309. else
  1310. flags |= SLOW_SRC2;
  1311. }
  1312. if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
  1313. if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
  1314. FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, src1, src1w));
  1315. FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw));
  1316. }
  1317. else {
  1318. FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, src2, src2w));
  1319. FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw));
  1320. }
  1321. }
  1322. else if (flags & SLOW_SRC1)
  1323. FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw));
  1324. else if (flags & SLOW_SRC2)
  1325. FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw));
  1326. if (src1 & SLJIT_MEM)
  1327. src1 = TMP_REG1;
  1328. if (src2 & SLJIT_MEM)
  1329. src2 = TMP_REG2;
  1330. if (src1 & SLJIT_IMM)
  1331. flags |= ARG1_IMM;
  1332. else
  1333. src1w = src1;
  1334. if (src2 & SLJIT_IMM)
  1335. flags |= ARG2_IMM;
  1336. else
  1337. src2w = src2;
  1338. emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);
  1339. if (dst & SLJIT_MEM) {
  1340. if (!(flags & SLOW_DEST)) {
  1341. getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw);
  1342. return compiler->error;
  1343. }
  1344. return getput_arg(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0);
  1345. }
  1346. return SLJIT_SUCCESS;
  1347. }
  1348. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
  1349. {
  1350. CHECK_REG_INDEX(check_sljit_get_register_index(reg));
  1351. return reg_map[reg];
  1352. }
  1353. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
  1354. {
  1355. CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
  1356. return reg;
  1357. }
  1358. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
  1359. void *instruction, sljit_si size)
  1360. {
  1361. CHECK_ERROR();
  1362. CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
  1363. return push_inst(compiler, *(sljit_ins*)instruction);
  1364. }
  1365. /* --------------------------------------------------------------------- */
  1366. /* Floating point operators */
  1367. /* --------------------------------------------------------------------- */
  1368. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
  1369. {
  1370. #ifdef SLJIT_IS_FPU_AVAILABLE
  1371. return SLJIT_IS_FPU_AVAILABLE;
  1372. #else
  1373. /* Available by default. */
  1374. return 1;
  1375. #endif
  1376. }
  1377. static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
  1378. {
  1379. sljit_ui shift = MEM_SIZE_SHIFT(flags);
  1380. sljit_ins ins_bits = (shift << 30);
  1381. sljit_si other_r;
  1382. sljit_sw diff;
  1383. SLJIT_ASSERT(arg & SLJIT_MEM);
  1384. if (!(flags & STORE))
  1385. ins_bits |= 1 << 22;
  1386. if (arg & OFFS_REG_MASK) {
  1387. argw &= 3;
  1388. if (!argw || argw == shift)
  1389. return push_inst(compiler, STR_FR | ins_bits | VT(reg)
  1390. | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));
  1391. other_r = OFFS_REG(arg);
  1392. arg &= REG_MASK;
  1393. FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | RM(other_r) | (argw << 10)));
  1394. arg = TMP_REG1;
  1395. argw = 0;
  1396. }
  1397. arg &= REG_MASK;
  1398. if (arg && argw >= 0 && ((argw >> shift) <= 0xfff) && (argw & ((1 << shift) - 1)) == 0)
  1399. return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(arg) | (argw << (10 - shift)));
  1400. if (arg && argw <= 255 && argw >= -256)
  1401. return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12));
  1402. /* Slow cases */
  1403. if (compiler->cache_arg == SLJIT_MEM && argw != compiler->cache_argw) {
  1404. diff = argw - compiler->cache_argw;
  1405. if (!arg && diff <= 255 && diff >= -256)
  1406. return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12));
  1407. if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
  1408. FAIL_IF(compiler->error);
  1409. compiler->cache_argw = argw;
  1410. }
  1411. }
  1412. if (compiler->cache_arg != SLJIT_MEM || argw != compiler->cache_argw) {
  1413. compiler->cache_arg = SLJIT_MEM;
  1414. compiler->cache_argw = argw;
  1415. FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
  1416. }
  1417. if (arg & REG_MASK)
  1418. return push_inst(compiler, STR_FR | ins_bits | VT(reg) | RN(arg) | RM(TMP_REG3));
  1419. return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3));
  1420. }
  1421. static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
  1422. sljit_si dst, sljit_sw dstw,
  1423. sljit_si src, sljit_sw srcw)
  1424. {
  1425. sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
  1426. sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
  1427. if (GET_OPCODE(op) == SLJIT_CONVI_FROMD)
  1428. inv_bits |= (1 << 31);
  1429. if (src & SLJIT_MEM) {
  1430. emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw);
  1431. src = TMP_FREG1;
  1432. }
  1433. FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src)));
  1434. if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED)
  1435. return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw);
  1436. return SLJIT_SUCCESS;
  1437. }
  1438. static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
  1439. sljit_si dst, sljit_sw dstw,
  1440. sljit_si src, sljit_sw srcw)
  1441. {
  1442. sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
  1443. sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
  1444. if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
  1445. inv_bits |= (1 << 31);
  1446. if (src & SLJIT_MEM) {
  1447. emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw);
  1448. src = TMP_REG1;
  1449. } else if (src & SLJIT_IMM) {
  1450. #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
  1451. if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
  1452. srcw = (sljit_si)srcw;
  1453. #endif
  1454. FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
  1455. src = TMP_REG1;
  1456. }
  1457. FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src)));
  1458. if (dst & SLJIT_MEM)
  1459. return emit_fop_mem(compiler, ((op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw);
  1460. return SLJIT_SUCCESS;
  1461. }
  1462. static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
  1463. sljit_si src1, sljit_sw src1w,
  1464. sljit_si src2, sljit_sw src2w)
  1465. {
  1466. sljit_si mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
  1467. sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
  1468. if (src1 & SLJIT_MEM) {
  1469. emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
  1470. src1 = TMP_FREG1;
  1471. }
  1472. if (src2 & SLJIT_MEM) {
  1473. emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);
  1474. src2 = TMP_FREG2;
  1475. }
  1476. return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2));
  1477. }
  1478. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
  1479. sljit_si dst, sljit_sw dstw,
  1480. sljit_si src, sljit_sw srcw)
  1481. {
  1482. sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
  1483. sljit_ins inv_bits;
  1484. CHECK_ERROR();
  1485. compiler->cache_arg = 0;
  1486. compiler->cache_argw = 0;
  1487. SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference);
  1488. SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
  1489. inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
  1490. dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
  1491. if (src & SLJIT_MEM) {
  1492. emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONVD_FROMS) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw);
  1493. src = dst_r;
  1494. }
  1495. switch (GET_OPCODE(op)) {
  1496. case SLJIT_DMOV:
  1497. if (src != dst_r) {
  1498. if (dst_r != TMP_FREG1)
  1499. FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));
  1500. else
  1501. dst_r = src;
  1502. }
  1503. break;
  1504. case SLJIT_DNEG:
  1505. FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src)));
  1506. break;
  1507. case SLJIT_DABS:
  1508. FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src)));
  1509. break;
  1510. case SLJIT_CONVD_FROMS:
  1511. FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_SINGLE_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src)));
  1512. break;
  1513. }
  1514. if (dst & SLJIT_MEM)
  1515. return emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw);
  1516. return SLJIT_SUCCESS;
  1517. }
  1518. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
  1519. sljit_si dst, sljit_sw dstw,
  1520. sljit_si src1, sljit_sw src1w,
  1521. sljit_si src2, sljit_sw src2w)
  1522. {
  1523. sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
  1524. sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
  1525. CHECK_ERROR();
  1526. CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
  1527. ADJUST_LOCAL_OFFSET(dst, dstw);
  1528. ADJUST_LOCAL_OFFSET(src1, src1w);
  1529. ADJUST_LOCAL_OFFSET(src2, src2w);
  1530. compiler->cache_arg = 0;
  1531. compiler->cache_argw = 0;
  1532. dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
  1533. if (src1 & SLJIT_MEM) {
  1534. emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
  1535. src1 = TMP_FREG1;
  1536. }
  1537. if (src2 & SLJIT_MEM) {
  1538. emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);
  1539. src2 = TMP_FREG2;
  1540. }
  1541. switch (GET_OPCODE(op)) {
  1542. case SLJIT_DADD:
  1543. FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
  1544. break;
  1545. case SLJIT_DSUB:
  1546. FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
  1547. break;
  1548. case SLJIT_DMUL:
  1549. FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
  1550. break;
  1551. case SLJIT_DDIV:
  1552. FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
  1553. break;
  1554. }
  1555. if (!(dst & SLJIT_MEM))
  1556. return SLJIT_SUCCESS;
  1557. return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw);
  1558. }
  1559. /* --------------------------------------------------------------------- */
  1560. /* Other instructions */
  1561. /* --------------------------------------------------------------------- */
  1562. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si 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. /* For UNUSED dst. Uncommon, but possible. */
  1568. if (dst == SLJIT_UNUSED)
  1569. return SLJIT_SUCCESS;
  1570. if (FAST_IS_REG(dst))
  1571. return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR));
  1572. /* Memory. */
  1573. return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw);
  1574. }
  1575. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
  1576. {
  1577. CHECK_ERROR();
  1578. CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
  1579. ADJUST_LOCAL_OFFSET(src, srcw);
  1580. if (FAST_IS_REG(src))
  1581. FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
  1582. else if (src & SLJIT_MEM)
  1583. FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw));
  1584. else if (src & SLJIT_IMM)
  1585. FAIL_IF(load_immediate(compiler, TMP_LR, srcw));
  1586. return push_inst(compiler, RET | RN(TMP_LR));
  1587. }
  1588. /* --------------------------------------------------------------------- */
  1589. /* Conditional instructions */
  1590. /* --------------------------------------------------------------------- */
  1591. static sljit_uw get_cc(sljit_si type)
  1592. {
  1593. switch (type) {
  1594. case SLJIT_EQUAL:
  1595. case SLJIT_MUL_NOT_OVERFLOW:
  1596. case SLJIT_D_EQUAL:
  1597. return 0x1;
  1598. case SLJIT_NOT_EQUAL:
  1599. case SLJIT_MUL_OVERFLOW:
  1600. case SLJIT_D_NOT_EQUAL:
  1601. return 0x0;
  1602. case SLJIT_LESS:
  1603. case SLJIT_D_LESS:
  1604. return 0x2;
  1605. case SLJIT_GREATER_EQUAL:
  1606. case SLJIT_D_GREATER_EQUAL:
  1607. return 0x3;
  1608. case SLJIT_GREATER:
  1609. case SLJIT_D_GREATER:
  1610. return 0x9;
  1611. case SLJIT_LESS_EQUAL:
  1612. case SLJIT_D_LESS_EQUAL:
  1613. return 0x8;
  1614. case SLJIT_SIG_LESS:
  1615. return 0xa;
  1616. case SLJIT_SIG_GREATER_EQUAL:
  1617. return 0xb;
  1618. case SLJIT_SIG_GREATER:
  1619. return 0xd;
  1620. case SLJIT_SIG_LESS_EQUAL:
  1621. return 0xc;
  1622. case SLJIT_OVERFLOW:
  1623. case SLJIT_D_UNORDERED:
  1624. return 0x7;
  1625. case SLJIT_NOT_OVERFLOW:
  1626. case SLJIT_D_ORDERED:
  1627. return 0x6;
  1628. default:
  1629. SLJIT_ASSERT_STOP();
  1630. return 0xe;
  1631. }
  1632. }
  1633. SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
  1634. {
  1635. struct sljit_label *label;
  1636. CHECK_ERROR_PTR();
  1637. CHECK_PTR(check_sljit_emit_label(compiler));
  1638. if (compiler->last_label && compiler->last_label->size == compiler->size)
  1639. return compiler->last_label;
  1640. label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
  1641. PTR_FAIL_IF(!label);
  1642. set_label(label, compiler);
  1643. return label;
  1644. }
  1645. SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
  1646. {
  1647. struct sljit_jump *jump;
  1648. CHECK_ERROR_PTR();
  1649. CHECK_PTR(check_sljit_emit_jump(compiler, type));
  1650. jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
  1651. PTR_FAIL_IF(!jump);
  1652. set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
  1653. type &= 0xff;
  1654. if (type < SLJIT_JUMP) {
  1655. jump->flags |= IS_COND;
  1656. PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(type)));
  1657. }
  1658. else if (type >= SLJIT_FAST_CALL)
  1659. jump->flags |= IS_BL;
  1660. PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
  1661. jump->addr = compiler->size;
  1662. PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)));
  1663. return jump;
  1664. }
  1665. static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_si type,
  1666. sljit_si src, sljit_sw srcw)
  1667. {
  1668. struct sljit_jump *jump;
  1669. sljit_ins inv_bits = (type & SLJIT_INT_OP) ? (1 << 31) : 0;
  1670. SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL);
  1671. ADJUST_LOCAL_OFFSET(src, srcw);
  1672. jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
  1673. PTR_FAIL_IF(!jump);
  1674. set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
  1675. jump->flags |= IS_CBZ | IS_COND;
  1676. if (src & SLJIT_MEM) {
  1677. PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw));
  1678. src = TMP_REG1;
  1679. }
  1680. else if (src & SLJIT_IMM) {
  1681. PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
  1682. src = TMP_REG1;
  1683. }
  1684. SLJIT_ASSERT(FAST_IS_REG(src));
  1685. if ((type & 0xff) == SLJIT_EQUAL)
  1686. inv_bits |= 1 << 24;
  1687. PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src)));
  1688. PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
  1689. jump->addr = compiler->size;
  1690. PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1)));
  1691. return jump;
  1692. }
  1693. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
  1694. {
  1695. struct sljit_jump *jump;
  1696. CHECK_ERROR();
  1697. CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
  1698. ADJUST_LOCAL_OFFSET(src, srcw);
  1699. /* In ARM, we don't need to touch the arguments. */
  1700. if (!(src & SLJIT_IMM)) {
  1701. if (src & SLJIT_MEM) {
  1702. FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw));
  1703. src = TMP_REG1;
  1704. }
  1705. return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src));
  1706. }
  1707. jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
  1708. FAIL_IF(!jump);
  1709. set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
  1710. jump->u.target = srcw;
  1711. FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
  1712. jump->addr = compiler->size;
  1713. return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1));
  1714. }
  1715. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
  1716. sljit_si dst, sljit_sw dstw,
  1717. sljit_si src, sljit_sw srcw,
  1718. sljit_si type)
  1719. {
  1720. sljit_si dst_r, flags, mem_flags;
  1721. sljit_ins cc;
  1722. CHECK_ERROR();
  1723. CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
  1724. ADJUST_LOCAL_OFFSET(dst, dstw);
  1725. ADJUST_LOCAL_OFFSET(src, srcw);
  1726. if (dst == SLJIT_UNUSED)
  1727. return SLJIT_SUCCESS;
  1728. cc = get_cc(type & 0xff);
  1729. dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
  1730. if (GET_OPCODE(op) < SLJIT_ADD) {
  1731. FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO)));
  1732. if (dst_r != TMP_REG1)
  1733. return SLJIT_SUCCESS;
  1734. return emit_op_mem(compiler, (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE, TMP_REG1, dst, dstw);
  1735. }
  1736. compiler->cache_arg = 0;
  1737. compiler->cache_argw = 0;
  1738. flags = GET_FLAGS(op) ? SET_FLAGS : 0;
  1739. mem_flags = WORD_SIZE;
  1740. if (op & SLJIT_INT_OP) {
  1741. flags |= INT_OP;
  1742. mem_flags = INT_SIZE;
  1743. }
  1744. if (src & SLJIT_MEM) {
  1745. FAIL_IF(emit_op_mem2(compiler, mem_flags, TMP_REG1, src, srcw, dst, dstw));
  1746. src = TMP_REG1;
  1747. srcw = 0;
  1748. } else if (src & SLJIT_IMM)
  1749. flags |= ARG1_IMM;
  1750. FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO)));
  1751. emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src, TMP_REG2);
  1752. if (dst_r != TMP_REG1)
  1753. return SLJIT_SUCCESS;
  1754. return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0);
  1755. }
  1756. SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
  1757. {
  1758. struct sljit_const *const_;
  1759. sljit_si dst_r;
  1760. CHECK_ERROR_PTR();
  1761. CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
  1762. ADJUST_LOCAL_OFFSET(dst, dstw);
  1763. const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
  1764. PTR_FAIL_IF(!const_);
  1765. set_const(const_, compiler);
  1766. dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
  1767. PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, init_value));
  1768. if (dst & SLJIT_MEM)
  1769. PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw));
  1770. return const_;
  1771. }
  1772. SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
  1773. {
  1774. sljit_ins* inst = (sljit_ins*)addr;
  1775. modify_imm64_const(inst, new_addr);
  1776. SLJIT_CACHE_FLUSH(inst, inst + 4);
  1777. }
  1778. SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
  1779. {
  1780. sljit_ins* inst = (sljit_ins*)addr;
  1781. modify_imm64_const(inst, new_constant);
  1782. SLJIT_CACHE_FLUSH(inst, inst + 4);
  1783. }