sljitNativeMIPS_32.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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. /* mips 32-bit arch dependent functions. */
  27. static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm)
  28. {
  29. if (!(imm & ~0xffff))
  30. return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
  31. if (imm < 0 && imm >= SIMM_MIN)
  32. return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
  33. FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));
  34. return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;
  35. }
  36. #define EMIT_LOGICAL(op_imm, op_norm) \
  37. if (flags & SRC2_IMM) { \
  38. if (op & SLJIT_SET_E) \
  39. FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
  40. if (CHECK_FLAGS(SLJIT_SET_E)) \
  41. FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
  42. } \
  43. else { \
  44. if (op & SLJIT_SET_E) \
  45. FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
  46. if (CHECK_FLAGS(SLJIT_SET_E)) \
  47. FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
  48. }
  49. #define EMIT_SHIFT(op_imm, op_v) \
  50. if (flags & SRC2_IMM) { \
  51. if (op & SLJIT_SET_E) \
  52. FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
  53. if (CHECK_FLAGS(SLJIT_SET_E)) \
  54. FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
  55. } \
  56. else { \
  57. if (op & SLJIT_SET_E) \
  58. FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
  59. if (CHECK_FLAGS(SLJIT_SET_E)) \
  60. FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \
  61. }
  62. static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
  63. sljit_si dst, sljit_si src1, sljit_sw src2)
  64. {
  65. switch (GET_OPCODE(op)) {
  66. case SLJIT_MOV:
  67. case SLJIT_MOV_UI:
  68. case SLJIT_MOV_SI:
  69. case SLJIT_MOV_P:
  70. SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
  71. if (dst != src2)
  72. return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
  73. return SLJIT_SUCCESS;
  74. case SLJIT_MOV_UB:
  75. case SLJIT_MOV_SB:
  76. SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
  77. if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
  78. if (op == SLJIT_MOV_SB) {
  79. #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
  80. return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
  81. #else
  82. FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
  83. return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
  84. #endif
  85. }
  86. return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
  87. }
  88. else if (dst != src2)
  89. SLJIT_ASSERT_STOP();
  90. return SLJIT_SUCCESS;
  91. case SLJIT_MOV_UH:
  92. case SLJIT_MOV_SH:
  93. SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
  94. if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
  95. if (op == SLJIT_MOV_SH) {
  96. #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
  97. return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
  98. #else
  99. FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
  100. return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
  101. #endif
  102. }
  103. return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
  104. }
  105. else if (dst != src2)
  106. SLJIT_ASSERT_STOP();
  107. return SLJIT_SUCCESS;
  108. case SLJIT_NOT:
  109. SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
  110. if (op & SLJIT_SET_E)
  111. FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
  112. if (CHECK_FLAGS(SLJIT_SET_E))
  113. FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
  114. return SLJIT_SUCCESS;
  115. case SLJIT_CLZ:
  116. SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
  117. #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
  118. if (op & SLJIT_SET_E)
  119. FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
  120. if (CHECK_FLAGS(SLJIT_SET_E))
  121. FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
  122. #else
  123. if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
  124. FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
  125. return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
  126. }
  127. /* Nearly all instructions are unmovable in the following sequence. */
  128. FAIL_IF(push_inst(compiler, ADDU | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
  129. /* Check zero. */
  130. FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));
  131. FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));
  132. FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(dst) | IMM(-1), DR(dst)));
  133. /* Loop for searching the highest bit. */
  134. FAIL_IF(push_inst(compiler, ADDIU | S(dst) | T(dst) | IMM(1), DR(dst)));
  135. FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
  136. FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
  137. if (op & SLJIT_SET_E)
  138. return push_inst(compiler, ADDU | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
  139. #endif
  140. return SLJIT_SUCCESS;
  141. case SLJIT_ADD:
  142. if (flags & SRC2_IMM) {
  143. if (op & SLJIT_SET_O) {
  144. if (src2 >= 0)
  145. FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  146. else
  147. FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  148. }
  149. if (op & SLJIT_SET_E)
  150. FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
  151. if (op & (SLJIT_SET_C | SLJIT_SET_O)) {
  152. if (src2 >= 0)
  153. FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
  154. else {
  155. FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
  156. FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
  157. }
  158. }
  159. /* dst may be the same as src1 or src2. */
  160. if (CHECK_FLAGS(SLJIT_SET_E))
  161. FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
  162. }
  163. else {
  164. if (op & SLJIT_SET_O)
  165. FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  166. if (op & SLJIT_SET_E)
  167. FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
  168. if (op & (SLJIT_SET_C | SLJIT_SET_O))
  169. FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
  170. /* dst may be the same as src1 or src2. */
  171. if (CHECK_FLAGS(SLJIT_SET_E))
  172. FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
  173. }
  174. /* a + b >= a | b (otherwise, the carry should be set to 1). */
  175. if (op & (SLJIT_SET_C | SLJIT_SET_O))
  176. FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
  177. if (!(op & SLJIT_SET_O))
  178. return SLJIT_SUCCESS;
  179. FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
  180. FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  181. FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  182. return push_inst(compiler, SLL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
  183. case SLJIT_ADDC:
  184. if (flags & SRC2_IMM) {
  185. if (op & SLJIT_SET_C) {
  186. if (src2 >= 0)
  187. FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
  188. else {
  189. FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
  190. FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  191. }
  192. }
  193. FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
  194. } else {
  195. if (op & SLJIT_SET_C)
  196. FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  197. /* dst may be the same as src1 or src2. */
  198. FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
  199. }
  200. if (op & SLJIT_SET_C)
  201. FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  202. FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
  203. if (!(op & SLJIT_SET_C))
  204. return SLJIT_SUCCESS;
  205. /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */
  206. FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
  207. /* Set carry flag. */
  208. return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG);
  209. case SLJIT_SUB:
  210. if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) {
  211. FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
  212. src2 = TMP_REG2;
  213. flags &= ~SRC2_IMM;
  214. }
  215. if (flags & SRC2_IMM) {
  216. if (op & SLJIT_SET_O) {
  217. if (src2 >= 0)
  218. FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  219. else
  220. FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  221. }
  222. if (op & SLJIT_SET_E)
  223. FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
  224. if (op & (SLJIT_SET_C | SLJIT_SET_O))
  225. FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
  226. /* dst may be the same as src1 or src2. */
  227. if (CHECK_FLAGS(SLJIT_SET_E))
  228. FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
  229. }
  230. else {
  231. if (op & SLJIT_SET_O)
  232. FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  233. if (op & SLJIT_SET_E)
  234. FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
  235. if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O))
  236. FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
  237. if (op & SLJIT_SET_U)
  238. FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
  239. if (op & SLJIT_SET_S) {
  240. FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
  241. FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
  242. }
  243. /* dst may be the same as src1 or src2. */
  244. if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
  245. FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
  246. }
  247. if (!(op & SLJIT_SET_O))
  248. return SLJIT_SUCCESS;
  249. FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
  250. FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  251. FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  252. return push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
  253. case SLJIT_SUBC:
  254. if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
  255. FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
  256. src2 = TMP_REG2;
  257. flags &= ~SRC2_IMM;
  258. }
  259. if (flags & SRC2_IMM) {
  260. if (op & SLJIT_SET_C)
  261. FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
  262. /* dst may be the same as src1 or src2. */
  263. FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
  264. }
  265. else {
  266. if (op & SLJIT_SET_C)
  267. FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
  268. /* dst may be the same as src1 or src2. */
  269. FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
  270. }
  271. if (op & SLJIT_SET_C)
  272. FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG));
  273. FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
  274. return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
  275. case SLJIT_MUL:
  276. SLJIT_ASSERT(!(flags & SRC2_IMM));
  277. if (!(op & SLJIT_SET_O)) {
  278. #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
  279. return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
  280. #else
  281. FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
  282. return push_inst(compiler, MFLO | D(dst), DR(dst));
  283. #endif
  284. }
  285. FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
  286. FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG));
  287. FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
  288. FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG));
  289. return push_inst(compiler, SUBU | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
  290. case SLJIT_AND:
  291. EMIT_LOGICAL(ANDI, AND);
  292. return SLJIT_SUCCESS;
  293. case SLJIT_OR:
  294. EMIT_LOGICAL(ORI, OR);
  295. return SLJIT_SUCCESS;
  296. case SLJIT_XOR:
  297. EMIT_LOGICAL(XORI, XOR);
  298. return SLJIT_SUCCESS;
  299. case SLJIT_SHL:
  300. EMIT_SHIFT(SLL, SLLV);
  301. return SLJIT_SUCCESS;
  302. case SLJIT_LSHR:
  303. EMIT_SHIFT(SRL, SRLV);
  304. return SLJIT_SUCCESS;
  305. case SLJIT_ASHR:
  306. EMIT_SHIFT(SRA, SRAV);
  307. return SLJIT_SUCCESS;
  308. }
  309. SLJIT_ASSERT_STOP();
  310. return SLJIT_SUCCESS;
  311. }
  312. static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value)
  313. {
  314. FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst)));
  315. return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
  316. }
  317. SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
  318. {
  319. sljit_ins *inst = (sljit_ins*)addr;
  320. inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
  321. inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
  322. SLJIT_CACHE_FLUSH(inst, inst + 2);
  323. }
  324. SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
  325. {
  326. sljit_ins *inst = (sljit_ins*)addr;
  327. inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
  328. inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
  329. SLJIT_CACHE_FLUSH(inst, inst + 2);
  330. }