instructions.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. /* Jumps */
  2. /* All Byte general instructions */
  3. #define ADDB(op1, op2, load, save) \
  4. lf_var1b = load(op1); \
  5. lf_var2b = op2; \
  6. lf_resb = lf_var1b+lf_var2b; \
  7. save(op1, lf_resb); \
  8. lflags.type = t_ADDb;
  9. #define ADCB(op1, op2, load, save) \
  10. lflags.oldcf = get_CF() != 0; \
  11. lf_var1b = load(op1); \
  12. lf_var2b = op2; \
  13. lf_resb = lf_var1b+lf_var2b+lflags.oldcf; \
  14. save(op1, lf_resb); \
  15. lflags.type = t_ADCb;
  16. #define SBBB(op1, op2, load, save) \
  17. lflags.oldcf = get_CF() != 0; \
  18. lf_var1b = load(op1); \
  19. lf_var2b = op2; \
  20. lf_resb = lf_var1b-(lf_var2b+lflags.oldcf); \
  21. save(op1, lf_resb); \
  22. lflags.type = t_SBBb;
  23. #define SUBB(op1, op2, load, save) \
  24. lf_var1b = load(op1); \
  25. lf_var2b = op2; \
  26. lf_resb = lf_var1b-lf_var2b; \
  27. save(op1, lf_resb); \
  28. lflags.type = t_SUBb;
  29. #define ORB(op1, op2, load, save) \
  30. lf_var1b = load(op1); \
  31. lf_var2b = op2; \
  32. lf_resb = lf_var1b|lf_var2b; \
  33. save(op1, lf_resb); \
  34. lflags.type = t_ORb;
  35. #define XORB(op1, op2, load, save) \
  36. lf_var1b = load(op1); \
  37. lf_var2b = op2; \
  38. lf_resb = lf_var1b^lf_var2b; \
  39. save(op1, lf_resb); \
  40. lflags.type = t_XORb;
  41. #define ANDB(op1, op2, load, save) \
  42. lf_var1b = load(op1); \
  43. lf_var2b = op2; \
  44. lf_resb = lf_var1b&lf_var2b; \
  45. save(op1, lf_resb); \
  46. lflags.type = t_ANDb;
  47. #define CMPB(op1, op2, load, save) \
  48. lf_var1b = load(op1); \
  49. lf_var2b = op2; \
  50. lf_resb = lf_var1b-lf_var2b; \
  51. lflags.type = t_CMPb;
  52. #define TESTB(op1, op2, load, save) \
  53. lf_var1b = load(op1); \
  54. lf_var2b = op2; \
  55. lf_resb = lf_var1b&lf_var2b; \
  56. lflags.type = t_TESTb;
  57. /* All Word General instructions */
  58. #define ADDW(op1, op2, load, save) \
  59. lf_var1w = load(op1); \
  60. lf_var2w = op2; \
  61. lf_resw = lf_var1w+lf_var2w; \
  62. save(op1, lf_resw); \
  63. lflags.type = t_ADDw;
  64. #define ADCW(op1,op2,load,save) \
  65. lflags.oldcf=get_CF()!=0; \
  66. lf_var1w=load(op1);lf_var2w=op2; \
  67. lf_resw=lf_var1w+lf_var2w+lflags.oldcf; \
  68. save(op1,lf_resw); \
  69. lflags.type=t_ADCw;
  70. #define SBBW(op1,op2,load,save) \
  71. lflags.oldcf=get_CF()!=0; \
  72. lf_var1w=load(op1);lf_var2w=op2; \
  73. lf_resw=lf_var1w-(lf_var2w+lflags.oldcf); \
  74. save(op1,lf_resw); \
  75. lflags.type=t_SBBw;
  76. #define SUBW(op1,op2,load,save) \
  77. lf_var1w=load(op1);lf_var2w=op2; \
  78. lf_resw=lf_var1w-lf_var2w; \
  79. save(op1,lf_resw); \
  80. lflags.type=t_SUBw;
  81. #define ORW(op1,op2,load,save) \
  82. lf_var1w=load(op1);lf_var2w=op2; \
  83. lf_resw=lf_var1w | lf_var2w; \
  84. save(op1,lf_resw); \
  85. lflags.type=t_ORw;
  86. #define XORW(op1,op2,load,save) \
  87. lf_var1w=load(op1);lf_var2w=op2; \
  88. lf_resw=lf_var1w ^ lf_var2w; \
  89. save(op1,lf_resw); \
  90. lflags.type=t_XORw;
  91. #define ANDW(op1,op2,load,save) \
  92. lf_var1w=load(op1);lf_var2w=op2; \
  93. lf_resw=lf_var1w & lf_var2w; \
  94. save(op1,lf_resw); \
  95. lflags.type=t_ANDw;
  96. #define CMPW(op1,op2,load,save) \
  97. lf_var1w=load(op1);lf_var2w=op2; \
  98. lf_resw=lf_var1w-lf_var2w; \
  99. lflags.type=t_CMPw;
  100. #define TESTW(op1,op2,load,save) \
  101. lf_var1w=load(op1);lf_var2w=op2; \
  102. lf_resw=lf_var1w & lf_var2w; \
  103. lflags.type=t_TESTw;
  104. /* All DWORD General Instructions */
  105. #define ADDD(op1,op2,load,save) \
  106. lf_var1d=load(op1);lf_var2d=op2; \
  107. lf_resd=lf_var1d+lf_var2d; \
  108. save(op1,lf_resd); \
  109. lflags.type=t_ADDd;
  110. #define ADCD(op1,op2,load,save) \
  111. lflags.oldcf=get_CF()!=0; \
  112. lf_var1d=load(op1);lf_var2d=op2; \
  113. lf_resd=lf_var1d+lf_var2d+lflags.oldcf; \
  114. save(op1,lf_resd); \
  115. lflags.type=t_ADCd;
  116. #define SBBD(op1,op2,load,save) \
  117. lflags.oldcf=get_CF()!=0; \
  118. lf_var1d=load(op1);lf_var2d=op2; \
  119. lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); \
  120. save(op1,lf_resd); \
  121. lflags.type=t_SBBd;
  122. #define SUBD(op1,op2,load,save) \
  123. lf_var1d=load(op1);lf_var2d=op2; \
  124. lf_resd=lf_var1d-lf_var2d; \
  125. save(op1,lf_resd); \
  126. lflags.type=t_SUBd;
  127. #define ORD(op1,op2,load,save) \
  128. lf_var1d=load(op1);lf_var2d=op2; \
  129. lf_resd=lf_var1d | lf_var2d; \
  130. save(op1,lf_resd); \
  131. lflags.type=t_ORd;
  132. #define XORD(op1,op2,load,save) \
  133. lf_var1d=load(op1);lf_var2d=op2; \
  134. lf_resd=lf_var1d ^ lf_var2d; \
  135. save(op1,lf_resd); \
  136. lflags.type=t_XORd;
  137. #define ANDD(op1,op2,load,save) \
  138. lf_var1d=load(op1);lf_var2d=op2; \
  139. lf_resd=lf_var1d & lf_var2d; \
  140. save(op1,lf_resd); \
  141. lflags.type=t_ANDd;
  142. #define CMPD(op1,op2,load,save) \
  143. lf_var1d=load(op1);lf_var2d=op2; \
  144. lf_resd=lf_var1d-lf_var2d; \
  145. lflags.type=t_CMPd;
  146. #define TESTD(op1,op2,load,save) \
  147. lf_var1d=load(op1);lf_var2d=op2; \
  148. lf_resd=lf_var1d & lf_var2d; \
  149. lflags.type=t_TESTd;
  150. #define INCB(op1,load,save) \
  151. LoadCF;lf_var1b=load(op1); \
  152. lf_resb=lf_var1b+1; \
  153. save(op1,lf_resb); \
  154. lflags.type=t_INCb; \
  155. #define INCW(op1,load,save) \
  156. LoadCF;lf_var1w=load(op1); \
  157. lf_resw=lf_var1w+1; \
  158. save(op1,lf_resw); \
  159. lflags.type=t_INCw;
  160. #define INCD(op1,load,save) \
  161. LoadCF;lf_var1d=load(op1); \
  162. lf_resd=lf_var1d+1; \
  163. save(op1,lf_resd); \
  164. lflags.type=t_INCd;
  165. #define DECB(op1,load,save) \
  166. LoadCF;lf_var1b=load(op1); \
  167. lf_resb=lf_var1b-1; \
  168. save(op1,lf_resb); \
  169. lflags.type=t_DECb;
  170. #define DECW(op1,load,save) \
  171. LoadCF;lf_var1w=load(op1); \
  172. lf_resw=lf_var1w-1; \
  173. save(op1,lf_resw); \
  174. lflags.type=t_DECw;
  175. #define DECD(op1,load,save) \
  176. LoadCF;lf_var1d=load(op1); \
  177. lf_resd=lf_var1d-1; \
  178. save(op1,lf_resd); \
  179. lflags.type=t_DECd;
  180. #define ROLB(op1, op2, load, save) \
  181. if (!(op2&0x7)) \
  182. { \
  183. if (op2&0x18) \
  184. { \
  185. FillFlagsNoCFOF(); \
  186. SETFLAGBIT(CF, op1&1); \
  187. SETFLAGBIT(OF, (op1&1)^(op1>>7)); \
  188. } \
  189. break; \
  190. } \
  191. FillFlagsNoCFOF(); \
  192. lf_var1b = load(op1); \
  193. lf_var2b = op2&0x07; \
  194. lf_resb = (lf_var1b<<lf_var2b)| \
  195. (lf_var1b>>(8-lf_var2b)); \
  196. save(op1, lf_resb); \
  197. SETFLAGBIT(CF, lf_resb&1); \
  198. SETFLAGBIT(OF, (lf_resb&1)^(lf_resb>>7));
  199. #define ROLW(op1,op2,load,save) \
  200. if (!(op2&0xf)) { \
  201. if (op2&0x10) { \
  202. FillFlagsNoCFOF(); \
  203. SETFLAGBIT(CF,op1 & 1); \
  204. SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15)); \
  205. } \
  206. break; \
  207. } \
  208. FillFlagsNoCFOF(); \
  209. lf_var1w=load(op1); \
  210. lf_var2b=op2&0xf; \
  211. lf_resw=(lf_var1w << lf_var2b) | \
  212. (lf_var1w >> (16-lf_var2b)); \
  213. save(op1,lf_resw); \
  214. SETFLAGBIT(CF,lf_resw & 1); \
  215. SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15));
  216. #define ROLD(op1,op2,load,save) \
  217. if (!op2) break; \
  218. FillFlagsNoCFOF(); \
  219. lf_var1d=load(op1); \
  220. lf_var2b=op2; \
  221. lf_resd=(lf_var1d << lf_var2b) | \
  222. (lf_var1d >> (32-lf_var2b)); \
  223. save(op1,lf_resd); \
  224. SETFLAGBIT(CF,lf_resd & 1); \
  225. SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31));
  226. #define RORB(op1,op2,load,save) \
  227. if (!(op2&0x7)) { \
  228. if (op2&0x18) { \
  229. FillFlagsNoCFOF(); \
  230. SETFLAGBIT(CF,op1>>7); \
  231. SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \
  232. } \
  233. break; \
  234. } \
  235. FillFlagsNoCFOF(); \
  236. lf_var1b=load(op1); \
  237. lf_var2b=op2&0x07; \
  238. lf_resb=(lf_var1b >> lf_var2b) | \
  239. (lf_var1b << (8-lf_var2b)); \
  240. save(op1,lf_resb); \
  241. SETFLAGBIT(CF,lf_resb & 0x80); \
  242. SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80);
  243. #define RORW(op1,op2,load,save) \
  244. if (!(op2&0xf)) { \
  245. if (op2&0x10) { \
  246. FillFlagsNoCFOF(); \
  247. SETFLAGBIT(CF,op1>>15); \
  248. SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1)); \
  249. } \
  250. break; \
  251. } \
  252. FillFlagsNoCFOF(); \
  253. lf_var1w=load(op1); \
  254. lf_var2b=op2&0xf; \
  255. lf_resw=(lf_var1w >> lf_var2b) | \
  256. (lf_var1w << (16-lf_var2b)); \
  257. save(op1,lf_resw); \
  258. SETFLAGBIT(CF,lf_resw & 0x8000); \
  259. SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000);
  260. #define RORD(op1,op2,load,save) \
  261. if (!op2) break; \
  262. FillFlagsNoCFOF(); \
  263. lf_var1d=load(op1); \
  264. lf_var2b=op2; \
  265. lf_resd=(lf_var1d >> lf_var2b) | \
  266. (lf_var1d << (32-lf_var2b)); \
  267. save(op1,lf_resd); \
  268. SETFLAGBIT(CF,lf_resd & 0x80000000); \
  269. SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000);
  270. #define RCLB(op1,op2,load,save) \
  271. if (!(op2%9)) break; \
  272. { Bit8u cf=(Bit8u)FillFlags()&0x1; \
  273. lf_var1b=load(op1); \
  274. lf_var2b=op2%9; \
  275. lf_resb=(lf_var1b << lf_var2b) | \
  276. (cf << (lf_var2b-1)) | \
  277. (lf_var1b >> (9-lf_var2b)); \
  278. save(op1,lf_resb); \
  279. SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \
  280. SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resb >> 7)); \
  281. }
  282. #define RCLW(op1,op2,load,save) \
  283. if (!(op2%17)) break; \
  284. { Bit16u cf=(Bit16u)FillFlags()&0x1; \
  285. lf_var1w=load(op1); \
  286. lf_var2b=op2%17; \
  287. lf_resw=(lf_var1w << lf_var2b) | \
  288. (cf << (lf_var2b-1)) | \
  289. (lf_var1w >> (17-lf_var2b)); \
  290. save(op1,lf_resw); \
  291. SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \
  292. SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resw >> 15)); \
  293. }
  294. #define RCLD(op1,op2,load,save) \
  295. if (!op2) break; \
  296. { Bit32u cf=(Bit32u)FillFlags()&0x1; \
  297. lf_var1d=load(op1); \
  298. lf_var2b=op2; \
  299. if (lf_var2b==1) { \
  300. lf_resd=(lf_var1d << 1) | cf; \
  301. } else { \
  302. lf_resd=(lf_var1d << lf_var2b) | \
  303. (cf << (lf_var2b-1)) | \
  304. (lf_var1d >> (33-lf_var2b)); \
  305. } \
  306. save(op1,lf_resd); \
  307. SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \
  308. SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31)); \
  309. }
  310. #define RCRB(op1,op2,load,save) \
  311. if (op2%9) { \
  312. Bit8u cf=(Bit8u)FillFlags()&0x1; \
  313. lf_var1b=load(op1); \
  314. lf_var2b=op2%9; \
  315. lf_resb=(lf_var1b >> lf_var2b) | \
  316. (cf << (8-lf_var2b)) | \
  317. (lf_var1b << (9-lf_var2b)); \
  318. save(op1,lf_resb); \
  319. SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1); \
  320. SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); \
  321. }
  322. #define RCRW(op1,op2,load,save) \
  323. if (op2%17) { \
  324. Bit16u cf=(Bit16u)FillFlags()&0x1; \
  325. lf_var1w=load(op1); \
  326. lf_var2b=op2%17; \
  327. lf_resw=(lf_var1w >> lf_var2b) | \
  328. (cf << (16-lf_var2b)) | \
  329. (lf_var1w << (17-lf_var2b)); \
  330. save(op1,lf_resw); \
  331. SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1); \
  332. SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); \
  333. }
  334. #define RCRD(op1,op2,load,save) \
  335. if (op2) { \
  336. Bit32u cf=(Bit32u)FillFlags()&0x1; \
  337. lf_var1d=load(op1); \
  338. lf_var2b=op2; \
  339. if (lf_var2b==1) { \
  340. lf_resd=lf_var1d >> 1 | cf << 31; \
  341. } else { \
  342. lf_resd=(lf_var1d >> lf_var2b) | \
  343. (cf << (32-lf_var2b)) | \
  344. (lf_var1d << (33-lf_var2b)); \
  345. } \
  346. save(op1,lf_resd); \
  347. SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1); \
  348. SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); \
  349. }
  350. #define SHLB(op1,op2,load,save) \
  351. if (!op2) break; \
  352. lf_var1b=load(op1);lf_var2b=op2; \
  353. lf_resb=lf_var1b << lf_var2b; \
  354. save(op1,lf_resb); \
  355. lflags.type=t_SHLb;
  356. #define SHLW(op1,op2,load,save) \
  357. if (!op2) break; \
  358. lf_var1w=load(op1);lf_var2b=op2 ; \
  359. lf_resw=lf_var1w << lf_var2b; \
  360. save(op1,lf_resw); \
  361. lflags.type=t_SHLw;
  362. #define SHLD(op1,op2,load,save) \
  363. if (!op2) break; \
  364. lf_var1d=load(op1);lf_var2b=op2; \
  365. lf_resd=lf_var1d << lf_var2b; \
  366. save(op1,lf_resd); \
  367. lflags.type=t_SHLd;
  368. #define SHRB(op1,op2,load,save) \
  369. if (!op2) break; \
  370. lf_var1b=load(op1);lf_var2b=op2; \
  371. lf_resb=lf_var1b >> lf_var2b; \
  372. save(op1,lf_resb); \
  373. lflags.type=t_SHRb;
  374. #define SHRW(op1,op2,load,save) \
  375. if (!op2) break; \
  376. lf_var1w=load(op1);lf_var2b=op2; \
  377. lf_resw=lf_var1w >> lf_var2b; \
  378. save(op1,lf_resw); \
  379. lflags.type=t_SHRw;
  380. #define SHRD(op1,op2,load,save) \
  381. if (!op2) break; \
  382. lf_var1d=load(op1);lf_var2b=op2; \
  383. lf_resd=lf_var1d >> lf_var2b; \
  384. save(op1,lf_resd); \
  385. lflags.type=t_SHRd;
  386. #define SARB(op1,op2,load,save) \
  387. if (!op2) break; \
  388. lf_var1b=load(op1);lf_var2b=op2; \
  389. if (lf_var2b>8) lf_var2b=8; \
  390. if (lf_var1b & 0x80) { \
  391. lf_resb=(lf_var1b >> lf_var2b)| \
  392. (0xff << (8 - lf_var2b)); \
  393. } else { \
  394. lf_resb=lf_var1b >> lf_var2b; \
  395. } \
  396. save(op1,lf_resb); \
  397. lflags.type=t_SARb;
  398. #define SARW(op1,op2,load,save) \
  399. if (!op2) break; \
  400. lf_var1w=load(op1);lf_var2b=op2; \
  401. if (lf_var2b>16) lf_var2b=16; \
  402. if (lf_var1w & 0x8000) { \
  403. lf_resw=(lf_var1w >> lf_var2b)| \
  404. (0xffff << (16 - lf_var2b)); \
  405. } else { \
  406. lf_resw=lf_var1w >> lf_var2b; \
  407. } \
  408. save(op1,lf_resw); \
  409. lflags.type=t_SARw;
  410. #define SARD(op1,op2,load,save) \
  411. if (!op2) break; \
  412. lf_var2b=op2;lf_var1d=load(op1); \
  413. if (lf_var1d & 0x80000000) { \
  414. lf_resd=(lf_var1d >> lf_var2b)| \
  415. (0xffffffff << (32 - lf_var2b)); \
  416. } else { \
  417. lf_resd=lf_var1d >> lf_var2b; \
  418. } \
  419. save(op1,lf_resd); \
  420. lflags.type=t_SARd;
  421. #define DAA() \
  422. if (((reg_al & 0x0F)>0x09) || get_AF()) { \
  423. if ((reg_al > 0x99) || get_CF()) { \
  424. reg_al+=0x60; \
  425. SETFLAGBIT(CF,true); \
  426. } else { \
  427. SETFLAGBIT(CF,false); \
  428. } \
  429. reg_al+=0x06; \
  430. SETFLAGBIT(AF,true); \
  431. } else { \
  432. if ((reg_al > 0x99) || get_CF()) { \
  433. reg_al+=0x60; \
  434. SETFLAGBIT(CF,true); \
  435. } else { \
  436. SETFLAGBIT(CF,false); \
  437. } \
  438. SETFLAGBIT(AF,false); \
  439. } \
  440. SETFLAGBIT(SF,(reg_al&0x80)); \
  441. SETFLAGBIT(ZF,(reg_al==0)); \
  442. SETFLAGBIT(PF,parity_lookup[reg_al]); \
  443. lflags.type=t_UNKNOWN;
  444. #define DAS() \
  445. { \
  446. Bit8u osigned=reg_al & 0x80; \
  447. if (((reg_al & 0x0f) > 9) || get_AF()) { \
  448. if ((reg_al>0x99) || get_CF()) { \
  449. reg_al-=0x60; \
  450. SETFLAGBIT(CF,true); \
  451. } else { \
  452. SETFLAGBIT(CF,(reg_al<=0x05)); \
  453. } \
  454. reg_al-=6; \
  455. SETFLAGBIT(AF,true); \
  456. } else { \
  457. if ((reg_al>0x99) || get_CF()) { \
  458. reg_al-=0x60; \
  459. SETFLAGBIT(CF,true); \
  460. } else { \
  461. SETFLAGBIT(CF,false); \
  462. } \
  463. SETFLAGBIT(AF,false); \
  464. } \
  465. SETFLAGBIT(OF,osigned && ((reg_al&0x80)==0)); \
  466. SETFLAGBIT(SF,(reg_al&0x80)); \
  467. SETFLAGBIT(ZF,(reg_al==0)); \
  468. SETFLAGBIT(PF,parity_lookup[reg_al]); \
  469. lflags.type=t_UNKNOWN; \
  470. }
  471. #define AAA() \
  472. SETFLAGBIT(SF,((reg_al>=0x7a) && (reg_al<=0xf9))); \
  473. if ((reg_al & 0xf) > 9) { \
  474. SETFLAGBIT(OF,(reg_al&0xf0)==0x70); \
  475. reg_ax += 0x106; \
  476. SETFLAGBIT(CF,true); \
  477. SETFLAGBIT(ZF,(reg_al == 0)); \
  478. SETFLAGBIT(AF,true); \
  479. } else if (get_AF()) { \
  480. reg_ax += 0x106; \
  481. SETFLAGBIT(OF,false); \
  482. SETFLAGBIT(CF,true); \
  483. SETFLAGBIT(ZF,false); \
  484. SETFLAGBIT(AF,true); \
  485. } else { \
  486. SETFLAGBIT(OF,false); \
  487. SETFLAGBIT(CF,false); \
  488. SETFLAGBIT(ZF,(reg_al == 0)); \
  489. SETFLAGBIT(AF,false); \
  490. } \
  491. SETFLAGBIT(PF,parity_lookup[reg_al]); \
  492. reg_al &= 0x0F; \
  493. lflags.type=t_UNKNOWN;
  494. #define AAS() \
  495. if ((reg_al & 0x0f)>9) { \
  496. SETFLAGBIT(SF,(reg_al>0x85)); \
  497. reg_ax -= 0x106; \
  498. SETFLAGBIT(OF,false); \
  499. SETFLAGBIT(CF,true); \
  500. SETFLAGBIT(AF,true); \
  501. } else if (get_AF()) { \
  502. SETFLAGBIT(OF,((reg_al>=0x80) && (reg_al<=0x85))); \
  503. SETFLAGBIT(SF,(reg_al<0x06) || (reg_al>0x85)); \
  504. reg_ax -= 0x106; \
  505. SETFLAGBIT(CF,true); \
  506. SETFLAGBIT(AF,true); \
  507. } else { \
  508. SETFLAGBIT(SF,(reg_al>=0x80)); \
  509. SETFLAGBIT(OF,false); \
  510. SETFLAGBIT(CF,false); \
  511. SETFLAGBIT(AF,false); \
  512. } \
  513. SETFLAGBIT(ZF,(reg_al == 0)); \
  514. SETFLAGBIT(PF,parity_lookup[reg_al]); \
  515. reg_al &= 0x0F; \
  516. lflags.type=t_UNKNOWN;
  517. #define AAM(op1) \
  518. { \
  519. Bit8u dv=op1; \
  520. if (dv!=0) { \
  521. reg_ah=reg_al / dv; \
  522. reg_al=reg_al % dv; \
  523. SETFLAGBIT(SF,(reg_al & 0x80)); \
  524. SETFLAGBIT(ZF,(reg_al == 0)); \
  525. SETFLAGBIT(PF,parity_lookup[reg_al]); \
  526. SETFLAGBIT(CF,false); \
  527. SETFLAGBIT(OF,false); \
  528. SETFLAGBIT(AF,false); \
  529. lflags.type=t_UNKNOWN; \
  530. } else EXCEPTION(0); \
  531. }
  532. //Took this from bochs, i seriously hate these weird bcd opcodes
  533. #define AAD(op1) \
  534. { \
  535. Bit16u ax1 = reg_ah * op1; \
  536. Bit16u ax2 = ax1 + reg_al; \
  537. reg_al = (Bit8u) ax2; \
  538. reg_ah = 0; \
  539. SETFLAGBIT(CF,false); \
  540. SETFLAGBIT(OF,false); \
  541. SETFLAGBIT(AF,false); \
  542. SETFLAGBIT(SF,reg_al >= 0x80); \
  543. SETFLAGBIT(ZF,reg_al == 0); \
  544. SETFLAGBIT(PF,parity_lookup[reg_al]); \
  545. lflags.type=t_UNKNOWN; \
  546. }
  547. #define MULB(op1,load,save) \
  548. reg_ax=reg_al*load(op1); \
  549. FillFlagsNoCFOF(); \
  550. SETFLAGBIT(ZF,reg_al == 0); \
  551. if (reg_ax & 0xff00) { \
  552. SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
  553. } else { \
  554. SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
  555. }
  556. #define MULW(op1,load,save) \
  557. { \
  558. Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \
  559. reg_ax=(Bit16u)(tempu); \
  560. reg_dx=(Bit16u)(tempu >> 16); \
  561. FillFlagsNoCFOF(); \
  562. SETFLAGBIT(ZF,reg_ax == 0); \
  563. if (reg_dx) { \
  564. SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
  565. } else { \
  566. SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
  567. } \
  568. }
  569. #define MULD(op1,load,save) \
  570. { \
  571. Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \
  572. reg_eax=(Bit32u)(tempu); \
  573. reg_edx=(Bit32u)(tempu >> 32); \
  574. FillFlagsNoCFOF(); \
  575. SETFLAGBIT(ZF,reg_eax == 0); \
  576. if (reg_edx) { \
  577. SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
  578. } else { \
  579. SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
  580. } \
  581. }
  582. #define DIVB(op1,load,save) \
  583. { \
  584. Bitu val=load(op1); \
  585. if (val==0) EXCEPTION(0); \
  586. Bitu quo=reg_ax / val; \
  587. Bit8u rem=(Bit8u)(reg_ax % val); \
  588. Bit8u quo8=(Bit8u)(quo&0xff); \
  589. if (quo>0xff) EXCEPTION(0); \
  590. reg_ah=rem; \
  591. reg_al=quo8; \
  592. }
  593. #define DIVW(op1,load,save) \
  594. { \
  595. Bitu val=load(op1); \
  596. if (val==0) EXCEPTION(0); \
  597. Bitu num=((Bit32u)reg_dx<<16)|reg_ax; \
  598. Bitu quo=num/val; \
  599. Bit16u rem=(Bit16u)(num % val); \
  600. Bit16u quo16=(Bit16u)(quo&0xffff); \
  601. if (quo!=(Bit32u)quo16) EXCEPTION(0); \
  602. reg_dx=rem; \
  603. reg_ax=quo16; \
  604. }
  605. #define DIVD(op1,load,save) \
  606. { \
  607. Bitu val=load(op1); \
  608. if (val==0) EXCEPTION(0); \
  609. Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; \
  610. Bit64u quo=num/val; \
  611. Bit32u rem=(Bit32u)(num % val); \
  612. Bit32u quo32=(Bit32u)(quo&0xffffffff); \
  613. if (quo!=(Bit64u)quo32) EXCEPTION(0); \
  614. reg_edx=rem; \
  615. reg_eax=quo32; \
  616. }
  617. #define IDIVB(op1,load,save) \
  618. { \
  619. Bits val=(Bit8s)(load(op1)); \
  620. if (val==0) EXCEPTION(0); \
  621. Bits quo=((Bit16s)reg_ax) / val; \
  622. Bit8s rem=(Bit8s)((Bit16s)reg_ax % val); \
  623. Bit8s quo8s=(Bit8s)(quo&0xff); \
  624. if (quo!=(Bit16s)quo8s) EXCEPTION(0); \
  625. reg_ah=rem; \
  626. reg_al=quo8s; \
  627. }
  628. #define IDIVW(op1,load,save) \
  629. { \
  630. Bits val=(Bit16s)(load(op1)); \
  631. if (val==0) EXCEPTION(0); \
  632. Bits num=(Bit32s)((reg_dx<<16)|reg_ax); \
  633. Bits quo=num/val; \
  634. Bit16s rem=(Bit16s)(num % val); \
  635. Bit16s quo16s=(Bit16s)quo; \
  636. if (quo!=(Bit32s)quo16s) EXCEPTION(0); \
  637. reg_dx=rem; \
  638. reg_ax=quo16s; \
  639. }
  640. #define IDIVD(op1,load,save) \
  641. { \
  642. Bits val=(Bit32s)(load(op1)); \
  643. if (val==0) EXCEPTION(0); \
  644. Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax; \
  645. Bit64s quo=num/val; \
  646. Bit32s rem=(Bit32s)(num % val); \
  647. Bit32s quo32s=(Bit32s)(quo&0xffffffff); \
  648. if (quo!=(Bit64s)quo32s) EXCEPTION(0); \
  649. reg_edx=rem; \
  650. reg_eax=quo32s; \
  651. }
  652. #define IMULB(op1,load,save) \
  653. { \
  654. reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \
  655. FillFlagsNoCFOF(); \
  656. if ((reg_ax & 0xff80)==0xff80 || \
  657. (reg_ax & 0xff80)==0x0000) { \
  658. SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
  659. } else { \
  660. SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
  661. } \
  662. }
  663. #define IMULW(op1,load,save) \
  664. { \
  665. Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \
  666. reg_ax=(Bit16s)(temps); \
  667. reg_dx=(Bit16s)(temps >> 16); \
  668. FillFlagsNoCFOF(); \
  669. if (((temps & 0xffff8000)==0xffff8000 || \
  670. (temps & 0xffff8000)==0x0000)) { \
  671. SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
  672. } else { \
  673. SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
  674. } \
  675. }
  676. #define IMULD(op1,load,save) \
  677. { \
  678. Bit64s temps=((Bit64s)((Bit32s)reg_eax))* \
  679. ((Bit64s)((Bit32s)(load(op1)))); \
  680. reg_eax=(Bit32u)(temps); \
  681. reg_edx=(Bit32u)(temps >> 32); \
  682. FillFlagsNoCFOF(); \
  683. if ((reg_edx==0xffffffff) && \
  684. (reg_eax & 0x80000000)) { \
  685. SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
  686. } else if ((reg_edx==0x00000000) && \
  687. (reg_eax< 0x80000000)) { \
  688. SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
  689. } else { \
  690. SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
  691. } \
  692. }
  693. #define DIMULW(op1,op2,op3,load,save) \
  694. { \
  695. Bits res=((Bit16s)op2) * ((Bit16s)op3); \
  696. save(op1,res & 0xffff); \
  697. FillFlagsNoCFOF(); \
  698. if ((res>= -32768) && (res<=32767)) { \
  699. SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
  700. } else { \
  701. SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
  702. } \
  703. }
  704. #define DIMULD(op1,op2,op3,load,save) \
  705. { \
  706. Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \
  707. save(op1,(Bit32s)res); \
  708. FillFlagsNoCFOF(); \
  709. if ((res>=-((Bit64s)(2147483647)+1)) && \
  710. (res<=(Bit64s)2147483647)) { \
  711. SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
  712. } else { \
  713. SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
  714. } \
  715. }
  716. #define GRP2B(blah) \
  717. { \
  718. GetRM;Bitu which=(rm>>3)&7; \
  719. if (rm >= 0xc0) { \
  720. GetEArb; \
  721. Bit8u val=blah & 0x1f; \
  722. switch (which) { \
  723. case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break; \
  724. case 0x01:RORB(*earb,val,LoadRb,SaveRb);break; \
  725. case 0x02:RCLB(*earb,val,LoadRb,SaveRb);break; \
  726. case 0x03:RCRB(*earb,val,LoadRb,SaveRb);break; \
  727. case 0x04:/* SHL and SAL are the same */ \
  728. case 0x06:SHLB(*earb,val,LoadRb,SaveRb);break; \
  729. case 0x05:SHRB(*earb,val,LoadRb,SaveRb);break; \
  730. case 0x07:SARB(*earb,val,LoadRb,SaveRb);break; \
  731. } \
  732. } else { \
  733. GetEAa; \
  734. Bit8u val=blah & 0x1f; \
  735. switch (which) { \
  736. case 0x00:ROLB(eaa,val,Mem_Lodsb,Mem_Stosb);break; \
  737. case 0x01:RORB(eaa,val,Mem_Lodsb,Mem_Stosb);break; \
  738. case 0x02:RCLB(eaa,val,Mem_Lodsb,Mem_Stosb);break; \
  739. case 0x03:RCRB(eaa,val,Mem_Lodsb,Mem_Stosb);break; \
  740. case 0x04:/* SHL and SAL are the same */ \
  741. case 0x06:SHLB(eaa,val,Mem_Lodsb,Mem_Stosb);break; \
  742. case 0x05:SHRB(eaa,val,Mem_Lodsb,Mem_Stosb);break; \
  743. case 0x07:SARB(eaa,val,Mem_Lodsb,Mem_Stosb);break; \
  744. } \
  745. } \
  746. }
  747. #define GRP2W(blah) \
  748. { \
  749. GetRM;Bitu which=(rm>>3)&7; \
  750. if (rm >= 0xc0) { \
  751. GetEArw; \
  752. Bit8u val=blah & 0x1f; \
  753. switch (which) { \
  754. case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break; \
  755. case 0x01:RORW(*earw,val,LoadRw,SaveRw);break; \
  756. case 0x02:RCLW(*earw,val,LoadRw,SaveRw);break; \
  757. case 0x03:RCRW(*earw,val,LoadRw,SaveRw);break; \
  758. case 0x04:/* SHL and SAL are the same */ \
  759. case 0x06:SHLW(*earw,val,LoadRw,SaveRw);break; \
  760. case 0x05:SHRW(*earw,val,LoadRw,SaveRw);break; \
  761. case 0x07:SARW(*earw,val,LoadRw,SaveRw);break; \
  762. } \
  763. } else { \
  764. GetEAa; \
  765. Bit8u val=blah & 0x1f; \
  766. switch (which) { \
  767. case 0x00:ROLW(eaa,val,Mem_Lodsw,Mem_Stosw);break; \
  768. case 0x01:RORW(eaa,val,Mem_Lodsw,Mem_Stosw);break; \
  769. case 0x02:RCLW(eaa,val,Mem_Lodsw,Mem_Stosw);break; \
  770. case 0x03:RCRW(eaa,val,Mem_Lodsw,Mem_Stosw);break; \
  771. case 0x04:/* SHL and SAL are the same */ \
  772. case 0x06:SHLW(eaa,val,Mem_Lodsw,Mem_Stosw);break; \
  773. case 0x05:SHRW(eaa,val,Mem_Lodsw,Mem_Stosw);break; \
  774. case 0x07:SARW(eaa,val,Mem_Lodsw,Mem_Stosw);break; \
  775. } \
  776. } \
  777. }
  778. #define GRP2D(blah) \
  779. { \
  780. GetRM;Bitu which=(rm>>3)&7; \
  781. if (rm >= 0xc0) { \
  782. GetEArd; \
  783. Bit8u val=blah & 0x1f; \
  784. switch (which) { \
  785. case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break; \
  786. case 0x01:RORD(*eard,val,LoadRd,SaveRd);break; \
  787. case 0x02:RCLD(*eard,val,LoadRd,SaveRd);break; \
  788. case 0x03:RCRD(*eard,val,LoadRd,SaveRd);break; \
  789. case 0x04:/* SHL and SAL are the same */ \
  790. case 0x06:SHLD(*eard,val,LoadRd,SaveRd);break; \
  791. case 0x05:SHRD(*eard,val,LoadRd,SaveRd);break; \
  792. case 0x07:SARD(*eard,val,LoadRd,SaveRd);break; \
  793. } \
  794. } else { \
  795. GetEAa; \
  796. Bit8u val=blah & 0x1f; \
  797. switch (which) { \
  798. case 0x00:ROLD(eaa,val,Mem_Lodsd,Mem_Stosd);break; \
  799. case 0x01:RORD(eaa,val,Mem_Lodsd,Mem_Stosd);break; \
  800. case 0x02:RCLD(eaa,val,Mem_Lodsd,Mem_Stosd);break; \
  801. case 0x03:RCRD(eaa,val,Mem_Lodsd,Mem_Stosd);break; \
  802. case 0x04:/* SHL and SAL are the same */ \
  803. case 0x06:SHLD(eaa,val,Mem_Lodsd,Mem_Stosd);break; \
  804. case 0x05:SHRD(eaa,val,Mem_Lodsd,Mem_Stosd);break; \
  805. case 0x07:SARD(eaa,val,Mem_Lodsd,Mem_Stosd);break; \
  806. } \
  807. } \
  808. }
  809. /* let's hope bochs has it correct with the higher than 16 shifts */
  810. /* double-precision shift left has low bits in second argument */
  811. #define DSHLW(op1,op2,op3,load,save) \
  812. Bit8u val=op3 & 0x1F; \
  813. if (!val) break; \
  814. lf_var2b=val;lf_var1d=(load(op1)<<16)|op2; \
  815. Bit32u tempd=lf_var1d << lf_var2b; \
  816. if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16)); \
  817. lf_resw=(Bit16u)(tempd >> 16); \
  818. save(op1,lf_resw); \
  819. lflags.type=t_DSHLw;
  820. #define DSHLD(op1,op2,op3,load,save) \
  821. Bit8u val=op3 & 0x1F; \
  822. if (!val) break; \
  823. lf_var2b=val;lf_var1d=load(op1); \
  824. lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b)); \
  825. save(op1,lf_resd); \
  826. lflags.type=t_DSHLd;
  827. /* double-precision shift right has high bits in second argument */
  828. #define DSHRW(op1,op2,op3,load,save) \
  829. Bit8u val=op3 & 0x1F; \
  830. if (!val) break; \
  831. lf_var2b=val;lf_var1d=(op2<<16)|load(op1); \
  832. Bit32u tempd=lf_var1d >> lf_var2b; \
  833. if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b)); \
  834. lf_resw=(Bit16u)(tempd); \
  835. save(op1,lf_resw); \
  836. lflags.type=t_DSHRw;
  837. #define DSHRD(op1,op2,op3,load,save) \
  838. Bit8u val=op3 & 0x1F; \
  839. if (!val) break; \
  840. lf_var2b=val;lf_var1d=load(op1); \
  841. lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b)); \
  842. save(op1,lf_resd); \
  843. lflags.type=t_DSHRd;