You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

602 lines
19 KiB

12 years ago
8 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
9 years ago
12 years ago
8 years ago
12 years ago
8 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
11 years ago
12 years ago
8 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
10 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
8 years ago
11 years ago
8 years ago
11 years ago
8 years ago
11 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
8 years ago
12 years ago
11 years ago
8 years ago
11 years ago
12 years ago
8 years ago
11 years ago
8 years ago
12 years ago
8 years ago
12 years ago
11 years ago
12 years ago
8 years ago
11 years ago
12 years ago
8 years ago
12 years ago
8 years ago
12 years ago
11 years ago
12 years ago
10 years ago
12 years ago
11 years ago
12 years ago
8 years ago
12 years ago
8 years ago
11 years ago
12 years ago
8 years ago
11 years ago
8 years ago
12 years ago
11 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
11 years ago
12 years ago
11 years ago
8 years ago
11 years ago
11 years ago
12 years ago
10 years ago
12 years ago
8 years ago
11 years ago
8 years ago
11 years ago
8 years ago
11 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
10 years ago
12 years ago
11 years ago
12 years ago
12 years ago
12 years ago
10 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
9 years ago
12 years ago
12 years ago
12 years ago
9 years ago
12 years ago
9 years ago
12 years ago
9 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
10 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
11 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
11 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
9 years ago
12 years ago
  1. /*
  2. * Stack-less Just-In-Time compiler
  3. *
  4. * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification, are
  7. * permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this list of
  10. * conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form must reproduce the above copyright notice, this list
  13. * of conditions and the following disclaimer in the documentation and/or other materials
  14. * provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  19. * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  21. * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  22. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  24. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. /* x86 32-bit arch dependent functions. */
  27. static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, sljit_sw imm)
  28. {
  29. sljit_u8 *inst;
  30. inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));
  31. FAIL_IF(!inst);
  32. INC_SIZE(1 + sizeof(sljit_sw));
  33. *inst++ = opcode;
  34. sljit_unaligned_store_sw(inst, imm);
  35. return SLJIT_SUCCESS;
  36. }
  37. static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset)
  38. {
  39. if (type == SLJIT_JUMP) {
  40. *code_ptr++ = JMP_i32;
  41. jump->addr++;
  42. }
  43. else if (type >= SLJIT_FAST_CALL) {
  44. *code_ptr++ = CALL_i32;
  45. jump->addr++;
  46. }
  47. else {
  48. *code_ptr++ = GROUP_0F;
  49. *code_ptr++ = get_jump_code(type);
  50. jump->addr += 2;
  51. }
  52. if (jump->flags & JUMP_LABEL)
  53. jump->flags |= PATCH_MW;
  54. else
  55. sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4) - (sljit_uw)executable_offset);
  56. code_ptr += 4;
  57. return code_ptr;
  58. }
  59. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
  60. sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
  61. sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
  62. {
  63. sljit_s32 size;
  64. sljit_u8 *inst;
  65. CHECK_ERROR();
  66. CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
  67. set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
  68. compiler->args = args;
  69. #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  70. /* [esp+0] for saving temporaries and third argument for calls. */
  71. compiler->saveds_offset = 1 * sizeof(sljit_sw);
  72. #else
  73. /* [esp+0] for saving temporaries and space for maximum three arguments. */
  74. if (scratches <= 1)
  75. compiler->saveds_offset = 1 * sizeof(sljit_sw);
  76. else
  77. compiler->saveds_offset = ((scratches == 2) ? 2 : 3) * sizeof(sljit_sw);
  78. #endif
  79. if (scratches > 3)
  80. compiler->saveds_offset += ((scratches > (3 + 6)) ? 6 : (scratches - 3)) * sizeof(sljit_sw);
  81. compiler->locals_offset = compiler->saveds_offset;
  82. if (saveds > 3)
  83. compiler->locals_offset += (saveds - 3) * sizeof(sljit_sw);
  84. if (options & SLJIT_F64_ALIGNMENT)
  85. compiler->locals_offset = (compiler->locals_offset + sizeof(sljit_f64) - 1) & ~(sizeof(sljit_f64) - 1);
  86. size = 1 + (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3);
  87. #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  88. size += (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);
  89. #else
  90. size += (args > 0 ? (2 + args * 3) : 0);
  91. #endif
  92. inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
  93. FAIL_IF(!inst);
  94. INC_SIZE(size);
  95. PUSH_REG(reg_map[TMP_REG1]);
  96. #if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  97. if (args > 0) {
  98. *inst++ = MOV_r_rm;
  99. *inst++ = MOD_REG | (reg_map[TMP_REG1] << 3) | 0x4 /* esp */;
  100. }
  101. #endif
  102. if (saveds > 2 || scratches > 9)
  103. PUSH_REG(reg_map[SLJIT_S2]);
  104. if (saveds > 1 || scratches > 10)
  105. PUSH_REG(reg_map[SLJIT_S1]);
  106. if (saveds > 0 || scratches > 11)
  107. PUSH_REG(reg_map[SLJIT_S0]);
  108. #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  109. if (args > 0) {
  110. *inst++ = MOV_r_rm;
  111. *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2];
  112. }
  113. if (args > 1) {
  114. *inst++ = MOV_r_rm;
  115. *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1];
  116. }
  117. if (args > 2) {
  118. *inst++ = MOV_r_rm;
  119. *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */;
  120. *inst++ = 0x24;
  121. *inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */
  122. }
  123. #else
  124. if (args > 0) {
  125. *inst++ = MOV_r_rm;
  126. *inst++ = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1];
  127. *inst++ = sizeof(sljit_sw) * 2;
  128. }
  129. if (args > 1) {
  130. *inst++ = MOV_r_rm;
  131. *inst++ = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1];
  132. *inst++ = sizeof(sljit_sw) * 3;
  133. }
  134. if (args > 2) {
  135. *inst++ = MOV_r_rm;
  136. *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1];
  137. *inst++ = sizeof(sljit_sw) * 4;
  138. }
  139. #endif
  140. SLJIT_ASSERT(SLJIT_LOCALS_OFFSET > 0);
  141. #if defined(__APPLE__)
  142. /* Ignore pushed registers and SLJIT_LOCALS_OFFSET when computing the aligned local size. */
  143. saveds = (2 + (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
  144. local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds;
  145. #else
  146. if (options & SLJIT_F64_ALIGNMENT)
  147. local_size = SLJIT_LOCALS_OFFSET + ((local_size + sizeof(sljit_f64) - 1) & ~(sizeof(sljit_f64) - 1));
  148. else
  149. local_size = SLJIT_LOCALS_OFFSET + ((local_size + sizeof(sljit_sw) - 1) & ~(sizeof(sljit_sw) - 1));
  150. #endif
  151. compiler->local_size = local_size;
  152. #ifdef _WIN32
  153. if (local_size > 1024) {
  154. #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  155. FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
  156. #else
  157. /* Space for a single argument. This amount is excluded when the stack is allocated below. */
  158. local_size -= sizeof(sljit_sw);
  159. FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
  160. FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
  161. SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, sizeof(sljit_sw)));
  162. #endif
  163. FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
  164. }
  165. #endif
  166. SLJIT_ASSERT(local_size > 0);
  167. #if !defined(__APPLE__)
  168. if (options & SLJIT_F64_ALIGNMENT) {
  169. EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_SP, 0);
  170. /* Some space might allocated during sljit_grow_stack() above on WIN32. */
  171. FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
  172. SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size + sizeof(sljit_sw)));
  173. #if defined _WIN32 && !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  174. if (compiler->local_size > 1024)
  175. FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
  176. TMP_REG1, 0, TMP_REG1, 0, SLJIT_IMM, sizeof(sljit_sw)));
  177. #endif
  178. inst = (sljit_u8*)ensure_buf(compiler, 1 + 6);
  179. FAIL_IF(!inst);
  180. INC_SIZE(6);
  181. inst[0] = GROUP_BINARY_81;
  182. inst[1] = MOD_REG | AND | reg_map[SLJIT_SP];
  183. sljit_unaligned_store_sw(inst + 2, ~(sizeof(sljit_f64) - 1));
  184. /* The real local size must be used. */
  185. return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), compiler->local_size, TMP_REG1, 0);
  186. }
  187. #endif
  188. return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
  189. SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size);
  190. }
  191. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
  192. sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
  193. sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
  194. {
  195. CHECK_ERROR();
  196. CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
  197. set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
  198. compiler->args = args;
  199. #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  200. /* [esp+0] for saving temporaries and third argument for calls. */
  201. compiler->saveds_offset = 1 * sizeof(sljit_sw);
  202. #else
  203. /* [esp+0] for saving temporaries and space for maximum three arguments. */
  204. if (scratches <= 1)
  205. compiler->saveds_offset = 1 * sizeof(sljit_sw);
  206. else
  207. compiler->saveds_offset = ((scratches == 2) ? 2 : 3) * sizeof(sljit_sw);
  208. #endif
  209. if (scratches > 3)
  210. compiler->saveds_offset += ((scratches > (3 + 6)) ? 6 : (scratches - 3)) * sizeof(sljit_sw);
  211. compiler->locals_offset = compiler->saveds_offset;
  212. if (saveds > 3)
  213. compiler->locals_offset += (saveds - 3) * sizeof(sljit_sw);
  214. if (options & SLJIT_F64_ALIGNMENT)
  215. compiler->locals_offset = (compiler->locals_offset + sizeof(sljit_f64) - 1) & ~(sizeof(sljit_f64) - 1);
  216. #if defined(__APPLE__)
  217. saveds = (2 + (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
  218. compiler->local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds;
  219. #else
  220. if (options & SLJIT_F64_ALIGNMENT)
  221. compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + sizeof(sljit_f64) - 1) & ~(sizeof(sljit_f64) - 1));
  222. else
  223. compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + sizeof(sljit_sw) - 1) & ~(sizeof(sljit_sw) - 1));
  224. #endif
  225. return SLJIT_SUCCESS;
  226. }
  227. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
  228. {
  229. sljit_s32 size;
  230. sljit_u8 *inst;
  231. CHECK_ERROR();
  232. CHECK(check_sljit_emit_return(compiler, op, src, srcw));
  233. SLJIT_ASSERT(compiler->args >= 0);
  234. FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
  235. SLJIT_ASSERT(compiler->local_size > 0);
  236. #if !defined(__APPLE__)
  237. if (compiler->options & SLJIT_F64_ALIGNMENT)
  238. EMIT_MOV(compiler, SLJIT_SP, 0, SLJIT_MEM1(SLJIT_SP), compiler->local_size)
  239. else
  240. FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
  241. SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
  242. #else
  243. FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
  244. SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
  245. #endif
  246. size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) +
  247. (compiler->saveds <= 3 ? compiler->saveds : 3);
  248. #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  249. if (compiler->args > 2)
  250. size += 2;
  251. #else
  252. if (compiler->args > 0)
  253. size += 2;
  254. #endif
  255. inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
  256. FAIL_IF(!inst);
  257. INC_SIZE(size);
  258. if (compiler->saveds > 0 || compiler->scratches > 11)
  259. POP_REG(reg_map[SLJIT_S0]);
  260. if (compiler->saveds > 1 || compiler->scratches > 10)
  261. POP_REG(reg_map[SLJIT_S1]);
  262. if (compiler->saveds > 2 || compiler->scratches > 9)
  263. POP_REG(reg_map[SLJIT_S2]);
  264. POP_REG(reg_map[TMP_REG1]);
  265. #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  266. if (compiler->args > 2)
  267. RET_I16(sizeof(sljit_sw));
  268. else
  269. RET();
  270. #else
  271. RET();
  272. #endif
  273. return SLJIT_SUCCESS;
  274. }
  275. /* --------------------------------------------------------------------- */
  276. /* Operators */
  277. /* --------------------------------------------------------------------- */
  278. /* Size contains the flags as well. */
  279. static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size,
  280. /* The register or immediate operand. */
  281. sljit_s32 a, sljit_sw imma,
  282. /* The general operand (not immediate). */
  283. sljit_s32 b, sljit_sw immb)
  284. {
  285. sljit_u8 *inst;
  286. sljit_u8 *buf_ptr;
  287. sljit_s32 flags = size & ~0xf;
  288. sljit_s32 inst_size;
  289. /* Both cannot be switched on. */
  290. SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
  291. /* Size flags not allowed for typed instructions. */
  292. SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
  293. /* Both size flags cannot be switched on. */
  294. SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
  295. /* SSE2 and immediate is not possible. */
  296. SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
  297. SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
  298. && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
  299. && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
  300. size &= 0xf;
  301. inst_size = size;
  302. if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
  303. inst_size++;
  304. if (flags & EX86_PREF_66)
  305. inst_size++;
  306. /* Calculate size of b. */
  307. inst_size += 1; /* mod r/m byte. */
  308. if (b & SLJIT_MEM) {
  309. if ((b & REG_MASK) == SLJIT_UNUSED)
  310. inst_size += sizeof(sljit_sw);
  311. else if (immb != 0 && !(b & OFFS_REG_MASK)) {
  312. /* Immediate operand. */
  313. if (immb <= 127 && immb >= -128)
  314. inst_size += sizeof(sljit_s8);
  315. else
  316. inst_size += sizeof(sljit_sw);
  317. }
  318. if ((b & REG_MASK) == SLJIT_SP && !(b & OFFS_REG_MASK))
  319. b |= TO_OFFS_REG(SLJIT_SP);
  320. if ((b & OFFS_REG_MASK) != SLJIT_UNUSED)
  321. inst_size += 1; /* SIB byte. */
  322. }
  323. /* Calculate size of a. */
  324. if (a & SLJIT_IMM) {
  325. if (flags & EX86_BIN_INS) {
  326. if (imma <= 127 && imma >= -128) {
  327. inst_size += 1;
  328. flags |= EX86_BYTE_ARG;
  329. } else
  330. inst_size += 4;
  331. }
  332. else if (flags & EX86_SHIFT_INS) {
  333. imma &= 0x1f;
  334. if (imma != 1) {
  335. inst_size ++;
  336. flags |= EX86_BYTE_ARG;
  337. }
  338. } else if (flags & EX86_BYTE_ARG)
  339. inst_size++;
  340. else if (flags & EX86_HALF_ARG)
  341. inst_size += sizeof(short);
  342. else
  343. inst_size += sizeof(sljit_sw);
  344. }
  345. else
  346. SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
  347. inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);
  348. PTR_FAIL_IF(!inst);
  349. /* Encoding the byte. */
  350. INC_SIZE(inst_size);
  351. if (flags & EX86_PREF_F2)
  352. *inst++ = 0xf2;
  353. if (flags & EX86_PREF_F3)
  354. *inst++ = 0xf3;
  355. if (flags & EX86_PREF_66)
  356. *inst++ = 0x66;
  357. buf_ptr = inst + size;
  358. /* Encode mod/rm byte. */
  359. if (!(flags & EX86_SHIFT_INS)) {
  360. if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
  361. *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
  362. if ((a & SLJIT_IMM) || (a == 0))
  363. *buf_ptr = 0;
  364. else if (!(flags & EX86_SSE2_OP1))
  365. *buf_ptr = reg_map[a] << 3;
  366. else
  367. *buf_ptr = a << 3;
  368. }
  369. else {
  370. if (a & SLJIT_IMM) {
  371. if (imma == 1)
  372. *inst = GROUP_SHIFT_1;
  373. else
  374. *inst = GROUP_SHIFT_N;
  375. } else
  376. *inst = GROUP_SHIFT_CL;
  377. *buf_ptr = 0;
  378. }
  379. if (!(b & SLJIT_MEM))
  380. *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_map[b] : b);
  381. else if ((b & REG_MASK) != SLJIT_UNUSED) {
  382. if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
  383. if (immb != 0) {
  384. if (immb <= 127 && immb >= -128)
  385. *buf_ptr |= 0x40;
  386. else
  387. *buf_ptr |= 0x80;
  388. }
  389. if ((b & OFFS_REG_MASK) == SLJIT_UNUSED)
  390. *buf_ptr++ |= reg_map[b & REG_MASK];
  391. else {
  392. *buf_ptr++ |= 0x04;
  393. *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3);
  394. }
  395. if (immb != 0) {
  396. if (immb <= 127 && immb >= -128)
  397. *buf_ptr++ = immb; /* 8 bit displacement. */
  398. else {
  399. sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */
  400. buf_ptr += sizeof(sljit_sw);
  401. }
  402. }
  403. }
  404. else {
  405. *buf_ptr++ |= 0x04;
  406. *buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3) | (immb << 6);
  407. }
  408. }
  409. else {
  410. *buf_ptr++ |= 0x05;
  411. sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */
  412. buf_ptr += sizeof(sljit_sw);
  413. }
  414. if (a & SLJIT_IMM) {
  415. if (flags & EX86_BYTE_ARG)
  416. *buf_ptr = imma;
  417. else if (flags & EX86_HALF_ARG)
  418. sljit_unaligned_store_s16(buf_ptr, imma);
  419. else if (!(flags & EX86_SHIFT_INS))
  420. sljit_unaligned_store_sw(buf_ptr, imma);
  421. }
  422. return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
  423. }
  424. /* --------------------------------------------------------------------- */
  425. /* Call / return instructions */
  426. /* --------------------------------------------------------------------- */
  427. static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type)
  428. {
  429. sljit_u8 *inst;
  430. #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
  431. inst = (sljit_u8*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
  432. FAIL_IF(!inst);
  433. INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
  434. if (type >= SLJIT_CALL3)
  435. PUSH_REG(reg_map[SLJIT_R2]);
  436. *inst++ = MOV_r_rm;
  437. *inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0];
  438. #else
  439. inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
  440. FAIL_IF(!inst);
  441. INC_SIZE(4 * (type - SLJIT_CALL0));
  442. *inst++ = MOV_rm_r;
  443. *inst++ = MOD_DISP8 | (reg_map[SLJIT_R0] << 3) | 0x4 /* SIB */;
  444. *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
  445. *inst++ = 0;
  446. if (type >= SLJIT_CALL2) {
  447. *inst++ = MOV_rm_r;
  448. *inst++ = MOD_DISP8 | (reg_map[SLJIT_R1] << 3) | 0x4 /* SIB */;
  449. *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
  450. *inst++ = sizeof(sljit_sw);
  451. }
  452. if (type >= SLJIT_CALL3) {
  453. *inst++ = MOV_rm_r;
  454. *inst++ = MOD_DISP8 | (reg_map[SLJIT_R2] << 3) | 0x4 /* SIB */;
  455. *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
  456. *inst++ = 2 * sizeof(sljit_sw);
  457. }
  458. #endif
  459. return SLJIT_SUCCESS;
  460. }
  461. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
  462. {
  463. sljit_u8 *inst;
  464. CHECK_ERROR();
  465. CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
  466. ADJUST_LOCAL_OFFSET(dst, dstw);
  467. CHECK_EXTRA_REGS(dst, dstw, (void)0);
  468. /* For UNUSED dst. Uncommon, but possible. */
  469. if (dst == SLJIT_UNUSED)
  470. dst = TMP_REG1;
  471. if (FAST_IS_REG(dst)) {
  472. /* Unused dest is possible here. */
  473. inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
  474. FAIL_IF(!inst);
  475. INC_SIZE(1);
  476. POP_REG(reg_map[dst]);
  477. return SLJIT_SUCCESS;
  478. }
  479. /* Memory. */
  480. inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
  481. FAIL_IF(!inst);
  482. *inst++ = POP_rm;
  483. return SLJIT_SUCCESS;
  484. }
  485. SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
  486. {
  487. sljit_u8 *inst;
  488. CHECK_ERROR();
  489. CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
  490. ADJUST_LOCAL_OFFSET(src, srcw);
  491. CHECK_EXTRA_REGS(src, srcw, (void)0);
  492. if (FAST_IS_REG(src)) {
  493. inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
  494. FAIL_IF(!inst);
  495. INC_SIZE(1 + 1);
  496. PUSH_REG(reg_map[src]);
  497. }
  498. else if (src & SLJIT_MEM) {
  499. inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
  500. FAIL_IF(!inst);
  501. *inst++ = GROUP_FF;
  502. *inst |= PUSH_rm;
  503. inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
  504. FAIL_IF(!inst);
  505. INC_SIZE(1);
  506. }
  507. else {
  508. /* SLJIT_IMM. */
  509. inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
  510. FAIL_IF(!inst);
  511. INC_SIZE(5 + 1);
  512. *inst++ = PUSH_i32;
  513. sljit_unaligned_store_sw(inst, srcw);
  514. inst += sizeof(sljit_sw);
  515. }
  516. RET();
  517. return SLJIT_SUCCESS;
  518. }