OUTAS386.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:33k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. #include        <stdio.h>
  23. #include <ctype.h>
  24. #include        "expr.h"
  25. #include        "c.h"
  26. #include        "gen386.h"
  27. #include  "diag.h"
  28. int skipsize = 0;
  29. int addsize = 0;
  30. typedef struct muldiv {
  31. struct muldiv * link;
  32. long value;
  33. double floatvalue;
  34. int size;
  35. int label;
  36. } MULDIV;
  37. /*      variable initialization         */
  38. char segregs[] = "CSDSESFSGSSS";
  39. extern char outfile[];
  40. extern int prm_flat;
  41. extern SYM *currentfunc;
  42. extern int prm_cmangle;
  43. extern HASHREC **globalhash;
  44. extern int phiused;
  45. extern long nextlabel;
  46. extern FILE *outputFile;
  47. extern int global_flag;
  48. enum e_gt { nogen, bytegen, wordgen, longgen, floatgen, doublegen, longdoublegen, storagegen,srrefgen };
  49. enum e_sg { noseg, codeseg, dataseg,bssxseg,startupxseg,rundownxseg,cppxseg };
  50. extern int prm_asmfile;
  51. extern int prm_lines,prm_nasm;
  52. static struct slit *strtab;
  53. static int uses_float;
  54. MULDIV *muldivlink = 0;
  55. enum e_gt  gentype = nogen; /* Current DC type */
  56. enum e_sg  curseg = noseg; /* Current seg */
  57. int        outcol = 0; /* Curront col (roughly) */
  58. int newlabel;
  59. int needpointer;
  60. static int nosize = 0;
  61. static int phiput;
  62. /* List of opcodes
  63.  * This list MUST be in the same order as the op_ enums 
  64.  */
  65. ASMNAME oplst[] = { 
  66. { "reserved", op_reserved,0 },
  67. { "line#", op_reserved,0 },
  68. { "label", op_reserved,0 },
  69. { "flabel", op_reserved,0 },
  70. { "seq@", op_reserved,0 },
  71. { "db", op_reserved,0 },
  72. { "dd", op_reserved,0 },
  73. { "aaa", op_aaa,0 },
  74. { "aad", op_aad,0 },
  75. { "aam", op_aam,0 },
  76. { "aas", op_aas,0 },
  77. { "add", op_add,OPE_MATH },
  78. { "adc", op_adc,OPE_MATH },
  79. { "and", op_and,OPE_MATH },
  80. { "arpl", op_arpl,OPE_ARPL },
  81. { "bound", op_bound,OPE_BOUND },
  82. { "bsf", op_bsf,OPE_BITSCAN },
  83. { "bsr", op_bsr,OPE_BITSCAN },
  84. { "bswap",op_bswap,OPE_REG32 },
  85. { "btc", op_btc,OPE_BIT },
  86. { "bt", op_bt,OPE_BIT },
  87. { "bts", op_bts,OPE_BIT },
  88. { "call", op_call,OPE_CALL },
  89. { "cbw", op_cbw,0 },
  90. { "cwde", op_cwde,0 },
  91. { "cwd", op_cwd, 0 },
  92. { "cdq", op_cdq,0 },
  93. { "clc", op_clc,0 },
  94. { "cld", op_cld,0 },
  95. { "cli", op_cli,0 },
  96. { "clts", op_clts, 0 },
  97. { "cmc", op_cmc, 0 },
  98. { "cmp", op_cmp, OPE_MATH },
  99. { "cmps", op_cmps, OPE_CMPS },
  100. { "cmpsb", op_cmpsb, 0 },
  101. { "cmpsw", op_cmpsw, 0 },
  102. { "cmpsd", op_cmpsd, 0 },
  103. { "daa",op_daa,0 },
  104. { "das", op_das,0 },
  105. { "dec",op_dec, OPE_INCDEC},
  106. { "div", op_div, OPE_RM},
  107. { "enter", op_enter, OPE_ENTER},
  108. { "hlt", op_hlt, 0 },
  109. { "idiv", op_idiv, OPE_RM },
  110. { "imul", op_imul, OPE_IMUL },
  111. { "in", op_in, OPE_IN },
  112. { "inc", op_inc, OPE_INCDEC },
  113. { "ins", op_ins, OPE_INS },
  114. { "insb", op_insb, 0 },
  115. { "insw", op_insw, 0 },
  116. { "insd", op_insd, 0 },
  117. { "int" , op_int, OPE_IMM8 },
  118. { "into", op_into, 0 },
  119. { "invd", op_invd, 0 },
  120. { "iret", op_iret, 0},
  121. { "iretd", op_iretd, 0},
  122. { "ja", op_ja, OPE_RELBRA},
  123. { "jnbe", op_jnbe, OPE_RELBRA},
  124. { "jae", op_jae, OPE_RELBRA},
  125. { "jnb", op_jnb, OPE_RELBRA},
  126. { "jnc", op_jnc, OPE_RELBRA},
  127. { "jb", op_jb, OPE_RELBRA},
  128. { "jc", op_jc, OPE_RELBRA},
  129. { "jnae", op_jnae, OPE_RELBRA},
  130. { "jbe", op_jbe, OPE_RELBRA},
  131. { "jna", op_jna, OPE_RELBRA},
  132. { "jecxz", op_jecxz, OPE_RELBR8},
  133. { "je",op_je, OPE_RELBRA },
  134. { "jg",op_jg, OPE_RELBRA },
  135. { "jnle",op_jnle, OPE_RELBRA },
  136. { "jl",op_jl, OPE_RELBRA },
  137. { "jnge",op_jnge, OPE_RELBRA },
  138. { "jge", op_jge, OPE_RELBRA },
  139. { "jnl", op_jnl, OPE_RELBRA },
  140. { "jle", op_jle, OPE_RELBRA },
  141. { "jng", op_jng, OPE_RELBRA },
  142. { "jne", op_jne, OPE_RELBRA },
  143. { "jo", op_jo, OPE_RELBRA },
  144. { "jno", op_jno, OPE_RELBRA },
  145. { "jp", op_jp, OPE_RELBRA },
  146. { "jpe", op_jpe, OPE_RELBRA },
  147. { "jpo", op_jpo, OPE_RELBRA },
  148. { "js", op_js, OPE_RELBRA} ,
  149. { "jns", op_jns, OPE_RELBRA },
  150. { "jmp", op_jmp, OPE_JMP },
  151. { "lahf", op_lahf, 0 },
  152. { "lar", op_lar, OPE_REGRM },
  153. { "lds", op_lds, OPE_LOADSEG },
  154. { "les", op_les, OPE_LOADSEG },
  155. { "lfs", op_lfs, OPE_LOADSEG },
  156. { "lgs", op_lgs, OPE_LOADSEG },
  157. { "lss", op_lss, OPE_LOADSEG },
  158. { "lea", op_lea, OPE_REGRM },
  159. { "leave", op_leave, 0 },
  160. { "lgdt", op_lgdt, OPE_LGDT },
  161. { "lidt", op_lidt, OPE_LIDT },
  162. { "lldt", op_lldt, OPE_RM16 },
  163. { "lmsw", op_lmsw, OPE_RM16 },
  164. { "lock", op_lock, 0 },
  165. { "lods", op_lods, OPE_LODS },
  166. { "lodsb", op_lodsb, 0 },
  167. { "lodsw", op_lodsw, 0 },
  168. { "lodsd", op_lodsd, 0 },
  169. { "loop",op_loop, OPE_RELBR8 },
  170. { "loope",op_loope, OPE_RELBR8 },
  171. { "loopz",op_loopz, OPE_RELBR8 },
  172. { "loopne",op_loopne, OPE_RELBR8 },
  173. { "loopnz",op_loopnz, OPE_RELBR8 },
  174. { "lsl", op_lsl, OPE_REGRM },
  175. { "ltr", op_ltr, OPE_RM16 },
  176. { "mov", op_mov, OPE_MOV },
  177. { "movs", op_movs, OPE_MOVS },
  178. { "movsb", op_movsb, 0 },
  179. { "movsw", op_movsw, 0 },
  180. { "movsd", op_movsd, 0 },
  181. { "movsx", op_movsx, OPE_MOVSX} ,
  182. { "movzx", op_movzx, OPE_MOVSX} ,
  183. { "mul", op_mul, OPE_RM },
  184. { "neg", op_neg, OPE_RM },
  185. { "not", op_not, OPE_RM },
  186. { "nop", op_nop, 0 },
  187. { "or", op_or,OPE_MATH },
  188. { "out", op_out,OPE_OUT },
  189. { "outs", op_outs, OPE_OUTS },
  190. { "outsb", op_outsb, 0 },
  191. { "outsw", op_outsw, 0 },
  192. { "outsd", op_outsd, 0 },
  193. { "pop",op_pop, OPE_PUSHPOP },
  194. { "popa", op_popa, 0 },
  195. { "popad", op_popad, 0 },
  196. { "popf", op_popf, 0 },
  197. { "popfd", op_popfd, 0 },
  198. { "push",op_push, OPE_PUSHPOP },
  199. { "pusha", op_pusha, 0 },
  200. { "pushad", op_pushad, 0 },
  201. { "pushf", op_pushf, 0 },
  202. { "pushfd", op_pushfd, 0 },
  203. { "rcl", op_rcl, OPE_SHIFT },
  204. { "rcr", op_rcr, OPE_SHIFT },
  205. { "rol", op_rol, OPE_SHIFT },
  206. { "ror", op_ror, OPE_SHIFT },
  207. { "rep", op_rep, 0 },
  208. { "repne", op_repne, 0 },
  209. { "repe", op_repe, 0 },
  210. { "repnz", op_repnz, 0 },
  211. { "repz", op_repz, 0 },
  212. { "ret", op_ret, OPE_RET },
  213. { "sahf", op_sahf, 0 },
  214. { "sal", op_sal, OPE_SHIFT },
  215. { "sar", op_sar, OPE_SHIFT },
  216. { "shl", op_shl, OPE_SHIFT },
  217. { "shr", op_shr, OPE_SHIFT },
  218. { "sbb", op_sbb,OPE_MATH },
  219. { "scas", op_scas, OPE_SCAS },
  220. { "scasb", op_scasb, 0 },
  221. { "scasw", op_scasw, 0 },
  222. { "scasd", op_scasd, 0 },
  223. { "seta", op_seta, OPE_SET},
  224. { "setnbe", op_setnbe, OPE_SET},
  225. { "setae", op_setae, OPE_SET},
  226. { "setnb", op_setnb, OPE_SET},
  227. { "setnc", op_setnc, OPE_SET},
  228. { "setb", op_setb, OPE_SET},
  229. { "setc", op_setc, OPE_SET},
  230. { "setnae", op_setnae, OPE_SET},
  231. { "setbe", op_setbe, OPE_SET},
  232. { "setna", op_setna, OPE_SET},
  233. { "sete",op_sete, OPE_SET },
  234. { "setg",op_setg, OPE_SET },
  235. { "setnle",op_setnle, OPE_SET },
  236. { "setl",op_setl, OPE_SET },
  237. { "setnge",op_setnge, OPE_SET },
  238. { "setge", op_setge, OPE_SET },
  239. { "setnl", op_setnl, OPE_SET },
  240. { "setle", op_setle, OPE_SET },
  241. { "setng", op_setng, OPE_SET },
  242. { "setne", op_setne, OPE_SET },
  243. { "seto", op_seto, OPE_SET },
  244. { "setno", op_setno, OPE_SET },
  245. { "setp", op_setp, OPE_SET },
  246. { "setpe", op_setpe, OPE_SET },
  247. { "setpo", op_setpo, OPE_SET },
  248. { "sets", op_sets, OPE_SET} ,
  249. { "setns", op_setns, OPE_SET },
  250. { "sgdt", op_sgdt, OPE_LGDT },
  251. { "sidt", op_sidt, OPE_LIDT },
  252. { "sldt", op_sldt, OPE_RM16 },
  253. { "smsw", op_smsw, OPE_RM16 },
  254. { "shld", op_shld, OPE_SHLD },
  255. { "shrd", op_shrd, OPE_SHLD },
  256. { "stc", op_stc, 0 },
  257. { "std", op_std, 0 },
  258. { "sti", op_sti, 0 },
  259. { "stos", op_stos, OPE_STOS },
  260. { "stosb", op_stosb, 0 },
  261. { "stosw", op_stosw, 0 },
  262. { "stosd", op_stosd, 0 },
  263. { "str", op_str, OPE_RM16 },
  264. { "sub", op_sub, OPE_MATH },
  265. { "test", op_test, OPE_TEST },
  266. { "verr", op_verr, OPE_RM16 },
  267. { "verw", op_verw, OPE_RM16 },
  268. { "wait", op_wait, 0 },
  269. { "wbinvd", op_wbinvd, 0 },
  270. { "xchg", op_xchg, OPE_XCHG },
  271. { "xlat", op_xlat, OPE_XLAT },
  272. { "xlatb", op_xlatb, 0 },
  273. { "xor", op_xor,OPE_MATH },
  274. { "f2xm1", op_f2xm1, 0 },
  275. { "fabs", op_fabs, 0 },
  276. { "fadd", op_fadd, OPE_FMATH },
  277. { "faddp", op_faddp, OPE_FMATHP },
  278. { "fiadd", op_fiadd, OPE_FMATHI },
  279. { "fchs", op_fchs, 0 },
  280. { "fclex", op_fclex, 0 },
  281. { "fnclex", op_fnclex, 0 },
  282. { "fcom", op_fcom, OPE_FCOM },
  283. { "fcomp", op_fcomp, OPE_FCOM },
  284. { "fcompp", op_fcompp, 0 },
  285. { "fcos", op_fcos, 0 },
  286. { "fdecstp", op_fdecstp, 0 },
  287. { "fdiv", op_fdiv, OPE_FMATH },
  288. { "fdivp", op_fdivp, OPE_FMATHP },
  289. { "fidiv", op_fidiv, OPE_FMATHI },
  290. { "fdivr", op_fdivr, OPE_FMATH },
  291. { "fdivrp", op_fdivrp, OPE_FMATHP },
  292. { "fidivr", op_fidivr, OPE_FMATHI },
  293. { "ffree", op_ffre, OPE_FREG },
  294. { "ficom", op_ficom, OPE_FICOM },
  295. { "ficomp", op_ficomp, OPE_FICOM },
  296. { "fild", op_fild, OPE_FILD },
  297. { "fincstp", op_fincstp, 0 },
  298. { "finit", op_finit, 0 },
  299. { "fninit", op_fninit, 0 },
  300. { "fist", op_fist, OPE_FIST },
  301. { "fistp", op_fistp, OPE_FILD },
  302. { "fld", op_fld, OPE_FLD },
  303. { "fldz", op_fldz, 0},
  304. { "fldpi", op_fldpi, 0},
  305. { "fld1", op_fld1, 0},
  306. { "fldl2t", op_fld2t, 0},
  307. { "fldl2e", op_fld2e, 0},
  308. { "fldlg2", op_fldlg2, 0},
  309. { "fldln2", op_fldln2, 0},
  310. { "fldcw", op_fldcw, OPE_M16 },
  311. { "fldsw", op_fldsw, OPE_M16 },
  312. { "fldenv", op_fldenv, OPE_MN },
  313. { "fmul", op_fmul, OPE_FMATH},
  314. { "fmulp", op_fmulp, OPE_FMATHP},
  315. { "fimul", op_fimul, OPE_FMATHI },
  316. { "fpatan", op_fpatan, 0 },
  317. { "fprem", op_fprem, 0 },
  318. { "fprem1", op_fprem1, 0 },
  319. { "fptan", op_fptan, 0 },
  320. { "frndint", op_frndint, 0 },
  321. { "frstor", op_frstor, OPE_MN },
  322. { "fsave", op_fsave, OPE_MN },
  323. { "fnsave", op_fnsave, OPE_MN },
  324. { "fscale", op_fscale, 0 },
  325. { "fsin", op_fsin, 0 },
  326. { "fsincos", op_fsincos, 0 },
  327. { "fsqrt", op_fsqrt, 0 },
  328. { "fst", op_fst, OPE_FST},
  329. { "fstp", op_fstp, OPE_FSTP},
  330. { "fstcw", op_fstcw, OPE_M16},
  331. { "fstsw", op_fstsw, OPE_M16},
  332. { "fnstcw", op_fnstcw, OPE_M16},
  333. { "fnstsw", op_fnstsw, OPE_M16},
  334. { "fstenv", op_fstenv, OPE_MN },
  335. { "fnstenv", op_fsntenv, OPE_MN },
  336. { "fsub", op_fsub, OPE_FMATH},
  337. { "fsubp", op_fsubp, OPE_FMATHP},
  338. { "fisub", op_fisub, OPE_FMATHI},
  339. { "fsubr", op_fsubr, OPE_FMATH},
  340. { "fsubrp", op_fsubrp, OPE_FMATHP},
  341. { "fisubr", op_fisubr, OPE_FMATHI},
  342. { "ftst", op_ftst, 0},
  343. { "fucom", op_fucom, OPE_FUCOM },
  344. { "fucomp", op_fucomp, OPE_FUCOM },
  345. { "fucompp", op_fucompp, 0 },
  346. { "fwait", op_fwait, 0 },
  347. { "fxam", op_fxam, 0 },
  348. { "fxch", op_fxch, OPE_FXCH },
  349. { "fxtract", op_fxtract, 0 },
  350. { "fyl2x", op_fyl2x, 0 },
  351. { "fyl2xp1", op_fyl2xp1, 0 },
  352. {0,0,0 },
  353. };
  354. /* Init module */
  355. void outcodeini(void)
  356. {
  357. strtab = 0;
  358. gentype = nogen;
  359. curseg = noseg;
  360. outcol = 0;
  361. newlabel = FALSE;
  362. phiput = FALSE;
  363. }
  364. void nl(void)
  365. /*
  366.  * New line
  367.  */
  368. {    if (prm_asmfile) {
  369.        if(outcol > 0) {
  370.                 fputc('n',outputFile);
  371.                 outcol = 0;
  372.                 gentype = nogen;
  373.                 }
  374.  if (phiused && !phiput)
  375. fputc(0x1f,outputFile);
  376.  }
  377. }
  378. /* Put an opcode
  379.  */
  380. void outop(char *name)
  381. {
  382. fputc('t',outputFile);
  383. while (*name)
  384. fputc(toupper(*name++),outputFile);
  385. }
  386. void putop(enum e_op op)
  387. {    
  388. if (prm_nasm) {   
  389.    skipsize =  (op == op_lea);
  390.    addsize = (op == op_push);
  391. if (op == op_fwait) {
  392. /* NASM uses WAIT instead of FWAIT */
  393. outop(oplst[op_fwait].word+1);
  394. return;
  395. }
  396. }
  397. if (op > op_fyl2xp1)
  398.     DIAG("illegal opcode.");
  399. else
  400. outop(oplst[op].word);
  401. uses_float=(op >=op_f2xm1);
  402. }
  403. void putconst(ENODE *offset)
  404. /*
  405.  *      put a constant to the outputFile file.
  406.  */
  407. {       switch( offset->nodetype )
  408.                 {
  409. case en_autoreg:
  410.                 case en_autocon:
  411.                 case en_icon:
  412.                 case en_lcon:
  413.                 case en_iucon:
  414.                 case en_lucon:
  415.                 case en_ccon:
  416. case en_absacon:
  417.                         fprintf(outputFile,"0%lXH",offset->v.i);
  418.                         break;
  419. case en_rcon:
  420. case en_fcon:
  421. case en_lrcon:
  422. fprintf(outputFile,"%f",offset->v.f);
  423. break;
  424.                 case en_labcon:
  425.                 case en_nalabcon:
  426. /* if (!prm_nasm && !prm_flat)
  427. fprintf(outputFile,"CS:");
  428. */                        fprintf(outputFile,"L_%d",offset->v.i);
  429.                         break;
  430. case en_napccon:
  431.                 case en_nacon:
  432.                         fprintf(outputFile,"%s",offset->v.p[0]);
  433.                         break;
  434.                 case en_add:
  435.                         putconst(offset->v.p[0]);
  436.                         fprintf(outputFile,"+");
  437.                         putconst(offset->v.p[1]);
  438.                         break;
  439.                 case en_sub:
  440.                         putconst(offset->v.p[0]);
  441.                         fprintf(outputFile,"-");
  442.                         putconst(offset->v.p[1]);
  443.                         break;
  444.                 case en_uminus:
  445.                         fprintf(outputFile,"-");
  446.                         putconst(offset->v.p[0]);
  447.                         break;
  448.                 default:
  449.                         DIAG("illegal constant node.");
  450.                         break;
  451.                 }
  452. }
  453. void putlen(int l)
  454. /*
  455.  *      append the length field to an instruction.
  456.  */
  457. if (l!= 10 && l != 8 && l != 6 && l != 4 && l != 1 && l != 2 && l != 0)
  458.      DIAG("illegal length field.");
  459. }
  460. void putsizedreg(char *string, int reg, int size)
  461. {
  462. static char *byteregs[] = { "AL","CL","DL","BL","AH","CH","DH","BH" };
  463. static char *wordregs[] = { "AX", "CX", "DX","BX","SP","BP","SI","DI"  };
  464. static char *longregs[] = { "EAX", "ECX", "EDX","EBX","ESP","EBP","ESI","EDI" };
  465.   if (size == 4)
  466. fprintf(outputFile,string,longregs[reg]);
  467. else if (size == 1)
  468. fprintf(outputFile,string,byteregs[reg]);
  469. else
  470. fprintf(outputFile,string,wordregs[reg]);
  471. }
  472. void pointersize(int size)
  473. {
  474. if (prm_nasm && skipsize)
  475. return;
  476. /* if (needpointer)
  477. */ switch (size) {
  478. case 10:
  479. fprintf(outputFile,"TBYTE ");
  480. break;
  481. case 8:                      
  482.         fprintf(outputFile,"QWORD ");
  483. break;
  484. case 6:
  485. if (!uses_float) {
  486. fprintf(outputFile,"FWORD ");
  487. break;
  488. }
  489. case 4:                      
  490. fprintf(outputFile,"DWORD ");
  491. break;
  492. case 2:
  493. fprintf(outputFile,"WORD ");
  494. break;
  495. case 1:
  496. fprintf(outputFile,"BYTE ");
  497. break;
  498. default:
  499. DIAG("Bad pointer");
  500. }
  501. if (!prm_nasm)
  502. fprintf(outputFile,"PTR ");
  503. }
  504. void putseg(int seg, int usecolon)
  505. {
  506. if (!seg)
  507. return;
  508. seg-=1;
  509. seg<<=1;
  510. fputc(segregs[seg], outputFile);
  511. fputc(segregs[seg+1], outputFile);
  512.   if (usecolon)
  513. fputc(':', outputFile);
  514. }
  515. void putamode(AMODE *ap)
  516. /*
  517.  *      output a general addressing mode.
  518.  */
  519. { int oldnasm, l;
  520.        switch( ap->mode )
  521.                 {
  522. case am_seg:
  523. putseg(ap->seg,0);
  524. break;
  525. case am_screg:
  526. fprintf(outputFile,"CR%d",ap->preg);
  527. break;
  528. case am_sdreg:
  529. fprintf(outputFile,"DR%d",ap->preg);
  530. break;
  531. case am_streg:
  532. fprintf(outputFile,"TR%d",ap->preg);
  533. break;
  534.                 case am_immed:
  535. if (ap->length && (ap->offset->nodetype == en_labcon 
  536. || ap->offset->nodetype == en_nacon || ap->offset->nodetype == en_nalabcon
  537. || ap->offset->nodetype == en_napccon)) {
  538. if (!prm_nasm)
  539. fprintf(outputFile,"OFFSET ");
  540.   else
  541. if (!nosize) 
  542. fprintf(outputFile,"DWORD ");
  543. }
  544. else
  545. if (prm_nasm && addsize)
  546. pointersize(ap->length);
  547.                         putconst(ap->offset);
  548. break;
  549.                 case am_direct:
  550. pointersize(ap->length);
  551. putseg(ap->seg,TRUE);
  552. /* if (!prm_flat)
  553. fprintf(outputFile,"DS:");
  554. */ fprintf(outputFile,"[");
  555. oldnasm = prm_nasm;
  556. prm_nasm = TRUE;
  557.                         putconst(ap->offset);
  558. fputc(']',outputFile);
  559. prm_nasm = oldnasm;
  560.                         break;
  561.                 case am_dreg:
  562. putsizedreg("%s",ap->preg,ap->length);
  563. break;
  564. case am_freg:
  565. fprintf(outputFile,"ST(%d)",ap->preg);
  566. break;
  567. case am_indisp:
  568. pointersize(ap->length);
  569. putseg(ap->seg,TRUE);
  570. putsizedreg("[%s",ap->preg,4);
  571. if (ap->offset) {
  572. fputc('+',outputFile);
  573. putconst(ap->offset);
  574. }
  575. fputc(']',outputFile);
  576. break;
  577. case am_indispscale: {
  578. int scale = 1,t=ap->scale;
  579. while (t--)
  580. scale <<=1;
  581. pointersize(ap->length);
  582. putseg(ap->seg,TRUE);
  583. if (ap->preg == -1)
  584. fputc('[',outputFile);
  585. else
  586. putsizedreg("[%s+",ap->preg,4);
  587. putsizedreg("%s",ap->sreg,4);
  588. if (scale != 1)
  589. fprintf(outputFile,"*%d",scale);
  590. if (ap->offset) {
  591. fputc('+',outputFile);
  592. putconst(ap->offset);
  593. }
  594. fputc(']',outputFile);
  595. }
  596. break;
  597.                 default:
  598.                         DIAG("illegal address mode.");
  599.                         break;
  600.                 }
  601. }
  602. void put_code(OCODE *cd)
  603. /*
  604.  *      outputFile a generic instruction.
  605.  */
  606. {       
  607. int op = cd->opcode,len=0,len2=0;
  608. AMODE *aps = cd->oper1,*apd = cd->oper2, *ap3 = cd->oper3;
  609. if (!prm_asmfile)
  610. return;
  611. if (op == op_line) {
  612. if (!prm_lines)
  613. return;
  614. fprintf(outputFile,";n; Line %d:t%sn;n",(int)apd,(char *)aps);
  615. return;
  616. }
  617. if (aps)
  618. len = aps->length;
  619. if (apd)
  620. len2 = apd->length;
  621. needpointer = (len != len2) || ((!aps || aps->mode !=am_dreg) && (!apd || apd->mode !=am_dreg));
  622. putop(op);
  623. if (prm_nasm && op >=op_ja && op <= op_jns)
  624. fprintf(outputFile,"tNEAR");
  625. switch (op) {
  626. case op_rep:
  627. case op_repz:
  628. case op_repe:
  629. case op_repnz:
  630. case op_repne:
  631. case op_lock:
  632. return;
  633. }
  634.     putlen(len);
  635.         if( aps != 0 ) {
  636.                 fprintf(outputFile,"t");
  637. if (op == op_dd)
  638. nosize = TRUE;
  639. putamode(aps);
  640. nosize = FALSE;
  641.                 if( apd != 0 ) 
  642.                         {
  643.                         fprintf(outputFile,",");
  644.                         putamode(apd);
  645.                         }
  646.                 if( ap3 != 0 ) 
  647.                         {
  648.                         fprintf(outputFile,",");
  649.                         putamode(ap3);
  650.                         }
  651. }
  652.   fprintf(outputFile,"n");
  653. }
  654. void gen_strlab(SYM *s)
  655. /*
  656.  *      generate a named label.
  657.  */
  658. {
  659. if (prm_asmfile)
  660. if (curseg == dataseg || curseg == bssxseg) {
  661. newlabel = TRUE;
  662.   fprintf(outputFile,"n%s",s->name);
  663. outcol = strlen(s->name)+1;
  664. }
  665. else
  666. if (currentfunc->pascaldefn) {
  667. char buf[100],*q=buf,*p=s->name;
  668. if (prm_cmangle)
  669. p++;
  670. while(*p)
  671. *q++=toupper(*p++);
  672. *q++ = 0;
  673.          fprintf(outputFile,"%s:n",buf);
  674. }
  675. else
  676.          fprintf(outputFile,"%s:n",s->name);
  677. }
  678. void put_label(int lab)
  679. /*
  680.  *      outputFile a compiler generated label.
  681.  */
  682. {
  683.        if (prm_asmfile)
  684. fprintf(outputFile,"L_%d:n",lab);
  685. }
  686. void put_staticlabel(long label)
  687. {
  688. if (prm_asmfile) {
  689. nl();
  690. if (curseg == dataseg || curseg == bssxseg) {
  691. newlabel = TRUE;
  692.   fprintf(outputFile,"nL_%ld",label);
  693. outcol = 8;
  694. }
  695. else
  696. fprintf(outputFile,"L_%ld:n",label);
  697. }
  698. }
  699. void genfloat(float val)
  700. /*
  701.  * Output a float value
  702.  */
  703. {  if (prm_asmfile)
  704.         if( gentype == floatgen && outcol < 60) {
  705.                 fprintf(outputFile,",%f",val);
  706.                 outcol += 8;
  707.                 }
  708.         else    {
  709. if (!newlabel)
  710. nl();
  711. else newlabel = FALSE;
  712.                 fprintf(outputFile,"tDDt%f",val);
  713.                 gentype = floatgen;
  714.                 outcol = 19;
  715.                 }
  716. }
  717. void gendouble(double val)
  718. /*
  719.  * Output a double value
  720.  */
  721. {  if (prm_asmfile)
  722.         if( gentype == doublegen && outcol < 60) {
  723.                 fprintf(outputFile,",%f",val);
  724.                 outcol += 8;
  725.                 }
  726.         else    {
  727. if (!newlabel)
  728. nl();
  729. else newlabel = FALSE;
  730.                 fprintf(outputFile,"tDQt%f",val);
  731.                 gentype = doublegen;
  732.                 outcol = 19;
  733.                 }
  734. }
  735. void genlongdouble(double val)
  736. /*
  737.  * Output a double value
  738.  */
  739. {  if (prm_asmfile)
  740.         if( gentype == longdoublegen && outcol < 60) {
  741.                 fprintf(outputFile,",%f",val);
  742.                 outcol += 8;
  743.                 }
  744.         else    {
  745. if (!newlabel)
  746. nl();
  747. else newlabel = FALSE;
  748.                 fprintf(outputFile,"tDTt%f",val);
  749.                 gentype = longdoublegen;
  750.                 outcol = 19;
  751.                 }
  752. }
  753. int genstring(char *str, int uselong)
  754. /*
  755.  * Generate a string literal
  756.  */
  757. {
  758. if (uselong) {
  759. while  (*(short *)str) {
  760. genword(*((short *)str));
  761. str+=2;
  762. }
  763. return pstrlen(str)*2;
  764. }
  765. else {
  766. while (*str)
  767. genbyte(*str++);
  768. return strlen(str);
  769. }
  770. }
  771. void genbyte(long val)
  772. /*
  773.  * Output a byte value
  774.  */
  775. {  if (prm_asmfile)
  776.         if( gentype == bytegen && outcol < 60) {
  777.                 fprintf(outputFile,",0%XH",val & 0x00ff);
  778.                 outcol += 4;
  779.                 }
  780.         else    {
  781. if (!newlabel)
  782. nl();
  783. else newlabel = FALSE;
  784.                 fprintf(outputFile,"tDBt0%XH",val & 0x00ff);
  785.                 gentype = bytegen;
  786.                 outcol = 19;
  787.                 }
  788. }
  789. void genword(long val)
  790. /*
  791.  * Output a word value
  792.  */
  793. {     if (prm_asmfile)
  794.         if( gentype == wordgen && outcol < 58) {
  795.                 fprintf(outputFile,",0%XH",val & 0x0ffff);
  796.                 outcol += 6;
  797.                 }
  798.         else    {
  799. if (!newlabel)
  800. nl();
  801. else newlabel = FALSE;
  802.                 fprintf(outputFile,"tDWt0%XH",val & 0x0ffff);
  803.                 gentype = wordgen;
  804.                 outcol = 21;
  805.                 }
  806. }
  807. void genlong(long val)
  808. /*
  809.  * Output a long value
  810.  */
  811. {     if (prm_asmfile)
  812.         if( gentype == longgen && outcol < 56) {
  813.                 fprintf(outputFile,",0%lXH",val);
  814.                 outcol += 10;
  815.                 }
  816.         else    {
  817. if (!newlabel)
  818. nl();
  819. else newlabel = FALSE;
  820.                 fprintf(outputFile,"tDDt0%lXH",val);
  821.                 gentype = longgen;
  822.                 outcol = 25;
  823.                 }
  824. }
  825. void gensrref(SYM *sp, int val)
  826. {
  827. if (prm_asmfile)
  828.         if( gentype == srrefgen && outcol < 56) {
  829.                 fprintf(outputFile,",%s,%d",sp->name,val);
  830.                 outcol += strlen(sp->name)+1;
  831.                 }
  832.         else    {
  833.                 nl();
  834.                 fprintf(outputFile,"tDDt%s,%d",sp->name,val);
  835.                 gentype = srrefgen;
  836.                 outcol = 25;
  837.                 }
  838. }
  839. void genref(SYM *sp,int offset)
  840. /*
  841.  * Output a reference to the data area (also gens fixups )
  842.  */
  843. {       char    sign;
  844. char buf[40];
  845.         if( offset < 0) {
  846.                 sign = '-';
  847.                 offset = -offset;
  848.                 }
  849.         else
  850.                 sign = '+';
  851. sprintf(buf,"%s%c%d",sp->name,sign,offset);
  852. if (prm_asmfile) {
  853.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  854.                 fprintf(outputFile,",%s",buf);
  855.                 outcol += (11 + strlen(sp->name));
  856.                 }
  857.         else    {
  858. if (!newlabel)
  859. nl();
  860. else newlabel = FALSE;
  861.                 fprintf(outputFile,"tDDt%s",buf);
  862.                 outcol = 26 + strlen(sp->name);
  863.                 gentype = longgen;
  864.                 }
  865. }
  866. }
  867. void genpcref(SYM *sp,int offset)
  868. /*
  869.  * Output a reference to the code area (also gens fixups )
  870.  */
  871. {
  872. genref(sp,offset);
  873. }
  874. void genstorage(int nbytes)
  875. /*
  876.  * Output bytes of storage
  877.  */
  878. { if (prm_asmfile) {
  879. if (!newlabel)
  880. nl();
  881. else newlabel = FALSE;
  882. if (prm_nasm)
  883.          fprintf(outputFile,"tRESBt0%XH",nbytes);
  884. else
  885.          fprintf(outputFile,"tDBt0%XH DUP (?)",nbytes);
  886. outcol = 28;
  887. gentype = storagegen;
  888. }
  889. }
  890. void gen_labref(int n)
  891. /*
  892.  * Generate a reference to a label
  893.  */
  894. { if (prm_asmfile)
  895.         if( gentype == longgen && outcol < 58) {
  896.                 fprintf(outputFile,",L_%d",n);
  897.                 outcol += 6;
  898.                 }
  899.         else    {
  900. if (!newlabel)
  901. nl();
  902. else newlabel = FALSE;
  903.                 fprintf(outputFile,"tDDtL_%d",n);
  904.                 outcol = 22;
  905.                 gentype = longgen;
  906.                 }
  907. }
  908. int     stringlit(char *s, int uselong)
  909. /*
  910.  *      make s a string literal and return it's label number.
  911.  */
  912. {       struct slit     *lp;
  913.         ++global_flag;          /* always allocate from global space. */
  914.         lp = xalloc(sizeof(struct slit));
  915.         lp->label = nextlabel++;
  916. if (uselong) 
  917. lp->str = plitlate(s);
  918. else
  919.          lp->str = litlate(s);
  920.         lp->next = strtab;
  921. lp->type = uselong;
  922.         strtab = lp;
  923.         --global_flag;
  924.         return lp->label;
  925. }
  926. void dumplits(void)
  927. /*
  928.  *      dump the string literal pool.
  929.  */
  930. {
  931.         while( strtab != 0) {
  932.                 cseg();
  933.                 nl();
  934.                 put_label(strtab->label);
  935. genstring(strtab->str,strtab->type);
  936. if (strtab->type)
  937. genword(0);
  938. else
  939. genbyte(0);
  940.                 strtab = strtab->next;
  941.                 }
  942.         nl();
  943. }
  944. /*
  945.  * Exit if from a special segment
  946.  */
  947. void exitseg(void)
  948. {
  949. if (!prm_nasm) {
  950. if (curseg == startupxseg) {
  951. curseg = noseg;
  952. fprintf(outputFile,"cstartuptENDSn");
  953. }
  954. else if (curseg == rundownxseg) {
  955. curseg = noseg;
  956. fprintf(outputFile,"crundowntENDSn");
  957. }
  958. else if (curseg == cppxseg) {
  959. curseg = noseg;
  960. fprintf(outputFile,"cppinittENDSn");
  961. }
  962. }
  963. }
  964. /*
  965.  * Switch to cseg 
  966.  */
  967. void cseg(void)
  968. { if (prm_asmfile)
  969.         if( curseg != codeseg) {
  970.                 nl();
  971. exitseg();
  972. if (prm_nasm)
  973.                  fprintf(outputFile,"[SECTION .text]n");
  974. else
  975.                  fprintf(outputFile,"t.CODEn");
  976.                 curseg = codeseg;
  977.                 }
  978. }
  979. /*
  980.  * Switch to deseg
  981.  */
  982. void dseg(void)
  983. {     if (prm_asmfile)  
  984. if( curseg != dataseg) {
  985.                 nl();
  986. exitseg();
  987. if (prm_nasm)
  988.                  fprintf(outputFile,"[SECTION .data]n");
  989. else
  990.                  fprintf(outputFile,"t.DATAn");
  991.                 curseg = dataseg;
  992.                 }
  993. }
  994. /*
  995.  * Switch to bssseg
  996.  */
  997. void bssseg(void)
  998. {     if (prm_asmfile)  
  999. if( curseg != bssxseg) {
  1000.                 nl();
  1001. exitseg();
  1002. if (prm_nasm)
  1003.                  fprintf(outputFile,"[SECTION .bss]n");
  1004. else
  1005.                  fprintf(outputFile,"t.DATA?n");
  1006.                 curseg = bssxseg;
  1007.                 }
  1008. }
  1009. /*
  1010.  * Switch to startupseg
  1011.  */
  1012. void startupseg(void)
  1013. {     if (prm_asmfile)  
  1014. if( curseg != startupxseg) {
  1015.                 nl();
  1016. exitseg();
  1017. if (prm_nasm)
  1018.                  fprintf(outputFile,"[SECTION cstartup]n");
  1019. else
  1020.                  fprintf(outputFile,"cstartuptSEGMENT USE32 PUBLIC DWORD 42INITDATA42n");
  1021.                 curseg = startupxseg;
  1022.                 }
  1023. }
  1024. /*
  1025.  * Switch to rundownseg
  1026.  */
  1027. void rundownseg(void)
  1028. {     if (prm_asmfile)  
  1029. if( curseg != rundownxseg) {
  1030.                 nl();
  1031. exitseg();
  1032. if (prm_nasm)
  1033.                 fprintf(outputFile,"[SECTION crundown]n");
  1034. else
  1035.                  fprintf(outputFile,"crundowntSEGMENT USE32 PUBLIC DWORD 42EXITDATA42n");
  1036.                 curseg = rundownxseg;
  1037.                 }
  1038. }
  1039. void cppseg(void)
  1040. {     if (prm_asmfile)  
  1041. if( curseg != cppxseg) {
  1042.                 nl();
  1043. exitseg();
  1044. if (prm_nasm)
  1045.                  fprintf(outputFile,"[SECTION cppinit]n");
  1046. else
  1047.                  fprintf(outputFile,"cppinittSEGMENT USE32 PUBLIC DWORD 42CPPDATA42n");
  1048.                 curseg = cppxseg;
  1049.                 }
  1050. }
  1051. void gen_virtual(char *name)
  1052. {
  1053. if (prm_asmfile) {
  1054. nl();
  1055. fprintf(outputFile,"@%stSEGMENT VIRTUAL",name);
  1056. }
  1057. }
  1058. void gen_endvirtual(char *name)
  1059. {
  1060. if (prm_asmfile) {
  1061. nl();
  1062. fprintf(outputFile,"@%stENDS",name);
  1063. }
  1064. }
  1065. /*
  1066.  * Align
  1067.  */
  1068. void align(int size)
  1069. {
  1070. if (prm_asmfile) {
  1071. nl();
  1072. if (prm_nasm)
  1073. /* NASM 0.91 wouldn't let me use parenthesis but this should work
  1074.  * according to the documented precedence levels
  1075.  */
  1076. fprintf(outputFile,"tTIMES $$-$ & %d NOPn",3);
  1077. else
  1078. fprintf(outputFile,"tALIGNt%dn",4);
  1079. }
  1080. }
  1081. /* muldiv val init
  1082.  */
  1083. void init_muldivval(void)
  1084. {
  1085. muldivlink = 0;
  1086. }
  1087. /*
  1088.  * queue muldiv val
  1089.  */
  1090. void queue_muldivval(int label, long number)
  1091. {
  1092. MULDIV *p = xalloc(sizeof(MULDIV));
  1093. p->link = muldivlink;
  1094. p->value = number;
  1095. p->label = label;
  1096. p->size = 0;
  1097. muldivlink = p;
  1098. }
  1099. void queue_floatval(int label, double number, int size)
  1100. {
  1101. MULDIV *p = xalloc(sizeof(MULDIV));
  1102. p->link = muldivlink;
  1103. p->floatvalue = number;
  1104. p->label = label;
  1105. p->size = size;
  1106. muldivlink = p;
  1107. }
  1108. void dump_muldivval(void)
  1109. {
  1110. int tag = FALSE;
  1111. if (prm_asmfile) {
  1112. fprintf(outputFile,"n");
  1113. if (muldivlink) {
  1114. tag = TRUE;
  1115. align(4);
  1116. }
  1117. while (muldivlink) {
  1118. put_label(muldivlink->label);
  1119. if (muldivlink->size == 0)
  1120. fprintf(outputFile,"tDDt0%xHn",muldivlink->value);
  1121. else if (muldivlink->size == 6)
  1122. fprintf(outputFile,"tDDt%fn",muldivlink->floatvalue);
  1123. else if (muldivlink->size == 8)
  1124. fprintf(outputFile,"tDQt%fn",muldivlink->floatvalue);
  1125. else
  1126. fprintf(outputFile,"tDTt%fn",muldivlink->floatvalue);
  1127. muldivlink = muldivlink->link;
  1128. }
  1129. if (tag)
  1130. fprintf(outputFile,"n");
  1131. }
  1132. }
  1133. void asm_header(void)
  1134. {
  1135. nl();
  1136. if (prm_nasm)
  1137. fprintf(outputFile,"[BITS 32]nn");
  1138. else {
  1139. fprintf(outputFile,"tTITLEt'%s'n",outfile);
  1140. if (prm_flat)
  1141. fprintf(outputFile,"t.486pnt.MODEL FLATnn");
  1142. else
  1143. fprintf(outputFile,"t.486pnt.MODEL SMALLnn");
  1144. }
  1145. }
  1146. void globaldef(SYM *sp)
  1147. {
  1148. char buf[100],*q=buf,*p=sp->name;
  1149. if (curseg == codeseg && currentfunc->pascaldefn) {
  1150. if (prm_cmangle)
  1151. p++;
  1152. while(*p)
  1153. *q++=toupper(*p++);
  1154. *q++ = 0;
  1155. }
  1156. else
  1157. strcpy(buf,p);
  1158. if (prm_nasm)
  1159.       fprintf(outputFile,"[GLOBALt%s]n",buf);
  1160. else
  1161.       fprintf(outputFile,"tPUBLICt%sn",buf);
  1162. }
  1163. void putexterns(void)
  1164. /*
  1165.  * Output the fixup tables and the global/external list
  1166.  */
  1167. {       SYM     *sp;
  1168. int i;
  1169. if (prm_asmfile){
  1170. int notyet = TRUE;
  1171. nl();
  1172. exitseg();
  1173. for (i=0; i < HASHTABLESIZE; i++) {
  1174. if ((sp=(SYM *) globalhash[i]) != 0) {
  1175. while (sp) {
  1176.           if( sp->storage_class == sc_externalfunc && sp->extflag) {
  1177. char buf[100],*q=buf,*p=sp->name;
  1178. if (curseg == codeseg && sp->pascaldefn) {
  1179. if (prm_cmangle)
  1180. p++;
  1181. while(*p)
  1182. *q++=toupper(*p++);
  1183. *q++ = 0;
  1184. }
  1185. else
  1186. strcpy(buf,p);
  1187. if (prm_nasm) {
  1188.   if (notyet) {
  1189. fprintf(outputFile,"n[SECTION .text]n");
  1190. notyet = FALSE;
  1191. }
  1192.                  fprintf(outputFile,"[EXTERNt%s]n",buf);
  1193. }
  1194. else {
  1195.   if (notyet) {
  1196. fprintf(outputFile,"nt.CODEn");
  1197. notyet = FALSE;
  1198. }
  1199.                  fprintf(outputFile,"tEXTRNt%s:PROCn",buf);
  1200. }
  1201. }
  1202.           sp = sp->next;
  1203. }
  1204. }
  1205. }
  1206. notyet = TRUE;
  1207. for (i=0; i < HASHTABLESIZE; i++) {
  1208. if ((sp=(SYM *) globalhash[i]) != 0) {
  1209. while (sp) {
  1210.          if( sp->storage_class == sc_external && sp->extflag) {
  1211. char buf[100],*q=buf,*p=sp->name;
  1212. if (curseg == codeseg && sp->pascaldefn) {
  1213. if (prm_cmangle)
  1214. p++;
  1215. while(*p)
  1216. *q++=toupper(*p++);
  1217. *q++ = 0;
  1218. }
  1219. else
  1220. strcpy(buf,p);
  1221.   if (prm_nasm) {
  1222.   if (notyet) {
  1223. fprintf(outputFile,"n[SECTION .data]n");
  1224. notyet = FALSE;
  1225. }
  1226.                  fprintf(outputFile,"[EXTERNt%s]n",buf);
  1227.   }
  1228.   else {
  1229. if (notyet) {
  1230. fprintf(outputFile,"nt.DATAn");
  1231. notyet = FALSE;
  1232. }
  1233.                  fprintf(outputFile,"tEXTRNt%sn",buf);
  1234.   }
  1235. }
  1236.           sp = sp->next;
  1237. }
  1238. }
  1239. }
  1240. if (!prm_nasm)
  1241. fprintf(outputFile,"tENDn");
  1242. }
  1243. }