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.

404 lines
8.3 KiB

  1. /* asmtab.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 <string.h>
  12. #include "asm86.h"
  13. #include "asmfcn.h"
  14. #include "asmopcod.h"
  15. #include "asmctype.h"
  16. #include "asmtab.h" /* common between asmtab.c and asmtabtb.c */
  17. extern struct pseudo FAR dir1tok[];
  18. extern struct pseudo FAR dir2tok[];
  19. extern struct opcentry FAR opctab[];
  20. extern UCHAR opprec[];
  21. extern KEYWORDS FAR t_siz_table;
  22. extern KEYWORDS FAR t_op_table;
  23. extern KEYWORDS FAR t_oc_table;
  24. extern KEYWORDS FAR t_seg_table;
  25. extern KEYWORDS FAR t_ps1_table;
  26. extern KEYWORDS FAR t_ps2_table;
  27. /*** fnsize - return size of operand
  28. *
  29. * flag = fnsize ();
  30. *
  31. * Entry naim = token to search for
  32. * Exit varsize = size of symbol
  33. * Returns TRUE if symbol found in size table
  34. * FALSE if symbol not found in size table
  35. * Calls none
  36. * Note 8/1/88 - MCH - Modified to perform text macro substitution.
  37. * This is a complete hack. iskey() is hardcoded to lookup
  38. * the string in naim, while symFet() sets symptr to the
  39. * symbol following the text macro expansion. Thus, lots of
  40. * contortions are necessary to get these routines to mesh.
  41. */
  42. /* size table */
  43. USHORT dirsize[] = {
  44. /* I_BYTE */ 1,
  45. /* I_DWORD */ 4,
  46. /* I_FAR */ CSFAR,
  47. /* I_NEAR */ CSNEAR,
  48. /* I_QWORD */ 8,
  49. /* I_TBYTE */ 10,
  50. /* I_WORD */ 2,
  51. /* I_FWORD */ 6,
  52. /* I_PROC */ CSNEAR
  53. };
  54. SHORT PASCAL CODESIZE
  55. fnsize ()
  56. {
  57. #ifdef FEATURE
  58. register USHORT v;
  59. if (*naim.pszName && ((v = iskey (&t_siz_table)) != NOTFOUND)) {
  60. varsize = dirsize[v];
  61. return (TRUE);
  62. }
  63. return (FALSE);
  64. #else
  65. register USHORT v;
  66. SYMBOL FARSYM * pSYsave;
  67. char * savelbufp, * savebegatom, * saveendatom;
  68. char szname[SYMMAX+1];
  69. FASTNAME saveInfo;
  70. char szSave[SYMMAX+1];
  71. if (*naim.pszName) {
  72. pSYsave = symptr;
  73. savelbufp = lbufp;
  74. savebegatom = begatom;
  75. saveendatom = endatom;
  76. memcpy (&saveInfo, &naim, sizeof( FASTNAME ) );
  77. memcpy (szSave, naim.pszName, SYMMAX + 1);
  78. if (symFet()) {
  79. STRNFCPY (szname, symptr->nampnt->id);
  80. lbufp = szname;
  81. getatom();
  82. }
  83. symptr = pSYsave;
  84. lbufp = savelbufp;
  85. begatom = savebegatom;
  86. endatom = saveendatom;
  87. if (*naim.pszName && ((v = iskey (&t_siz_table)) != NOTFOUND)) {
  88. varsize = dirsize[v];
  89. return (TRUE);
  90. }
  91. memcpy (naim.pszName, szSave, SYMMAX + 1);
  92. memcpy (&naim, &saveInfo, sizeof( FASTNAME ) );
  93. }
  94. return (FALSE);
  95. #endif
  96. }
  97. /*** fnPtr - find a type to a pointer or size and return a CV type
  98. *
  99. * flag = fnPtr (ptrSize)
  100. *
  101. * Entry token = token to search for
  102. * Exit CV - type
  103. */
  104. SHORT PASCAL CODESIZE
  105. fnPtr (
  106. SHORT sizePtr
  107. ){
  108. SYMBOL FARSYM *pSYtype, FARSYM *pT, FARSYM *pSY;
  109. SHORT fFarPtr;
  110. fFarPtr = sizePtr > wordsize;
  111. if (fnsize() || *naim.pszName == 0)
  112. return (typeFet(varsize) |
  113. makeType(0, ((fFarPtr)? BT_FARP: BT_NEARP), 0));
  114. pT = symptr;
  115. if (symsrch()) {
  116. pSY = symptr; /* restore old symptr */
  117. symptr = pT;
  118. if (pSY->symkind == STRUC) {
  119. if (fFarPtr) {
  120. if (pSY->symu.rsmsym.rsmtype.rsmstruc.typePtrFar)
  121. return(pSY->symu.rsmsym.rsmtype.rsmstruc.typePtrFar);
  122. }
  123. else if (pSY->symu.rsmsym.rsmtype.rsmstruc.typePtrNear)
  124. return(pSY->symu.rsmsym.rsmtype.rsmstruc.typePtrNear);
  125. /* Neither derived type is allocated, so make an allocation */
  126. pSYtype = (SYMBOL FARSYM *)falloc((SHORT)( &(((SYMBOL FARSYM *)0)->symu) ), "fnPtr" );
  127. if (pStrucCur)
  128. pStrucCur->alpha = pSYtype;
  129. else
  130. pStrucFirst = pSYtype;
  131. pStrucCur = pSYtype;
  132. pSYtype->attr = (unsigned char)fFarPtr;
  133. pSYtype->symkind = 0;
  134. pSYtype->alpha = 0;
  135. pSYtype->symtype = pSY->symu.rsmsym.rsmtype.rsmstruc.type;
  136. if (fFarPtr)
  137. pSY->symu.rsmsym.rsmtype.rsmstruc.typePtrFar = typeIndex;
  138. else
  139. pSY->symu.rsmsym.rsmtype.rsmstruc.typePtrNear = typeIndex;
  140. return(typeIndex++);
  141. }
  142. }
  143. return (FALSE);
  144. }
  145. /*** fnoper - search for operator
  146. *
  147. * flag = fnoper (token, type, prec);
  148. *
  149. * Entry token = token to search for
  150. * Exit opertype = type of operator
  151. * operprec = precedence of operator
  152. * Returns TRUE if token is an operator
  153. * FALSE if token is not an operator
  154. * Calls none
  155. */
  156. SHORT PASCAL CODESIZE
  157. fnoper ()
  158. {
  159. register USHORT v;
  160. if (*naim.pszName && ((v = iskey (&t_op_table)) != NOTFOUND)) {
  161. opertype = (char)v;
  162. operprec = opprec[v];
  163. return (TRUE);
  164. }
  165. return (FALSE);
  166. }
  167. /*** opcodesearch - search for opcode
  168. *
  169. * flag = opcodesearch ();
  170. *
  171. * Entry *naim.pszName = token to search for
  172. * cputype = cpu type (8086, 186, 286)
  173. * Exit opcbase = opcode base value
  174. * opctype = type of opcode
  175. * modrm = modrm value
  176. * Returns TRUE if token is an opcode
  177. * FALSE if token is not an opcode
  178. * Calls none
  179. */
  180. char PASCAL CODESIZE
  181. opcodesearch ()
  182. {
  183. register USHORT v;
  184. struct opcentry FAR *opc;
  185. UCHAR cputypeandprot;
  186. UCHAR opctabmask;
  187. int workaround;
  188. if (*naim.pszName && ((v = iskey (&t_oc_table)) != NOTFOUND)) {
  189. cputypeandprot = cputype & PROT;
  190. opctabmask = opctab[v].cpumask&PROT;
  191. workaround = cputypeandprot >= opctabmask ? 1 : 0;
  192. if (((cpu = (opc = &(opctab[v]))->cpumask) & cputype) &&
  193. workaround) {
  194. opcbase = opc->opcb;
  195. modrm = opc->mr;
  196. opctype = opc->opct;
  197. if (crefing) {
  198. fSecondArg = FALSE;
  199. switch (opctype) {
  200. case PJUMP:
  201. case PRELJMP:
  202. case PCALL:
  203. opcref = REF_XFER << 4 | REF_NONE;
  204. break;
  205. default:
  206. v = opc->cpumask;
  207. opcref = (char)((v&F_W)? REF_WRITE << 4: REF_READ << 4);
  208. opcref |= (v&S_W)? REF_WRITE: REF_READ;
  209. }
  210. }
  211. return (TRUE);
  212. }
  213. }
  214. return (FALSE);
  215. }
  216. /*** fnspar - return token index and type from table.
  217. *
  218. * flag = fnspar ();
  219. *
  220. * Entry naim = token to search for
  221. * Exit segtyp = type of segment
  222. * segidx = index of token in table
  223. * Returns TRUE if symbol found in size table
  224. * FALSE if symbol not found in size table
  225. * Calls iskey
  226. *
  227. * I spent several hours trying to debug through the silly
  228. * redundant level of indirection, so I removed it for the
  229. * index. this changes all the token numbers by 1, so they
  230. * are consistent. see accompanying change in asmdir:segalign
  231. * -Hans Apr 8 1986
  232. */
  233. SHORT PASCAL CODESIZE
  234. fnspar ()
  235. {
  236. register USHORT v;
  237. /* Must match IS_... in asmindex.h under "segment attributes.
  238. These values are the segment types put in the segdef OMF */
  239. static char tokseg[] = {
  240. /* IS_AT */ 0,
  241. /* IS_BYTE */ 1,
  242. /* IS_COMMON */ 6,
  243. /* IS_MEMORY */ 1,
  244. /* IS_PAGE */ 4,
  245. /* IS_PARA */ 3,
  246. /* IS_PUBLIC */ 2,
  247. /* IS_STACK */ 5,
  248. /* IS_WORD */ 2,
  249. /* IS_DWORD */ 5,
  250. /* IS_USE32 */ 0,
  251. /* IS_USE16 */ 0,
  252. };
  253. if (*naim.pszName && ((v = iskey (&t_seg_table)) != NOTFOUND)) {
  254. segtyp = tokseg[v];
  255. segidx = v;
  256. return (TRUE);
  257. }
  258. return (FALSE);
  259. }
  260. /*** fndir - return size of operand
  261. *
  262. * flag = fndir ();
  263. *
  264. * Entry naim = token to search for
  265. * Exit opty = size of symbol
  266. * opkind = kind of symbol
  267. * Returns TRUE if symbol found in size table
  268. * FALSE if symbol not found in size table
  269. * Calls none
  270. */
  271. SHORT PASCAL CODESIZE
  272. fndir ()
  273. {
  274. register USHORT v;
  275. if (*naim.pszName && ((v = iskey (&t_ps1_table)) != NOTFOUND)) {
  276. optyp = dir1tok[v].type;
  277. opkind = dir1tok[v].kind;
  278. return (TRUE);
  279. }
  280. return (FALSE);
  281. }
  282. /*** fndir2 - return type of directive
  283. *
  284. * flag = fndir2 ();
  285. * Entry naim = token to search for
  286. * Exit opty = size of symbol
  287. * opkind = kind of symbol
  288. *
  289. * Returns TRUE if symbol found in size table
  290. * FALSE if symbol not found in size table
  291. * Calls none
  292. */
  293. SHORT PASCAL CODESIZE
  294. fndir2 ()
  295. {
  296. register USHORT v;
  297. if (*naim.pszName && ((v = iskey (&t_ps2_table)) != NOTFOUND)) {
  298. optyp = dir2tok[v].type;
  299. opkind = dir2tok[v].kind;
  300. return (TRUE);
  301. }
  302. return (FALSE);
  303. }
  304. SHORT PASCAL CODESIZE
  305. checkRes()
  306. {
  307. USHORT v;
  308. xcreflag--;
  309. if (fCheckRes &&
  310. (((v = iskey (&t_oc_table)) != NOTFOUND &&
  311. (opctab[v].cpumask & cputype)) ||
  312. iskey (&t_ps1_table) != NOTFOUND ||
  313. iskey (&t_ps2_table) != NOTFOUND ||
  314. iskey (&t_op_table) != NOTFOUND ||
  315. iskey (&t_siz_table) != NOTFOUND ||
  316. /* iskey (&t_seg_table) != NOTFOUND || */
  317. (symsearch() && symptr->symkind == REGISTER) ||
  318. (naim.pszName[1] == 0 && (*naim.pszName == '$'||
  319. *naim.pszName == '%' || *naim.pszName == '?')))){
  320. errorn(E_RES);
  321. xcreflag++;
  322. return(TRUE);
  323. }
  324. xcreflag++;
  325. return(FALSE);
  326. }