OUTAS68.C
Upload User: hlzzc88
Upload Date: 2007-01-06
Package Size: 220k
Code Size: 32k
Development Platform:

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        "gen68.h"
  27. #include  "diag.h"
  28. /*      variable initialization         */
  29. extern int global_flag;
  30. extern SYM *currentfunc;
  31. extern HASHREC **globalhash;
  32. extern OCODE *peep_insert, *peep_head, *peep_tail;
  33. extern int prm_rel;
  34. extern long nextlabel;
  35. extern FILE *outputFile;
  36. extern int prm_asmfile;
  37. extern int prm_lines;
  38. extern int phiused;
  39. extern int prm_cmangle;
  40. enum e_gt  gentype = nogen; /* Current DC type */
  41. enum e_sg  curseg = noseg; /* Current seg */
  42. int        outcol = 0; /* Curront col (roughly) */
  43. int   dataofs; /* Offset from last label */
  44. SYM *datasp; /* Symbol of last named label */
  45. static DATALINK *datahead, *datatail; /* links for fixup gen */
  46. static int phiput;
  47. ASMREG reglst[] = {
  48. { 0 , 0 , 0 },
  49. };
  50. /* List of opcodes
  51.  * This list MUST be in the same order as the op_ enums 
  52.  */
  53. ASMNAME oplst[] = {
  54. { "?reserved",op_reserved,0 },
  55. { "?line#",op_reserved,0 },
  56. { "?seq@",op_reserved,0 },
  57. { "?slit",op_reserved,0 },
  58. { "?label",op_reserved,0 },
  59. { "?flabel",op_reserved,0 },
  60. { "dc",op_reserved,0 },
  61. { "dc",op_reserved,0 },
  62. { "dc",op_reserved,0 },
  63. { "abcd",op_abcd,0 },
  64. { "add",op_add,0 },
  65. { "adda",op_adda,0 },
  66. { "addi",op_addi,0 },
  67. { "addq",op_addq,0 },
  68. { "addx",op_addx,0 },
  69. { "and",op_and,0 },
  70. { "andi",op_andi,0 },
  71. { "asl",op_asl,0 },
  72. { "asr",op_asr,0 },
  73. { "bra",op_bra,0 },
  74. { "beq",op_beq,0 },
  75. { "bne",op_bne,0 },
  76. { "blt",op_blt,0 },
  77. { "ble",op_ble,0 },
  78. { "bgt",op_bgt,0 },
  79. { "bge",op_bge,0 },
  80. { "bhi",op_bhi,0 },
  81. { "bhs",op_bhs,0 },
  82. { "blo",op_blo,0 },
  83. { "bls",op_bls,0 },
  84. { "bsr",op_bsr,0 },
  85. { "bcc", op_bcc,0 },
  86. { "bcs", op_bcs,0 },
  87. { "bmi", op_bmi,0 },
  88. { "bpl", op_bpl,0 },
  89. { "bvc", op_bvc,0 },
  90. { "bvs", op_bvs,0 },
  91. { "bchg",op_bchg,0 },
  92. { "bclr",op_bclr,0 },
  93. { "bfchg",op_bfchg,0 },
  94. { "bfclr",op_bfclr,0 },
  95. { "bfexts",op_bfexts,0 },
  96. { "bfextu",op_bfextu,0 },
  97. { "bfffo",op_bfffo,0 },
  98. { "bfins",op_bfins,0 },
  99. { "bfset",op_bfset,0 },
  100. { "bftst",op_bftst,0 },
  101. { "bkpt", op_bkpt,0 },
  102. { "bset",op_bset,0 },
  103. { "btst",op_btst,0 },
  104. { "chk",op_chk,0 },
  105. { "chk2",op_chk2,0 },
  106. { "clr",op_clr,0 },
  107. { "cmp",op_cmp,0 },
  108. { "cmpa",op_cmpa,0 },
  109. { "cmpi",op_cmpi,0 },
  110. { "cmpm",op_cmpm,0 },
  111. { "cmp2",op_cmp2,0 },
  112. { "dbeq",op_dbeq,0 },
  113. { "dbne",op_dbne,0 },
  114. { "dblt",op_dblt,0 },
  115. { "dble",op_dble,0 },
  116. { "dbgt",op_dbgt,0 },
  117. { "dbge",op_dbge,0 },
  118. { "dbhi",op_dbhi,0 },
  119. { "dbhs",op_dbhs,0 },
  120. { "dblo",op_dblo,0 },
  121. { "dbls",op_dbls,0 },
  122. { "dbsr",op_dbsr,0 },
  123. { "dbcc", op_dbcc,0 },
  124. { "dbcs", op_dbcs,0 },
  125. { "dbmi", op_dbmi,0 },
  126. { "dbpl", op_dbpl,0 },
  127. { "dbvc", op_dbvc,0 },
  128. { "dbvs", op_dbvs,0 },
  129. { "dbt", op_dbt,0 },
  130. { "dbf", op_dbf,0 },
  131. { "dbra",op_dbra,0 },
  132. { "divs",op_divs,0 },
  133. { "divu",op_divu,0 },
  134. { "divsl",op_divsl,0 },
  135. { "divul",op_divul,0 },
  136. { "eor",op_eor,0 },
  137. { "eori",op_eori,0 },
  138. { "exg",op_exg,0 },
  139. { "ext",op_ext,0 },
  140. { "extb",op_extb,0 },
  141. { "illegal", op_illegal, 0 },
  142. { "jmp",op_jmp,0 },
  143. { "jsr",op_jsr,0 },
  144. { "lea",op_lea,0 },
  145. { "link",op_link,0 },
  146. { "lsl",op_lsl,0 },
  147. { "lsr",op_lsr,0 },
  148. { "move",op_move,0 },
  149. { "movea",op_movea,0 },
  150. { "movec",op_movec,0 },
  151. { "movem",op_movem,0 },
  152. { "movep",op_movep,0 },
  153. { "moveq",op_moveq,0 },
  154. { "moves",op_moves,0 },
  155. { "muls",op_muls,0 },
  156. { "mulu",op_mulu,0 },
  157. { "nbcd",op_nbcd,0 },
  158. { "neg",op_neg,0 },
  159. { "negx",op_negx,0 },
  160. { "nop",op_nop,0 },
  161. { "not",op_not,0 },
  162. { "or",op_or,0 },
  163. { "ori",op_ori,0 },
  164. { "pack",op_pack,0 },
  165. { "pea",op_pea,0 },
  166. { "reset",op_reset,0 },
  167. { "rol",op_rol,0 },
  168. { "ror",op_ror,0 },
  169. { "roxl",op_roxl,0 },
  170. { "roxr",op_roxr,0 },
  171. { "rtd",op_rtd,0 },
  172. { "rte",op_rte,0 },
  173. { "rtr",op_rtr,0 },
  174. { "rts",op_rts,0 },
  175. { "sbcd",op_sbcd,0 },
  176. { "seteq",op_seteq,0 },
  177. { "setne",op_setne,0 },
  178. { "setlt",op_setlt,0 },
  179. { "setle",op_setle,0 },
  180. { "setgt",op_setgt,0 },
  181. { "setge",op_setge,0 },
  182. { "sethi",op_sethi,0 },
  183. { "seths",op_seths,0 },
  184. { "setlo",op_setlo,0 },
  185. { "setls",op_setls,0 },
  186. { "setsr",op_setsr,0 },
  187. { "setcc", op_setcc,0 },
  188. { "setcs", op_setcs,0 },
  189. { "setmi", op_setmi,0 },
  190. { "setpl", op_setpl,0 },
  191. { "setvc", op_setvc,0 },
  192. { "setvs", op_setvs,0 },
  193. { "sett", op_sett,0 },
  194. { "setf", op_setf,0 },
  195. { "sub",op_sub,0 },
  196. { "stop",op_stop,0 },
  197. { "suba",op_suba,0 },
  198. { "subi",op_subi,0 },
  199. { "subq",op_subq,0 },
  200. { "subx",op_subx,0 },
  201. { "swap",op_swap,0 },
  202. { "tas",op_tas,0 },
  203. { "trap",op_trap,0 },
  204. { "trapeq",op_trapeq,0 },
  205. { "trapne",op_trapne,0 },
  206. { "traplt",op_traplt,0 },
  207. { "traple",op_traple,0 },
  208. { "trapgt",op_trapgt,0 },
  209. { "trapge",op_trapge,0 },
  210. { "traphi",op_traphi,0 },
  211. { "traphs",op_traphs,0 },
  212. { "traplo",op_traplo,0 },
  213. { "trapls",op_trapls,0 },
  214. { "trapsr",op_trapsr,0 },
  215. { "trapcc", op_trapcc,0 },
  216. { "trapcs", op_trapcs,0 },
  217. { "trapmi", op_trapmi,0 },
  218. { "trappl", op_trappl,0 },
  219. { "trapvc", op_trapvc,0 },
  220. { "trapvs", op_trapvs,0 },
  221. { "trapt", op_trapt,0 },
  222. { "trapf", op_trapf,0 },
  223. { "trapv", op_trapv,0 },
  224. { "tst",op_tst,0 },
  225. { "unlk",op_unlk,0 },
  226. { "unpk",op_unpk,0 },
  227. { "fabs",op_fabs,0 },
  228. { "facos",op_facos,0 },
  229. { "fadd",op_fadd,0 },
  230. { "fasin",op_fasin,0 },
  231. { "fatan",op_fatan,0 },
  232. { "fatanh",op_fatanh,0 },
  233. { "fbeq", op_fbeq, 0 },
  234. { "fbne", op_fbne, 0 },
  235. { "fbgt", op_fbgt, 0 },
  236. { "fbngt", op_fbngt, 0 },
  237. { "fbge", op_fbge, 0 },
  238. { "fbnge", op_fbnge, 0 },
  239. { "fblt", op_fblt, 0 },
  240. { "fbnlt", op_fbnlt, 0 },
  241. { "fble", op_fble, 0 },
  242. { "fbnle", op_fbnle, 0 },
  243. { "fbgl", op_fbgl, 0 },
  244. { "fbngl", op_fbngl, 0 },
  245. { "fbgle", op_fbgle, 0 },
  246. { "fbngle", op_fbngle, 0 },
  247. { "fbogt", op_fbogt, 0 },
  248. { "fbule", op_fbule, 0 },
  249. { "fboge", op_fboge, 0 },
  250. { "fbult", op_fbult, 0 },
  251. { "fbolt", op_fbolt, 0 },
  252. { "fbuge", op_fbuge, 0 },
  253. { "fbole", op_fbole, 0 },
  254. { "fbugt", op_fbugt, 0 },
  255. { "fbogl", op_fbogl, 0 },
  256. { "fbueq", op_fbueq, 0 },
  257. { "fbor", op_fbor, 0 },
  258. { "fbun", op_fbun, 0 },
  259. { "fbt", op_fbt, 0 },
  260. { "fbf", op_fbf, 0 },
  261. { "fbst", op_fbst, 0 },
  262. { "fbsf", op_fbsf, 0 },
  263. { "fbseq", op_fbseq, 0 },
  264. { "fbsne", op_fbsne, 0 },
  265. { "fcmp",op_fcmp,0 },
  266. { "fcos",op_fcos,0 },
  267. { "fcosh",op_fcosh,0 },
  268. { "fdbeq", op_fdbeq, 0 },
  269. { "fdbne", op_fdbne, 0 },
  270. { "fdbgt", op_fdbgt, 0 },
  271. { "fdbngt", op_fdbngt, 0 },
  272. { "fdbge", op_fdbge, 0 },
  273. { "fdbnge", op_fdbnge, 0 },
  274. { "fdblt", op_fdblt, 0 },
  275. { "fdbnlt", op_fdbnlt, 0 },
  276. { "fdble", op_fdble, 0 },
  277. { "fdbnle", op_fdbnle, 0 },
  278. { "fdbgl", op_fdbgl, 0 },
  279. { "fdbngl", op_fdbngl, 0 },
  280. { "fdbgle", op_fdbgle, 0 },
  281. { "fdbngle", op_fdbngle, 0 },
  282. { "fdbogt", op_fdbogt, 0 },
  283. { "fdbule", op_fdbule, 0 },
  284. { "fdboge", op_fdboge, 0 },
  285. { "fdbult", op_fdbult, 0 },
  286. { "fdbolt", op_fdbolt, 0 },
  287. { "fdbuge", op_fdbuge, 0 },
  288. { "fdbole", op_fdbole, 0 },
  289. { "fdbugt", op_fdbugt, 0 },
  290. { "fdbogl", op_fdbogl, 0 },
  291. { "fdbueq", op_fdbueq, 0 },
  292. { "fdbor", op_fdbor, 0 },
  293. { "fdbun", op_fdbun, 0 },
  294. { "fdbt", op_fdbt, 0 },
  295. { "fdbf", op_fdbf, 0 },
  296. { "fdbst", op_fdbst, 0 },
  297. { "fdbsf", op_fdbsf, 0 },
  298. { "fdbseq", op_fdbseq, 0 },
  299. { "fdbsne", op_fdbsne, 0 },
  300. { "fdiv",op_fdiv,0 },
  301. { "fetox",op_fetox,0 },
  302. { "fetoxm1",op_fetoxm1,0 },
  303. { "fgetexp",op_fgetexp,0 },
  304. { "fgetman",op_fgetman,0 },
  305. { "fint",op_fint,0 },
  306. { "fintrz",op_fintrz,0 },
  307. { "flog10",op_flog10,0 },
  308. { "flog2",op_flog2,0 },
  309. { "flogn",op_flogn,0 },
  310. { "flognp1",op_flognp1,0 },
  311. { "fmod",op_fmod,0 },
  312. { "fmove",op_fmove,0 },
  313. { "fmovecr",op_fmovecr,0 },
  314. { "fmovem",op_fmovem,0 },
  315. { "fmul",op_fmul,0 },
  316. { "fneg",op_fneg,0 },
  317. { "fnop",op_fnop,0 },
  318. { "frem",op_frem,0 },
  319. { "fscale",op_fscale,0 },
  320. { "fseq", op_fseq, 0 },
  321. { "fsne", op_fsne, 0 },
  322. { "fsgt", op_fsgt, 0 },
  323. { "fsngt", op_fsngt, 0 },
  324. { "fsge", op_fsge, 0 },
  325. { "fsnge", op_fsnge, 0 },
  326. { "fslt", op_fslt, 0 },
  327. { "fsnlt", op_fsnlt, 0 },
  328. { "fsle", op_fsle, 0 },
  329. { "fsnle", op_fsnle, 0 },
  330. { "fsgl", op_fsgl, 0 },
  331. { "fsngl", op_fsngl, 0 },
  332. { "fsgle", op_fsgle, 0 },
  333. { "fsngle", op_fsngle, 0 },
  334. { "fsogt", op_fsogt, 0 },
  335. { "fsule", op_fsule, 0 },
  336. { "fsoge", op_fsoge, 0 },
  337. { "fsult", op_fsult, 0 },
  338. { "fsolt", op_fsolt, 0 },
  339. { "fsuge", op_fsuge, 0 },
  340. { "fsole", op_fsole, 0 },
  341. { "fsugt", op_fsugt, 0 },
  342. { "fsogl", op_fsogl, 0 },
  343. { "fsueq", op_fsueq, 0 },
  344. { "fsor", op_fsor, 0 },
  345. { "fsun", op_fsun, 0 },
  346. { "fst", op_fst, 0 },
  347. { "fsf", op_fsf, 0 },
  348. { "fsst", op_fsst, 0 },
  349. { "fssf", op_fssf, 0 },
  350. { "fsseq", op_fsseq, 0 },
  351. { "fssne", op_fssne, 0 },
  352. { "fsgldiv",op_fsgldiv,0 },
  353. { "fsglmul",op_fsglmul,0 },
  354. { "fsin",op_fsin,0 },
  355. { "fsincos",op_fsincos,0 },
  356. { "fsinh",op_fsinh,0 },
  357. { "fsqrt",op_fsqrt,0 },
  358. { "fsub",op_fsub,0 },
  359. { "ftan",op_ftan,0 },
  360. { "ftanh",op_ftanh,0 },
  361. { "ftentox",op_ftentox,0 },
  362. { "ftrapeq", op_ftrapeq, 0 },
  363. { "ftrapne", op_ftrapne, 0 },
  364. { "ftrapgt", op_ftrapgt, 0 },
  365. { "ftrapngt", op_ftrapngt, 0 },
  366. { "ftrapge", op_ftrapge, 0 },
  367. { "ftrapnge", op_ftrapnge, 0 },
  368. { "ftraplt", op_ftraplt, 0 },
  369. { "ftrapnlt", op_ftrapnlt, 0 },
  370. { "ftraple", op_ftraple, 0 },
  371. { "ftrapnle", op_ftrapnle, 0 },
  372. { "ftrapgl", op_ftrapgl, 0 },
  373. { "ftrapngl", op_ftrapngl, 0 },
  374. { "ftrapgle", op_ftrapgle, 0 },
  375. { "ftrapngle", op_ftrapngle, 0 },
  376. { "ftrapogt", op_ftrapogt, 0 },
  377. { "ftrapule", op_ftrapule, 0 },
  378. { "ftrapoge", op_ftrapoge, 0 },
  379. { "ftrapult", op_ftrapult, 0 },
  380. { "ftrapolt", op_ftrapolt, 0 },
  381. { "ftrapuge", op_ftrapuge, 0 },
  382. { "ftrapole", op_ftrapole, 0 },
  383. { "ftrapugt", op_ftrapugt, 0 },
  384. { "ftrapogl", op_ftrapogl, 0 },
  385. { "ftrapueq", op_ftrapueq, 0 },
  386. { "ftrapor", op_ftrapor, 0 },
  387. { "ftrapun", op_ftrapun, 0 },
  388. { "ftrapt", op_ftrapt, 0 },
  389. { "ftrapf", op_ftrapf, 0 },
  390. { "ftrapst", op_ftrapst, 0 },
  391. { "ftrapsf", op_ftrapsf, 0 },
  392. { "ftrapseq", op_ftrapseq, 0 },
  393. { "ftrapsne", op_ftrapsne, 0 },
  394. { "ftst",op_ftst,0 },
  395. { "ftwotox",op_ftwotox,0 },
  396. { 0,0,0 },
  397.  };
  398. /* Init module */
  399. void outcodeini(void)
  400. {
  401. gentype = nogen;
  402. curseg = noseg;
  403. outcol = 0;
  404. datahead = datatail = 0;   
  405. phiput = FALSE;
  406. }
  407. /*
  408.  * Register a fixup 
  409.  */
  410. void datalink(int flag)
  411. {
  412. DATALINK *p;
  413. if (!prm_rel)
  414. return;
  415. global_flag++; /* Global tab */
  416. p = xalloc(sizeof(DATALINK));
  417. p->sp = datasp;
  418. p->type = flag;
  419. p->offset = dataofs;
  420. p->next = 0;
  421. if (datahead) {
  422. datatail->next = p;
  423. datatail=datatail->next;
  424. }
  425. else
  426. datahead = datatail = p;
  427. global_flag--;
  428. }
  429. void nl(void)
  430. /*
  431.  * New line
  432.  */
  433. {    if (prm_asmfile) {
  434.        if(outcol > 0) {
  435.                 fputc('n',outputFile);
  436.                 outcol = 0;
  437.                 gentype = nogen;
  438.                 }
  439.  if (phiused && !phiput)
  440. fputc(0x1f,outputFile);
  441.  }
  442. }
  443. /* Put an opcode
  444.  */
  445. void outop(char *name)
  446. {
  447. fputc('t',outputFile);
  448. while (*name)
  449. fputc(toupper(*name++),outputFile);
  450. }
  451. void putop(int op)
  452. {       
  453. if (op > op_ftwotox)
  454.     DIAG("illegal opcode.");
  455. else
  456. outop(oplst[op].word);
  457. }
  458. void putconst(ENODE *offset)
  459. /*
  460.  *      put a constant to the outputFile file.
  461.  */
  462. {       switch( offset->nodetype )
  463.                 {
  464. case en_autoreg:
  465.                 case en_autocon:
  466.                 case en_icon:
  467.                 case en_lcon:
  468.                 case en_iucon:
  469.                 case en_lucon:
  470.                 case en_ccon:
  471. case en_absacon:
  472.                         fprintf(outputFile,"$%lX",offset->v.i);
  473. break;
  474. case en_rcon:
  475. case en_fcon:
  476. case en_lrcon:
  477. fprintf(outputFile,"%f",offset->v.f);
  478. break;
  479.                 case en_labcon:
  480.                 case en_nalabcon:
  481.                         fprintf(outputFile,"L_%ld",offset->v.i);
  482.                         break;
  483. case en_napccon:
  484.                 case en_nacon:
  485.                         fprintf(outputFile,"%s",offset->v.p[0]);
  486.                         break;
  487.                 case en_add:
  488.                         putconst(offset->v.p[0]);
  489.                         fprintf(outputFile,"+");
  490.                         putconst(offset->v.p[1]);
  491.                         break;
  492.                 case en_sub:
  493.                         putconst(offset->v.p[0]);
  494.                         fprintf(outputFile,"-");
  495.                         putconst(offset->v.p[1]);
  496.                         break;
  497.                 case en_uminus:
  498.                         fprintf(outputFile,"-");
  499.                         putconst(offset->v.p[0]);
  500.                         break;
  501.                 default:
  502.                         DIAG("illegal constant node.");
  503.                         break;
  504.                 }
  505. }
  506. void putlen(int l)
  507. /*
  508.  *      append the length field to an instruction.
  509.  */
  510. {       switch( l )
  511.                 {
  512.                 case 0:
  513.                         break;  /* no length field */
  514.                 case 1:
  515.                         fprintf(outputFile,".B");
  516.                         break;
  517.                 case 2:
  518.                         fprintf(outputFile,".W");
  519.                         break;
  520.                 case 4:
  521.                         fprintf(outputFile,".L");
  522.                         break;
  523. case 6:
  524. fprintf(outputFile,".S");
  525. break;
  526. case 8:
  527. fprintf(outputFile,".D");
  528. break;
  529. case 10:
  530. fprintf(outputFile,".X");
  531. break;
  532.                 default:
  533.                         DIAG("illegal length field.");
  534.                         break;
  535.                 }
  536. }
  537. void putamode(AMODE *ap)
  538. /*
  539.  *      outputFile a general addressing mode.
  540.  */
  541. {       int scale,t;
  542. switch( ap->mode )
  543.                 {
  544. case am_sr:
  545. fprintf(outputFile, "SR");
  546. break;
  547. case am_bf:
  548. fprintf(outputFile," {%d:%d}",ap->preg,ap->sreg);
  549. break;
  550. case am_divsl:
  551. fprintf(outputFile,"D%d:D%d",ap->preg, ap->sreg);
  552. break;
  553.                 case am_immed:
  554.                         fprintf(outputFile,"#");
  555.                 case am_direct:
  556.                         putconst(ap->offset);
  557.                         break;
  558.                 case am_adirect:
  559. fputc('(',outputFile);
  560.                         putconst(ap->offset);
  561. fputc(')',outputFile);
  562. putlen(ap->preg);
  563.                         break;
  564.                 case am_areg:
  565.                         fprintf(outputFile,"A%d",ap->preg);
  566.                         break;
  567.                 case am_dreg:
  568.                         fprintf(outputFile,"D%d",ap->preg);
  569.                         break;
  570. case am_freg:
  571. fprintf(outputFile,"FP%d",ap->preg);
  572. break;
  573.                 case am_ind:
  574.                         fprintf(outputFile,"(A%d)",ap->preg);
  575.                         break;
  576.                 case am_ainc:
  577.                         fprintf(outputFile,"(A%d)+",ap->preg);
  578.                         break;
  579.                 case am_adec:
  580.                         fprintf(outputFile,"-(A%d)",ap->preg);
  581.                         break;
  582.                 case am_indx:
  583.                         fprintf(outputFile,"(");
  584.                         putconst(ap->offset);
  585.                         fprintf(outputFile,",A%d)",ap->preg);
  586.                         break;
  587. case am_pcindx:
  588.                         fprintf(outputFile,"(");
  589.                         putconst(ap->offset);
  590.                         fprintf(outputFile,",PC)");
  591.                         break;
  592.                 case am_baseindxdata:
  593. scale = 1;
  594. t = ap->scale;
  595. while (t--)
  596. scale <<=1;
  597.                         fprintf(outputFile,"(");
  598.                         putconst(ap->offset);
  599. if (ap->preg != -1)
  600.                          fprintf(outputFile,",A%d",ap->preg);
  601.                         fprintf(outputFile,",D%d.L",ap->sreg);
  602. if (scale != 1)
  603. fprintf(outputFile,"*%d",scale);
  604. fputc(')', outputFile);
  605.                         break;
  606.                 case am_baseindxaddr:
  607. scale = 1;
  608. t = ap->scale;
  609. while (t--)
  610. scale <<=1;
  611.                         fprintf(outputFile,"(");
  612.                         putconst(ap->offset);
  613. if (ap->preg != -1)
  614.                          fprintf(outputFile,",A%d",ap->preg);
  615.                         fprintf(outputFile,",A%d.L",ap->sreg);
  616. if (scale != 1)
  617. fprintf(outputFile,"*%d",scale);
  618. fputc(')', outputFile);
  619.                         break;
  620.                 case am_mask:
  621.                         put_mask((int)ap->offset, ap->preg);
  622.                         break;
  623. case am_fmask:
  624.                         put_fmask((int)ap->offset, ap->preg);
  625.                         break;
  626.                 default:
  627.                         DIAG("illegal address mode.");
  628.                         break;
  629.                 }
  630. }
  631. void put_code(OCODE *cd)
  632. /*
  633.  *      outputFile a generic instruction.
  634.  */
  635. {    
  636. int op = cd->opcode,len = cd->length;
  637. AMODE *aps = cd->oper1,*apd = cd->oper2, *ape = cd->oper3;   
  638. nl();
  639. if (!prm_asmfile) {
  640. ;/* oc_putop(cd); */
  641. return;
  642. }
  643. if (op == op_line) {
  644. if (!prm_lines)
  645. return;
  646. fprintf(outputFile,";n; Line %d:t%sn;n",len,(char *)aps);
  647. return;
  648. }
  649. if (op == op_slit) {
  650. int l =genstring((char *)cd->oper1,(int)cd->oper2);
  651. if ((int)cd->oper2)
  652. genword(0);
  653. else {
  654. if (!(l & 1))
  655. genbyte(0);
  656. genbyte(0);
  657. }
  658. return;
  659. }
  660. if( op == op_dcl)
  661. {
  662. putop(op);
  663. putlen(len);
  664.       fprintf(outputFile,"t");
  665. putamode(aps);
  666. if (prm_rel)
  667. fprintf(outputFile,"-*");
  668.       fprintf(outputFile,"n");
  669. return;
  670. }
  671. else
  672. {
  673. putop(op);
  674.       putlen(len);
  675. }
  676.     if( aps != 0 )
  677.     {
  678.       fprintf(outputFile,"t");
  679. putamode(aps);
  680.       if( apd != 0 )
  681.       {
  682. if (apd->mode != am_bf)
  683.           fprintf(outputFile,",");
  684.         putamode(apd);
  685. if (ape) {
  686. if (ape->mode != am_bf)
  687. fprintf(outputFile,",");
  688. putamode(ape);
  689. }
  690.       }
  691.     }
  692.   fprintf(outputFile,"n");
  693. }
  694. void put_fmask(int mask, int reverse)
  695. /*
  696.  *      generate a register mask for floating restore and save.
  697.  */
  698. {
  699. unsigned put = FALSE,i,bit;
  700. if (!reverse) {
  701. bit = 0x80;
  702. for (i=0; i < 8; i++) {
  703. if (bit & (unsigned) mask) {
  704. if (put)
  705. fputc('/', outputFile);
  706. put = TRUE;
  707. putreg(i+16);
  708. }
  709.   bit >>= 1;
  710. }
  711. }
  712. else{
  713.   bit = 1;
  714. for (i=0; i < 8; i++) {
  715. if (bit & (unsigned)mask) {
  716. if (put)
  717. fputc('/', outputFile);
  718. put = TRUE;
  719. putreg(i+16);
  720. }
  721. bit <<= 1;
  722. }
  723. }
  724. }
  725. void put_mask(int mask, int reverse)
  726. /*
  727.  *      generate a register mask for integer restore and save.
  728.  */
  729. {
  730. unsigned put = FALSE,i,bit;
  731. if (!reverse) {
  732. bit = 0x8000;
  733. for (i=0; i < 16; i++) {
  734. if (bit & (unsigned) mask) {
  735. if (put)
  736. fputc('/', outputFile);
  737. put = TRUE;
  738. putreg(i);
  739. }
  740.   bit >>= 1;
  741. }
  742. }
  743. else{
  744.   bit = 1;
  745. for (i=0; i < 16; i++) {
  746. if (bit & (unsigned)mask) {
  747. if (put)
  748. fputc('/', outputFile);
  749. put = TRUE;
  750. putreg(i);
  751. }
  752. bit <<= 1;
  753. }
  754. }
  755. }
  756. void putreg(int r)
  757. /*
  758.  *      generate a register name from a tempref number.
  759.  */
  760. {       if( r < 8 )
  761.                 fprintf(outputFile,"D%d",r);
  762.         else if (r <16)
  763.                 fprintf(outputFile,"A%d",r - 8);
  764. else fprintf(outputFile,"FP%d",r-16);
  765. }
  766. void gen_strlab(SYM *sp)
  767. /*
  768.  *      generate a named label.
  769.  */
  770. {
  771. datasp = sp;
  772. if (prm_asmfile) {
  773. nl();
  774. if (curseg == codeseg && currentfunc->pascaldefn) {
  775. char buf[100],*q=buf,*p=sp->name;
  776. if (prm_cmangle)
  777. p++;
  778. while(*p)
  779. *q++=toupper(*p++);
  780. *q++ = 0;
  781.          fprintf(outputFile,"%s:n",buf);
  782. }
  783. else
  784.          fprintf(outputFile,"%s:n",sp->name);
  785. }
  786. else
  787. ;/* oc_namedlab(sp); */
  788. dataofs = 0;
  789. }
  790. void put_label(OCODE *cd)
  791. /*
  792.  *      outputFile a compiler generated label.
  793.  */
  794. {
  795.         if (prm_asmfile) {
  796. nl();
  797. fprintf(outputFile,"L_%ld:n",(long)(cd->oper1));
  798. }
  799. else
  800. ;/* oc_unnamedlab(cd); */
  801. }
  802. void put_staticlabel(long label)
  803. {
  804. if (prm_asmfile) {
  805. nl();
  806. fprintf(outputFile,"L_%ld:n",label);
  807. }
  808. }
  809. void genfloat(float val)
  810. /*
  811.  * Output a float value
  812.  */
  813. {  if (prm_asmfile)
  814.         if( gentype == floatgen && outcol < 60) {
  815.                 fprintf(outputFile,",%f",val);
  816.                 outcol += 8;
  817.                 }
  818.         else    {
  819.                 nl();
  820.                 fprintf(outputFile,"tDC.St%f",val);
  821.                 gentype = floatgen;
  822.                 outcol = 19;
  823.                 }
  824. else
  825. ;/* oc_genfloat(val); */
  826. dataofs+=4;
  827. }
  828. void gendouble(double val)
  829. /*
  830.  * Output a double value
  831.  */
  832. {  if (prm_asmfile)
  833.         if( gentype == doublegen && outcol < 60) {
  834.                 fprintf(outputFile,",%f",val);
  835.                 outcol += 8;
  836.                 }
  837.         else    {
  838.                 nl();
  839.                 fprintf(outputFile,"tDC.Dt%f",val);
  840.                 gentype = doublegen;
  841.                 outcol = 19;
  842.                 }
  843. else
  844. ;/* oc_gendouble(val); */
  845. dataofs+=8;
  846. }
  847. void genlongdouble(long double val)
  848. /*
  849.  * Output a double value
  850.  */
  851. {  if (prm_asmfile)
  852.         if( gentype == longdoublegen && outcol < 60) {
  853.                 fprintf(outputFile,",%f",val);
  854.                 outcol += 8;
  855.                 }
  856.         else    {
  857.                 nl();
  858.                 fprintf(outputFile,"tDTt%f",val);
  859.                 gentype = longdoublegen;
  860.                 outcol = 19;
  861.                 }
  862. else
  863. ;/* oc_genlongdouble(val); */
  864. dataofs+=8;
  865. }
  866. int genstring(char *str, int uselong)
  867. /*
  868.  * Generate a string literal
  869.  */
  870. {
  871. if (uselong) {
  872. while  (*(short *)str) {
  873. genword(*((short *)str));
  874. str += sizeof(short);
  875. }
  876. genword(0);
  877. return pstrlen(str)*2;
  878. }
  879. else {
  880. int size = 0;
  881. while (*str) {
  882. genbyte(*str++);
  883. size++;
  884. }
  885. return size;
  886. }
  887. }
  888. void genbyte(long val)
  889. /*
  890.  * Output a byte value
  891.  */
  892. {  if (prm_asmfile)
  893.         if( gentype == bytegen && outcol < 60) {
  894.                 fprintf(outputFile,",$%X",val & 0x00ff);
  895.                 outcol += 4;
  896.                 }
  897.         else    {
  898.                 nl();
  899.                 fprintf(outputFile,"tDC.Bt$%X",val & 0x00ff);
  900.                 gentype = bytegen;
  901.                 outcol = 19;
  902.                 }
  903. else
  904. ;/* oc_genbyte(val); */
  905. dataofs+=1;
  906. }
  907. void genword(long val)
  908. /*
  909.  * Output a word value
  910.  */
  911. {     if (prm_asmfile)
  912.         if( gentype == wordgen && outcol < 58) {
  913.                 fprintf(outputFile,",$%X",val & 0x0ffff);
  914.                 outcol += 6;
  915.                 }
  916.         else    {
  917.                 nl();
  918.                 fprintf(outputFile,"tDC.Wt$%X",val & 0x0ffff);
  919.                 gentype = wordgen;
  920.                 outcol = 21;
  921.                 }
  922. else
  923. ;/* oc_genword(val); */
  924. dataofs+=2;
  925. }
  926. void genlong(long val)
  927. /*
  928.  * Output a long value
  929.  */
  930. {     if (prm_asmfile)
  931.         if( gentype == longgen && outcol < 56) {
  932.                 fprintf(outputFile,",$%lX",val);
  933.                 outcol += 10;
  934.                 }
  935.         else    {
  936.                 nl();
  937.                 fprintf(outputFile,"tDC.Lt$%lX",val);
  938.                 gentype = longgen;
  939.                 outcol = 25;
  940.                 }
  941. else
  942. ;/* oc_genlong(val); */
  943. dataofs+=4;
  944. }
  945. /*
  946.  * Generate a startup or rundown reference
  947.  */
  948. void gensrref(SYM *sp,int val)
  949. {
  950. if (prm_asmfile)
  951.         if( gentype == srrefgen && outcol < 56) {
  952.                 fprintf(outputFile,",%s,%d",sp->name,val);
  953.                 outcol += strlen(sp->name)+1;
  954.                 }
  955.         else    {
  956.                 nl();
  957.                 fprintf(outputFile,"tDC.Lt%s,%d",sp->name,val);
  958.                 gentype = srrefgen;
  959.                 outcol = 25;
  960.                 }
  961. else 
  962. ;/* oc_gensrref(sp,val); */
  963. }
  964. void genref(SYM *sp,int offset)
  965. /*
  966.  * Output a reference to the data area (also gens fixups )
  967.  */
  968. {       char    sign;
  969. char buf[40];
  970.         if( offset < 0) {
  971.                 sign = '-';
  972.                 offset = -offset;
  973.                 }
  974.         else
  975.                 sign = '+';
  976. sprintf(buf,"%s%c%d",sp->name,sign,offset);
  977. datalink(FALSE);
  978. if (prm_asmfile) {
  979.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  980.                 fprintf(outputFile,",%s",buf);
  981.                 outcol += (11 + strlen(sp->name));
  982.                 }
  983.         else    {
  984.                 nl();
  985.                 fprintf(outputFile,"tDC.Lt%s",buf);
  986.                 outcol = 26 + strlen(sp->name);
  987.                 gentype = longgen;
  988.                 }
  989. }
  990. else
  991. ;/* oc_genref(sp,val); */
  992. dataofs+=4;
  993. }
  994. void genpcref(SYM *sp,int offset)
  995. /*
  996.  * Output a reference to the code area (also gens fixups )
  997.  */
  998. {       char    sign;
  999. char buf[40];
  1000.         if( offset < 0) {
  1001.                 sign = '-';
  1002.                 offset = -offset;
  1003.                 }
  1004.         else
  1005.                 sign = '+';
  1006. sprintf(buf,"%s%c%d",sp->name,sign,offset);
  1007. datalink(TRUE);
  1008. if (prm_asmfile) {
  1009.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  1010.                 fprintf(outputFile,",%s",buf);
  1011.                 outcol += (11 + strlen(sp->name));
  1012.                 }
  1013.         else    {
  1014.                 nl();
  1015.                 fprintf(outputFile,"tDC.Lt%s",buf);
  1016.                 outcol = 26 + strlen(sp->name);
  1017.                 gentype = longgen;
  1018.                 }
  1019. }
  1020. else
  1021. ;/* oc_genpcref(sp,val); */
  1022. dataofs+=4;
  1023. }
  1024. void genstorage(int nbytes)
  1025. /*
  1026.  * Output bytes of storage
  1027.  */
  1028. { if (prm_asmfile) {
  1029.         nl();
  1030.         fprintf(outputFile,"tDS.Bt$%Xn",nbytes);
  1031. }
  1032. else
  1033. ;/* oc_genstorage(nbytes); */
  1034. dataofs+=nbytes;
  1035. }
  1036. void gen_labref(int n)
  1037. /*
  1038.  * Generate a reference to a label
  1039.  */
  1040. { if (prm_asmfile)
  1041.         if( gentype == longgen && outcol < 58) {
  1042.                 fprintf(outputFile,",L_%d",n);
  1043.                 outcol += 6;
  1044.                 }
  1045.         else    {
  1046.                 nl();
  1047.                 fprintf(outputFile,"tDC.LtL_%d",n);
  1048.                 outcol = 22;
  1049.                 gentype = longgen;
  1050.                 }
  1051. else
  1052. ;/* oc_genlabref(n); */
  1053. datalink(TRUE);
  1054. dataofs+=4;
  1055. }
  1056. int     stringlit(char *s, int uselong)
  1057. /*
  1058.  *      make s a string literal and return it's label number.
  1059.  */
  1060. {       OCODE     *ip;
  1061. ip = xalloc(sizeof(OCODE));
  1062. ip->opcode = op_label;
  1063. ip->oper1 = (AMODE *)nextlabel;
  1064.         ip->back = 0;
  1065. if (!peep_head) 
  1066. peep_head = peep_tail = peep_insert = ip;
  1067. else {
  1068. if (peep_insert->fwd) {
  1069. peep_insert->fwd->back = ip;
  1070. }
  1071. ip->back = peep_insert;
  1072. ip->fwd = peep_insert->fwd;
  1073. if (peep_tail == peep_insert)
  1074. peep_tail = ip;
  1075. peep_insert = peep_insert->fwd = ip;
  1076. }
  1077.         ip = xalloc(sizeof(OCODE));
  1078. ip->opcode = op_slit;
  1079. if (uselong) {
  1080.          ip->oper1 = plitlate(s);
  1081. ip->oper2 = (AMODE *)1;
  1082. }
  1083. else {
  1084.          ip->oper1 = litlate(s);
  1085. ip->oper2 = 0;
  1086. }
  1087. if (peep_insert->fwd)
  1088. peep_insert->fwd->back = ip;
  1089. ip->back = peep_insert;
  1090. ip->fwd = peep_insert->fwd;
  1091. if (peep_tail == peep_insert)
  1092. peep_tail = ip;
  1093. peep_insert = peep_insert->fwd = ip;
  1094.         return nextlabel++;
  1095. }
  1096. void dumplits(void)
  1097. {
  1098. }
  1099. /*
  1100.  * Switch to cseg 
  1101.  */
  1102. void cseg(void)
  1103. { if (prm_asmfile)
  1104.         if( curseg != codeseg) {
  1105.                 nl();
  1106.                 fprintf(outputFile,"tSECTIONtcoden");
  1107.                 curseg = codeseg;
  1108.                 }
  1109. }
  1110. /*
  1111.  * Switch to dseg
  1112.  */
  1113. void dseg(void)
  1114. {     if (prm_asmfile)  
  1115. if( curseg != dataseg) {
  1116.                 nl();
  1117.                 fprintf(outputFile,"tSECTIONtdatan");
  1118.                 curseg = dataseg;
  1119.                 }
  1120. }
  1121. /*
  1122.  * Switch to bssseg
  1123.  */
  1124. void bssseg(void)
  1125. {     if (prm_asmfile)  
  1126. if( curseg != bssxseg) {
  1127.                 nl();
  1128.                 fprintf(outputFile,"tSECTIONtbssn");
  1129.                 curseg = bssxseg;
  1130.                 }
  1131. }
  1132. /*
  1133.  * Switch to startupseg
  1134.  */
  1135. void startupseg(void)
  1136. {     if (prm_asmfile)  
  1137. if( curseg != startupxseg) {
  1138.                 nl();
  1139.                 fprintf(outputFile,"tSECTIONtcstartupn");
  1140.                 curseg = startupxseg;
  1141.                 }
  1142. }
  1143. /*
  1144.  * Switch to rundownseg
  1145.  */
  1146. void rundownseg(void)
  1147. {     if (prm_asmfile)  
  1148. if( curseg != rundownxseg) {
  1149.                 nl();
  1150.                 fprintf(outputFile,"tSECTIONtcrundownn");
  1151.                 curseg = rundownxseg;
  1152.                 }
  1153. }
  1154. /*
  1155.  * Switch to cppseg
  1156.  */
  1157. void cppseg(void)
  1158. {     if (prm_asmfile)  
  1159. if( curseg != cppxseg) {
  1160.                 nl();
  1161.                 fprintf(outputFile,"tSECTIONtcppinitn");
  1162.                 curseg = cppxseg;
  1163.                 }
  1164. }
  1165. void gen_virtual(char *name)
  1166. /*
  1167.  * Generate a virtual segment
  1168.  */
  1169. {
  1170. if (prm_asmfile) {
  1171. nl();
  1172. fprintf(outputFile,"@%stVIRTUAL",name);
  1173. }
  1174. }
  1175. void gen_endvirtual(char *name)
  1176. /*
  1177.  * Generate the end of a virtual segment
  1178.  */
  1179. {
  1180. if (prm_asmfile) {
  1181. nl();
  1182. fprintf(outputFile,"@%stENDVIRTUAL",name);
  1183. }
  1184. }
  1185. void genlongref(DATALINK *p)
  1186. /*
  1187.  * Generate a reference reference for fixup tables
  1188.  */
  1189. {
  1190. if (prm_asmfile) 
  1191.         if( gentype == longgen && outcol < 56) {
  1192.                 fprintf(outputFile,",%s+$%X",p->sp->name,p->offset);
  1193.                 outcol += 10;
  1194.                 }
  1195.         else    {
  1196.                 nl();
  1197.                 fprintf(outputFile,"tDC.Lt%s+$%X",p->sp->name,p->offset);
  1198.                 gentype = longgen;
  1199.                 outcol = 25;
  1200.                 }
  1201. else
  1202. ;/* oc_longen(p->sp,p->offset); */
  1203. }
  1204. /*
  1205.  * Assembly file header
  1206.  */
  1207. void asm_header(void)
  1208. {
  1209. }
  1210. void globaldef(SYM *sp)
  1211. /*
  1212.  * Stick in a global definition
  1213.  */
  1214. {
  1215. if (prm_asmfile) {
  1216. char buf[100],*q=buf,*p=sp->name;
  1217. nl();
  1218. if (curseg == codeseg && sp->pascaldefn) {
  1219. if (prm_cmangle)
  1220. p++;
  1221. while(*p)
  1222. *q++=toupper(*p++);
  1223. *q++ = 0;
  1224. }
  1225. else
  1226. strcpy(buf,p);
  1227.     fprintf(outputFile,"tXDEFt%sn",buf);
  1228. }
  1229. }
  1230. void putexterns(void)
  1231. /*
  1232.  * Output the fixup tables and the global/external list
  1233.  */
  1234. {       SYM     *sp;
  1235. DATALINK *p;
  1236. int i;
  1237. int started = FALSE;
  1238. p = datahead;
  1239. curseg = fixcseg;
  1240. while (p) {
  1241. if (p->type) {
  1242. if (!started && prm_asmfile) {
  1243.                 nl();
  1244.                 fprintf(outputFile,"tSECTIONtcodefixn");
  1245. started = TRUE;
  1246. }
  1247. genlongref(p);
  1248. }
  1249. p = p->next;
  1250. }
  1251. started = FALSE;
  1252. p = datahead;
  1253. curseg = fixdseg;
  1254. while (p) {
  1255. if (!p->type) {
  1256. if (!started && prm_asmfile) {
  1257.                 nl();
  1258.                 fprintf(outputFile,"tSECTIONtdatafixn");
  1259. started = TRUE;
  1260. }
  1261. genlongref(p);
  1262. }
  1263. p = p->next;
  1264. }
  1265. curseg = noseg;
  1266. if (prm_asmfile) {
  1267. nl();
  1268. for (i=0; i < HASHTABLESIZE; i++) {
  1269. if ((sp=(SYM *) globalhash[i]) != 0) {
  1270. while (sp) {
  1271.         if( (sp->storage_class == sc_external  || sp->storage_class == sc_externalfunc)&& sp->extflag) {
  1272. char buf[100],*q=buf,*p=sp->name;
  1273. if (curseg == codeseg && sp->pascaldefn) {
  1274. if (prm_cmangle)
  1275. p++;
  1276. while(*p)
  1277. *q++=toupper(*p++);
  1278. *q++ = 0;
  1279. }
  1280. else
  1281. strcpy(buf,p);
  1282.                fprintf(outputFile,"tXREFt%sn",buf);
  1283. }
  1284.          sp = sp->next;
  1285. }
  1286. }
  1287. }
  1288. }
  1289. else
  1290. ;/* oc_gencode(); */
  1291. }