sljitNativeSPARC_common.c 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435
  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 "SPARC" SLJIT_CPUINFO;
  29. }
  30. /* Length of an instruction word
  31. Both for sparc-32 and sparc-64 */
  32. typedef sljit_ui sljit_ins;
  33. static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
  34. {
  35. #if defined(__SUNPRO_C) && __SUNPRO_C < 0x590
  36. __asm (
  37. /* if (from == to) return */
  38. "cmp %i0, %i1\n"
  39. "be .leave\n"
  40. "nop\n"
  41. /* loop until from >= to */
  42. ".mainloop:\n"
  43. "flush %i0\n"
  44. "add %i0, 8, %i0\n"
  45. "cmp %i0, %i1\n"
  46. "bcs .mainloop\n"
  47. "nop\n"
  48. /* The comparison was done above. */
  49. "bne .leave\n"
  50. /* nop is not necessary here, since the
  51. sub operation has no side effect. */
  52. "sub %i0, 4, %i0\n"
  53. "flush %i0\n"
  54. ".leave:"
  55. );
  56. #else
  57. if (SLJIT_UNLIKELY(from == to))
  58. return;
  59. do {
  60. __asm__ volatile (
  61. "flush %0\n"
  62. : : "r"(from)
  63. );
  64. /* Operates at least on doubleword. */
  65. from += 2;
  66. } while (from < to);
  67. if (from == to) {
  68. /* Flush the last word. */
  69. from --;
  70. __asm__ volatile (
  71. "flush %0\n"
  72. : : "r"(from)
  73. );
  74. }
  75. #endif
  76. }
  77. /* TMP_REG2 is not used by getput_arg */
  78. #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
  79. #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
  80. #define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
  81. #define TMP_LINK (SLJIT_NUMBER_OF_REGISTERS + 5)
  82. #define TMP_FREG1 (0)
  83. #define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
  84. static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
  85. 0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15
  86. };
  87. /* --------------------------------------------------------------------- */
  88. /* Instrucion forms */
  89. /* --------------------------------------------------------------------- */
  90. #define D(d) (reg_map[d] << 25)
  91. #define DA(d) ((d) << 25)
  92. #define S1(s1) (reg_map[s1] << 14)
  93. #define S2(s2) (reg_map[s2])
  94. #define S1A(s1) ((s1) << 14)
  95. #define S2A(s2) (s2)
  96. #define IMM_ARG 0x2000
  97. #define DOP(op) ((op) << 5)
  98. #define IMM(imm) (((imm) & 0x1fff) | IMM_ARG)
  99. #define DR(dr) (reg_map[dr])
  100. #define OPC1(opcode) ((opcode) << 30)
  101. #define OPC2(opcode) ((opcode) << 22)
  102. #define OPC3(opcode) ((opcode) << 19)
  103. #define SET_FLAGS OPC3(0x10)
  104. #define ADD (OPC1(0x2) | OPC3(0x00))
  105. #define ADDC (OPC1(0x2) | OPC3(0x08))
  106. #define AND (OPC1(0x2) | OPC3(0x01))
  107. #define ANDN (OPC1(0x2) | OPC3(0x05))
  108. #define CALL (OPC1(0x1))
  109. #define FABSS (OPC1(0x2) | OPC3(0x34) | DOP(0x09))
  110. #define FADDD (OPC1(0x2) | OPC3(0x34) | DOP(0x42))
  111. #define FADDS (OPC1(0x2) | OPC3(0x34) | DOP(0x41))
  112. #define FCMPD (OPC1(0x2) | OPC3(0x35) | DOP(0x52))
  113. #define FCMPS (OPC1(0x2) | OPC3(0x35) | DOP(0x51))
  114. #define FDIVD (OPC1(0x2) | OPC3(0x34) | DOP(0x4e))
  115. #define FDIVS (OPC1(0x2) | OPC3(0x34) | DOP(0x4d))
  116. #define FDTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd2))
  117. #define FDTOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc6))
  118. #define FITOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc8))
  119. #define FITOS (OPC1(0x2) | OPC3(0x34) | DOP(0xc4))
  120. #define FMOVS (OPC1(0x2) | OPC3(0x34) | DOP(0x01))
  121. #define FMULD (OPC1(0x2) | OPC3(0x34) | DOP(0x4a))
  122. #define FMULS (OPC1(0x2) | OPC3(0x34) | DOP(0x49))
  123. #define FNEGS (OPC1(0x2) | OPC3(0x34) | DOP(0x05))
  124. #define FSTOD (OPC1(0x2) | OPC3(0x34) | DOP(0xc9))
  125. #define FSTOI (OPC1(0x2) | OPC3(0x34) | DOP(0xd1))
  126. #define FSUBD (OPC1(0x2) | OPC3(0x34) | DOP(0x46))
  127. #define FSUBS (OPC1(0x2) | OPC3(0x34) | DOP(0x45))
  128. #define JMPL (OPC1(0x2) | OPC3(0x38))
  129. #define NOP (OPC1(0x0) | OPC2(0x04))
  130. #define OR (OPC1(0x2) | OPC3(0x02))
  131. #define ORN (OPC1(0x2) | OPC3(0x06))
  132. #define RDY (OPC1(0x2) | OPC3(0x28) | S1A(0))
  133. #define RESTORE (OPC1(0x2) | OPC3(0x3d))
  134. #define SAVE (OPC1(0x2) | OPC3(0x3c))
  135. #define SETHI (OPC1(0x0) | OPC2(0x04))
  136. #define SLL (OPC1(0x2) | OPC3(0x25))
  137. #define SLLX (OPC1(0x2) | OPC3(0x25) | (1 << 12))
  138. #define SRA (OPC1(0x2) | OPC3(0x27))
  139. #define SRAX (OPC1(0x2) | OPC3(0x27) | (1 << 12))
  140. #define SRL (OPC1(0x2) | OPC3(0x26))
  141. #define SRLX (OPC1(0x2) | OPC3(0x26) | (1 << 12))
  142. #define SUB (OPC1(0x2) | OPC3(0x04))
  143. #define SUBC (OPC1(0x2) | OPC3(0x0c))
  144. #define TA (OPC1(0x2) | OPC3(0x3a) | (8 << 25))
  145. #define WRY (OPC1(0x2) | OPC3(0x30) | DA(0))
  146. #define XOR (OPC1(0x2) | OPC3(0x03))
  147. #define XNOR (OPC1(0x2) | OPC3(0x07))
  148. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  149. #define MAX_DISP (0x1fffff)
  150. #define MIN_DISP (-0x200000)
  151. #define DISP_MASK (0x3fffff)
  152. #define BICC (OPC1(0x0) | OPC2(0x2))
  153. #define FBFCC (OPC1(0x0) | OPC2(0x6))
  154. #define SLL_W SLL
  155. #define SDIV (OPC1(0x2) | OPC3(0x0f))
  156. #define SMUL (OPC1(0x2) | OPC3(0x0b))
  157. #define UDIV (OPC1(0x2) | OPC3(0x0e))
  158. #define UMUL (OPC1(0x2) | OPC3(0x0a))
  159. #else
  160. #define SLL_W SLLX
  161. #endif
  162. #define SIMM_MAX (0x0fff)
  163. #define SIMM_MIN (-0x1000)
  164. /* dest_reg is the absolute name of the register
  165. Useful for reordering instructions in the delay slot. */
  166. static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot)
  167. {
  168. sljit_ins *ptr;
  169. SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS
  170. || (delay_slot & DST_INS_MASK) == MOVABLE_INS
  171. || (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f));
  172. ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
  173. FAIL_IF(!ptr);
  174. *ptr = ins;
  175. compiler->size++;
  176. compiler->delay_slot = delay_slot;
  177. return SLJIT_SUCCESS;
  178. }
  179. static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
  180. {
  181. sljit_sw diff;
  182. sljit_uw target_addr;
  183. sljit_ins *inst;
  184. sljit_ins saved_inst;
  185. if (jump->flags & SLJIT_REWRITABLE_JUMP)
  186. return code_ptr;
  187. if (jump->flags & JUMP_ADDR)
  188. target_addr = jump->u.target;
  189. else {
  190. SLJIT_ASSERT(jump->flags & JUMP_LABEL);
  191. target_addr = (sljit_uw)(code + jump->u.label->size);
  192. }
  193. inst = (sljit_ins*)jump->addr;
  194. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  195. if (jump->flags & IS_CALL) {
  196. /* Call is always patchable on sparc 32. */
  197. jump->flags |= PATCH_CALL;
  198. if (jump->flags & IS_MOVABLE) {
  199. inst[0] = inst[-1];
  200. inst[-1] = CALL;
  201. jump->addr -= sizeof(sljit_ins);
  202. return inst;
  203. }
  204. inst[0] = CALL;
  205. inst[1] = NOP;
  206. return inst + 1;
  207. }
  208. #else
  209. /* Both calls and BPr instructions shall not pass this point. */
  210. #error "Implementation required"
  211. #endif
  212. if (jump->flags & IS_COND)
  213. inst--;
  214. if (jump->flags & IS_MOVABLE) {
  215. diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2;
  216. if (diff <= MAX_DISP && diff >= MIN_DISP) {
  217. jump->flags |= PATCH_B;
  218. inst--;
  219. if (jump->flags & IS_COND) {
  220. saved_inst = inst[0];
  221. inst[0] = inst[1] ^ (1 << 28);
  222. inst[1] = saved_inst;
  223. } else {
  224. inst[1] = inst[0];
  225. inst[0] = BICC | DA(0x8);
  226. }
  227. jump->addr = (sljit_uw)inst;
  228. return inst + 1;
  229. }
  230. }
  231. diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2;
  232. if (diff <= MAX_DISP && diff >= MIN_DISP) {
  233. jump->flags |= PATCH_B;
  234. if (jump->flags & IS_COND)
  235. inst[0] ^= (1 << 28);
  236. else
  237. inst[0] = BICC | DA(0x8);
  238. inst[1] = NOP;
  239. jump->addr = (sljit_uw)inst;
  240. return inst + 1;
  241. }
  242. return code_ptr;
  243. }
  244. SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
  245. {
  246. struct sljit_memory_fragment *buf;
  247. sljit_ins *code;
  248. sljit_ins *code_ptr;
  249. sljit_ins *buf_ptr;
  250. sljit_ins *buf_end;
  251. sljit_uw word_count;
  252. sljit_uw addr;
  253. struct sljit_label *label;
  254. struct sljit_jump *jump;
  255. struct sljit_const *const_;
  256. CHECK_ERROR_PTR();
  257. CHECK_PTR(check_sljit_generate_code(compiler));
  258. reverse_buf(compiler);
  259. code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
  260. PTR_FAIL_WITH_EXEC_IF(code);
  261. buf = compiler->buf;
  262. code_ptr = code;
  263. word_count = 0;
  264. label = compiler->labels;
  265. jump = compiler->jumps;
  266. const_ = compiler->consts;
  267. do {
  268. buf_ptr = (sljit_ins*)buf->memory;
  269. buf_end = buf_ptr + (buf->used_size >> 2);
  270. do {
  271. *code_ptr = *buf_ptr++;
  272. SLJIT_ASSERT(!label || label->size >= word_count);
  273. SLJIT_ASSERT(!jump || jump->addr >= word_count);
  274. SLJIT_ASSERT(!const_ || const_->addr >= word_count);
  275. /* These structures are ordered by their address. */
  276. if (label && label->size == word_count) {
  277. /* Just recording the address. */
  278. label->addr = (sljit_uw)code_ptr;
  279. label->size = code_ptr - code;
  280. label = label->next;
  281. }
  282. if (jump && jump->addr == word_count) {
  283. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  284. jump->addr = (sljit_uw)(code_ptr - 3);
  285. #else
  286. jump->addr = (sljit_uw)(code_ptr - 6);
  287. #endif
  288. code_ptr = detect_jump_type(jump, code_ptr, code);
  289. jump = jump->next;
  290. }
  291. if (const_ && const_->addr == word_count) {
  292. /* Just recording the address. */
  293. const_->addr = (sljit_uw)code_ptr;
  294. const_ = const_->next;
  295. }
  296. code_ptr ++;
  297. word_count ++;
  298. } while (buf_ptr < buf_end);
  299. buf = buf->next;
  300. } while (buf);
  301. if (label && label->size == word_count) {
  302. label->addr = (sljit_uw)code_ptr;
  303. label->size = code_ptr - code;
  304. label = label->next;
  305. }
  306. SLJIT_ASSERT(!label);
  307. SLJIT_ASSERT(!jump);
  308. SLJIT_ASSERT(!const_);
  309. SLJIT_ASSERT(code_ptr - code <= (sljit_si)compiler->size);
  310. jump = compiler->jumps;
  311. while (jump) {
  312. do {
  313. addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
  314. buf_ptr = (sljit_ins*)jump->addr;
  315. if (jump->flags & PATCH_CALL) {
  316. addr = (sljit_sw)(addr - jump->addr) >> 2;
  317. SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
  318. buf_ptr[0] = CALL | (addr & 0x3fffffff);
  319. break;
  320. }
  321. if (jump->flags & PATCH_B) {
  322. addr = (sljit_sw)(addr - jump->addr) >> 2;
  323. SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
  324. buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
  325. break;
  326. }
  327. /* Set the fields of immediate loads. */
  328. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  329. buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff);
  330. buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff);
  331. #else
  332. #error "Implementation required"
  333. #endif
  334. } while (0);
  335. jump = jump->next;
  336. }
  337. compiler->error = SLJIT_ERR_COMPILED;
  338. compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
  339. SLJIT_CACHE_FLUSH(code, code_ptr);
  340. return code;
  341. }
  342. /* --------------------------------------------------------------------- */
  343. /* Entry, exit */
  344. /* --------------------------------------------------------------------- */
  345. /* Creates an index in data_transfer_insts array. */
  346. #define LOAD_DATA 0x01
  347. #define WORD_DATA 0x00
  348. #define BYTE_DATA 0x02
  349. #define HALF_DATA 0x04
  350. #define INT_DATA 0x06
  351. #define SIGNED_DATA 0x08
  352. /* Separates integer and floating point registers */
  353. #define GPR_REG 0x0f
  354. #define DOUBLE_DATA 0x10
  355. #define SINGLE_DATA 0x12
  356. #define MEM_MASK 0x1f
  357. #define WRITE_BACK 0x00020
  358. #define ARG_TEST 0x00040
  359. #define ALT_KEEP_CACHE 0x00080
  360. #define CUMULATIVE_OP 0x00100
  361. #define IMM_OP 0x00200
  362. #define SRC2_IMM 0x00400
  363. #define REG_DEST 0x00800
  364. #define REG2_SOURCE 0x01000
  365. #define SLOW_SRC1 0x02000
  366. #define SLOW_SRC2 0x04000
  367. #define SLOW_DEST 0x08000
  368. /* SET_FLAGS (0x10 << 19) also belong here! */
  369. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  370. #include "sljitNativeSPARC_32.c"
  371. #else
  372. #include "sljitNativeSPARC_64.c"
  373. #endif
  374. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
  375. sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
  376. sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
  377. {
  378. CHECK_ERROR();
  379. CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
  380. set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
  381. local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
  382. compiler->local_size = local_size;
  383. if (local_size <= SIMM_MAX) {
  384. FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | IMM(-local_size), UNMOVABLE_INS));
  385. }
  386. else {
  387. FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size));
  388. FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | S2(TMP_REG1), UNMOVABLE_INS));
  389. }
  390. /* Arguments are in their appropriate registers. */
  391. return SLJIT_SUCCESS;
  392. }
  393. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
  394. sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
  395. sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
  396. {
  397. CHECK_ERROR();
  398. CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
  399. set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
  400. compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
  401. return SLJIT_SUCCESS;
  402. }
  403. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
  404. {
  405. CHECK_ERROR();
  406. CHECK(check_sljit_emit_return(compiler, op, src, srcw));
  407. if (op != SLJIT_MOV || !FAST_IS_REG(src)) {
  408. FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
  409. src = SLJIT_R0;
  410. }
  411. FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS));
  412. return push_inst(compiler, RESTORE | D(SLJIT_R0) | S1(src) | S2(0), UNMOVABLE_INS);
  413. }
  414. /* --------------------------------------------------------------------- */
  415. /* Operators */
  416. /* --------------------------------------------------------------------- */
  417. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  418. #define ARCH_32_64(a, b) a
  419. #else
  420. #define ARCH_32_64(a, b) b
  421. #endif
  422. static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = {
  423. /* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
  424. /* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
  425. /* u b s */ OPC1(3) | OPC3(0x05) /* stb */,
  426. /* u b l */ OPC1(3) | OPC3(0x01) /* ldub */,
  427. /* u h s */ OPC1(3) | OPC3(0x06) /* sth */,
  428. /* u h l */ OPC1(3) | OPC3(0x02) /* lduh */,
  429. /* u i s */ OPC1(3) | OPC3(0x04) /* stw */,
  430. /* u i l */ OPC1(3) | OPC3(0x00) /* lduw */,
  431. /* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
  432. /* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
  433. /* s b s */ OPC1(3) | OPC3(0x05) /* stb */,
  434. /* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */,
  435. /* s h s */ OPC1(3) | OPC3(0x06) /* sth */,
  436. /* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */,
  437. /* s i s */ OPC1(3) | OPC3(0x04) /* stw */,
  438. /* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */),
  439. /* d s */ OPC1(3) | OPC3(0x27),
  440. /* d l */ OPC1(3) | OPC3(0x23),
  441. /* s s */ OPC1(3) | OPC3(0x24),
  442. /* s l */ OPC1(3) | OPC3(0x20),
  443. };
  444. #undef ARCH_32_64
  445. /* Can perform an operation using at most 1 instruction. */
  446. static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
  447. {
  448. SLJIT_ASSERT(arg & SLJIT_MEM);
  449. if (!(flags & WRITE_BACK) || !(arg & REG_MASK)) {
  450. if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN)
  451. || ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) {
  452. /* Works for both absoulte and relative addresses (immediate case). */
  453. if (SLJIT_UNLIKELY(flags & ARG_TEST))
  454. return 1;
  455. FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK]
  456. | ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg))
  457. | S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)),
  458. ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS));
  459. return -1;
  460. }
  461. }
  462. return 0;
  463. }
  464. /* See getput_arg below.
  465. Note: can_cache is called only for binary operators. Those
  466. operators always uses word arguments without write back. */
  467. static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
  468. {
  469. SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
  470. /* Simple operation except for updates. */
  471. if (arg & OFFS_REG_MASK) {
  472. argw &= 0x3;
  473. SLJIT_ASSERT(argw);
  474. next_argw &= 0x3;
  475. if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == next_argw)
  476. return 1;
  477. return 0;
  478. }
  479. if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN))
  480. return 1;
  481. return 0;
  482. }
  483. /* Emit the necessary instructions. See can_cache above. */
  484. static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
  485. {
  486. sljit_si base, arg2, delay_slot;
  487. sljit_ins dest;
  488. SLJIT_ASSERT(arg & SLJIT_MEM);
  489. if (!(next_arg & SLJIT_MEM)) {
  490. next_arg = 0;
  491. next_argw = 0;
  492. }
  493. base = arg & REG_MASK;
  494. if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
  495. argw &= 0x3;
  496. SLJIT_ASSERT(argw != 0);
  497. /* Using the cache. */
  498. if (((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) && (argw == compiler->cache_argw))
  499. arg2 = TMP_REG3;
  500. else {
  501. if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) {
  502. compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
  503. compiler->cache_argw = argw;
  504. arg2 = TMP_REG3;
  505. }
  506. else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && reg != OFFS_REG(arg))
  507. arg2 = reg;
  508. else /* It must be a mov operation, so tmp1 must be free to use. */
  509. arg2 = TMP_REG1;
  510. FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | argw, DR(arg2)));
  511. }
  512. }
  513. else {
  514. /* Using the cache. */
  515. if ((compiler->cache_arg == SLJIT_MEM) && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
  516. if (argw != compiler->cache_argw) {
  517. FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
  518. compiler->cache_argw = argw;
  519. }
  520. arg2 = TMP_REG3;
  521. } else {
  522. if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) {
  523. compiler->cache_arg = SLJIT_MEM;
  524. compiler->cache_argw = argw;
  525. arg2 = TMP_REG3;
  526. }
  527. else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base)
  528. arg2 = reg;
  529. else /* It must be a mov operation, so tmp1 must be free to use. */
  530. arg2 = TMP_REG1;
  531. FAIL_IF(load_immediate(compiler, arg2, argw));
  532. }
  533. }
  534. dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg));
  535. delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS;
  536. if (!base)
  537. return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot);
  538. if (!(flags & WRITE_BACK))
  539. return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
  540. FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot));
  541. return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base));
  542. }
  543. static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
  544. {
  545. if (getput_arg_fast(compiler, flags, reg, arg, argw))
  546. return compiler->error;
  547. compiler->cache_arg = 0;
  548. compiler->cache_argw = 0;
  549. return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
  550. }
  551. 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)
  552. {
  553. if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
  554. return compiler->error;
  555. return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
  556. }
  557. static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
  558. sljit_si dst, sljit_sw dstw,
  559. sljit_si src1, sljit_sw src1w,
  560. sljit_si src2, sljit_sw src2w)
  561. {
  562. /* arg1 goes to TMP_REG1 or src reg
  563. arg2 goes to TMP_REG2, imm or src reg
  564. TMP_REG3 can be used for caching
  565. result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
  566. sljit_si dst_r = TMP_REG2;
  567. sljit_si src1_r;
  568. sljit_sw src2_r = 0;
  569. sljit_si sugg_src2_r = TMP_REG2;
  570. if (!(flags & ALT_KEEP_CACHE)) {
  571. compiler->cache_arg = 0;
  572. compiler->cache_argw = 0;
  573. }
  574. if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
  575. if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
  576. return SLJIT_SUCCESS;
  577. }
  578. else if (FAST_IS_REG(dst)) {
  579. dst_r = dst;
  580. flags |= REG_DEST;
  581. if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
  582. sugg_src2_r = dst_r;
  583. }
  584. else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
  585. flags |= SLOW_DEST;
  586. if (flags & IMM_OP) {
  587. if ((src2 & SLJIT_IMM) && src2w) {
  588. if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) {
  589. flags |= SRC2_IMM;
  590. src2_r = src2w;
  591. }
  592. }
  593. if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
  594. if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) {
  595. flags |= SRC2_IMM;
  596. src2_r = src1w;
  597. /* And swap arguments. */
  598. src1 = src2;
  599. src1w = src2w;
  600. src2 = SLJIT_IMM;
  601. /* src2w = src2_r unneeded. */
  602. }
  603. }
  604. }
  605. /* Source 1. */
  606. if (FAST_IS_REG(src1))
  607. src1_r = src1;
  608. else if (src1 & SLJIT_IMM) {
  609. if (src1w) {
  610. FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
  611. src1_r = TMP_REG1;
  612. }
  613. else
  614. src1_r = 0;
  615. }
  616. else {
  617. if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))
  618. FAIL_IF(compiler->error);
  619. else
  620. flags |= SLOW_SRC1;
  621. src1_r = TMP_REG1;
  622. }
  623. /* Source 2. */
  624. if (FAST_IS_REG(src2)) {
  625. src2_r = src2;
  626. flags |= REG2_SOURCE;
  627. if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
  628. dst_r = src2_r;
  629. }
  630. else if (src2 & SLJIT_IMM) {
  631. if (!(flags & SRC2_IMM)) {
  632. if (src2w) {
  633. FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
  634. src2_r = sugg_src2_r;
  635. }
  636. else {
  637. src2_r = 0;
  638. if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM))
  639. dst_r = 0;
  640. }
  641. }
  642. }
  643. else {
  644. if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w))
  645. FAIL_IF(compiler->error);
  646. else
  647. flags |= SLOW_SRC2;
  648. src2_r = sugg_src2_r;
  649. }
  650. if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
  651. SLJIT_ASSERT(src2_r == TMP_REG2);
  652. if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
  653. FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
  654. FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
  655. }
  656. else {
  657. FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
  658. FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
  659. }
  660. }
  661. else if (flags & SLOW_SRC1)
  662. FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
  663. else if (flags & SLOW_SRC2)
  664. FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
  665. FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
  666. if (dst & SLJIT_MEM) {
  667. if (!(flags & SLOW_DEST)) {
  668. getput_arg_fast(compiler, flags, dst_r, dst, dstw);
  669. return compiler->error;
  670. }
  671. return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0);
  672. }
  673. return SLJIT_SUCCESS;
  674. }
  675. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
  676. {
  677. CHECK_ERROR();
  678. CHECK(check_sljit_emit_op0(compiler, op));
  679. op = GET_OPCODE(op);
  680. switch (op) {
  681. case SLJIT_BREAKPOINT:
  682. return push_inst(compiler, TA, UNMOVABLE_INS);
  683. case SLJIT_NOP:
  684. return push_inst(compiler, NOP, UNMOVABLE_INS);
  685. case SLJIT_LUMUL:
  686. case SLJIT_LSMUL:
  687. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  688. FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
  689. return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1));
  690. #else
  691. #error "Implementation required"
  692. #endif
  693. case SLJIT_UDIVMOD:
  694. case SLJIT_SDIVMOD:
  695. case SLJIT_UDIVI:
  696. case SLJIT_SDIVI:
  697. SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
  698. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  699. if ((op | 0x2) == SLJIT_UDIVI)
  700. FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));
  701. else {
  702. FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1)));
  703. FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));
  704. }
  705. if (op <= SLJIT_SDIVMOD)
  706. FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
  707. FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
  708. if (op >= SLJIT_UDIVI)
  709. return SLJIT_SUCCESS;
  710. FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1)));
  711. return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1));
  712. #else
  713. #error "Implementation required"
  714. #endif
  715. }
  716. return SLJIT_SUCCESS;
  717. }
  718. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
  719. sljit_si dst, sljit_sw dstw,
  720. sljit_si src, sljit_sw srcw)
  721. {
  722. sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
  723. CHECK_ERROR();
  724. CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
  725. ADJUST_LOCAL_OFFSET(dst, dstw);
  726. ADJUST_LOCAL_OFFSET(src, srcw);
  727. op = GET_OPCODE(op);
  728. switch (op) {
  729. case SLJIT_MOV:
  730. case SLJIT_MOV_P:
  731. return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  732. case SLJIT_MOV_UI:
  733. return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  734. case SLJIT_MOV_SI:
  735. return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  736. case SLJIT_MOV_UB:
  737. return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
  738. case SLJIT_MOV_SB:
  739. return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
  740. case SLJIT_MOV_UH:
  741. return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
  742. case SLJIT_MOV_SH:
  743. return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
  744. case SLJIT_MOVU:
  745. case SLJIT_MOVU_P:
  746. return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
  747. case SLJIT_MOVU_UI:
  748. return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
  749. case SLJIT_MOVU_SI:
  750. return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
  751. case SLJIT_MOVU_UB:
  752. return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
  753. case SLJIT_MOVU_SB:
  754. return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
  755. case SLJIT_MOVU_UH:
  756. return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
  757. case SLJIT_MOVU_SH:
  758. return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
  759. case SLJIT_NOT:
  760. case SLJIT_CLZ:
  761. return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
  762. case SLJIT_NEG:
  763. return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
  764. }
  765. return SLJIT_SUCCESS;
  766. }
  767. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
  768. sljit_si dst, sljit_sw dstw,
  769. sljit_si src1, sljit_sw src1w,
  770. sljit_si src2, sljit_sw src2w)
  771. {
  772. sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
  773. CHECK_ERROR();
  774. CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
  775. ADJUST_LOCAL_OFFSET(dst, dstw);
  776. ADJUST_LOCAL_OFFSET(src1, src1w);
  777. ADJUST_LOCAL_OFFSET(src2, src2w);
  778. op = GET_OPCODE(op);
  779. switch (op) {
  780. case SLJIT_ADD:
  781. case SLJIT_ADDC:
  782. case SLJIT_MUL:
  783. case SLJIT_AND:
  784. case SLJIT_OR:
  785. case SLJIT_XOR:
  786. return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
  787. case SLJIT_SUB:
  788. case SLJIT_SUBC:
  789. return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
  790. case SLJIT_SHL:
  791. case SLJIT_LSHR:
  792. case SLJIT_ASHR:
  793. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  794. if (src2 & SLJIT_IMM)
  795. src2w &= 0x1f;
  796. #else
  797. SLJIT_ASSERT_STOP();
  798. #endif
  799. return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
  800. }
  801. return SLJIT_SUCCESS;
  802. }
  803. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
  804. {
  805. CHECK_REG_INDEX(check_sljit_get_register_index(reg));
  806. return reg_map[reg];
  807. }
  808. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
  809. {
  810. CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
  811. return reg << 1;
  812. }
  813. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
  814. void *instruction, sljit_si size)
  815. {
  816. CHECK_ERROR();
  817. CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
  818. return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
  819. }
  820. /* --------------------------------------------------------------------- */
  821. /* Floating point operators */
  822. /* --------------------------------------------------------------------- */
  823. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
  824. {
  825. #ifdef SLJIT_IS_FPU_AVAILABLE
  826. return SLJIT_IS_FPU_AVAILABLE;
  827. #else
  828. /* Available by default. */
  829. return 1;
  830. #endif
  831. }
  832. #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7))
  833. #define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double)
  834. #define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw))
  835. static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
  836. sljit_si dst, sljit_sw dstw,
  837. sljit_si src, sljit_sw srcw)
  838. {
  839. if (src & SLJIT_MEM) {
  840. FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
  841. src = TMP_FREG1;
  842. }
  843. else
  844. src <<= 1;
  845. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | DA(TMP_FREG1) | S2A(src), MOVABLE_INS));
  846. if (dst == SLJIT_UNUSED)
  847. return SLJIT_SUCCESS;
  848. if (FAST_IS_REG(dst)) {
  849. FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
  850. return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET);
  851. }
  852. /* Store the integer value from a VFP register. */
  853. return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
  854. }
  855. static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
  856. sljit_si dst, sljit_sw dstw,
  857. sljit_si src, sljit_sw srcw)
  858. {
  859. sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
  860. if (src & SLJIT_IMM) {
  861. #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
  862. if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
  863. srcw = (sljit_si)srcw;
  864. #endif
  865. FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
  866. src = TMP_REG1;
  867. srcw = 0;
  868. }
  869. if (FAST_IS_REG(src)) {
  870. FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
  871. src = SLJIT_MEM1(SLJIT_SP);
  872. srcw = FLOAT_TMP_MEM_OFFSET;
  873. }
  874. FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
  875. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | DA(dst_r) | S2A(TMP_FREG1), MOVABLE_INS));
  876. if (dst & SLJIT_MEM)
  877. return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
  878. return SLJIT_SUCCESS;
  879. }
  880. static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
  881. sljit_si src1, sljit_sw src1w,
  882. sljit_si src2, sljit_sw src2w)
  883. {
  884. if (src1 & SLJIT_MEM) {
  885. FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
  886. src1 = TMP_FREG1;
  887. }
  888. else
  889. src1 <<= 1;
  890. if (src2 & SLJIT_MEM) {
  891. FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
  892. src2 = TMP_FREG2;
  893. }
  894. else
  895. src2 <<= 1;
  896. return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS);
  897. }
  898. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
  899. sljit_si dst, sljit_sw dstw,
  900. sljit_si src, sljit_sw srcw)
  901. {
  902. sljit_si dst_r;
  903. CHECK_ERROR();
  904. compiler->cache_arg = 0;
  905. compiler->cache_argw = 0;
  906. SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
  907. SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
  908. if (GET_OPCODE(op) == SLJIT_CONVD_FROMS)
  909. op ^= SLJIT_SINGLE_OP;
  910. dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
  911. if (src & SLJIT_MEM) {
  912. FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
  913. src = dst_r;
  914. }
  915. else
  916. src <<= 1;
  917. switch (GET_OPCODE(op)) {
  918. case SLJIT_DMOV:
  919. if (src != dst_r) {
  920. if (dst_r != TMP_FREG1) {
  921. FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS));
  922. if (!(op & SLJIT_SINGLE_OP))
  923. FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
  924. }
  925. else
  926. dst_r = src;
  927. }
  928. break;
  929. case SLJIT_DNEG:
  930. FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS));
  931. if (dst_r != src && !(op & SLJIT_SINGLE_OP))
  932. FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
  933. break;
  934. case SLJIT_DABS:
  935. FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS));
  936. if (dst_r != src && !(op & SLJIT_SINGLE_OP))
  937. FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
  938. break;
  939. case SLJIT_CONVD_FROMS:
  940. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS));
  941. op ^= SLJIT_SINGLE_OP;
  942. break;
  943. }
  944. if (dst & SLJIT_MEM)
  945. FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
  946. return SLJIT_SUCCESS;
  947. }
  948. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
  949. sljit_si dst, sljit_sw dstw,
  950. sljit_si src1, sljit_sw src1w,
  951. sljit_si src2, sljit_sw src2w)
  952. {
  953. sljit_si dst_r, flags = 0;
  954. CHECK_ERROR();
  955. CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
  956. ADJUST_LOCAL_OFFSET(dst, dstw);
  957. ADJUST_LOCAL_OFFSET(src1, src1w);
  958. ADJUST_LOCAL_OFFSET(src2, src2w);
  959. compiler->cache_arg = 0;
  960. compiler->cache_argw = 0;
  961. dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
  962. if (src1 & SLJIT_MEM) {
  963. if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
  964. FAIL_IF(compiler->error);
  965. src1 = TMP_FREG1;
  966. } else
  967. flags |= SLOW_SRC1;
  968. }
  969. else
  970. src1 <<= 1;
  971. if (src2 & SLJIT_MEM) {
  972. if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
  973. FAIL_IF(compiler->error);
  974. src2 = TMP_FREG2;
  975. } else
  976. flags |= SLOW_SRC2;
  977. }
  978. else
  979. src2 <<= 1;
  980. if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
  981. if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
  982. FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
  983. FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
  984. }
  985. else {
  986. FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
  987. FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
  988. }
  989. }
  990. else if (flags & SLOW_SRC1)
  991. FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
  992. else if (flags & SLOW_SRC2)
  993. FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
  994. if (flags & SLOW_SRC1)
  995. src1 = TMP_FREG1;
  996. if (flags & SLOW_SRC2)
  997. src2 = TMP_FREG2;
  998. switch (GET_OPCODE(op)) {
  999. case SLJIT_DADD:
  1000. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
  1001. break;
  1002. case SLJIT_DSUB:
  1003. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
  1004. break;
  1005. case SLJIT_DMUL:
  1006. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
  1007. break;
  1008. case SLJIT_DDIV:
  1009. FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
  1010. break;
  1011. }
  1012. if (dst_r == TMP_FREG2)
  1013. FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
  1014. return SLJIT_SUCCESS;
  1015. }
  1016. #undef FLOAT_DATA
  1017. #undef SELECT_FOP
  1018. /* --------------------------------------------------------------------- */
  1019. /* Other instructions */
  1020. /* --------------------------------------------------------------------- */
  1021. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
  1022. {
  1023. CHECK_ERROR();
  1024. CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
  1025. ADJUST_LOCAL_OFFSET(dst, dstw);
  1026. /* For UNUSED dst. Uncommon, but possible. */
  1027. if (dst == SLJIT_UNUSED)
  1028. return SLJIT_SUCCESS;
  1029. if (FAST_IS_REG(dst))
  1030. return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst));
  1031. /* Memory. */
  1032. return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw);
  1033. }
  1034. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
  1035. {
  1036. CHECK_ERROR();
  1037. CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
  1038. ADJUST_LOCAL_OFFSET(src, srcw);
  1039. if (FAST_IS_REG(src))
  1040. FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
  1041. else if (src & SLJIT_MEM)
  1042. FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
  1043. else if (src & SLJIT_IMM)
  1044. FAIL_IF(load_immediate(compiler, TMP_LINK, srcw));
  1045. FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
  1046. return push_inst(compiler, NOP, UNMOVABLE_INS);
  1047. }
  1048. /* --------------------------------------------------------------------- */
  1049. /* Conditional instructions */
  1050. /* --------------------------------------------------------------------- */
  1051. SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
  1052. {
  1053. struct sljit_label *label;
  1054. CHECK_ERROR_PTR();
  1055. CHECK_PTR(check_sljit_emit_label(compiler));
  1056. if (compiler->last_label && compiler->last_label->size == compiler->size)
  1057. return compiler->last_label;
  1058. label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
  1059. PTR_FAIL_IF(!label);
  1060. set_label(label, compiler);
  1061. compiler->delay_slot = UNMOVABLE_INS;
  1062. return label;
  1063. }
  1064. static sljit_ins get_cc(sljit_si type)
  1065. {
  1066. switch (type) {
  1067. case SLJIT_EQUAL:
  1068. case SLJIT_MUL_NOT_OVERFLOW:
  1069. case SLJIT_D_NOT_EQUAL: /* Unordered. */
  1070. return DA(0x1);
  1071. case SLJIT_NOT_EQUAL:
  1072. case SLJIT_MUL_OVERFLOW:
  1073. case SLJIT_D_EQUAL:
  1074. return DA(0x9);
  1075. case SLJIT_LESS:
  1076. case SLJIT_D_GREATER: /* Unordered. */
  1077. return DA(0x5);
  1078. case SLJIT_GREATER_EQUAL:
  1079. case SLJIT_D_LESS_EQUAL:
  1080. return DA(0xd);
  1081. case SLJIT_GREATER:
  1082. case SLJIT_D_GREATER_EQUAL: /* Unordered. */
  1083. return DA(0xc);
  1084. case SLJIT_LESS_EQUAL:
  1085. case SLJIT_D_LESS:
  1086. return DA(0x4);
  1087. case SLJIT_SIG_LESS:
  1088. return DA(0x3);
  1089. case SLJIT_SIG_GREATER_EQUAL:
  1090. return DA(0xb);
  1091. case SLJIT_SIG_GREATER:
  1092. return DA(0xa);
  1093. case SLJIT_SIG_LESS_EQUAL:
  1094. return DA(0x2);
  1095. case SLJIT_OVERFLOW:
  1096. case SLJIT_D_UNORDERED:
  1097. return DA(0x7);
  1098. case SLJIT_NOT_OVERFLOW:
  1099. case SLJIT_D_ORDERED:
  1100. return DA(0xf);
  1101. default:
  1102. SLJIT_ASSERT_STOP();
  1103. return DA(0x8);
  1104. }
  1105. }
  1106. SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
  1107. {
  1108. struct sljit_jump *jump;
  1109. CHECK_ERROR_PTR();
  1110. CHECK_PTR(check_sljit_emit_jump(compiler, type));
  1111. jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
  1112. PTR_FAIL_IF(!jump);
  1113. set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
  1114. type &= 0xff;
  1115. if (type < SLJIT_D_EQUAL) {
  1116. jump->flags |= IS_COND;
  1117. if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET))
  1118. jump->flags |= IS_MOVABLE;
  1119. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  1120. PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
  1121. #else
  1122. #error "Implementation required"
  1123. #endif
  1124. }
  1125. else if (type < SLJIT_JUMP) {
  1126. jump->flags |= IS_COND;
  1127. if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET))
  1128. jump->flags |= IS_MOVABLE;
  1129. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  1130. PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
  1131. #else
  1132. #error "Implementation required"
  1133. #endif
  1134. } else {
  1135. if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
  1136. jump->flags |= IS_MOVABLE;
  1137. if (type >= SLJIT_FAST_CALL)
  1138. jump->flags |= IS_CALL;
  1139. }
  1140. PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
  1141. PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS));
  1142. jump->addr = compiler->size;
  1143. PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
  1144. return jump;
  1145. }
  1146. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
  1147. {
  1148. struct sljit_jump *jump = NULL;
  1149. sljit_si src_r;
  1150. CHECK_ERROR();
  1151. CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
  1152. ADJUST_LOCAL_OFFSET(src, srcw);
  1153. if (FAST_IS_REG(src))
  1154. src_r = src;
  1155. else if (src & SLJIT_IMM) {
  1156. jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
  1157. FAIL_IF(!jump);
  1158. set_jump(jump, compiler, JUMP_ADDR);
  1159. jump->u.target = srcw;
  1160. if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
  1161. jump->flags |= IS_MOVABLE;
  1162. if (type >= SLJIT_FAST_CALL)
  1163. jump->flags |= IS_CALL;
  1164. FAIL_IF(emit_const(compiler, TMP_REG2, 0));
  1165. src_r = TMP_REG2;
  1166. }
  1167. else {
  1168. FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw));
  1169. src_r = TMP_REG2;
  1170. }
  1171. FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS));
  1172. if (jump)
  1173. jump->addr = compiler->size;
  1174. return push_inst(compiler, NOP, UNMOVABLE_INS);
  1175. }
  1176. SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
  1177. sljit_si dst, sljit_sw dstw,
  1178. sljit_si src, sljit_sw srcw,
  1179. sljit_si type)
  1180. {
  1181. sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0);
  1182. CHECK_ERROR();
  1183. CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
  1184. ADJUST_LOCAL_OFFSET(dst, dstw);
  1185. if (dst == SLJIT_UNUSED)
  1186. return SLJIT_SUCCESS;
  1187. #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  1188. op = GET_OPCODE(op);
  1189. reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
  1190. compiler->cache_arg = 0;
  1191. compiler->cache_argw = 0;
  1192. if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
  1193. ADJUST_LOCAL_OFFSET(src, srcw);
  1194. FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
  1195. src = TMP_REG1;
  1196. srcw = 0;
  1197. }
  1198. type &= 0xff;
  1199. if (type < SLJIT_D_EQUAL)
  1200. FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS));
  1201. else
  1202. FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS));
  1203. FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS));
  1204. FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS));
  1205. if (op >= SLJIT_ADD)
  1206. return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
  1207. return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS;
  1208. #else
  1209. #error "Implementation required"
  1210. #endif
  1211. }
  1212. SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
  1213. {
  1214. sljit_si reg;
  1215. struct sljit_const *const_;
  1216. CHECK_ERROR_PTR();
  1217. CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
  1218. ADJUST_LOCAL_OFFSET(dst, dstw);
  1219. const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
  1220. PTR_FAIL_IF(!const_);
  1221. set_const(const_, compiler);
  1222. reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
  1223. PTR_FAIL_IF(emit_const(compiler, reg, init_value));
  1224. if (dst & SLJIT_MEM)
  1225. PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
  1226. return const_;
  1227. }