mkcalls.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  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 checkarg(struct e_arg *arg, int typset)
  31. {
  32. if (((!typset) && arg->ema_argtype) ||
  33. ((!arg->ema_argtype) && typset)) {
  34. /* End of arguments expected, but there are more, or
  35. an argument expected, but there is none
  36. */
  37. EM_error = "Illegal number of parameters";
  38. return 0;
  39. }
  40. if (!(arg->ema_argtype & typset)) {
  41. /* Type error */
  42. EM_error = "Illegal parameter type";
  43. return 0;
  44. }
  45. return 1;
  46. }
  47. #else /* not CHECKING */
  48. PRIVATE int checkarg(struct e_arg *arg, int typset)
  49. {
  50. return 1;
  51. }
  52. //#define checkarg(arg, x) (1)
  53. #endif /* CHECKING */
  54. /* EM_doinstr: An EM instruction
  55. */
  56. PRIVATE void EM_doinstr(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 EM_dopseudo(struct e_instr *p)
  89. {
  90. switch(p->em_opcode) {
  91. case ps_exc: {
  92. C_exc(p->em_exc1, p->em_exc2);
  93. break;
  94. }
  95. case ps_hol: {
  96. if (! checkarg(&(p->em_arg), par_ptyp)) break;
  97. switch(p->em_argtype) {
  98. case cst_ptyp:
  99. C_hol_cst(EM_holsize,
  100. p->em_cst,
  101. EM_holinit);
  102. break;
  103. case ico_ptyp:
  104. C_hol_icon(EM_holsize,
  105. p->em_string,
  106. p->em_size,
  107. EM_holinit);
  108. break;
  109. case uco_ptyp:
  110. C_hol_ucon(EM_holsize,
  111. p->em_string,
  112. p->em_size,
  113. EM_holinit);
  114. break;
  115. case fco_ptyp:
  116. C_hol_fcon(EM_holsize,
  117. p->em_string,
  118. p->em_size,
  119. EM_holinit);
  120. break;
  121. case sof_ptyp:
  122. C_hol_dnam(EM_holsize,
  123. p->em_dnam,
  124. p->em_off,
  125. EM_holinit);
  126. break;
  127. case nof_ptyp:
  128. C_hol_dlb(EM_holsize,
  129. p->em_dlb,
  130. p->em_off,
  131. EM_holinit);
  132. break;
  133. case ilb_ptyp:
  134. C_hol_ilb(EM_holsize,
  135. p->em_ilb,
  136. EM_holinit);
  137. break;
  138. case pro_ptyp:
  139. C_hol_pnam(EM_holsize,
  140. p->em_pnam,
  141. EM_holinit);
  142. break;
  143. default:
  144. EM_error = "Illegal parameter type";
  145. break;
  146. }
  147. break;
  148. }
  149. case ps_bss: {
  150. if (! checkarg(&(p->em_arg), par_ptyp)) break;
  151. switch(p->em_argtype) {
  152. case cst_ptyp:
  153. C_bss_cst(EM_bsssize,
  154. p->em_cst,
  155. EM_bssinit);
  156. break;
  157. case ico_ptyp:
  158. C_bss_icon(EM_bsssize,
  159. p->em_string,
  160. p->em_size,
  161. EM_bssinit);
  162. break;
  163. case uco_ptyp:
  164. C_bss_ucon(EM_bsssize,
  165. p->em_string,
  166. p->em_size,
  167. EM_bssinit);
  168. break;
  169. case fco_ptyp:
  170. C_bss_fcon(EM_bsssize,
  171. p->em_string,
  172. p->em_size,
  173. EM_bssinit);
  174. break;
  175. case sof_ptyp:
  176. C_bss_dnam(EM_bsssize,
  177. p->em_dnam,
  178. p->em_off,
  179. EM_bssinit);
  180. break;
  181. case nof_ptyp:
  182. C_bss_dlb(EM_bsssize,
  183. p->em_dlb,
  184. p->em_off,
  185. EM_bssinit);
  186. break;
  187. case ilb_ptyp:
  188. C_bss_ilb(EM_bsssize,
  189. p->em_ilb,
  190. EM_bssinit);
  191. break;
  192. case pro_ptyp:
  193. C_bss_pnam(EM_bsssize,
  194. p->em_pnam,
  195. EM_bssinit);
  196. break;
  197. default:
  198. EM_error = "Illegal parameter type";
  199. break;
  200. }
  201. break;
  202. }
  203. case ps_end:
  204. if (p->em_argtype != 0) {
  205. if (! checkarg(&(p->em_arg), cst_ptyp)) break;
  206. C_end(p->em_cst);
  207. break;
  208. }
  209. C_end_narg();
  210. break;
  211. case ps_exa:
  212. case ps_ina:
  213. if (! checkarg(&(p->em_arg), lab_ptyp)) break;
  214. if (p->em_argtype == nof_ptyp) {
  215. if (p->em_opcode == ps_exa) {
  216. C_exa_dlb(p->em_dlb);
  217. }
  218. else C_ina_dlb(p->em_dlb);
  219. break;
  220. }
  221. if (p->em_opcode == ps_exa) {
  222. C_exa_dnam(p->em_dnam);
  223. }
  224. else C_ina_dnam(p->em_dnam);
  225. break;
  226. case ps_exp:
  227. if (! checkarg(&(p->em_arg), pro_ptyp)) break;
  228. C_exp(p->em_pnam);
  229. break;
  230. case ps_inp:
  231. if (! checkarg(&(p->em_arg), pro_ptyp)) break;
  232. C_inp(p->em_pnam);
  233. break;
  234. case ps_pro:
  235. if (! checkarg(&(p->em_arg), pro_ptyp)) break;
  236. if (p->em_nlocals >= 0) {
  237. C_pro(p->em_pnam, p->em_nlocals);
  238. }
  239. else C_pro_narg(p->em_pnam);
  240. break;
  241. case ps_con:
  242. if (! checkarg(&(p->em_arg), val_ptyp)) break;
  243. switch(p->em_argtype) {
  244. case ilb_ptyp:
  245. C_con_ilb(p->em_ilb);
  246. break;
  247. case nof_ptyp:
  248. C_con_dlb(p->em_dlb, p->em_off);
  249. break;
  250. case sof_ptyp:
  251. C_con_dnam(p->em_dnam, p->em_off);
  252. break;
  253. case cst_ptyp:
  254. C_con_cst(p->em_cst);
  255. break;
  256. case pro_ptyp:
  257. C_con_pnam(p->em_pnam);
  258. break;
  259. case str_ptyp:
  260. C_con_scon(p->em_string, p->em_size);
  261. break;
  262. case ico_ptyp:
  263. C_con_icon(p->em_string, p->em_size);
  264. break;
  265. case uco_ptyp:
  266. C_con_ucon(p->em_string, p->em_size);
  267. break;
  268. case fco_ptyp:
  269. C_con_fcon(p->em_string, p->em_size);
  270. break;
  271. default:
  272. EM_error = "Illegal argument type";
  273. return;
  274. }
  275. break;
  276. case ps_rom:
  277. if (! checkarg(&(p->em_arg), val_ptyp)) break;
  278. switch(p->em_argtype) {
  279. case ilb_ptyp:
  280. C_rom_ilb(p->em_ilb);
  281. break;
  282. case nof_ptyp:
  283. C_rom_dlb(p->em_dlb, p->em_off);
  284. break;
  285. case sof_ptyp:
  286. C_rom_dnam(p->em_dnam, p->em_off);
  287. break;
  288. case cst_ptyp:
  289. C_rom_cst(p->em_cst);
  290. break;
  291. case pro_ptyp:
  292. C_rom_pnam(p->em_pnam);
  293. break;
  294. case str_ptyp:
  295. C_rom_scon(p->em_string, p->em_size);
  296. break;
  297. case ico_ptyp:
  298. C_rom_icon(p->em_string, p->em_size);
  299. break;
  300. case uco_ptyp:
  301. C_rom_ucon(p->em_string, p->em_size);
  302. break;
  303. case fco_ptyp:
  304. C_rom_fcon(p->em_string, p->em_size);
  305. break;
  306. default:
  307. EM_error = "Illegal argument type";
  308. return;
  309. }
  310. break;
  311. default:
  312. EM_error = "Illegal pseudo instruction";
  313. break;
  314. }
  315. }
  316. PRIVATE void EM_docon(struct e_instr *p)
  317. {
  318. checkarg(&(p->em_arg), val_ptyp);
  319. switch(p->em_argtype) {
  320. case ilb_ptyp:
  321. C_ilb(p->em_ilb);
  322. break;
  323. case nof_ptyp:
  324. C_dlb(p->em_dlb, p->em_off);
  325. break;
  326. case sof_ptyp:
  327. C_dnam(p->em_dnam, p->em_off);
  328. break;
  329. case cst_ptyp:
  330. C_cst(p->em_cst);
  331. break;
  332. case pro_ptyp:
  333. C_pnam(p->em_pnam);
  334. break;
  335. case str_ptyp:
  336. C_scon(p->em_string, p->em_size);
  337. break;
  338. case ico_ptyp:
  339. C_icon(p->em_string, p->em_size);
  340. break;
  341. case uco_ptyp:
  342. C_ucon(p->em_string, p->em_size);
  343. break;
  344. case fco_ptyp:
  345. C_fcon(p->em_string, p->em_size);
  346. break;
  347. default:
  348. EM_error = "Illegal argument type";
  349. break;
  350. }
  351. }
  352. PRIVATE void EM_dostartmes(struct e_instr *p)
  353. {
  354. if (listtype) {
  355. EM_error = "Message not ended";
  356. return;
  357. }
  358. if (! checkarg(&(p->em_arg), cst_ptyp)) return;
  359. C_mes_begin((int) (p->em_cst));
  360. listtype = ps_mes;
  361. }
  362. EXPORT int EM_mkcalls(struct e_instr *line)
  363. {
  364. #ifdef CHECKING
  365. if (listtype && line->em_type != EM_MESARG && line->em_type != EM_ENDMES) {
  366. EM_error = "Message not ended";
  367. return 0;
  368. }
  369. #endif /* CHECKING */
  370. EM_error = 0;
  371. switch(line->em_type) {
  372. default:
  373. EM_error = "Illegal EM line";
  374. break;
  375. case EM_MNEM:
  376. /* normal instruction */
  377. EM_doinstr(line);
  378. break;
  379. case EM_DEFILB:
  380. /* defining occurrence of an instruction label */
  381. C_df_ilb(line->em_ilb);
  382. break;
  383. case EM_DEFDLB:
  384. /* defining occurrence of a global data label */
  385. C_df_dlb(line->em_dlb);
  386. break;
  387. case EM_DEFDNAM:
  388. /* defining occurrence of a non-numeric data label */
  389. C_df_dnam(line->em_dnam);
  390. break;
  391. case EM_PSEU:
  392. /* pseudo */
  393. EM_dopseudo(line);
  394. break;
  395. case EM_STARTMES:
  396. /* start of a MES pseudo */
  397. EM_dostartmes(line);
  398. break;
  399. case EM_MESARG:
  400. case EM_ENDMES:
  401. #ifdef CHECKING
  402. if (!listtype) {
  403. EM_error = "Message not started";
  404. return 0;
  405. }
  406. #endif
  407. if (line->em_type == EM_MESARG) {
  408. EM_docon(line);
  409. break;
  410. }
  411. C_mes_end();
  412. listtype = 0;
  413. break;
  414. }
  415. if (EM_error) return 0;
  416. return 1;
  417. }