mkcalls.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* makecalls: expand a datastructure as delivered by "EM_getline"
  7. into calls to the procedural interface.
  8. Exported routine:
  9. EM_mkcalls
  10. */
  11. #include <em_spec.h>
  12. #include <em_mnem.h>
  13. #include <em_pseu.h>
  14. #include <em_flag.h>
  15. #include "em_ptyp.h"
  16. #include <em.h>
  17. #include "em_comp.h"
  18. #include <assert.h>
  19. extern char em_flag[]; /* One per EM instruction: indicates parameter kind */
  20. extern short em_ptyp[]; /* One per parameter kind: indicates parameter type */
  21. static int listtype = 0; /* indicates pseudo when generating code for
  22. variable length argument lists
  23. (only for MES)
  24. */
  25. #ifdef CHECKING
  26. /* c_getarg: Check the argument indicated by "args".
  27. The argument must be of a type allowed by "typset".
  28. Return a pointer to the next argument.
  29. */
  30. PRIVATE int
  31. checkarg(arg, typset)
  32. register struct e_arg *arg;
  33. {
  34. if (((!typset) && arg->ema_argtype) ||
  35. ((!arg->ema_argtype) && typset)) {
  36. /* End of arguments expected, but there are more, or
  37. an argument expected, but there is none
  38. */
  39. EM_error = "Illegal number of parameters";
  40. return 0;
  41. }
  42. if (!(arg->ema_argtype & typset)) {
  43. /* Type error */
  44. EM_error = "Illegal parameter type";
  45. return 0;
  46. }
  47. return 1;
  48. }
  49. #else /* not CHECKING */
  50. #define checkarg(arg, x) 1
  51. #endif /* CHECKING */
  52. /* EM_doinstr: An EM instruction
  53. */
  54. PRIVATE void
  55. EM_doinstr(p)
  56. register struct e_instr *p;
  57. {
  58. register int parametertype; /* parametertype of the instruction */
  59. parametertype = em_flag[p->em_opcode-sp_fmnem] & EM_PAR;
  60. #ifdef CHECKING
  61. if (parametertype != PAR_NO && parametertype != PAR_W) {
  62. if (p->em_argtype == 0) {
  63. EM_error = "Illegal number of parameters";
  64. return;
  65. }
  66. }
  67. #endif /* CHECKING */
  68. switch(parametertype) {
  69. case PAR_NO:
  70. break;
  71. default:
  72. if (! checkarg(&(p->em_arg), em_ptyp[parametertype])) {
  73. return;
  74. }
  75. break;
  76. case PAR_W:
  77. if (p->em_argtype != 0) {
  78. if (! checkarg(&(p->em_arg), cst_ptyp)) return;
  79. }
  80. else {
  81. #include "C_mnem_narg.h"
  82. return;
  83. }
  84. break;
  85. }
  86. #include "C_mnem.h"
  87. }
  88. PRIVATE void
  89. EM_dopseudo(p)
  90. register struct e_instr *p;
  91. {
  92. switch(p->em_opcode) {
  93. case ps_exc: {
  94. C_exc(p->em_exc1, p->em_exc2);
  95. break;
  96. }
  97. case ps_hol: {
  98. if (! checkarg(&(p->em_arg), par_ptyp)) break;
  99. switch(p->em_argtype) {
  100. case cst_ptyp:
  101. C_hol_cst(EM_holsize,
  102. p->em_cst,
  103. EM_holinit);
  104. break;
  105. case ico_ptyp:
  106. C_hol_icon(EM_holsize,
  107. p->em_string,
  108. p->em_size,
  109. EM_holinit);
  110. break;
  111. case uco_ptyp:
  112. C_hol_ucon(EM_holsize,
  113. p->em_string,
  114. p->em_size,
  115. EM_holinit);
  116. break;
  117. case fco_ptyp:
  118. C_hol_fcon(EM_holsize,
  119. p->em_string,
  120. p->em_size,
  121. EM_holinit);
  122. break;
  123. case sof_ptyp:
  124. C_hol_dnam(EM_holsize,
  125. p->em_dnam,
  126. p->em_off,
  127. EM_holinit);
  128. break;
  129. case nof_ptyp:
  130. C_hol_dlb(EM_holsize,
  131. p->em_dlb,
  132. p->em_off,
  133. EM_holinit);
  134. break;
  135. case ilb_ptyp:
  136. C_hol_ilb(EM_holsize,
  137. p->em_ilb,
  138. EM_holinit);
  139. break;
  140. case pro_ptyp:
  141. C_hol_pnam(EM_holsize,
  142. p->em_pnam,
  143. EM_holinit);
  144. break;
  145. default:
  146. EM_error = "Illegal parameter type";
  147. break;
  148. }
  149. break;
  150. }
  151. case ps_bss: {
  152. if (! checkarg(&(p->em_arg), par_ptyp)) break;
  153. switch(p->em_argtype) {
  154. case cst_ptyp:
  155. C_bss_cst(EM_bsssize,
  156. p->em_cst,
  157. EM_bssinit);
  158. break;
  159. case ico_ptyp:
  160. C_bss_icon(EM_bsssize,
  161. p->em_string,
  162. p->em_size,
  163. EM_bssinit);
  164. break;
  165. case uco_ptyp:
  166. C_bss_ucon(EM_bsssize,
  167. p->em_string,
  168. p->em_size,
  169. EM_bssinit);
  170. break;
  171. case fco_ptyp:
  172. C_bss_fcon(EM_bsssize,
  173. p->em_string,
  174. p->em_size,
  175. EM_bssinit);
  176. break;
  177. case sof_ptyp:
  178. C_bss_dnam(EM_bsssize,
  179. p->em_dnam,
  180. p->em_off,
  181. EM_bssinit);
  182. break;
  183. case nof_ptyp:
  184. C_bss_dlb(EM_bsssize,
  185. p->em_dlb,
  186. p->em_off,
  187. EM_bssinit);
  188. break;
  189. case ilb_ptyp:
  190. C_bss_ilb(EM_bsssize,
  191. p->em_ilb,
  192. EM_bssinit);
  193. break;
  194. case pro_ptyp:
  195. C_bss_pnam(EM_bsssize,
  196. p->em_pnam,
  197. EM_bssinit);
  198. break;
  199. default:
  200. EM_error = "Illegal parameter type";
  201. break;
  202. }
  203. break;
  204. }
  205. case ps_end:
  206. if (p->em_argtype != 0) {
  207. if (! checkarg(&(p->em_arg), cst_ptyp)) break;
  208. C_end(p->em_cst);
  209. break;
  210. }
  211. C_end_narg();
  212. break;
  213. case ps_exa:
  214. case ps_ina:
  215. if (! checkarg(&(p->em_arg), lab_ptyp)) break;
  216. if (p->em_argtype == nof_ptyp) {
  217. if (p->em_opcode == ps_exa) {
  218. C_exa_dlb(p->em_dlb);
  219. }
  220. else C_ina_dlb(p->em_dlb);
  221. break;
  222. }
  223. if (p->em_opcode == ps_exa) {
  224. C_exa_dnam(p->em_dnam);
  225. }
  226. else C_ina_dnam(p->em_dnam);
  227. break;
  228. case ps_exp:
  229. if (! checkarg(&(p->em_arg), pro_ptyp)) break;
  230. C_exp(p->em_pnam);
  231. break;
  232. case ps_inp:
  233. if (! checkarg(&(p->em_arg), pro_ptyp)) break;
  234. C_inp(p->em_pnam);
  235. break;
  236. case ps_pro:
  237. if (! checkarg(&(p->em_arg), pro_ptyp)) break;
  238. if (p->em_nlocals >= 0) {
  239. C_pro(p->em_pnam, p->em_nlocals);
  240. }
  241. else C_pro_narg(p->em_pnam);
  242. break;
  243. case ps_con:
  244. if (! checkarg(&(p->em_arg), val_ptyp)) break;
  245. switch(p->em_argtype) {
  246. case ilb_ptyp:
  247. C_con_ilb(p->em_ilb);
  248. break;
  249. case nof_ptyp:
  250. C_con_dlb(p->em_dlb, p->em_off);
  251. break;
  252. case sof_ptyp:
  253. C_con_dnam(p->em_dnam, p->em_off);
  254. break;
  255. case cst_ptyp:
  256. C_con_cst(p->em_cst);
  257. break;
  258. case pro_ptyp:
  259. C_con_pnam(p->em_pnam);
  260. break;
  261. case str_ptyp:
  262. C_con_scon(p->em_string, p->em_size);
  263. break;
  264. case ico_ptyp:
  265. C_con_icon(p->em_string, p->em_size);
  266. break;
  267. case uco_ptyp:
  268. C_con_ucon(p->em_string, p->em_size);
  269. break;
  270. case fco_ptyp:
  271. C_con_fcon(p->em_string, p->em_size);
  272. break;
  273. default:
  274. EM_error = "Illegal argument type";
  275. return;
  276. }
  277. break;
  278. case ps_rom:
  279. if (! checkarg(&(p->em_arg), val_ptyp)) break;
  280. switch(p->em_argtype) {
  281. case ilb_ptyp:
  282. C_rom_ilb(p->em_ilb);
  283. break;
  284. case nof_ptyp:
  285. C_rom_dlb(p->em_dlb, p->em_off);
  286. break;
  287. case sof_ptyp:
  288. C_rom_dnam(p->em_dnam, p->em_off);
  289. break;
  290. case cst_ptyp:
  291. C_rom_cst(p->em_cst);
  292. break;
  293. case pro_ptyp:
  294. C_rom_pnam(p->em_pnam);
  295. break;
  296. case str_ptyp:
  297. C_rom_scon(p->em_string, p->em_size);
  298. break;
  299. case ico_ptyp:
  300. C_rom_icon(p->em_string, p->em_size);
  301. break;
  302. case uco_ptyp:
  303. C_rom_ucon(p->em_string, p->em_size);
  304. break;
  305. case fco_ptyp:
  306. C_rom_fcon(p->em_string, p->em_size);
  307. break;
  308. default:
  309. EM_error = "Illegal argument type";
  310. return;
  311. }
  312. break;
  313. default:
  314. EM_error = "Illegal pseudo instruction";
  315. break;
  316. }
  317. }
  318. PRIVATE void
  319. EM_docon(p)
  320. register struct e_instr *p;
  321. {
  322. checkarg(&(p->em_arg), val_ptyp);
  323. switch(p->em_argtype) {
  324. case ilb_ptyp:
  325. C_ilb(p->em_ilb);
  326. break;
  327. case nof_ptyp:
  328. C_dlb(p->em_dlb, p->em_off);
  329. break;
  330. case sof_ptyp:
  331. C_dnam(p->em_dnam, p->em_off);
  332. break;
  333. case cst_ptyp:
  334. C_cst(p->em_cst);
  335. break;
  336. case pro_ptyp:
  337. C_pnam(p->em_pnam);
  338. break;
  339. case str_ptyp:
  340. C_scon(p->em_string, p->em_size);
  341. break;
  342. case ico_ptyp:
  343. C_icon(p->em_string, p->em_size);
  344. break;
  345. case uco_ptyp:
  346. C_ucon(p->em_string, p->em_size);
  347. break;
  348. case fco_ptyp:
  349. C_fcon(p->em_string, p->em_size);
  350. break;
  351. default:
  352. EM_error = "Illegal argument type";
  353. break;
  354. }
  355. }
  356. PRIVATE void
  357. EM_dostartmes(p)
  358. register struct e_instr *p;
  359. {
  360. if (listtype) {
  361. EM_error = "Message not ended";
  362. return;
  363. }
  364. if (! checkarg(&(p->em_arg), cst_ptyp)) return;
  365. C_mes_begin((int) (p->em_cst));
  366. listtype = ps_mes;
  367. }
  368. EXPORT int
  369. EM_mkcalls(line)
  370. register struct e_instr *line;
  371. {
  372. #ifdef CHECKING
  373. if (listtype && line->em_type != EM_MESARG && line->em_type != EM_ENDMES) {
  374. EM_error = "Message not ended";
  375. return 0;
  376. }
  377. #endif /* CHECKING */
  378. EM_error = 0;
  379. switch(line->em_type) {
  380. default:
  381. EM_error = "Illegal EM line";
  382. break;
  383. case EM_MNEM:
  384. /* normal instruction */
  385. EM_doinstr(line);
  386. break;
  387. case EM_DEFILB:
  388. /* defining occurrence of an instruction label */
  389. C_df_ilb(line->em_ilb);
  390. break;
  391. case EM_DEFDLB:
  392. /* defining occurrence of a global data label */
  393. C_df_dlb(line->em_dlb);
  394. break;
  395. case EM_DEFDNAM:
  396. /* defining occurrence of a non-numeric data label */
  397. C_df_dnam(line->em_dnam);
  398. break;
  399. case EM_PSEU:
  400. /* pseudo */
  401. EM_dopseudo(line);
  402. break;
  403. case EM_STARTMES:
  404. /* start of a MES pseudo */
  405. EM_dostartmes(line);
  406. break;
  407. case EM_MESARG:
  408. case EM_ENDMES:
  409. #ifdef CHECKING
  410. if (!listtype) {
  411. EM_error = "Message not started";
  412. return 0;
  413. }
  414. #endif
  415. if (line->em_type == EM_MESARG) {
  416. EM_docon(line);
  417. break;
  418. }
  419. C_mes_end();
  420. listtype = 0;
  421. break;
  422. }
  423. if (EM_error) return 0;
  424. return 1;
  425. }