misc_instr.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. #include <assert.h>
  2. #include <math.h>
  3. #include <stdbool.h>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include "const.h"
  7. #include "cpu.h"
  8. #include "fpu.h"
  9. #include "global_pointers.h"
  10. #include "js_imports.h"
  11. #include "log.h"
  12. #include "misc_instr.h"
  13. bool getcf()
  14. {
  15. if(*flags_changed & 1)
  16. {
  17. return (*last_op1 ^ (*last_op1 ^ *last_op2) & (*last_op2 ^ *last_add_result)) >> *last_op_size & 1;
  18. }
  19. else
  20. {
  21. return *flags & 1;
  22. }
  23. }
  24. bool getpf()
  25. {
  26. if(*flags_changed & FLAG_PARITY)
  27. {
  28. // inverted lookup table
  29. return 0x9669 << 2 >> ((*last_result ^ *last_result >> 4) & 0xF) & FLAG_PARITY;
  30. }
  31. else
  32. {
  33. return *flags & FLAG_PARITY;
  34. }
  35. }
  36. bool getaf()
  37. {
  38. if(*flags_changed & FLAG_ADJUST)
  39. {
  40. return (*last_op1 ^ *last_op2 ^ *last_add_result) & FLAG_ADJUST;
  41. }
  42. else
  43. {
  44. return *flags & FLAG_ADJUST;
  45. }
  46. }
  47. bool getzf()
  48. {
  49. if(*flags_changed & FLAG_ZERO)
  50. {
  51. return (~*last_result & *last_result - 1) >> *last_op_size & 1;
  52. }
  53. else
  54. {
  55. return *flags & FLAG_ZERO;
  56. }
  57. }
  58. bool getsf()
  59. {
  60. if(*flags_changed & FLAG_SIGN)
  61. {
  62. return *last_result >> *last_op_size & 1;
  63. }
  64. else
  65. {
  66. return *flags & FLAG_SIGN;
  67. }
  68. }
  69. bool getof()
  70. {
  71. if(*flags_changed & FLAG_OVERFLOW)
  72. {
  73. return ((*last_op1 ^ *last_add_result) & (*last_op2 ^ *last_add_result)) >> *last_op_size & 1;
  74. }
  75. else
  76. {
  77. return *flags & FLAG_OVERFLOW;
  78. }
  79. }
  80. bool test_o() { return getof(); }
  81. bool test_b() { return getcf(); }
  82. bool test_z() { return getzf(); }
  83. bool test_s() { return getsf(); }
  84. bool test_p() { return getpf(); }
  85. bool test_be() { return getcf() || getzf(); }
  86. bool test_l() { return getsf() != getof(); }
  87. bool test_le() { return getzf() || getsf() != getof(); }
  88. bool test_no() { return !test_o(); }
  89. bool test_nb() { return !test_b(); }
  90. bool test_nz() { return !test_z(); }
  91. bool test_ns() { return !test_s(); }
  92. bool test_np() { return !test_p(); }
  93. bool test_nbe() { return !test_be(); }
  94. bool test_nl() { return !test_l(); }
  95. bool test_nle() { return !test_le(); }
  96. void jmp_rel16(int32_t rel16)
  97. {
  98. int32_t cs_offset = get_seg_cs();
  99. // limit ip to 16 bit
  100. *instruction_pointer = cs_offset + ((*instruction_pointer - cs_offset + rel16) & 0xFFFF);
  101. }
  102. void jmpcc16(bool condition, int32_t imm16)
  103. {
  104. if(condition)
  105. {
  106. jmp_rel16(imm16);
  107. }
  108. }
  109. void jmpcc32(bool condition, int32_t imm32)
  110. {
  111. if(condition)
  112. {
  113. *instruction_pointer += imm32;
  114. }
  115. }
  116. void loopne16(int32_t imm8s) { jmpcc16(decr_ecx_asize() && !getzf(), imm8s); }
  117. void loope16(int32_t imm8s) { jmpcc16(decr_ecx_asize() && getzf(), imm8s); }
  118. void loop16(int32_t imm8s) { jmpcc16(decr_ecx_asize(), imm8s); }
  119. void jcxz16(int32_t imm8s) { jmpcc16(get_reg_asize(ECX) == 0, imm8s); }
  120. void loopne32(int32_t imm8s) { jmpcc32(decr_ecx_asize() && !getzf(), imm8s); }
  121. void loope32(int32_t imm8s) { jmpcc32(decr_ecx_asize() && getzf(), imm8s); }
  122. void loop32(int32_t imm8s) { jmpcc32(decr_ecx_asize(), imm8s); }
  123. void jcxz32(int32_t imm8s) { jmpcc32(get_reg_asize(ECX) == 0, imm8s); }
  124. void cmovcc16(bool condition, int32_t value, int32_t r)
  125. {
  126. if(condition)
  127. {
  128. write_reg16(r, value);
  129. }
  130. }
  131. void cmovcc32(bool condition, int32_t value, int32_t r)
  132. {
  133. if(condition)
  134. {
  135. write_reg32(r, value);
  136. }
  137. }
  138. int32_t get_stack_pointer(int32_t offset)
  139. {
  140. if(*stack_size_32)
  141. {
  142. return get_seg_ss() + reg32s[ESP] + offset;
  143. }
  144. else
  145. {
  146. return get_seg_ss() + (reg16[SP] + offset & 0xFFFF);
  147. }
  148. }
  149. void adjust_stack_reg(int32_t adjustment)
  150. {
  151. if(*stack_size_32)
  152. {
  153. reg32s[ESP] += adjustment;
  154. }
  155. else
  156. {
  157. reg16[SP] += adjustment;
  158. }
  159. }
  160. __attribute__((always_inline))
  161. void push16_ss16(int32_t imm16)
  162. {
  163. int32_t sp = get_seg_ss() + (reg16[SP] - 2 & 0xFFFF);
  164. safe_write16(sp, imm16);
  165. reg16[SP] += -2;
  166. }
  167. __attribute__((always_inline))
  168. void push16_ss32(int32_t imm16)
  169. {
  170. int32_t sp = get_seg_ss() + reg32s[ESP] - 2;
  171. safe_write16(sp, imm16);
  172. reg32s[ESP] += -2;
  173. }
  174. void push16_ss16_mem(int32_t addr) { push16_ss16(safe_read16(addr)); }
  175. void push16_ss32_mem(int32_t addr) { push16_ss32(safe_read16(addr)); }
  176. void push16(int32_t imm16)
  177. {
  178. if(*stack_size_32)
  179. {
  180. push16_ss32(imm16);
  181. }
  182. else
  183. {
  184. push16_ss16(imm16);
  185. }
  186. }
  187. __attribute__((always_inline))
  188. void push32_ss16(int32_t imm32)
  189. {
  190. int32_t new_sp = reg16[SP] - 4 & 0xFFFF;
  191. safe_write32(get_seg_ss() + new_sp, imm32);
  192. reg16[SP] = new_sp;
  193. }
  194. __attribute__((always_inline))
  195. void push32_ss32(int32_t imm32)
  196. {
  197. int32_t new_esp = reg32s[ESP] - 4;
  198. safe_write32(get_seg_ss() + new_esp, imm32);
  199. reg32s[ESP] = new_esp;
  200. }
  201. void push32_ss16_mem(int32_t addr) { push32_ss16(safe_read32s(addr)); }
  202. void push32_ss32_mem(int32_t addr) { push32_ss32(safe_read32s(addr)); }
  203. __attribute__((always_inline))
  204. void push32(int32_t imm32)
  205. {
  206. if(*stack_size_32)
  207. {
  208. push32_ss32(imm32);
  209. }
  210. else
  211. {
  212. push32_ss16(imm32);
  213. }
  214. }
  215. __attribute__((always_inline))
  216. int32_t pop16_ss16()
  217. {
  218. int32_t sp = get_seg_ss() + reg16[SP];
  219. int32_t result = safe_read16(sp);
  220. reg16[SP] += 2;
  221. return result;
  222. }
  223. __attribute__((always_inline))
  224. int32_t pop16_ss32()
  225. {
  226. int32_t esp = get_seg_ss() + reg32s[ESP];
  227. int32_t result = safe_read16(esp);
  228. reg32s[ESP] += 2;
  229. return result;
  230. }
  231. __attribute__((always_inline))
  232. int32_t pop16()
  233. {
  234. if(*stack_size_32)
  235. {
  236. return pop16_ss32();
  237. }
  238. else
  239. {
  240. return pop16_ss16();
  241. }
  242. }
  243. __attribute__((always_inline))
  244. int32_t pop32s_ss16()
  245. {
  246. int32_t sp = reg16[SP];
  247. int32_t result = safe_read32s(get_seg_ss() + sp);
  248. reg16[SP] = sp + 4;
  249. return result;
  250. }
  251. __attribute__((always_inline))
  252. int32_t pop32s_ss32()
  253. {
  254. int32_t esp = reg32s[ESP];
  255. int32_t result = safe_read32s(get_seg_ss() + esp);
  256. reg32s[ESP] = esp + 4;
  257. return result;
  258. }
  259. __attribute__((always_inline))
  260. int32_t pop32s()
  261. {
  262. if(*stack_size_32)
  263. {
  264. return pop32s_ss32();
  265. }
  266. else
  267. {
  268. return pop32s_ss16();
  269. }
  270. }
  271. void pusha16()
  272. {
  273. uint16_t temp = reg16[SP];
  274. // make sure we don't get a pagefault after having
  275. // pushed several registers already
  276. writable_or_pagefault(get_stack_pointer(-16), 16);
  277. push16(reg16[AX]);
  278. push16(reg16[CX]);
  279. push16(reg16[DX]);
  280. push16(reg16[BX]);
  281. push16(temp);
  282. push16(reg16[BP]);
  283. push16(reg16[SI]);
  284. push16(reg16[DI]);
  285. }
  286. void pusha32()
  287. {
  288. int32_t temp = reg32s[ESP];
  289. writable_or_pagefault(get_stack_pointer(-32), 32);
  290. push32(reg32s[EAX]);
  291. push32(reg32s[ECX]);
  292. push32(reg32s[EDX]);
  293. push32(reg32s[EBX]);
  294. push32(temp);
  295. push32(reg32s[EBP]);
  296. push32(reg32s[ESI]);
  297. push32(reg32s[EDI]);
  298. }
  299. void setcc_reg(bool condition, int32_t r) {
  300. write_reg8(r, condition ? 1 : 0);
  301. }
  302. void setcc_mem(bool condition, int32_t addr) {
  303. safe_write8(addr, condition ? 1 : 0);
  304. }
  305. void fxsave(uint32_t addr)
  306. {
  307. writable_or_pagefault(addr, 512);
  308. safe_write16(addr + 0, *fpu_control_word);
  309. safe_write16(addr + 2, fpu_load_status_word());
  310. safe_write8( addr + 4, ~*fpu_stack_empty & 0xFF);
  311. safe_write16(addr + 6, *fpu_opcode);
  312. safe_write32(addr + 8, *fpu_ip);
  313. safe_write16(addr + 12, *fpu_ip_selector);
  314. safe_write32(addr + 16, *fpu_dp);
  315. safe_write16(addr + 20, *fpu_dp_selector);
  316. safe_write32(addr + 24, *mxcsr);
  317. safe_write32(addr + 28, MXCSR_MASK);
  318. for(int32_t i = 0; i < 8; i++)
  319. {
  320. fpu_store_m80(addr + 32 + (i << 4), fpu_st[*fpu_stack_ptr + i & 7]);
  321. }
  322. // If the OSFXSR bit in control register CR4 is not set, the FXSAVE
  323. // instruction may not save these registers. This behavior is
  324. // implementation dependent.
  325. for(int32_t i = 0; i < 8; i++)
  326. {
  327. safe_write32(addr + 160 + (i << 4) + 0, reg_xmm[i].u32[0]);
  328. safe_write32(addr + 160 + (i << 4) + 4, reg_xmm[i].u32[1]);
  329. safe_write32(addr + 160 + (i << 4) + 8, reg_xmm[i].u32[2]);
  330. safe_write32(addr + 160 + (i << 4) + 12, reg_xmm[i].u32[3]);
  331. }
  332. }
  333. void fxrstor(uint32_t addr)
  334. {
  335. translate_address_read(addr);
  336. translate_address_read(addr + 511);
  337. int32_t new_mxcsr = safe_read32s(addr + 24);
  338. if(new_mxcsr & ~MXCSR_MASK)
  339. {
  340. dbg_log("#gp Invalid mxcsr bits");
  341. trigger_gp(0);
  342. }
  343. *fpu_control_word = safe_read16(addr + 0);
  344. fpu_set_status_word(safe_read16(addr + 2));
  345. *fpu_stack_empty = ~safe_read8(addr + 4) & 0xFF;
  346. *fpu_opcode = safe_read16(addr + 6);
  347. *fpu_ip = safe_read32s(addr + 8);
  348. *fpu_ip = safe_read16(addr + 12);
  349. *fpu_dp = safe_read32s(addr + 16);
  350. *fpu_dp_selector = safe_read16(addr + 20);
  351. *mxcsr = new_mxcsr;
  352. for(int32_t i = 0; i < 8; i++)
  353. {
  354. fpu_st[*fpu_stack_ptr + i & 7] = fpu_load_m80(addr + 32 + (i << 4));
  355. }
  356. for(int32_t i = 0; i < 8; i++)
  357. {
  358. reg_xmm[i].u32[0] = safe_read32s(addr + 160 + (i << 4) + 0);
  359. reg_xmm[i].u32[1] = safe_read32s(addr + 160 + (i << 4) + 4);
  360. reg_xmm[i].u32[2] = safe_read32s(addr + 160 + (i << 4) + 8);
  361. reg_xmm[i].u32[3] = safe_read32s(addr + 160 + (i << 4) + 12);
  362. }
  363. }
  364. int32_t xchg8(int32_t data, int32_t r8)
  365. {
  366. int32_t tmp = reg8[r8];
  367. reg8[r8] = data;
  368. return tmp;
  369. }
  370. int32_t xchg16(int32_t data, int32_t r16)
  371. {
  372. int32_t tmp = reg16[r16];
  373. reg16[r16] = data;
  374. return tmp;
  375. }
  376. void xchg16r(int32_t r16)
  377. {
  378. int32_t tmp = reg16[AX];
  379. reg16[AX] = reg16[r16];
  380. reg16[r16] = tmp;
  381. }
  382. int32_t xchg32(int32_t data, int32_t r32)
  383. {
  384. int32_t tmp = reg32s[r32];
  385. reg32s[r32] = data;
  386. return tmp;
  387. }
  388. void xchg32r(int32_t r32)
  389. {
  390. int32_t tmp = reg32s[EAX];
  391. reg32s[EAX] = reg32s[r32];
  392. reg32s[r32] = tmp;
  393. }