instructions.c 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621
  1. #include <assert.h>
  2. #include <math.h>
  3. #include <stdbool.h>
  4. #include <stdint.h>
  5. #include "arith.h"
  6. #include "const.h"
  7. #include "cpu.h"
  8. #include "fpu.h"
  9. #include "global_pointers.h"
  10. #include "instructions.h"
  11. #include "instructions_0f.h"
  12. #include "js_imports.h"
  13. #include "log.h"
  14. #include "memory.h"
  15. #include "misc_instr.h"
  16. #include "profiler/profiler.h"
  17. #include "shared.h"
  18. #include "string.h"
  19. #pragma clang diagnostic push
  20. #pragma clang diagnostic ignored "-Wunused-parameter"
  21. DEFINE_MODRM_INSTR_READ_WRITE_8(instr_00, add8(___, read_reg8(r)))
  22. DEFINE_MODRM_INSTR_READ_WRITE_16(instr16_01, add16(___, read_reg16(r)))
  23. DEFINE_MODRM_INSTR_READ_WRITE_32(instr32_01, add32(___, read_reg32(r)))
  24. DEFINE_MODRM_INSTR_READ8(instr_02, write_reg8(r, add8(read_reg8(r), ___)))
  25. DEFINE_MODRM_INSTR_READ16(instr16_03, write_reg16(r, add16(read_reg16(r), ___)))
  26. DEFINE_MODRM_INSTR_READ32(instr32_03, write_reg32(r, add32(read_reg32(r), ___)))
  27. void instr_04(int32_t imm8) { reg8[AL] = add8(reg8[AL], imm8); }
  28. void instr16_05(int32_t imm16) { reg16[AX] = add16(reg16[AX], imm16); }
  29. void instr32_05(int32_t imm32) { reg32s[EAX] = add32(reg32s[EAX], imm32); }
  30. void instr16_06() { push16(sreg[ES]); }
  31. void instr32_06() { push32(sreg[ES]); }
  32. void instr16_07() {
  33. switch_seg(ES, safe_read16(get_stack_pointer(0)));
  34. adjust_stack_reg(2);
  35. }
  36. void instr32_07() {
  37. switch_seg(ES, safe_read32s(get_stack_pointer(0)) & 0xFFFF);
  38. adjust_stack_reg(4);
  39. }
  40. DEFINE_MODRM_INSTR_READ_WRITE_8(instr_08, or8(___, read_reg8(r)))
  41. DEFINE_MODRM_INSTR_READ_WRITE_16(instr16_09, or16(___, read_reg16(r)))
  42. DEFINE_MODRM_INSTR_READ_WRITE_32(instr32_09, or32(___, read_reg32(r)))
  43. DEFINE_MODRM_INSTR_READ8(instr_0A, write_reg8(r, or8(read_reg8(r), ___)))
  44. DEFINE_MODRM_INSTR_READ16(instr16_0B, write_reg16(r, or16(read_reg16(r), ___)))
  45. DEFINE_MODRM_INSTR_READ32(instr32_0B, write_reg32(r, or32(read_reg32(r), ___)))
  46. void instr_0C(int32_t imm8) { reg8[AL] = or8(reg8[AL], imm8); }
  47. void instr16_0D(int32_t imm16) { reg16[AX] = or16(reg16[AX], imm16); }
  48. void instr32_0D(int32_t imm32) { reg32s[EAX] = or32(reg32s[EAX], imm32); }
  49. void instr16_0E() { push16(sreg[CS]); }
  50. void instr32_0E() { push32(sreg[CS]); }
  51. void instr16_0F() {
  52. run_instruction0f_16(read_imm8());
  53. }
  54. void instr32_0F() {
  55. run_instruction0f_32(read_imm8());
  56. }
  57. DEFINE_MODRM_INSTR_READ_WRITE_8(instr_10, adc8(___, read_reg8(r)))
  58. DEFINE_MODRM_INSTR_READ_WRITE_16(instr16_11, adc16(___, read_reg16(r)))
  59. DEFINE_MODRM_INSTR_READ_WRITE_32(instr32_11, adc32(___, read_reg32(r)))
  60. DEFINE_MODRM_INSTR_READ8(instr_12, write_reg8(r, adc8(read_reg8(r), ___)))
  61. DEFINE_MODRM_INSTR_READ16(instr16_13, write_reg16(r, adc16(read_reg16(r), ___)))
  62. DEFINE_MODRM_INSTR_READ32(instr32_13, write_reg32(r, adc32(read_reg32(r), ___)))
  63. void instr_14(int32_t imm8) { reg8[AL] = adc8(reg8[AL], imm8); }
  64. void instr16_15(int32_t imm16) { reg16[AX] = adc16(reg16[AX], imm16); }
  65. void instr32_15(int32_t imm32) { reg32s[EAX] = adc32(reg32s[EAX], imm32); }
  66. void instr16_16() { push16(sreg[SS]); }
  67. void instr32_16() { push32(sreg[SS]); }
  68. void instr16_17() {
  69. switch_seg(SS, safe_read16(get_stack_pointer(0)));
  70. adjust_stack_reg(2);
  71. //clear_prefixes();
  72. //cycle_internal();
  73. }
  74. void instr32_17() {
  75. switch_seg(SS, safe_read32s(get_stack_pointer(0)) & 0xFFFF);
  76. adjust_stack_reg(4);
  77. //clear_prefixes();
  78. //cycle_internal();
  79. }
  80. DEFINE_MODRM_INSTR_READ_WRITE_8(instr_18, sbb8(___, read_reg8(r)))
  81. DEFINE_MODRM_INSTR_READ_WRITE_16(instr16_19, sbb16(___, read_reg16(r)))
  82. DEFINE_MODRM_INSTR_READ_WRITE_32(instr32_19, sbb32(___, read_reg32(r)))
  83. DEFINE_MODRM_INSTR_READ8(instr_1A, write_reg8(r, sbb8(read_reg8(r), ___)))
  84. DEFINE_MODRM_INSTR_READ16(instr16_1B, write_reg16(r, sbb16(read_reg16(r), ___)))
  85. DEFINE_MODRM_INSTR_READ32(instr32_1B, write_reg32(r, sbb32(read_reg32(r), ___)))
  86. void instr_1C(int32_t imm8) { reg8[AL] = sbb8(reg8[AL], imm8); }
  87. void instr16_1D(int32_t imm16) { reg16[AX] = sbb16(reg16[AX], imm16); }
  88. void instr32_1D(int32_t imm32) { reg32s[EAX] = sbb32(reg32s[EAX], imm32); }
  89. void instr16_1E() { push16(sreg[DS]); }
  90. void instr32_1E() { push32(sreg[DS]); }
  91. void instr16_1F() {
  92. switch_seg(DS, safe_read16(get_stack_pointer(0)));
  93. adjust_stack_reg(2);
  94. }
  95. void instr32_1F() {
  96. switch_seg(DS, safe_read32s(get_stack_pointer(0)) & 0xFFFF);
  97. adjust_stack_reg(4);
  98. }
  99. DEFINE_MODRM_INSTR_READ_WRITE_8(instr_20, and8(___, read_reg8(r)))
  100. DEFINE_MODRM_INSTR_READ_WRITE_16(instr16_21, and16(___, read_reg16(r)))
  101. DEFINE_MODRM_INSTR_READ_WRITE_32(instr32_21, and32(___, read_reg32(r)))
  102. DEFINE_MODRM_INSTR_READ8(instr_22, write_reg8(r, and8(read_reg8(r), ___)))
  103. DEFINE_MODRM_INSTR_READ16(instr16_23, write_reg16(r, and16(read_reg16(r), ___)))
  104. DEFINE_MODRM_INSTR_READ32(instr32_23, write_reg32(r, and32(read_reg32(r), ___)))
  105. void instr_24(int32_t imm8) { reg8[AL] = and8(reg8[AL], imm8); }
  106. void instr16_25(int32_t imm16) { reg16[AX] = and16(reg16[AX], imm16); }
  107. void instr32_25(int32_t imm32) { reg32s[EAX] = and32(reg32s[EAX], imm32); }
  108. void instr_26() { segment_prefix_op(ES); }
  109. void instr_27() { bcd_daa(); }
  110. DEFINE_MODRM_INSTR_READ_WRITE_8(instr_28, sub8(___, read_reg8(r)))
  111. DEFINE_MODRM_INSTR_READ_WRITE_16(instr16_29, sub16(___, read_reg16(r)))
  112. DEFINE_MODRM_INSTR_READ_WRITE_32(instr32_29, sub32(___, read_reg32(r)))
  113. DEFINE_MODRM_INSTR_READ8(instr_2A, write_reg8(r, sub8(read_reg8(r), ___)))
  114. DEFINE_MODRM_INSTR_READ16(instr16_2B, write_reg16(r, sub16(read_reg16(r), ___)))
  115. DEFINE_MODRM_INSTR_READ32(instr32_2B, write_reg32(r, sub32(read_reg32(r), ___)))
  116. void instr_2C(int32_t imm8) { reg8[AL] = sub8(reg8[AL], imm8); }
  117. void instr16_2D(int32_t imm16) { reg16[AX] = sub16(reg16[AX], imm16); }
  118. void instr32_2D(int32_t imm32) { reg32s[EAX] = sub32(reg32s[EAX], imm32); }
  119. void instr_2E() { segment_prefix_op(CS); }
  120. void instr_2F() { bcd_das(); }
  121. DEFINE_MODRM_INSTR_READ_WRITE_8(instr_30, xor8(___, read_reg8(r)))
  122. DEFINE_MODRM_INSTR_READ_WRITE_16(instr16_31, xor16(___, read_reg16(r)))
  123. DEFINE_MODRM_INSTR_READ_WRITE_32(instr32_31, xor32(___, read_reg32(r)))
  124. DEFINE_MODRM_INSTR_READ8(instr_32, write_reg8(r, xor8(read_reg8(r), ___)))
  125. DEFINE_MODRM_INSTR_READ16(instr16_33, write_reg16(r, xor16(read_reg16(r), ___)))
  126. DEFINE_MODRM_INSTR_READ32(instr32_33, write_reg32(r, xor32(read_reg32(r), ___)))
  127. void instr_34(int32_t imm8) { reg8[AL] = xor8(reg8[AL], imm8); }
  128. void instr16_35(int32_t imm16) { reg16[AX] = xor16(reg16[AX], imm16); }
  129. void instr32_35(int32_t imm32) { reg32s[EAX] = xor32(reg32s[EAX], imm32); }
  130. void instr_36() { segment_prefix_op(SS); }
  131. void instr_37() { bcd_aaa(); }
  132. DEFINE_MODRM_INSTR_READ8(instr_38, cmp8(___, read_reg8(r)))
  133. DEFINE_MODRM_INSTR_READ16(instr16_39, cmp16(___, read_reg16(r)))
  134. DEFINE_MODRM_INSTR_READ32(instr32_39, cmp32(___, read_reg32(r)))
  135. DEFINE_MODRM_INSTR_READ8(instr_3A, cmp8(read_reg8(r), ___))
  136. DEFINE_MODRM_INSTR_READ16(instr16_3B, cmp16(read_reg16(r), ___))
  137. DEFINE_MODRM_INSTR_READ32(instr32_3B, cmp32(read_reg32(r), ___))
  138. void instr_3C(int32_t imm8) { cmp8(reg8[AL], imm8); }
  139. void instr16_3D(int32_t imm16) { cmp16(reg16[AX], imm16); }
  140. void instr32_3D(int32_t imm32) { cmp32(reg32s[EAX], imm32); }
  141. void instr_3E() { segment_prefix_op(DS); }
  142. void instr_3F() { bcd_aas(); }
  143. void instr16_40() { reg16[AX] = inc16(reg16[AX]); }
  144. void instr32_40() { reg32s[EAX] = inc32(reg32s[EAX]); }
  145. void instr16_41() { reg16[CX] = inc16(reg16[CX]); }
  146. void instr32_41() { reg32s[ECX] = inc32(reg32s[ECX]); }
  147. void instr16_42() { reg16[DX] = inc16(reg16[DX]); }
  148. void instr32_42() { reg32s[EDX] = inc32(reg32s[EDX]); }
  149. void instr16_43() { reg16[BX] = inc16(reg16[BX]); }
  150. void instr32_43() { reg32s[EBX] = inc32(reg32s[EBX]); }
  151. void instr16_44() { reg16[SP] = inc16(reg16[SP]); }
  152. void instr32_44() { reg32s[ESP] = inc32(reg32s[ESP]); }
  153. void instr16_45() { reg16[BP] = inc16(reg16[BP]); }
  154. void instr32_45() { reg32s[EBP] = inc32(reg32s[EBP]); }
  155. void instr16_46() { reg16[SI] = inc16(reg16[SI]); }
  156. void instr32_46() { reg32s[ESI] = inc32(reg32s[ESI]); }
  157. void instr16_47() { reg16[DI] = inc16(reg16[DI]); }
  158. void instr32_47() { reg32s[EDI] = inc32(reg32s[EDI]); }
  159. void instr16_48() { reg16[AX] = dec16(reg16[AX]); }
  160. void instr32_48() { reg32s[EAX] = dec32(reg32s[EAX]); }
  161. void instr16_49() { reg16[CX] = dec16(reg16[CX]); }
  162. void instr32_49() { reg32s[ECX] = dec32(reg32s[ECX]); }
  163. void instr16_4A() { reg16[DX] = dec16(reg16[DX]); }
  164. void instr32_4A() { reg32s[EDX] = dec32(reg32s[EDX]); }
  165. void instr16_4B() { reg16[BX] = dec16(reg16[BX]); }
  166. void instr32_4B() { reg32s[EBX] = dec32(reg32s[EBX]); }
  167. void instr16_4C() { reg16[SP] = dec16(reg16[SP]); }
  168. void instr32_4C() { reg32s[ESP] = dec32(reg32s[ESP]); }
  169. void instr16_4D() { reg16[BP] = dec16(reg16[BP]); }
  170. void instr32_4D() { reg32s[EBP] = dec32(reg32s[EBP]); }
  171. void instr16_4E() { reg16[SI] = dec16(reg16[SI]); }
  172. void instr32_4E() { reg32s[ESI] = dec32(reg32s[ESI]); }
  173. void instr16_4F() { reg16[DI] = dec16(reg16[DI]); }
  174. void instr32_4F() { reg32s[EDI] = dec32(reg32s[EDI]); }
  175. void instr16_50() { push16(reg16[AX]); }
  176. void instr32_50() { push32(reg32s[EAX]); }
  177. void instr16_51() { push16(reg16[CX]); }
  178. void instr32_51() { push32(reg32s[ECX]); }
  179. void instr16_52() { push16(reg16[DX]); }
  180. void instr32_52() { push32(reg32s[EDX]); }
  181. void instr16_53() { push16(reg16[BX]); }
  182. void instr32_53() { push32(reg32s[EBX]); }
  183. void instr16_54() { push16(reg16[SP]); }
  184. void instr32_54() { push32(reg32s[ESP]); }
  185. void instr16_55() { push16(reg16[BP]); }
  186. void instr32_55() { push32(reg32s[EBP]); }
  187. void instr16_56() { push16(reg16[SI]); }
  188. void instr32_56() { push32(reg32s[ESI]); }
  189. void instr16_57() { push16(reg16[DI]); }
  190. void instr32_57() { push32(reg32s[EDI]); }
  191. void instr16_58() { reg16[AX] = pop16(); }
  192. void instr32_58() { reg32s[EAX] = pop32s(); }
  193. void instr16_59() { reg16[CX] = pop16(); }
  194. void instr32_59() { reg32s[ECX] = pop32s(); }
  195. void instr16_5A() { reg16[DX] = pop16(); }
  196. void instr32_5A() { reg32s[EDX] = pop32s(); }
  197. void instr16_5B() { reg16[BX] = pop16(); }
  198. void instr32_5B() { reg32s[EBX] = pop32s(); }
  199. void instr16_5C() { reg16[SP] = safe_read16(get_stack_pointer(0)); }
  200. void instr32_5C() { reg32s[ESP] = safe_read32s(get_stack_pointer(0)); }
  201. void instr16_5D() { reg16[BP] = pop16(); }
  202. void instr32_5D() { reg32s[EBP] = pop32s(); }
  203. void instr16_5E() { reg16[SI] = pop16(); }
  204. void instr32_5E() { reg32s[ESI] = pop32s(); }
  205. void instr16_5F() { reg16[DI] = pop16(); }
  206. void instr32_5F() { reg32s[EDI] = pop32s(); }
  207. void instr16_60() { pusha16(); }
  208. void instr32_60() { pusha32(); }
  209. void instr16_61() { popa16(); }
  210. void instr32_61() { popa32(); }
  211. void instr_62_reg(int32_t r2, int32_t r) {
  212. // bound
  213. dbg_log("Unimplemented BOUND instruction");
  214. dbg_assert(false);
  215. }
  216. void instr_62_mem(int32_t addr, int32_t r) {
  217. dbg_log("Unimplemented BOUND instruction");
  218. dbg_assert(false);
  219. }
  220. DEFINE_MODRM_INSTR_READ_WRITE_16(instr_63, arpl(___, read_reg16(r)))
  221. void instr_64() { segment_prefix_op(FS); }
  222. void instr_65() { segment_prefix_op(GS); }
  223. void instr_66() {
  224. // Operand-size override prefix
  225. *prefixes |= PREFIX_MASK_OPSIZE;
  226. run_prefix_instruction();
  227. *prefixes = 0;
  228. }
  229. void instr_67() {
  230. // Address-size override prefix
  231. dbg_assert(is_asize_32() == *is_32);
  232. *prefixes |= PREFIX_MASK_ADDRSIZE;
  233. run_prefix_instruction();
  234. *prefixes = 0;
  235. }
  236. void instr16_68(int32_t imm16) { push16(imm16); }
  237. void instr32_68(int32_t imm32) { push32(imm32); }
  238. void instr16_69_mem(int32_t addr, int32_t r, int32_t imm) { write_reg16(r, imul_reg16(safe_read16(addr) << 16 >> 16, imm << 16 >> 16)); }
  239. void instr16_69_reg(int32_t r1, int32_t r, int32_t imm) { write_reg16(r, imul_reg16(read_reg16(r1) << 16 >> 16, imm << 16 >> 16)); }
  240. void instr32_69_mem(int32_t addr, int32_t r, int32_t imm) { write_reg32(r, imul_reg32(safe_read32s(addr), imm)); }
  241. void instr32_69_reg(int32_t r1, int32_t r, int32_t imm) { write_reg32(r, imul_reg32(read_reg32(r1), imm)); }
  242. void instr16_6A(int32_t imm8) { push16(imm8); }
  243. void instr32_6A(int32_t imm8) { push32(imm8); }
  244. void instr16_6B_mem(int32_t addr, int32_t r, int32_t imm) { write_reg16(r, imul_reg16(safe_read16(addr) << 16 >> 16, imm)); }
  245. void instr16_6B_reg(int32_t r1, int32_t r, int32_t imm) { write_reg16(r, imul_reg16(read_reg16(r1) << 16 >> 16, imm)); }
  246. void instr32_6B_mem(int32_t addr, int32_t r, int32_t imm) { write_reg32(r, imul_reg32(safe_read32s(addr), imm)); }
  247. void instr32_6B_reg(int32_t r1, int32_t r, int32_t imm) { write_reg32(r, imul_reg32(read_reg32(r1), imm)); }
  248. void instr_6C() { insb(); }
  249. void instr16_6D() { insw(); }
  250. void instr32_6D() { insd(); }
  251. void instr_6E() { outsb(); }
  252. void instr16_6F() { outsw(); }
  253. void instr32_6F() { outsd(); }
  254. void instr16_70(int32_t imm8) { jmpcc16( test_o(), imm8); }
  255. void instr16_71(int32_t imm8) { jmpcc16(!test_o(), imm8); }
  256. void instr16_72(int32_t imm8) { jmpcc16( test_b(), imm8); }
  257. void instr16_73(int32_t imm8) { jmpcc16(!test_b(), imm8); }
  258. void instr16_74(int32_t imm8) { jmpcc16( test_z(), imm8); }
  259. void instr16_75(int32_t imm8) { jmpcc16(!test_z(), imm8); }
  260. void instr16_76(int32_t imm8) { jmpcc16( test_be(), imm8); }
  261. void instr16_77(int32_t imm8) { jmpcc16(!test_be(), imm8); }
  262. void instr16_78(int32_t imm8) { jmpcc16( test_s(), imm8); }
  263. void instr16_79(int32_t imm8) { jmpcc16(!test_s(), imm8); }
  264. void instr16_7A(int32_t imm8) { jmpcc16( test_p(), imm8); }
  265. void instr16_7B(int32_t imm8) { jmpcc16(!test_p(), imm8); }
  266. void instr16_7C(int32_t imm8) { jmpcc16( test_l(), imm8); }
  267. void instr16_7D(int32_t imm8) { jmpcc16(!test_l(), imm8); }
  268. void instr16_7E(int32_t imm8) { jmpcc16( test_le(), imm8); }
  269. void instr16_7F(int32_t imm8) { jmpcc16(!test_le(), imm8); }
  270. void instr32_70(int32_t imm8) { jmpcc32( test_o(), imm8); }
  271. void instr32_71(int32_t imm8) { jmpcc32(!test_o(), imm8); }
  272. void instr32_72(int32_t imm8) { jmpcc32( test_b(), imm8); }
  273. void instr32_73(int32_t imm8) { jmpcc32(!test_b(), imm8); }
  274. void instr32_74(int32_t imm8) { jmpcc32( test_z(), imm8); }
  275. void instr32_75(int32_t imm8) { jmpcc32(!test_z(), imm8); }
  276. void instr32_76(int32_t imm8) { jmpcc32( test_be(), imm8); }
  277. void instr32_77(int32_t imm8) { jmpcc32(!test_be(), imm8); }
  278. void instr32_78(int32_t imm8) { jmpcc32( test_s(), imm8); }
  279. void instr32_79(int32_t imm8) { jmpcc32(!test_s(), imm8); }
  280. void instr32_7A(int32_t imm8) { jmpcc32( test_p(), imm8); }
  281. void instr32_7B(int32_t imm8) { jmpcc32(!test_p(), imm8); }
  282. void instr32_7C(int32_t imm8) { jmpcc32( test_l(), imm8); }
  283. void instr32_7D(int32_t imm8) { jmpcc32(!test_l(), imm8); }
  284. void instr32_7E(int32_t imm8) { jmpcc32( test_le(), imm8); }
  285. void instr32_7F(int32_t imm8) { jmpcc32(!test_le(), imm8); }
  286. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_80_0, add8(___, imm))
  287. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_80_1, or8(___, imm))
  288. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_80_2, adc8(___, imm))
  289. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_80_3, sbb8(___, imm))
  290. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_80_4, and8(___, imm))
  291. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_80_5, sub8(___, imm))
  292. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_80_6, xor8(___, imm))
  293. void instr_80_7_reg(int32_t r, int32_t imm) { cmp8(read_reg8(r), imm); }
  294. void instr_80_7_mem(int32_t addr, int32_t imm) { cmp8(safe_read8(addr), imm); }
  295. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_81_0, add16(___, imm))
  296. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_81_1, or16(___, imm))
  297. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_81_2, adc16(___, imm))
  298. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_81_3, sbb16(___, imm))
  299. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_81_4, and16(___, imm))
  300. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_81_5, sub16(___, imm))
  301. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_81_6, xor16(___, imm))
  302. void instr16_81_7_reg(int32_t r, int32_t imm) { cmp16(read_reg16(r), imm); }
  303. void instr16_81_7_mem(int32_t addr, int32_t imm) { cmp16(safe_read16(addr), imm); }
  304. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_81_0, add32(___, imm))
  305. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_81_1, or32(___, imm))
  306. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_81_2, adc32(___, imm))
  307. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_81_3, sbb32(___, imm))
  308. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_81_4, and32(___, imm))
  309. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_81_5, sub32(___, imm))
  310. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_81_6, xor32(___, imm))
  311. void instr32_81_7_reg(int32_t r, int32_t imm) { cmp32(read_reg32(r), imm); }
  312. void instr32_81_7_mem(int32_t addr, int32_t imm) { cmp32(safe_read32s(addr), imm); }
  313. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_82_0, add8(___, imm))
  314. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_82_1, or8(___, imm))
  315. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_82_2, adc8(___, imm))
  316. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_82_3, sbb8(___, imm))
  317. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_82_4, and8(___, imm))
  318. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_82_5, sub8(___, imm))
  319. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_82_6, xor8(___, imm))
  320. void instr_82_7_reg(int32_t r, int32_t imm) { cmp8(read_reg8(r), imm); }
  321. void instr_82_7_mem(int32_t addr, int32_t imm) { cmp8(safe_read8(addr), imm); }
  322. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_83_0, add16(___, imm))
  323. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_83_1, or16(___, imm))
  324. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_83_2, adc16(___, imm))
  325. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_83_3, sbb16(___, imm))
  326. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_83_4, and16(___, imm))
  327. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_83_5, sub16(___, imm))
  328. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_83_6, xor16(___, imm))
  329. void instr16_83_7_reg(int32_t r, int32_t imm) { cmp16(read_reg16(r), imm); }
  330. void instr16_83_7_mem(int32_t addr, int32_t imm) { cmp16(safe_read16(addr), imm); }
  331. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_83_0, add32(___, imm))
  332. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_83_1, or32(___, imm))
  333. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_83_2, adc32(___, imm))
  334. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_83_3, sbb32(___, imm))
  335. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_83_4, and32(___, imm))
  336. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_83_5, sub32(___, imm))
  337. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_83_6, xor32(___, imm))
  338. void instr32_83_7_reg(int32_t r, int32_t imm) { cmp32(read_reg32(r), imm); }
  339. void instr32_83_7_mem(int32_t addr, int32_t imm) { cmp32(safe_read32s(addr), imm); }
  340. DEFINE_MODRM_INSTR_READ8(instr_84, test8(___, read_reg8(r)))
  341. DEFINE_MODRM_INSTR_READ16(instr16_85, test16(___, read_reg16(r)))
  342. DEFINE_MODRM_INSTR_READ32(instr32_85, test32(___, read_reg32(r)))
  343. DEFINE_MODRM_INSTR_READ_WRITE_8(instr_86, xchg8(___, get_reg8_index(r)))
  344. DEFINE_MODRM_INSTR_READ_WRITE_16(instr16_87, xchg16(___, get_reg16_index(r)))
  345. DEFINE_MODRM_INSTR_READ_WRITE_32(instr32_87, xchg32(___, r))
  346. void instr_88_reg(int32_t r2, int32_t r) { write_reg8(r2, read_reg8(r)); }
  347. void instr_88_mem(int32_t addr, int32_t r) { safe_write8(addr, read_reg8(r)); }
  348. void instr16_89_reg(int32_t r2, int32_t r) { write_reg16(r2, read_reg16(r)); }
  349. void instr16_89_mem(int32_t addr, int32_t r) { safe_write16(addr, read_reg16(r)); }
  350. void instr32_89_reg(int32_t r2, int32_t r) { write_reg32(r2, read_reg32(r)); }
  351. void instr32_89_mem(int32_t addr, int32_t r) { safe_write32(addr, read_reg32(r)); }
  352. DEFINE_MODRM_INSTR_READ8(instr_8A, write_reg8(r, ___))
  353. DEFINE_MODRM_INSTR_READ16(instr16_8B, write_reg16(r, ___))
  354. DEFINE_MODRM_INSTR_READ32(instr32_8B, write_reg32(r, ___))
  355. void instr_8C_check_sreg(int32_t sreg) {
  356. if(sreg >= 6)
  357. {
  358. dbg_log("mov sreg #ud");
  359. trigger_ud();
  360. }
  361. }
  362. void instr16_8C_reg(int32_t r, int32_t seg) { instr_8C_check_sreg(seg); write_reg16(r, sreg[seg]); }
  363. void instr16_8C_mem(int32_t addr, int32_t seg) { instr_8C_check_sreg(seg); safe_write16(addr, sreg[seg]); }
  364. void instr32_8C_reg(int32_t r, int32_t seg) { instr_8C_check_sreg(seg); write_reg32(r, sreg[seg]); }
  365. void instr32_8C_mem(int32_t addr, int32_t seg) { instr_8C_check_sreg(seg); safe_write32(addr, sreg[seg]); }
  366. void instr16_8D_reg(int32_t r, int32_t r2)
  367. {
  368. dbg_log("lea #ud");
  369. trigger_ud();
  370. }
  371. void instr16_8D_mem_pre()
  372. {
  373. // override prefix, so modrm_resolve does not return the segment part
  374. *prefixes |= SEG_PREFIX_ZERO;
  375. }
  376. void instr16_8D_mem(int32_t addr, int32_t r)
  377. {
  378. // lea
  379. write_reg16(r, addr);
  380. *prefixes = 0;
  381. }
  382. void instr32_8D_reg(int32_t r, int32_t r2)
  383. {
  384. dbg_log("lea #ud");
  385. trigger_ud();
  386. }
  387. void instr32_8D_mem_pre()
  388. {
  389. // override prefix, so modrm_resolve does not return the segment part
  390. *prefixes |= SEG_PREFIX_ZERO;
  391. }
  392. void instr32_8D_mem(int32_t addr, int32_t r) {
  393. // lea
  394. write_reg32(r, addr);
  395. *prefixes = 0;
  396. }
  397. void instr_8E_helper(int32_t data, int32_t mod)
  398. {
  399. if(mod == ES || mod == SS || mod == DS || mod == FS || mod == GS)
  400. {
  401. switch_seg(mod, data);
  402. if(mod == SS)
  403. {
  404. // run next instruction, so no interrupts are handled
  405. clear_prefixes();
  406. //cycle_internal();
  407. }
  408. }
  409. else
  410. {
  411. dbg_log("mov sreg #ud");
  412. }
  413. }
  414. DEFINE_MODRM_INSTR_READ16(instr_8E, instr_8E_helper(___, r))
  415. void instr16_8F_0_mem_pre()
  416. {
  417. for(int32_t i = 0; i < 8; i++) { translate_address_read(*instruction_pointer + i); }; // XXX
  418. adjust_stack_reg(2);
  419. }
  420. void instr16_8F_0_mem(int32_t addr)
  421. {
  422. // pop
  423. adjust_stack_reg(-2);
  424. int32_t sp = safe_read16(get_stack_pointer(0));
  425. safe_write16(addr, sp);
  426. adjust_stack_reg(2);
  427. }
  428. void instr16_8F_0_reg(int32_t r)
  429. {
  430. write_reg16(r, pop16());
  431. }
  432. void instr32_8F_0_mem_pre()
  433. {
  434. // prevent page faults during modrm_resolve
  435. for(int32_t i = 0; i < 8; i++) { translate_address_read(*instruction_pointer + i); }; // XXX
  436. // esp must be adjusted before calling modrm_resolve
  437. // The order of calls is: instr32_8F_0_mem_pre -> modrm_resolve -> instr32_8F_0_mem
  438. adjust_stack_reg(4);
  439. }
  440. void instr32_8F_0_mem(int32_t addr)
  441. {
  442. // Before attempting a write that might cause a page fault,
  443. // we must set esp to the old value. Fuck Intel.
  444. adjust_stack_reg(-4);
  445. int32_t sp = safe_read32s(get_stack_pointer(0));
  446. safe_write32(addr, sp);
  447. adjust_stack_reg(4);
  448. }
  449. void instr32_8F_0_reg(int32_t r)
  450. {
  451. write_reg32(r, pop32s());
  452. }
  453. void instr_90() { }
  454. void instr16_91() { xchg16r(CX); }
  455. void instr32_91() { xchg32r(ECX); }
  456. void instr16_92() { xchg16r(DX); }
  457. void instr32_92() { xchg32r(EDX); }
  458. void instr16_93() { xchg16r(BX); }
  459. void instr32_93() { xchg32r(EBX); }
  460. void instr16_94() { xchg16r(SP); }
  461. void instr32_94() { xchg32r(ESP); }
  462. void instr16_95() { xchg16r(BP); }
  463. void instr32_95() { xchg32r(EBP); }
  464. void instr16_96() { xchg16r(SI); }
  465. void instr32_96() { xchg32r(ESI); }
  466. void instr16_97() { xchg16r(DI); }
  467. void instr32_97() { xchg32r(EDI); }
  468. void instr16_98() { /* cbw */ reg16[AX] = reg8s[AL]; }
  469. void instr32_98() { /* cwde */ reg32s[EAX] = reg16s[AX]; }
  470. void instr16_99() { /* cwd */ reg16[DX] = reg16s[AX] >> 15; }
  471. void instr32_99() { /* cdq */ reg32s[EDX] = reg32s[EAX] >> 31; }
  472. void instr16_9A(int32_t new_ip, int32_t new_cs) {
  473. // callf
  474. far_jump(new_ip, new_cs, true);
  475. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  476. }
  477. void instr32_9A(int32_t new_ip, int32_t new_cs) {
  478. if(!*protected_mode || vm86_mode())
  479. {
  480. if(new_ip & 0xFFFF0000)
  481. {
  482. assert(false);
  483. //throw debug.unimpl("#GP handler");
  484. }
  485. }
  486. far_jump(new_ip, new_cs, true);
  487. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  488. }
  489. void instr_9B() {
  490. // fwait: check for pending fpu exceptions
  491. if((cr[0] & (CR0_MP | CR0_TS)) == (CR0_MP | CR0_TS))
  492. {
  493. // task switched and MP bit is set
  494. trigger_nm();
  495. }
  496. else
  497. {
  498. //if(fpu)
  499. {
  500. fwait();
  501. }
  502. //else
  503. //{
  504. // // EM bit isn't checked
  505. // // If there's no FPU, do nothing
  506. //}
  507. }
  508. }
  509. void instr16_9C() {
  510. // pushf
  511. if((flags[0] & FLAG_VM) && getiopl() < 3)
  512. {
  513. dbg_assert(*protected_mode);
  514. dbg_log("pushf #gp");
  515. trigger_gp(0);
  516. }
  517. else
  518. {
  519. push16(get_eflags());
  520. }
  521. }
  522. void instr32_9C() {
  523. // pushf
  524. if((flags[0] & FLAG_VM) && getiopl() < 3)
  525. {
  526. // trap to virtual 8086 monitor
  527. dbg_assert(*protected_mode);
  528. dbg_log("pushf #gp");
  529. trigger_gp(0);
  530. }
  531. else
  532. {
  533. // vm and rf flag are cleared in image stored on the stack
  534. push32(get_eflags() & 0x00FCFFFF);
  535. }
  536. }
  537. void instr16_9D() {
  538. // popf
  539. if((flags[0] & FLAG_VM) && getiopl() < 3)
  540. {
  541. dbg_log("popf #gp");
  542. trigger_gp(0);
  543. }
  544. update_eflags((flags[0] & ~0xFFFF) | pop16());
  545. if(flags[0] & FLAG_TRAP)
  546. {
  547. // XXX: Problems with fdgame
  548. //clear_prefixes();
  549. //cycle_internal();
  550. flags[0] &= ~FLAG_TRAP;
  551. //instruction_pointer = previous_ip;
  552. //raise_exception(1);
  553. }
  554. else
  555. {
  556. handle_irqs();
  557. }
  558. }
  559. void instr32_9D() {
  560. // popf
  561. if((flags[0] & FLAG_VM) && getiopl() < 3)
  562. {
  563. dbg_log("popf #gp");
  564. trigger_gp(0);
  565. }
  566. update_eflags(pop32s());
  567. handle_irqs();
  568. }
  569. void instr_9E() {
  570. // sahf
  571. flags[0] = (flags[0] & ~0xFF) | reg8[AH];
  572. flags[0] = (flags[0] & FLAGS_MASK) | FLAGS_DEFAULT;
  573. flags_changed[0] &= ~0xFF;
  574. }
  575. void instr_9F() {
  576. // lahf
  577. reg8[AH] = get_eflags();
  578. }
  579. void instr_A0(int32_t moffs) {
  580. // mov
  581. int32_t data = safe_read8(get_seg_prefix_ds(moffs));
  582. reg8[AL] = data;
  583. }
  584. void instr16_A1(int32_t moffs) {
  585. // mov
  586. int32_t data = safe_read16(get_seg_prefix_ds(moffs));
  587. reg16[AX] = data;
  588. }
  589. void instr32_A1(int32_t moffs) {
  590. int32_t data = safe_read32s(get_seg_prefix_ds(moffs));
  591. reg32s[EAX] = data;
  592. }
  593. void instr_A2(int32_t moffs) {
  594. // mov
  595. safe_write8(get_seg_prefix_ds(moffs), reg8[AL]);
  596. }
  597. void instr16_A3(int32_t moffs) {
  598. // mov
  599. safe_write16(get_seg_prefix_ds(moffs), reg16[AX]);
  600. }
  601. void instr32_A3(int32_t moffs) {
  602. safe_write32(get_seg_prefix_ds(moffs), reg32s[EAX]);
  603. }
  604. void instr_A4() { movsb(); }
  605. void instr16_A5() { movsw(); }
  606. void instr32_A5() { movsd(); }
  607. void instr_A6() { cmpsb(); }
  608. void instr16_A7() { cmpsw(); }
  609. void instr32_A7() { cmpsd(); }
  610. void instr_A8(int32_t imm8) {
  611. test8(reg8[AL], imm8);
  612. }
  613. void instr16_A9(int32_t imm16) {
  614. test16(reg16[AX], imm16);
  615. }
  616. void instr32_A9(int32_t imm32) {
  617. test32(reg32s[EAX], imm32);
  618. }
  619. void instr_AA() { stosb(); }
  620. void instr16_AB() { stosw(); }
  621. void instr32_AB() { stosd(); }
  622. void instr_AC() { lodsb(); }
  623. void instr16_AD() { lodsw(); }
  624. void instr32_AD() { lodsd(); }
  625. void instr_AE() { scasb(); }
  626. void instr16_AF() { scasw(); }
  627. void instr32_AF() { scasd(); }
  628. void instr_B0(int32_t imm8) { reg8[AL] = imm8; }
  629. void instr_B1(int32_t imm8) { reg8[CL] = imm8; }
  630. void instr_B2(int32_t imm8) { reg8[DL] = imm8; }
  631. void instr_B3(int32_t imm8) { reg8[BL] = imm8; }
  632. void instr_B4(int32_t imm8) { reg8[AH] = imm8; }
  633. void instr_B5(int32_t imm8) { reg8[CH] = imm8; }
  634. void instr_B6(int32_t imm8) { reg8[DH] = imm8; }
  635. void instr_B7(int32_t imm8) { reg8[BH] = imm8; }
  636. void instr16_B8(int32_t imm) { reg16[AX] = imm; }
  637. void instr32_B8(int32_t imm) { reg32s[EAX] = imm; }
  638. void instr16_B9(int32_t imm) { reg16[CX] = imm; }
  639. void instr32_B9(int32_t imm) { reg32s[ECX] = imm; }
  640. void instr16_BA(int32_t imm) { reg16[DX] = imm; }
  641. void instr32_BA(int32_t imm) { reg32s[EDX] = imm; }
  642. void instr16_BB(int32_t imm) { reg16[BX] = imm; }
  643. void instr32_BB(int32_t imm) { reg32s[EBX] = imm; }
  644. void instr16_BC(int32_t imm) { reg16[SP] = imm; }
  645. void instr32_BC(int32_t imm) { reg32s[ESP] = imm; }
  646. void instr16_BD(int32_t imm) { reg16[BP] = imm; }
  647. void instr32_BD(int32_t imm) { reg32s[EBP] = imm; }
  648. void instr16_BE(int32_t imm) { reg16[SI] = imm; }
  649. void instr32_BE(int32_t imm) { reg32s[ESI] = imm; }
  650. void instr16_BF(int32_t imm) { reg16[DI] = imm; }
  651. void instr32_BF(int32_t imm) { reg32s[EDI] = imm; }
  652. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_C0_0, rol8(___, imm & 31))
  653. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_C0_1, ror8(___, imm & 31))
  654. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_C0_2, rcl8(___, imm & 31))
  655. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_C0_3, rcr8(___, imm & 31))
  656. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_C0_4, shl8(___, imm & 31))
  657. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_C0_5, shr8(___, imm & 31))
  658. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_C0_6, shl8(___, imm & 31))
  659. DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_C0_7, sar8(___, imm & 31))
  660. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_C1_0, rol16(___, imm & 31))
  661. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_C1_1, ror16(___, imm & 31))
  662. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_C1_2, rcl16(___, imm & 31))
  663. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_C1_3, rcr16(___, imm & 31))
  664. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_C1_4, shl16(___, imm & 31))
  665. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_C1_5, shr16(___, imm & 31))
  666. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_C1_6, shl16(___, imm & 31))
  667. DEFINE_MODRM_INSTR2_READ_WRITE_16(instr16_C1_7, sar16(___, imm & 31))
  668. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_C1_0, rol32(___, imm & 31))
  669. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_C1_1, ror32(___, imm & 31))
  670. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_C1_2, rcl32(___, imm & 31))
  671. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_C1_3, rcr32(___, imm & 31))
  672. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_C1_4, shl32(___, imm & 31))
  673. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_C1_5, shr32(___, imm & 31))
  674. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_C1_6, shl32(___, imm & 31))
  675. DEFINE_MODRM_INSTR2_READ_WRITE_32(instr32_C1_7, sar32(___, imm & 31))
  676. void instr16_C2(int32_t imm16) {
  677. // retn
  678. int32_t cs = get_seg_cs();
  679. instruction_pointer[0] = cs + pop16();
  680. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  681. adjust_stack_reg(imm16);
  682. }
  683. void instr32_C2(int32_t imm16) {
  684. // retn
  685. int32_t cs = get_seg_cs();
  686. int32_t ip = pop32s();
  687. dbg_assert(is_asize_32() || ip < 0x10000);
  688. instruction_pointer[0] = cs + ip;
  689. adjust_stack_reg(imm16);
  690. }
  691. void instr16_C3() {
  692. // retn
  693. int32_t cs = get_seg_cs();
  694. instruction_pointer[0] = cs + pop16();
  695. }
  696. void instr32_C3() {
  697. // retn
  698. int32_t cs = get_seg_cs();
  699. int32_t ip = pop32s();
  700. dbg_assert(is_asize_32() || ip < 0x10000);
  701. instruction_pointer[0] = cs + ip;
  702. }
  703. void instr16_C4_reg(int32_t _unused1, int32_t _unused2) { trigger_ud(); }
  704. void instr16_C4_mem(int32_t addr, int32_t r) {
  705. lss16(addr, get_reg16_index(r), ES);
  706. }
  707. void instr32_C4_reg(int32_t _unused1, int32_t _unused2) { trigger_ud(); }
  708. void instr32_C4_mem(int32_t addr, int32_t r) {
  709. lss32(addr, r, ES);
  710. }
  711. void instr16_C5_reg(int32_t _unused1, int32_t _unused2) { trigger_ud(); }
  712. void instr16_C5_mem(int32_t addr, int32_t r) {
  713. lss16(addr, get_reg16_index(r), DS);
  714. }
  715. void instr32_C5_reg(int32_t _unused1, int32_t _unused2) { trigger_ud(); }
  716. void instr32_C5_mem(int32_t addr, int32_t r) {
  717. lss32(addr, r, DS);
  718. }
  719. void instr_C6_0_reg(int32_t r, int32_t imm) { write_reg8(r, imm); }
  720. void instr_C6_0_mem(int32_t addr, int32_t imm) { safe_write8(addr, imm); }
  721. void instr16_C7_0_reg(int32_t r, int32_t imm) { write_reg16(r, imm); }
  722. void instr16_C7_0_mem(int32_t addr, int32_t imm) { safe_write16(addr, imm); }
  723. void instr32_C7_0_reg(int32_t r, int32_t imm) { write_reg32(r, imm); }
  724. void instr32_C7_0_mem(int32_t addr, int32_t imm) { safe_write32(addr, imm); }
  725. void instr16_C8(int32_t size, int32_t nesting) { enter16(size, nesting); }
  726. void instr32_C8(int32_t size, int32_t nesting) { enter32(size, nesting); }
  727. void instr16_C9() {
  728. // leave
  729. int32_t old_vbp = *stack_size_32 ? reg32s[EBP] : reg16[BP];
  730. int32_t new_bp = safe_read16(get_seg_ss() + old_vbp);
  731. set_stack_reg(old_vbp + 2);
  732. reg16[BP] = new_bp;
  733. }
  734. void instr32_C9() {
  735. int32_t old_vbp = *stack_size_32 ? reg32s[EBP] : reg16[BP];
  736. int32_t new_ebp = safe_read32s(get_seg_ss() + old_vbp);
  737. set_stack_reg(old_vbp + 4);
  738. reg32s[EBP] = new_ebp;
  739. }
  740. void instr16_CA(int32_t imm16) {
  741. // retf
  742. int32_t ip = safe_read16(get_stack_pointer(0));
  743. int32_t cs = safe_read16(get_stack_pointer(2));
  744. far_return(ip, cs, imm16);
  745. }
  746. void instr32_CA(int32_t imm16) {
  747. // retf
  748. int32_t ip = safe_read32s(get_stack_pointer(0));
  749. int32_t cs = safe_read32s(get_stack_pointer(4)) & 0xFFFF;
  750. far_return(ip, cs, imm16);
  751. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  752. }
  753. void instr16_CB() {
  754. // retf
  755. int32_t ip = safe_read16(get_stack_pointer(0));
  756. int32_t cs = safe_read16(get_stack_pointer(2));
  757. far_return(ip, cs, 0);
  758. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  759. }
  760. void instr32_CB() {
  761. // retf
  762. int32_t ip = safe_read32s(get_stack_pointer(0));
  763. int32_t cs = safe_read32s(get_stack_pointer(4)) & 0xFFFF;
  764. far_return(ip, cs, 0);
  765. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  766. }
  767. void instr_CC() {
  768. // INT3
  769. // TODO: inhibit iopl checks
  770. dbg_log("INT3");
  771. call_interrupt_vector(3, true, false, 0);
  772. }
  773. void instr_CD(int32_t imm8) {
  774. // INT
  775. call_interrupt_vector(imm8, true, false, 0);
  776. }
  777. void instr_CE() {
  778. // INTO
  779. dbg_log("INTO");
  780. if(getof())
  781. {
  782. // TODO: inhibit iopl checks
  783. call_interrupt_vector(4, true, false, 0);
  784. }
  785. }
  786. void instr16_CF() {
  787. // iret
  788. iret16();
  789. }
  790. void instr32_CF() {
  791. iret32();
  792. }
  793. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D0_0, rol8(___, 1))
  794. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D0_1, ror8(___, 1))
  795. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D0_2, rcl8(___, 1))
  796. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D0_3, rcr8(___, 1))
  797. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D0_4, shl8(___, 1))
  798. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D0_5, shr8(___, 1))
  799. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D0_6, shl8(___, 1))
  800. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D0_7, sar8(___, 1))
  801. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D1_0, rol16(___, 1))
  802. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D1_1, ror16(___, 1))
  803. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D1_2, rcl16(___, 1))
  804. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D1_3, rcr16(___, 1))
  805. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D1_4, shl16(___, 1))
  806. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D1_5, shr16(___, 1))
  807. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D1_6, shl16(___, 1))
  808. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D1_7, sar16(___, 1))
  809. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D1_0, rol32(___, 1))
  810. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D1_1, ror32(___, 1))
  811. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D1_2, rcl32(___, 1))
  812. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D1_3, rcr32(___, 1))
  813. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D1_4, shl32(___, 1))
  814. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D1_5, shr32(___, 1))
  815. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D1_6, shl32(___, 1))
  816. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D1_7, sar32(___, 1))
  817. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D2_0, rol8(___, reg8[CL] & 31))
  818. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D2_1, ror8(___, reg8[CL] & 31))
  819. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D2_2, rcl8(___, reg8[CL] & 31))
  820. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D2_3, rcr8(___, reg8[CL] & 31))
  821. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D2_4, shl8(___, reg8[CL] & 31))
  822. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D2_5, shr8(___, reg8[CL] & 31))
  823. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D2_6, shl8(___, reg8[CL] & 31))
  824. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_D2_7, sar8(___, reg8[CL] & 31))
  825. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D3_0, rol16(___, reg8[CL] & 31))
  826. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D3_1, ror16(___, reg8[CL] & 31))
  827. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D3_2, rcl16(___, reg8[CL] & 31))
  828. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D3_3, rcr16(___, reg8[CL] & 31))
  829. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D3_4, shl16(___, reg8[CL] & 31))
  830. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D3_5, shr16(___, reg8[CL] & 31))
  831. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D3_6, shl16(___, reg8[CL] & 31))
  832. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_D3_7, sar16(___, reg8[CL] & 31))
  833. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D3_0, rol32(___, reg8[CL] & 31))
  834. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D3_1, ror32(___, reg8[CL] & 31))
  835. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D3_2, rcl32(___, reg8[CL] & 31))
  836. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D3_3, rcr32(___, reg8[CL] & 31))
  837. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D3_4, shl32(___, reg8[CL] & 31))
  838. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D3_5, shr32(___, reg8[CL] & 31))
  839. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D3_6, shl32(___, reg8[CL] & 31))
  840. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_D3_7, sar32(___, reg8[CL] & 31))
  841. void instr_D4(int32_t arg) {
  842. bcd_aam(arg);
  843. }
  844. void instr_D5(int32_t arg) {
  845. bcd_aad(arg);
  846. }
  847. void instr_D6() {
  848. // salc
  849. reg8[AL] = -getcf();
  850. }
  851. void instr_D7() {
  852. // xlat
  853. if(is_asize_32())
  854. {
  855. reg8[AL] = safe_read8(get_seg_prefix(DS) + reg32s[EBX] + reg8[AL]);
  856. }
  857. else
  858. {
  859. reg8[AL] = safe_read8(get_seg_prefix(DS) + (reg16[BX] + reg8[AL] & 0xFFFF));
  860. }
  861. }
  862. DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_0, fpu_fadd(0, ___))
  863. DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_1, fpu_fmul(0, ___))
  864. DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_2, fpu_fcom(___))
  865. DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_3, fpu_fcomp(___))
  866. DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_4, fpu_fsub(0, ___))
  867. DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_5, fpu_fsubr(0, ___))
  868. DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_6, fpu_fdiv(0, ___))
  869. DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_7, fpu_fdivr(0, ___))
  870. DEFINE_MODRM_INSTR_FPU_READ32(instr_D9_0, fpu_push(___))
  871. void instr_D9_1_mem(int32_t addr) { task_switch_test(); dbg_log("d9/1"); trigger_ud(); }
  872. void instr_D9_1_reg(int32_t r) { task_switch_test(); fpu_fxch(r); }
  873. void instr_D9_2_mem(int32_t addr) { task_switch_test(); fpu_fstm32(addr); }
  874. void instr_D9_2_reg(int32_t r) { task_switch_test(); if(r != 0) { trigger_ud(); } }
  875. void instr_D9_3_mem(int32_t addr) { task_switch_test(); fpu_fstm32p(addr); }
  876. void instr_D9_3_reg(int32_t r) { task_switch_test(); dbg_log("fstp1"); trigger_ud(); }
  877. void instr_D9_4_mem(int32_t addr) { task_switch_test(); fpu_fldenv(addr); }
  878. void instr_D9_4_reg(int32_t r)
  879. {
  880. task_switch_test();
  881. double_t st0 = fpu_get_st0();
  882. switch(r)
  883. {
  884. case 0:
  885. // fchs
  886. fpu_st[*fpu_stack_ptr] = -st0;
  887. break;
  888. case 1:
  889. // fabs
  890. fpu_st[*fpu_stack_ptr] = fabs(st0);
  891. break;
  892. case 4:
  893. fpu_ftst(st0);
  894. break;
  895. case 5:
  896. fpu_fxam(st0);
  897. break;
  898. default:
  899. dbg_log("%x", r);
  900. trigger_ud();
  901. }
  902. }
  903. void instr_D9_5_mem(int32_t addr) { task_switch_test(); fpu_fldcw(addr); }
  904. void instr_D9_5_reg(int32_t r)
  905. {
  906. // fld1/fldl2t/fldl2e/fldpi/fldlg2/fldln2/fldz
  907. task_switch_test();
  908. switch(r)
  909. {
  910. case 0: fpu_push(1); break;
  911. case 1: fpu_push(M_LN10 / M_LN2); break;
  912. case 2: fpu_push(M_LOG2E); break;
  913. case 3: fpu_push(M_PI); break;
  914. case 4: fpu_push(M_LN2 / M_LN10); break;
  915. case 5: fpu_push(M_LN2); break;
  916. case 6: fpu_push(0); break;
  917. case 7: dbg_log("d9/5/7"); trigger_ud(); break;
  918. }
  919. }
  920. void instr_D9_6_mem(int32_t addr) { task_switch_test(); fpu_fstenv(addr); }
  921. void instr_D9_6_reg(int32_t r)
  922. {
  923. task_switch_test();
  924. double_t st0 = fpu_get_st0();
  925. switch(r)
  926. {
  927. case 0:
  928. // f2xm1
  929. fpu_st[*fpu_stack_ptr] = pow(2, st0) - 1;
  930. break;
  931. case 1:
  932. // fyl2x
  933. fpu_st[*fpu_stack_ptr + 1 & 7] = fpu_get_sti(1) * log(st0) / M_LN2;
  934. fpu_pop();
  935. break;
  936. case 2:
  937. // fptan
  938. fpu_st[*fpu_stack_ptr] = tan(st0);
  939. fpu_push(1); // no bug: push constant 1
  940. break;
  941. case 3:
  942. // fpatan
  943. fpu_st[*fpu_stack_ptr + 1 & 7] = atan2(fpu_get_sti(1), st0);
  944. fpu_pop();
  945. break;
  946. case 4:
  947. fpu_fxtract();
  948. break;
  949. case 5:
  950. // fprem1
  951. fpu_st[*fpu_stack_ptr] = fmod(st0, fpu_get_sti(1));
  952. break;
  953. case 6:
  954. // fdecstp
  955. *fpu_stack_ptr = *fpu_stack_ptr - 1 & 7;
  956. *fpu_status_word &= ~FPU_C1;
  957. break;
  958. case 7:
  959. // fincstp
  960. *fpu_stack_ptr = *fpu_stack_ptr + 1 & 7;
  961. *fpu_status_word &= ~FPU_C1;
  962. break;
  963. default:
  964. dbg_assert(false);
  965. }
  966. }
  967. void instr_D9_7_mem(int32_t addr) { task_switch_test(); fpu_fstcw(addr); }
  968. void instr_D9_7_reg(int32_t r)
  969. {
  970. task_switch_test();
  971. double_t st0 = fpu_get_st0();
  972. switch(r)
  973. {
  974. case 0:
  975. fpu_fprem();
  976. break;
  977. case 1:
  978. // fyl2xp1: y * log2(x+1) and pop
  979. fpu_st[*fpu_stack_ptr + 1 & 7] = fpu_get_sti(1) * log(st0 + 1) / M_LN2;
  980. fpu_pop();
  981. break;
  982. case 2:
  983. fpu_st[*fpu_stack_ptr] = sqrt(st0);
  984. break;
  985. case 3:
  986. fpu_st[*fpu_stack_ptr] = sin(st0);
  987. fpu_push(cos(st0));
  988. break;
  989. case 4:
  990. // frndint
  991. fpu_st[*fpu_stack_ptr] = fpu_integer_round(st0);
  992. break;
  993. case 5:
  994. // fscale
  995. fpu_st[*fpu_stack_ptr] = st0 * pow(2, trunc(fpu_get_sti(1)));
  996. break;
  997. case 6:
  998. fpu_st[*fpu_stack_ptr] = sin(st0);
  999. break;
  1000. case 7:
  1001. fpu_st[*fpu_stack_ptr] = cos(st0);
  1002. break;
  1003. default:
  1004. dbg_assert(false);
  1005. }
  1006. }
  1007. void instr_DA_0_mem(int32_t addr) { task_switch_test(); fpu_fadd(0, safe_read32s(addr)); }
  1008. void instr_DA_1_mem(int32_t addr) { task_switch_test(); fpu_fmul(0, safe_read32s(addr)); }
  1009. void instr_DA_2_mem(int32_t addr) { task_switch_test(); fpu_fcom(safe_read32s(addr)); }
  1010. void instr_DA_3_mem(int32_t addr) { task_switch_test(); fpu_fcomp(safe_read32s(addr)); }
  1011. void instr_DA_4_mem(int32_t addr) { task_switch_test(); fpu_fsub(0, safe_read32s(addr)); }
  1012. void instr_DA_5_mem(int32_t addr) { task_switch_test(); fpu_fsubr(0, safe_read32s(addr)); }
  1013. void instr_DA_6_mem(int32_t addr) { task_switch_test(); fpu_fdiv(0, safe_read32s(addr)); }
  1014. void instr_DA_7_mem(int32_t addr) { task_switch_test(); fpu_fdivr(0, safe_read32s(addr)); }
  1015. void instr_DA_0_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(test_b(), r); }
  1016. void instr_DA_1_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(test_z(), r); }
  1017. void instr_DA_2_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(test_be(), r); }
  1018. void instr_DA_3_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(test_p(), r); }
  1019. void instr_DA_4_reg(int32_t r) { trigger_ud(); }
  1020. void instr_DA_5_reg(int32_t r) { task_switch_test(); if(r == 1) { fpu_fucompp(); } else { trigger_ud(); } }
  1021. void instr_DA_6_reg(int32_t r) { trigger_ud(); }
  1022. void instr_DA_7_reg(int32_t r) { trigger_ud(); }
  1023. void instr_DB_0_mem(int32_t addr) { task_switch_test(); fpu_fldm32(addr); }
  1024. void instr_DB_1_mem(int32_t addr) { trigger_ud(); }
  1025. void instr_DB_2_mem(int32_t addr) { task_switch_test(); fpu_fistm32(addr); }
  1026. void instr_DB_3_mem(int32_t addr) { task_switch_test(); fpu_fistm32p(addr); }
  1027. void instr_DB_4_mem(int32_t addr) { trigger_ud(); }
  1028. void instr_DB_5_mem(int32_t addr) { task_switch_test(); fpu_fldm80(addr); }
  1029. void instr_DB_6_mem(int32_t addr) { trigger_ud(); }
  1030. void instr_DB_7_mem(int32_t addr) { task_switch_test(); fpu_fst80p(addr); }
  1031. void instr_DB_0_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(!test_b(), r); }
  1032. void instr_DB_1_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(!test_z(), r); }
  1033. void instr_DB_2_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(!test_be(), r); }
  1034. void instr_DB_3_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(!test_p(), r); }
  1035. void instr_DB_4_reg(int32_t r)
  1036. {
  1037. task_switch_test();
  1038. if(r == 3)
  1039. {
  1040. fpu_finit();
  1041. }
  1042. else if(r == 4 || r == 1)
  1043. {
  1044. // fsetpm and fdisi; treated as nop
  1045. }
  1046. else if(r == 2)
  1047. {
  1048. fpu_fclex();
  1049. }
  1050. else
  1051. {
  1052. trigger_ud();
  1053. }
  1054. }
  1055. void instr_DB_5_reg(int32_t r) { task_switch_test(); fpu_fucomi(r); }
  1056. void instr_DB_6_reg(int32_t r) { task_switch_test(); fpu_fcomi(r); }
  1057. void instr_DB_7_reg(int32_t r) { trigger_ud(); }
  1058. void instr_DC_0_mem(int32_t addr) { task_switch_test(); fpu_fadd(0, fpu_load_m64(addr)); }
  1059. void instr_DC_1_mem(int32_t addr) { task_switch_test(); fpu_fmul(0, fpu_load_m64(addr)); }
  1060. void instr_DC_2_mem(int32_t addr) { task_switch_test(); fpu_fcom(fpu_load_m64(addr)); }
  1061. void instr_DC_3_mem(int32_t addr) { task_switch_test(); fpu_fcomp(fpu_load_m64(addr)); }
  1062. void instr_DC_4_mem(int32_t addr) { task_switch_test(); fpu_fsub(0, fpu_load_m64(addr)); }
  1063. void instr_DC_5_mem(int32_t addr) { task_switch_test(); fpu_fsubr(0, fpu_load_m64(addr)); }
  1064. void instr_DC_6_mem(int32_t addr) { task_switch_test(); fpu_fdiv(0, fpu_load_m64(addr)); }
  1065. void instr_DC_7_mem(int32_t addr) { task_switch_test(); fpu_fdivr(0, fpu_load_m64(addr)); }
  1066. void instr_DC_0_reg(int32_t r) { task_switch_test(); fpu_fadd(r, fpu_get_sti(r)); }
  1067. void instr_DC_1_reg(int32_t r) { task_switch_test(); fpu_fmul(r, fpu_get_sti(r)); }
  1068. void instr_DC_2_reg(int32_t r) { task_switch_test(); fpu_fcom(fpu_get_sti(r)); }
  1069. void instr_DC_3_reg(int32_t r) { task_switch_test(); fpu_fcomp(fpu_get_sti(r)); }
  1070. void instr_DC_4_reg(int32_t r) { task_switch_test(); fpu_fsub(r, fpu_get_sti(r)); }
  1071. void instr_DC_5_reg(int32_t r) { task_switch_test(); fpu_fsubr(r, fpu_get_sti(r)); }
  1072. void instr_DC_6_reg(int32_t r) { task_switch_test(); fpu_fdiv(r, fpu_get_sti(r)); }
  1073. void instr_DC_7_reg(int32_t r) { task_switch_test(); fpu_fdivr(r, fpu_get_sti(r)); }
  1074. void instr_DD_0_mem(int32_t addr) { task_switch_test(); fpu_fldm64(addr); }
  1075. void instr_DD_1_mem(int32_t addr) { dbg_log("fisttp"); trigger_ud(); }
  1076. void instr_DD_2_mem(int32_t addr) { task_switch_test(); fpu_fstm64(addr); }
  1077. void instr_DD_3_mem(int32_t addr) { task_switch_test(); fpu_fstm64p(addr); }
  1078. void instr_DD_4_mem(int32_t addr) { task_switch_test(); fpu_frstor(addr); }
  1079. void instr_DD_5_mem(int32_t addr) { dbg_log("dd/5"); trigger_ud(); }
  1080. void instr_DD_6_mem(int32_t addr) { task_switch_test(); fpu_fsave(addr); }
  1081. void instr_DD_7_mem(int32_t addr) { task_switch_test(); fpu_fnstsw_mem(addr); }
  1082. void instr_DD_0_reg(int32_t r) { task_switch_test(); fpu_ffree(r); }
  1083. void instr_DD_1_reg(int32_t r) { trigger_ud(); }
  1084. void instr_DD_2_reg(int32_t r) { task_switch_test(); fpu_fst(r); }
  1085. void instr_DD_3_reg(int32_t r) { task_switch_test(); fpu_fstp(r); }
  1086. void instr_DD_4_reg(int32_t r) { task_switch_test(); fpu_fucom(r); }
  1087. void instr_DD_5_reg(int32_t r) { task_switch_test(); fpu_fucomp(r); }
  1088. void instr_DD_6_reg(int32_t r) { trigger_ud(); }
  1089. void instr_DD_7_reg(int32_t r) { trigger_ud(); }
  1090. void instr_DE_0_mem(int32_t addr) { task_switch_test(); fpu_fadd(0, (int16_t) safe_read16(addr)); }
  1091. void instr_DE_1_mem(int32_t addr) { task_switch_test(); fpu_fmul(0, (int16_t) safe_read16(addr)); }
  1092. void instr_DE_2_mem(int32_t addr) { task_switch_test(); fpu_fcom((int16_t) safe_read16(addr)); }
  1093. void instr_DE_3_mem(int32_t addr) { task_switch_test(); fpu_fcomp((int16_t) safe_read16(addr)); }
  1094. void instr_DE_4_mem(int32_t addr) { task_switch_test(); fpu_fsub(0, (int16_t) safe_read16(addr)); }
  1095. void instr_DE_5_mem(int32_t addr) { task_switch_test(); fpu_fsubr(0, (int16_t) safe_read16(addr)); }
  1096. void instr_DE_6_mem(int32_t addr) { task_switch_test(); fpu_fdiv(0, (int16_t) safe_read16(addr)); }
  1097. void instr_DE_7_mem(int32_t addr) { task_switch_test(); fpu_fdivr(0, (int16_t) safe_read16(addr)); }
  1098. void instr_DE_0_reg(int32_t r) { task_switch_test(); fpu_fadd(r, fpu_get_sti(r)); fpu_pop(); }
  1099. void instr_DE_1_reg(int32_t r) { task_switch_test(); fpu_fmul(r, fpu_get_sti(r)); fpu_pop(); }
  1100. void instr_DE_2_reg(int32_t r) { task_switch_test(); fpu_fcom(fpu_get_sti(r)); fpu_pop(); }
  1101. void instr_DE_3_reg(int32_t r) { task_switch_test(); fpu_fcomp(fpu_get_sti(r)); fpu_pop(); }
  1102. void instr_DE_4_reg(int32_t r) { task_switch_test(); fpu_fsub(r, fpu_get_sti(r)); fpu_pop(); }
  1103. void instr_DE_5_reg(int32_t r) { task_switch_test(); fpu_fsubr(r, fpu_get_sti(r)); fpu_pop(); }
  1104. void instr_DE_6_reg(int32_t r) { task_switch_test(); fpu_fdiv(r, fpu_get_sti(r)); fpu_pop(); }
  1105. void instr_DE_7_reg(int32_t r) { task_switch_test(); fpu_fdivr(r, fpu_get_sti(r)); fpu_pop(); }
  1106. void instr_DF_0_mem(int32_t addr) { task_switch_test(); fpu_push((int16_t) safe_read16(addr)); }
  1107. void instr_DF_1_mem(int32_t addr) { dbg_log("df/fisttp"); trigger_ud(); }
  1108. void instr_DF_2_mem(int32_t addr) { task_switch_test(); fpu_fistm16(addr); }
  1109. void instr_DF_3_mem(int32_t addr) { task_switch_test(); fpu_fistm16p(addr); }
  1110. void instr_DF_4_mem(int32_t addr) { dbg_log("fbld"); trigger_ud(); }
  1111. void instr_DF_5_mem(int32_t addr) { task_switch_test(); fpu_fildm64(addr); }
  1112. void instr_DF_6_mem(int32_t addr) { dbg_log("fbstp"); trigger_ud(); }
  1113. void instr_DF_7_mem(int32_t addr) { task_switch_test(); fpu_fistm64p(addr); }
  1114. void instr_DF_0_reg(int32_t r) { trigger_ud(); }
  1115. void instr_DF_1_reg(int32_t r) { trigger_ud(); }
  1116. void instr_DF_2_reg(int32_t r) { trigger_ud(); }
  1117. void instr_DF_3_reg(int32_t r) { trigger_ud(); }
  1118. void instr_DF_4_reg(int32_t r) { task_switch_test(); if(r == 0) { fpu_fnstsw_reg(); } else { trigger_ud(); } }
  1119. void instr_DF_5_reg(int32_t r) { task_switch_test(); fpu_fucomip(r); }
  1120. void instr_DF_6_reg(int32_t r) { task_switch_test(); fpu_fcomip(r); }
  1121. void instr_DF_7_reg(int32_t r) { trigger_ud(); }
  1122. void instr16_E0(int32_t imm8s) { loopne16(imm8s); }
  1123. void instr16_E1(int32_t imm8s) { loope16(imm8s); }
  1124. void instr16_E2(int32_t imm8s) { loop16(imm8s); }
  1125. void instr16_E3(int32_t imm8s) { jcxz16(imm8s); }
  1126. void instr32_E0(int32_t imm8s) { loopne32(imm8s); }
  1127. void instr32_E1(int32_t imm8s) { loope32(imm8s); }
  1128. void instr32_E2(int32_t imm8s) { loop32(imm8s); }
  1129. void instr32_E3(int32_t imm8s) { jcxz32(imm8s); }
  1130. void instr_E4(int32_t port) {
  1131. test_privileges_for_io(port, 1);
  1132. reg8[AL] = io_port_read8(port);
  1133. }
  1134. void instr16_E5(int32_t port) {
  1135. test_privileges_for_io(port, 2);
  1136. reg16[AX] = io_port_read16(port);
  1137. }
  1138. void instr32_E5(int32_t port) {
  1139. test_privileges_for_io(port, 4);
  1140. reg32s[EAX] = io_port_read32(port);
  1141. }
  1142. void instr_E6(int32_t port) {
  1143. test_privileges_for_io(port, 1);
  1144. io_port_write8(port, reg8[AL]);
  1145. }
  1146. void instr16_E7(int32_t port) {
  1147. test_privileges_for_io(port, 2);
  1148. io_port_write16(port, reg16[AX]);
  1149. }
  1150. void instr32_E7(int32_t port) {
  1151. test_privileges_for_io(port, 4);
  1152. io_port_write32(port, reg32s[EAX]);
  1153. }
  1154. void instr16_E8(int32_t imm16) {
  1155. // call
  1156. push16(get_real_eip());
  1157. jmp_rel16(imm16);
  1158. }
  1159. void instr32_E8(int32_t imm32s) {
  1160. // call
  1161. push32(get_real_eip());
  1162. instruction_pointer[0] = instruction_pointer[0] + imm32s;
  1163. //dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1164. }
  1165. void instr16_E9(int32_t imm16) {
  1166. // jmp
  1167. jmp_rel16(imm16);
  1168. }
  1169. void instr32_E9(int32_t imm32s) {
  1170. // jmp
  1171. instruction_pointer[0] = instruction_pointer[0] + imm32s;
  1172. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1173. }
  1174. void instr16_EA(int32_t new_ip, int32_t cs) {
  1175. // jmpf
  1176. far_jump(new_ip, cs, false);
  1177. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1178. }
  1179. void instr32_EA(int32_t new_ip, int32_t cs) {
  1180. // jmpf
  1181. far_jump(new_ip, cs, false);
  1182. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1183. }
  1184. void instr16_EB(int32_t imm8) {
  1185. // jmp near
  1186. jmp_rel16(imm8);
  1187. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1188. }
  1189. void instr32_EB(int32_t imm8) {
  1190. // jmp near
  1191. instruction_pointer[0] = instruction_pointer[0] + imm8;
  1192. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1193. }
  1194. void instr_EC() {
  1195. int32_t port = reg16[DX];
  1196. test_privileges_for_io(port, 1);
  1197. reg8[AL] = io_port_read8(port);
  1198. }
  1199. void instr16_ED() {
  1200. int32_t port = reg16[DX];
  1201. test_privileges_for_io(port, 2);
  1202. reg16[AX] = io_port_read16(port);
  1203. }
  1204. void instr32_ED() {
  1205. int32_t port = reg16[DX];
  1206. test_privileges_for_io(port, 4);
  1207. reg32s[EAX] = io_port_read32(port);
  1208. }
  1209. void instr_EE() {
  1210. int32_t port = reg16[DX];
  1211. test_privileges_for_io(port, 1);
  1212. io_port_write8(port, reg8[AL]);
  1213. }
  1214. void instr16_EF() {
  1215. int32_t port = reg16[DX];
  1216. test_privileges_for_io(port, 2);
  1217. io_port_write16(port, reg16[AX]);
  1218. }
  1219. void instr32_EF() {
  1220. int32_t port = reg16[DX];
  1221. test_privileges_for_io(port, 4);
  1222. io_port_write32(port, reg32s[EAX]);
  1223. }
  1224. void instr_F0() {
  1225. // lock
  1226. //dbg_log("lock");
  1227. // TODO
  1228. // This triggers UD when used with
  1229. // some instructions that don't write to memory
  1230. run_prefix_instruction();
  1231. }
  1232. void instr_F1() {
  1233. // INT1
  1234. // https://code.google.com/p/corkami/wiki/x86oddities#IceBP
  1235. //throw debug.unimpl("int1 instruction");
  1236. assert(false);
  1237. }
  1238. void instr_F2() {
  1239. // repnz
  1240. dbg_assert((*prefixes & PREFIX_MASK_REP) == 0);
  1241. *prefixes |= PREFIX_REPNZ;
  1242. run_prefix_instruction();
  1243. *prefixes = 0;
  1244. }
  1245. void instr_F3() {
  1246. // repz
  1247. dbg_assert((*prefixes & PREFIX_MASK_REP) == 0);
  1248. *prefixes |= PREFIX_REPZ;
  1249. run_prefix_instruction();
  1250. *prefixes = 0;
  1251. }
  1252. void instr_F4() {
  1253. hlt_op();
  1254. }
  1255. void instr_F5() {
  1256. // cmc
  1257. flags[0] = (flags[0] | 1) ^ getcf();
  1258. flags_changed[0] &= ~1;
  1259. }
  1260. DEFINE_MODRM_INSTR2_READ8(instr_F6_0, test8(___, imm))
  1261. DEFINE_MODRM_INSTR2_READ8(instr_F6_1, test8(___, imm))
  1262. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_F6_2, ~___)
  1263. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_F6_3, neg8(___))
  1264. DEFINE_MODRM_INSTR1_READ8(instr_F6_4, mul8(___))
  1265. DEFINE_MODRM_INSTR1_READ8(instr_F6_5, imul8(___ << 24 >> 24))
  1266. DEFINE_MODRM_INSTR1_READ8(instr_F6_6, div8(___))
  1267. DEFINE_MODRM_INSTR1_READ8(instr_F6_7, idiv8(___ << 24 >> 24))
  1268. DEFINE_MODRM_INSTR2_READ16(instr16_F7_0, test16(___, imm))
  1269. DEFINE_MODRM_INSTR2_READ16(instr16_F7_1, test16(___, imm))
  1270. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_F7_2, ~___)
  1271. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_F7_3, neg16(___))
  1272. DEFINE_MODRM_INSTR1_READ16(instr16_F7_4, mul16(___))
  1273. DEFINE_MODRM_INSTR1_READ16(instr16_F7_5, imul16(___ << 16 >> 16))
  1274. DEFINE_MODRM_INSTR1_READ16(instr16_F7_6, div16(___))
  1275. DEFINE_MODRM_INSTR1_READ16(instr16_F7_7, idiv16(___ << 16 >> 16))
  1276. DEFINE_MODRM_INSTR2_READ32(instr32_F7_0, test32(___, imm))
  1277. DEFINE_MODRM_INSTR2_READ32(instr32_F7_1, test32(___, imm))
  1278. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_F7_2, ~___)
  1279. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_F7_3, neg32(___))
  1280. DEFINE_MODRM_INSTR1_READ32(instr32_F7_4, mul32(___))
  1281. DEFINE_MODRM_INSTR1_READ32(instr32_F7_5, imul32(___))
  1282. DEFINE_MODRM_INSTR1_READ32(instr32_F7_6, div32(___))
  1283. DEFINE_MODRM_INSTR1_READ32(instr32_F7_7, idiv32(___))
  1284. void instr_F8() {
  1285. // clc
  1286. flags[0] &= ~FLAG_CARRY;
  1287. flags_changed[0] &= ~1;
  1288. }
  1289. void instr_F9() {
  1290. // stc
  1291. flags[0] |= FLAG_CARRY;
  1292. flags_changed[0] &= ~1;
  1293. }
  1294. void instr_FA() {
  1295. // cli
  1296. //dbg_log("interrupts off");
  1297. if(!*protected_mode || ((flags[0] & FLAG_VM) ?
  1298. getiopl() == 3 : getiopl() >= *cpl))
  1299. {
  1300. flags[0] &= ~FLAG_INTERRUPT;
  1301. }
  1302. else
  1303. {
  1304. //if(getiopl() < 3 && ((flags & FLAG_VM) ?
  1305. // (cr[4] & CR4_VME) :
  1306. // (*cpl == 3 && (cr[4] & CR4_PVI))))
  1307. //{
  1308. // flags &= ~flag_vif;
  1309. //}
  1310. //else
  1311. {
  1312. dbg_log("cli #gp");
  1313. trigger_gp(0);
  1314. }
  1315. }
  1316. }
  1317. void instr_FB() {
  1318. // sti
  1319. //dbg_log("interrupts on");
  1320. int32_t old_if = flags[0] & FLAG_INTERRUPT;
  1321. if(!*protected_mode || ((flags[0] & FLAG_VM) ?
  1322. getiopl() == 3 : getiopl() >= *cpl))
  1323. {
  1324. flags[0] |= FLAG_INTERRUPT;
  1325. if(old_if == 0)
  1326. {
  1327. //clear_prefixes();
  1328. //cycle_internal();
  1329. handle_irqs();
  1330. }
  1331. }
  1332. else
  1333. {
  1334. //if(getiopl() < 3 && (flags & flag_vip) == 0 && ((flags & FLAG_VM) ?
  1335. // (cr[4] & CR4_VME) :
  1336. // (cpl == 3 && (cr[4] & CR4_PVI))))
  1337. //{
  1338. // flags |= flag_vif;
  1339. //}
  1340. //else
  1341. {
  1342. dbg_log("sti #gp");
  1343. trigger_gp(0);
  1344. }
  1345. }
  1346. }
  1347. void instr_FC() {
  1348. // cld
  1349. flags[0] &= ~FLAG_DIRECTION;
  1350. }
  1351. void instr_FD() {
  1352. // std
  1353. flags[0] |= FLAG_DIRECTION;
  1354. }
  1355. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_FE_0, inc8(___))
  1356. DEFINE_MODRM_INSTR1_READ_WRITE_8(instr_FE_1, dec8(___))
  1357. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_FF_0, inc16(___))
  1358. DEFINE_MODRM_INSTR1_READ_WRITE_16(instr16_FF_1, dec16(___))
  1359. void instr16_FF_2_helper(int32_t data)
  1360. {
  1361. // call near
  1362. int32_t cs = get_seg_cs();
  1363. push16(get_real_eip());
  1364. instruction_pointer[0] = cs + data;
  1365. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1366. }
  1367. DEFINE_MODRM_INSTR1_READ16(instr16_FF_2, instr16_FF_2_helper(___))
  1368. void instr16_FF_3_reg(int32_t r)
  1369. {
  1370. dbg_log("callf #ud");
  1371. trigger_ud();
  1372. }
  1373. void instr16_FF_3_mem(int32_t addr)
  1374. {
  1375. // callf
  1376. int32_t new_ip = safe_read16(addr);
  1377. int32_t new_cs = safe_read16(addr + 2);
  1378. far_jump(new_ip, new_cs, true);
  1379. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1380. }
  1381. void instr16_FF_4_helper(int32_t data)
  1382. {
  1383. // jmp near
  1384. instruction_pointer[0] = get_seg_cs() + data;
  1385. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1386. }
  1387. DEFINE_MODRM_INSTR1_READ16(instr16_FF_4, instr16_FF_4_helper(___))
  1388. void instr16_FF_5_reg(int32_t r)
  1389. {
  1390. dbg_log("jmpf #ud");
  1391. trigger_ud();
  1392. }
  1393. void instr16_FF_5_mem(int32_t addr)
  1394. {
  1395. // jmpf
  1396. int32_t new_ip = safe_read16(addr);
  1397. int32_t new_cs = safe_read16(addr + 2);
  1398. far_jump(new_ip, new_cs, false);
  1399. dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
  1400. }
  1401. DEFINE_MODRM_INSTR1_READ16(instr16_FF_6, push16(___))
  1402. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_FF_0, inc32(___))
  1403. DEFINE_MODRM_INSTR1_READ_WRITE_32(instr32_FF_1, dec32(___))
  1404. void instr32_FF_2_helper(int32_t data)
  1405. {
  1406. // call near
  1407. int32_t cs = get_seg_cs();
  1408. push32(get_real_eip());
  1409. dbg_assert(is_asize_32() || data < 0x10000);
  1410. instruction_pointer[0] = cs + data;
  1411. }
  1412. DEFINE_MODRM_INSTR1_READ32(instr32_FF_2, instr32_FF_2_helper(___))
  1413. void instr32_FF_3_reg(int32_t r)
  1414. {
  1415. dbg_log("callf #ud");
  1416. trigger_ud();
  1417. }
  1418. void instr32_FF_3_mem(int32_t addr)
  1419. {
  1420. // callf
  1421. int32_t new_ip = safe_read32s(addr);
  1422. int32_t new_cs = safe_read16(addr + 4);
  1423. if(!*protected_mode || vm86_mode())
  1424. {
  1425. if(new_ip & 0xFFFF0000)
  1426. {
  1427. //throw debug.unimpl("#GP handler");
  1428. assert(false);
  1429. }
  1430. }
  1431. far_jump(new_ip, new_cs, true);
  1432. dbg_assert(is_asize_32() || new_ip < 0x10000);
  1433. }
  1434. void instr32_FF_4_helper(int32_t data)
  1435. {
  1436. // jmp near
  1437. dbg_assert(is_asize_32() || data < 0x10000);
  1438. instruction_pointer[0] = get_seg_cs() + data;
  1439. }
  1440. DEFINE_MODRM_INSTR1_READ32(instr32_FF_4, instr32_FF_4_helper(___))
  1441. void instr32_FF_5_reg(int32_t r)
  1442. {
  1443. dbg_log("jmpf #ud");
  1444. trigger_ud();
  1445. }
  1446. void instr32_FF_5_mem(int32_t addr)
  1447. {
  1448. // jmpf
  1449. int32_t new_ip = safe_read32s(addr);
  1450. int32_t new_cs = safe_read16(addr + 4);
  1451. if(!*protected_mode || vm86_mode())
  1452. {
  1453. if(new_ip & 0xFFFF0000)
  1454. {
  1455. //throw debug.unimpl("#GP handler");
  1456. assert(false);
  1457. }
  1458. }
  1459. far_jump(new_ip, new_cs, false);
  1460. dbg_assert(is_asize_32() || new_ip < 0x10000);
  1461. }
  1462. DEFINE_MODRM_INSTR1_READ32(instr32_FF_6, push32(___))
  1463. void run_instruction(int32_t opcode)
  1464. {
  1465. #include "../../build/interpreter.c"
  1466. }
  1467. #pragma clang diagnostic pop