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

504 lines
11 KiB

  1. /* asmflt.c -- microsoft 80x86 assembler
  2. **
  3. ** microsoft (r) macro assembler
  4. ** copyright (c) microsoft corp 1986. all rights reserved
  5. **
  6. ** randy nevin
  7. **
  8. ** 10/90 - Quick conversion to 32 bit by Jeff Spencer
  9. */
  10. #include <stdio.h>
  11. #include "asm86.h"
  12. #include "asmfcn.h"
  13. #include "asmctype.h"
  14. #include "asmopcod.h"
  15. #define TOLOWER(c) (c | 0x20) /* works only for alpha inputs */
  16. /* Handle 8087 opcodes, they have the following types:
  17. Fnoargs: No arguments at all.
  18. F2memstk: 0-2 args; memory 4,8 byte | ST,ST(i) | ST(i),ST
  19. | blank( equiv ST )
  20. Fstks: ST(i),ST
  21. Fmemstk: memory 4,8 | ST | ST(i) | blank
  22. Fstk: ST(i)
  23. Fmem42: memory 4,8 byte
  24. Fmem842: memory 2,4,8 bytes
  25. Fmem4810 memory 4,8,10 bytes | ST(i)
  26. Fmem2: memory 2 byte
  27. Fmem14: memory 14 bytes( don't force size )
  28. Fmem94: memory 94 bytes( don't force size )
  29. Fwait: Noargs, output WAIT
  30. Fbcdmem: memory Bcd
  31. */
  32. /*** fltwait - output WAIT for 8087 instruction
  33. *
  34. * fltwait (p);
  35. *
  36. * Entry
  37. * Exit
  38. * Returns
  39. * Calls
  40. */
  41. VOID PASCAL CODESIZE
  42. fltwait (
  43. UCHAR fseg
  44. ){
  45. register SHORT idx;
  46. char override;
  47. register struct psop *pso;
  48. if (fltemulate) {
  49. idx = 0;
  50. /* Check for data and fixup space */
  51. if (pass2 && (emitcleanq ((UCHAR)(5)) || !fixroom (15)))
  52. emitdumpdata (0xA1); /* RN */
  53. if (opctype != FWAIT) {
  54. override = 0;
  55. if (fltdsc) {
  56. pso = &(fltdsc->dsckind.opnd);
  57. if ((idx = pso->seg) < NOSEG && idx != fseg)
  58. override = 1;
  59. }
  60. if (override)
  61. emitfltfix ('I',fltfixmisc[idx][0],&fltfixmisc[idx][1]);
  62. else
  63. emitfltfix ('I','D',&fltfixmisc[7][1]);
  64. }
  65. else {
  66. emitfltfix ('I','W', &fltfixmisc[8][1]);
  67. emitopcode(0x90);
  68. }
  69. }
  70. if (fltemulate || cputype&P86 || (cpu & FORCEWAIT)) {
  71. emitopcode (O_WAIT);
  72. if (fltemulate && override && idx)
  73. emitfltfix ('J',fltfixmisc[idx+3][0],&fltfixmisc[idx+3][1]);
  74. }
  75. }
  76. SHORT CODESIZE
  77. if_fwait()
  78. {
  79. /* if second byte of opcode is 'N', we don't generate fwait */
  80. return (TOLOWER(svname.pszName[1]) != 'n');
  81. }
  82. /*** fltmodrm - emit 8087 MODRM byte
  83. *
  84. * fltmodrm (base, p);
  85. *
  86. * Entry
  87. * Exit
  88. * Returns
  89. * Calls
  90. * Note The MODRM byte for 8087 opcode:
  91. * M M b b b R / M
  92. * M = mode, 3 is for non-memory 8087
  93. * b = base opcode. Together with ESC gives 6 bit opcode
  94. * R/M memory indexing type
  95. */
  96. VOID PASCAL CODESIZE
  97. fltmodrm (
  98. register USHORT base,
  99. struct fltrec *p
  100. ){
  101. register USHORT mod;
  102. mod = modrm;
  103. if (!fltdsc) {
  104. if (mod < 8)
  105. mod <<= 3;
  106. if (mod < 0xC0)
  107. mod += 0xC0;
  108. /* ST(i) mode */
  109. emitopcode ((UCHAR)(mod + base + p->stknum));
  110. }
  111. else {
  112. emitmodrm ((USHORT)fltdsc->dsckind.opnd.mode, (USHORT)(mod + base),
  113. fltdsc->dsckind.opnd.rm);
  114. emitrest (fltdsc);
  115. }
  116. }
  117. /*** fltscan - scan operands and build fltdsc
  118. *
  119. * fltscan (p);
  120. *
  121. * Entry
  122. * Exit
  123. * Returns
  124. * Calls
  125. */
  126. VOID PASCAL CODESIZE
  127. fltscan (
  128. register struct fltrec *p
  129. ){
  130. register struct psop *pso;
  131. p->args = FALSE;
  132. fltdsc = NULL;
  133. skipblanks ();
  134. if (ISTERM (PEEKC ())) {
  135. p->fseg = NOSEG;
  136. p->stknum = 1;
  137. }
  138. else {
  139. p->args = TRUE;
  140. p->fseg = DSSEG;
  141. fltdsc = expreval (&p->fseg);
  142. pso = &(fltdsc->dsckind.opnd);
  143. if (pso->mode == 3
  144. && !(pso->rm == 0 && opcbase == O_FSTSW && modrm == R_FSTSW
  145. && (cputype & (P286|P386))))
  146. errorc (E_IUR); /* Illegal use of reg */
  147. if (1 << FLTSTACK & pso->dtype) {
  148. /* Have ST or ST(i) */
  149. p->stknum = (USHORT)(pso->doffset & 7);
  150. if (pso->doffset > 7 || pso->dsign)
  151. /* # too big */
  152. errorc (E_VOR);
  153. if (pso->dsegment || pso->dcontext ||
  154. pso->dflag == XTERNAL || pso->mode != 4)
  155. /* Must have a constant */
  156. errorc (E_CXP);
  157. /* This means ST(i) */
  158. pso->mode = 3;
  159. oblititem (fltdsc);
  160. fltdsc = NULL;
  161. }
  162. else if (pso->mode == 4){
  163. /* pass1 error caused invalide mode assignment,
  164. map immdiate to direct, error on pass 2 */
  165. if (pass2)
  166. errorc(E_NIM);
  167. pso->mode = 2;
  168. if (wordsize == 4)
  169. pso->mode = 7;
  170. }
  171. }
  172. }
  173. /*** fltopcode - process 8087 opcode
  174. *
  175. * routine ();
  176. *
  177. * Entry
  178. * Exit
  179. * Returns
  180. * Calls
  181. */
  182. VOID PASCAL CODESIZE
  183. fltopcode ()
  184. {
  185. struct fltrec a;
  186. USHORT i;
  187. register struct psop *pso;
  188. /* Save opcode name */
  189. switchname ();
  190. a.stknum = 0;
  191. /* Scan 1st arg, if any */
  192. fltscan (&a);
  193. if (if_fwait() || (opcbase == O_FNOP && modrm == R_FNOP))
  194. fltwait (a.fseg);
  195. if (fltdsc){
  196. pso = &(fltdsc->dsckind.opnd);
  197. emit67(pso, NULL);
  198. }
  199. switch (opctype) {
  200. case FNOARGS:
  201. /* No args allowed */
  202. a.stknum = 0;
  203. if (opcbase == O_FSETPM && modrm == R_FSETPM) {
  204. if (!(cputype&PROT))
  205. errorcSYN ();
  206. }
  207. /* Output escape byte */
  208. emitopcode (opcbase);
  209. fltmodrm (0, &a);
  210. if (a.args)
  211. /* Operands not allowed */
  212. errorc (E_ECL);
  213. break;
  214. case FWAIT:
  215. a.stknum = 0;
  216. if (a.args)
  217. /* Operands not allowed */
  218. errorc (E_ECL);
  219. break;
  220. case FSTK:
  221. if (TOLOWER(svname.pszName[1]) == 'f' && !a.args) /* ffree w/o arg */
  222. errorc(E_MOP);
  223. /* Output Escape */
  224. emitopcode (opcbase);
  225. /* Modrm byte */
  226. fltmodrm (0, &a);
  227. if (fltdsc)
  228. /*Must be ST(i) */
  229. errorc (E_IOT);
  230. break;
  231. case FMEM42:
  232. case FMEM842:
  233. case FMEM2:
  234. case FMEM14:
  235. case FMEM94:
  236. case FBCDMEM:
  237. /* All use a memory operand. Some force size */
  238. if (fltemulate && !if_fwait())
  239. /* Can't emulate */
  240. errorc (E_7OE);
  241. if (!fltdsc)
  242. /* must have arg */
  243. errorc (E_IOT);
  244. else {
  245. emitescape (fltdsc, a.fseg);
  246. if (opctype == FMEM42) {
  247. /* Integer 2,4 byte */
  248. forcesize (fltdsc);
  249. if (pso->dsize == 4)
  250. /* 4 byte */
  251. emitopcode (opcbase);
  252. else {
  253. emitopcode ((UCHAR)(opcbase + 4));
  254. if (pso->dsize != 2)
  255. errorc (E_IIS);
  256. }
  257. }
  258. else if (opctype == FMEM842) {
  259. /* Int 8,4,2 */
  260. forcesize (fltdsc);
  261. if (pso->dsize == 2 || pso->dsize == 8)
  262. emitopcode ((UCHAR)(opcbase + 4));
  263. else {
  264. emitopcode (opcbase);
  265. if (pso->dsize != 4)
  266. errorc (E_IIS);
  267. }
  268. }
  269. else if ((opctype == FMEM2) || (opctype == FBCDMEM)) {
  270. if (opctype == FMEM2)
  271. if (pso->dsize != 2 && pso->dsize)
  272. errorc (E_IIS);
  273. else {
  274. if (cputype & (P286|P386) &&
  275. opcbase == O_FSTSW && modrm == R_FSTSW &&
  276. pso->mode == 3 && pso->rm == 0) {
  277. opcbase = O_FSTSWAX;
  278. modrm = R_FSTSWAX;
  279. }
  280. }
  281. else if (pso->dsize != 10 && pso->dsize )
  282. errorc (E_IIS);
  283. emitopcode (opcbase);
  284. }
  285. else
  286. emitopcode (opcbase);
  287. if ((pso->mode == 3 || pso->mode == 4) &&
  288. (opcbase != O_FSTSWAX || modrm != R_FSTSWAX))
  289. /* Only memory operands */
  290. errorc (E_IOT);
  291. if (opctype == FMEM842 && pso->dsize == 8)
  292. if (TOLOWER(svname.pszName[2]) == 'l')
  293. fltmodrm (5, &a);
  294. else
  295. fltmodrm (4, &a);
  296. else
  297. fltmodrm (0, &a);
  298. }
  299. break;
  300. case FSTKS:
  301. if (!a.args)
  302. /* Operand required */
  303. errorc (E_MOP);
  304. else if (fltdsc)
  305. /* Must be stack */
  306. errorc (E_IOT);
  307. else {
  308. /* ESC */
  309. emitopcode (opcbase);
  310. /* ST(i) */
  311. fltmodrm (0, &a);
  312. if (PEEKC () != ',')
  313. error (E_EXP,"comma");
  314. /* Must have 2 args */
  315. /* Get 2nd operand */
  316. SKIPC ();
  317. fltscan (&a);
  318. pso = NULL;
  319. if (!a.args || fltdsc)
  320. errorc (E_IOT);
  321. if (a.stknum)
  322. errorc (E_OCI);
  323. }
  324. break;
  325. case FMEM4810:
  326. /* Fwait */
  327. if (TOLOWER(svname.pszName[1]) == 'l')
  328. /* FLD */
  329. if (!fltdsc) {/* Have ST(i) */
  330. if (!a.args) /* fld w/o arg */
  331. errorc(E_MOP);
  332. emitopcode (opcbase);
  333. fltmodrm (0, &a);
  334. }
  335. else {
  336. /* Any segment override */
  337. emitescape (fltdsc, a.fseg);
  338. if (pso->dsize == 10) {
  339. /* Have temp real */
  340. emitopcode ((UCHAR)(opcbase + 2));
  341. fltmodrm (5, &a);
  342. }
  343. else {
  344. /* Have normal real */
  345. forcesize (fltdsc);
  346. if (pso->dsize == 8)
  347. emitopcode ((UCHAR)(opcbase + 4));
  348. else {
  349. emitopcode (opcbase);
  350. if (pso->dsize != 4)
  351. errorc (E_IOT);
  352. }
  353. fltmodrm (0, &a);
  354. }
  355. }
  356. else if (!fltdsc) {
  357. /* Have ST(i) */
  358. /* Have FSTP */
  359. if (!a.args)
  360. errorc( E_IOT );
  361. emitopcode ((UCHAR)(opcbase + 4));
  362. fltmodrm (0, &a);
  363. }
  364. else {
  365. emitescape (fltdsc, a.fseg);
  366. /* Any segment override */
  367. if (pso->dsize == 10) {
  368. /* Have temp real */
  369. emitopcode( (UCHAR)(opcbase + 2) );
  370. fltmodrm (4, &a);
  371. }
  372. else {
  373. /* Have normal real */
  374. forcesize (fltdsc);
  375. if (pso->dsize == 8)
  376. emitopcode( (UCHAR)(opcbase + 4) );
  377. else
  378. emitopcode (opcbase);
  379. fltmodrm (0, &a);
  380. }
  381. }
  382. break;
  383. case F2MEMSTK:
  384. if (!a.args) {
  385. /* Have ST(1),ST */
  386. emitopcode( (UCHAR)(opcbase + 6) );
  387. if ((i = modrm & 7) > 3)
  388. modrm = i^1;
  389. fltmodrm (0, &a);
  390. }
  391. else if (!fltdsc) {/* Have stacks */
  392. if (a.stknum == 0)
  393. emitopcode (opcbase);
  394. else {
  395. /* Might need to reverse R bit */
  396. if ((modrm & 7) > 3) /* Have FSUBx FDIVx */
  397. modrm ^= 1;
  398. emitopcode( (UCHAR)(opcbase + 4) );
  399. /* D bit is set */
  400. }
  401. /* Save in case ST(i) */
  402. a.stk1st = a.stknum;
  403. if (PEEKC () != ',')
  404. /* Must have , */
  405. error (E_EXP,"comma");
  406. /* Get 2nd operand */
  407. SKIPC ();
  408. fltscan (&a);
  409. if (fltdsc)
  410. /* not stack */
  411. errorc (E_IOT);
  412. if (a.args && a.stknum && a.stk1st)
  413. errorc (E_IOT);
  414. if (a.stk1st)
  415. a.stknum = a.stk1st;
  416. fltmodrm (0, &a);
  417. }
  418. else { /* Have real memory */
  419. forcesize (fltdsc);
  420. emitescape (fltdsc, a.fseg);
  421. if (pso->dsize == 8)
  422. emitopcode( (UCHAR)(opcbase + 4) );
  423. else {
  424. emitopcode (opcbase);
  425. if (pso->dsize != 4)
  426. errorc (E_IIS);
  427. }
  428. fltmodrm (0, &a);
  429. }
  430. break;
  431. case FMEMSTK:
  432. if (!fltdsc)/* Have ST(i) */
  433. if (TOLOWER(svname.pszName[1]) == 's') {
  434. /* Special case */
  435. if (!a.args)
  436. errorc( E_IOT );
  437. emitopcode( (UCHAR)(opcbase + 4) );
  438. }
  439. else
  440. emitopcode (opcbase);
  441. else {
  442. /* Have real memory */
  443. emitescape (fltdsc, a.fseg);
  444. forcesize (fltdsc);
  445. if (pso->dsize == 8)
  446. emitopcode( (UCHAR)(opcbase + 4) );
  447. else {
  448. emitopcode (opcbase);
  449. if (pso->dsize != 4)
  450. errorc (E_IOT);
  451. }
  452. }
  453. fltmodrm (0, &a);
  454. break;
  455. }
  456. if (fltdsc)
  457. oblititem (fltdsc);
  458. }