code.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* $Header$ */
  6. /* C O D E - G E N E R A T I N G R O U T I N E S */
  7. #include <em.h>
  8. #include "botch_free.h"
  9. #include <alloc.h>
  10. #include "nofloat.h"
  11. #include "dataflow.h"
  12. #include "use_tmp.h"
  13. #include "arith.h"
  14. #include "type.h"
  15. #include "idf.h"
  16. #include "label.h"
  17. #include "code.h"
  18. #include "stmt.h"
  19. #include "def.h"
  20. #include "expr.h"
  21. #include "sizes.h"
  22. #include "stack.h"
  23. #include "level.h"
  24. #include "decspecs.h"
  25. #include "declar.h"
  26. #include "Lpars.h"
  27. #include "mes.h"
  28. #include "LLlex.h"
  29. #include "specials.h"
  30. #include "atw.h"
  31. #include "assert.h"
  32. #include "align.h"
  33. #include "noRoption.h"
  34. label lab_count = 1;
  35. label datlab_count = 1;
  36. #ifndef NOFLOAT
  37. int fp_used;
  38. #endif NOFLOAT
  39. extern char options[];
  40. char *symbol2str();
  41. init_code(dst_file)
  42. char *dst_file;
  43. {
  44. /* init_code() initialises the output file on which the
  45. compact EM code is written
  46. */
  47. C_init(word_size, pointer_size); /* initialise EM module */
  48. if (C_open(dst_file) == 0)
  49. fatal("cannot write to %s\n", dst_file);
  50. #ifdef USE_TMP
  51. if (options['N'])
  52. #endif USE_TMP
  53. famous_first_words();
  54. }
  55. famous_first_words()
  56. {
  57. C_magic();
  58. C_ms_emx(word_size, pointer_size);
  59. }
  60. static struct string_cst *str_list = 0;
  61. code_string(val, len, dlb)
  62. char *val;
  63. int len;
  64. label dlb;
  65. {
  66. register struct string_cst *sc = new_string_cst();
  67. C_ina_dlb(dlb);
  68. sc->next = str_list;
  69. str_list = sc;
  70. sc->sc_value = val;
  71. sc->sc_len = len;
  72. sc->sc_dlb = dlb;
  73. }
  74. def_strings(sc)
  75. register struct string_cst *sc;
  76. {
  77. if (sc) {
  78. def_strings(sc->next);
  79. C_df_dlb(sc->sc_dlb);
  80. str_cst(sc->sc_value, sc->sc_len);
  81. free_string_cst(sc);
  82. }
  83. }
  84. end_code()
  85. {
  86. /* end_code() performs the actions to be taken when closing
  87. the output stream.
  88. */
  89. def_strings(str_list);
  90. str_list = 0;
  91. C_ms_src((int)(LineNumber - 2), FileName);
  92. C_close();
  93. }
  94. #ifdef USE_TMP
  95. prepend_scopes(dst_file)
  96. char *dst_file;
  97. {
  98. /* prepend_scopes() runs down the list of global idf's
  99. and generates those exa's, exp's, ina's and inp's
  100. that superior hindsight has provided, on the file dst_file.
  101. */
  102. register struct stack_entry *se = local_level->sl_entry;
  103. if (C_open(dst_file) == 0)
  104. fatal("cannot create %s", dst_file ? dst_file : "stdout");
  105. famous_first_words();
  106. while (se != 0) {
  107. register struct idf *id = se->se_idf;
  108. register struct def *df = id->id_def;
  109. if (df && (df->df_initialized || df->df_used || df->df_alloc))
  110. code_scope(id->id_text, df);
  111. se = se->next;
  112. }
  113. C_close();
  114. }
  115. #endif USE_TMP
  116. code_scope(text, def)
  117. char *text;
  118. register struct def *def;
  119. {
  120. /* generates code for one name, text, of the storage class
  121. as given by def, if meaningful.
  122. */
  123. int fund = def->df_type->tp_fund;
  124. switch (def->df_sc) {
  125. case EXTERN:
  126. case GLOBAL:
  127. case IMPLICIT:
  128. if (fund == FUNCTION)
  129. C_exp(text);
  130. else
  131. C_exa_dnam(text);
  132. break;
  133. case STATIC:
  134. if (fund == FUNCTION)
  135. C_inp(text);
  136. else
  137. C_ina_dnam(text);
  138. break;
  139. }
  140. }
  141. static label return_label;
  142. static char return_expr_occurred;
  143. static struct type *func_tp;
  144. static label func_res_label;
  145. static char *last_fn_given = "";
  146. static label file_name_label;
  147. begin_proc(name, def) /* to be called when entering a procedure */
  148. char *name;
  149. register struct def *def;
  150. {
  151. /* begin_proc() is called at the entrance of a new function
  152. and performs the necessary code generation:
  153. - a scope indicator (if needed) exp/inp
  154. - the procedure entry pro $name
  155. - reserves some space if the result of the function
  156. does not fit in the return area
  157. - a fil pseudo instruction
  158. */
  159. arith size;
  160. register struct type *tp = def->df_type;
  161. #ifdef USE_TMP
  162. if (options['N']) code_scope(name,def);
  163. #else USE_TMP
  164. code_scope(name, def);
  165. #endif USE_TMP
  166. #ifdef DATAFLOW
  167. if (options['d'])
  168. DfaStartFunction(name);
  169. #endif DATAFLOW
  170. if (tp->tp_fund != FUNCTION) {
  171. error("making function body for non-function");
  172. tp = error_type;
  173. }
  174. else
  175. tp = tp->tp_up;
  176. func_tp = tp;
  177. size = ATW(tp->tp_size);
  178. C_pro_narg(name);
  179. if (is_struct_or_union(tp->tp_fund)) {
  180. C_df_dlb(func_res_label = data_label());
  181. C_bss_cst(size, (arith)0, 1);
  182. }
  183. else
  184. func_res_label = 0;
  185. /* Special arrangements if the function result doesn't fit in
  186. the function return area of the EM machine. The size of
  187. the function return area is implementation dependent.
  188. */
  189. lab_count = (label) 1;
  190. return_label = text_label();
  191. return_expr_occurred = 0;
  192. prc_entry(name);
  193. if (! options['L']) { /* profiling */
  194. if (strcmp(last_fn_given, FileName) != 0) {
  195. /* previous function came from other file */
  196. C_df_dlb(file_name_label = data_label());
  197. C_con_scon(last_fn_given = FileName,
  198. (arith)(strlen(FileName) + 1));
  199. }
  200. /* enable debug trace of EM source */
  201. C_fil_dlb(file_name_label, (arith)0);
  202. C_lin((arith)LineNumber);
  203. }
  204. }
  205. end_proc(fbytes, nbytes)
  206. arith fbytes, nbytes;
  207. {
  208. /* end_proc() deals with the code to be generated at the end of
  209. a function, as there is:
  210. - the EM ret instruction: "ret 0"
  211. - loading of the function result in the function
  212. result area if there has been a return <expr>
  213. in the function body (see do_return_expr())
  214. - indication of the use of floating points
  215. - indication of the number of bytes used for
  216. formal parameters
  217. - use of special identifiers such as "setjmp"
  218. - "end" + number of bytes used for local variables
  219. */
  220. static int mes_flt_given = 0; /* once for the whole program */
  221. #ifdef DATAFLOW
  222. if (options['d'])
  223. DfaEndFunction();
  224. #endif DATAFLOW
  225. prc_exit();
  226. C_ret((arith)0);
  227. if (return_expr_occurred != 0) {
  228. C_df_ilb(return_label);
  229. prc_exit();
  230. if (func_res_label != 0) {
  231. C_lae_dlb(func_res_label, (arith)0);
  232. store_block(func_tp->tp_size, func_tp->tp_align);
  233. C_lae_dlb(func_res_label, (arith)0);
  234. C_ret(pointer_size);
  235. }
  236. else
  237. C_ret(ATW(func_tp->tp_size));
  238. }
  239. #ifndef NOFLOAT
  240. if (fp_used && mes_flt_given == 0) {
  241. /* floating point used */
  242. C_ms_flt();
  243. mes_flt_given++;
  244. }
  245. #endif NOFLOAT
  246. C_ms_par(fbytes); /* # bytes for formals */
  247. if (sp_occurred[SP_SETJMP]) { /* indicate use of "setjmp" */
  248. C_ms_gto();
  249. sp_occurred[SP_SETJMP] = 0;
  250. }
  251. C_end(ATW(nbytes));
  252. }
  253. do_return()
  254. {
  255. /* do_return generates a direct return */
  256. /* isn't a jump to the return label smarter ??? */
  257. prc_exit();
  258. C_ret((arith)0);
  259. }
  260. do_return_expr(expr)
  261. struct expr *expr;
  262. {
  263. /* do_return_expr() generates the expression and the jump for
  264. a return statement with an expression.
  265. */
  266. ch7cast(&expr, RETURN, func_tp);
  267. code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
  268. C_bra(return_label);
  269. return_expr_occurred = 1;
  270. }
  271. code_declaration(idf, expr, lvl, sc)
  272. register struct idf *idf; /* idf to be declared */
  273. struct expr *expr; /* initialisation; NULL if absent */
  274. int lvl; /* declaration level */
  275. int sc; /* storage class, as in the declaration */
  276. {
  277. /* code_declaration() does the actual declaration of the
  278. variable indicated by "idf" on declaration level "lvl".
  279. If the variable is initialised, the expression is given
  280. in "expr", but for global and static initialisations it
  281. is just non-zero, as the expression is not parsed yet.
  282. There are some cases to be considered:
  283. - filter out typedefs, they don't correspond to code;
  284. - global variables, coded only if initialized;
  285. - local static variables;
  286. - local automatic variables;
  287. Since the expression may be modified in the process,
  288. code_declaration() frees it after use, as the caller can
  289. no longer do so.
  290. If there is a storage class indication (EXTERN/STATIC),
  291. code_declaration() will generate an exa or ina.
  292. The sc is the actual storage class, as given in the
  293. declaration. This is to allow:
  294. extern int a;
  295. int a = 5;
  296. while at the same time forbidding
  297. extern int a = 5;
  298. */
  299. char *text = idf->id_text;
  300. register struct def *def = idf->id_def;
  301. register arith size = def->df_type->tp_size;
  302. int def_sc = def->df_sc;
  303. if (def_sc == TYPEDEF) /* no code for typedefs */
  304. return;
  305. if (sc == EXTERN && expr && !is_anon_idf(idf))
  306. error("%s is extern; cannot initialize", text);
  307. if (lvl == L_GLOBAL) { /* global variable */
  308. /* is this an allocating declaration? */
  309. if ( (sc == 0 || sc == STATIC)
  310. && def->df_type->tp_fund != FUNCTION
  311. && size >= 0
  312. )
  313. def->df_alloc = ALLOC_SEEN;
  314. if (expr) { /* code only if initialized */
  315. #ifdef USE_TMP
  316. if (options['N'])
  317. #endif USE_TMP
  318. code_scope(text, def);
  319. def->df_alloc = ALLOC_DONE;
  320. C_df_dnam(text);
  321. }
  322. }
  323. else
  324. if (lvl >= L_LOCAL) { /* local variable */
  325. /* STATIC, EXTERN, GLOBAL, IMPLICIT, AUTO or REGISTER */
  326. switch (def_sc) {
  327. case STATIC:
  328. if (def->df_type->tp_fund == FUNCTION) {
  329. /* should produce "inp $function" ??? */
  330. break;
  331. }
  332. /* they are handled on the spot and get an
  333. integer label in EM.
  334. */
  335. C_df_dlb((label)def->df_address);
  336. if (expr) { /* there is an initialisation */
  337. }
  338. else { /* produce blank space */
  339. if (size <= 0) {
  340. error("size of %s unknown", text);
  341. size = (arith)0;
  342. }
  343. C_bss_cst(ATW(size), (arith)0, 1);
  344. }
  345. break;
  346. case EXTERN:
  347. case GLOBAL:
  348. case IMPLICIT:
  349. /* we are sure there is no expression */
  350. #ifdef USE_TMP
  351. if (options['N'])
  352. #endif USE_TMP
  353. code_scope(text, def);
  354. break;
  355. case AUTO:
  356. case REGISTER:
  357. if (expr)
  358. loc_init(expr, idf);
  359. break;
  360. default:
  361. crash("bad local storage class");
  362. break;
  363. }
  364. }
  365. }
  366. loc_init(expr, id)
  367. struct expr *expr;
  368. register struct idf *id;
  369. {
  370. /* loc_init() generates code for the assignment of
  371. expression expr to the local variable described by id.
  372. It frees the expression afterwards.
  373. */
  374. register struct type *tp = id->id_def->df_type;
  375. register struct expr *e = expr;
  376. ASSERT(id->id_def->df_sc != STATIC);
  377. switch (tp->tp_fund) {
  378. case ARRAY:
  379. case STRUCT:
  380. case UNION:
  381. error("no automatic aggregate initialisation");
  382. free_expression(e);
  383. return;
  384. }
  385. if (ISCOMMA(e)) { /* embraced: int i = {12}; */
  386. #ifndef NOROPTION
  387. if (options['R']) {
  388. if (ISCOMMA(e->OP_LEFT)) /* int i = {{1}} */
  389. expr_error(e, "extra braces not allowed");
  390. else
  391. if (e->OP_RIGHT != 0) /* int i = {1 , 2} */
  392. expr_error(e, "too many initializers");
  393. }
  394. #endif NOROPTION
  395. while (e) {
  396. loc_init(e->OP_LEFT, id);
  397. e = e->OP_RIGHT;
  398. }
  399. }
  400. else { /* not embraced */
  401. struct value vl;
  402. ch7cast(&expr, '=', tp); /* may modify expr */
  403. EVAL(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
  404. free_expression(expr);
  405. vl.vl_class = Name;
  406. vl.vl_data.vl_idf = id;
  407. vl.vl_value = (arith)0;
  408. store_val(&vl, tp);
  409. }
  410. }
  411. bss(idf)
  412. register struct idf *idf;
  413. {
  414. /* bss() allocates bss space for the global idf.
  415. */
  416. arith size = idf->id_def->df_type->tp_size;
  417. #ifdef USE_TMP
  418. if (options['N'])
  419. #endif USE_TMP
  420. code_scope(idf->id_text, idf->id_def);
  421. /* Since bss() is only called if df_alloc is non-zero, and
  422. since df_alloc is only non-zero if size >= 0, we have:
  423. */
  424. /* but we already gave a warning at the declaration of the
  425. array. Besides, the message given here does not apply to
  426. voids
  427. if (options['R'] && size == 0)
  428. warning("actual array of size 0");
  429. */
  430. C_df_dnam(idf->id_text);
  431. C_bss_cst(ATW(size), (arith)0, 1);
  432. }
  433. formal_cvt(df)
  434. register struct def *df;
  435. {
  436. /* formal_cvt() converts a formal parameter of type char or
  437. short from int to that type.
  438. */
  439. register struct type *tp = df->df_type;
  440. if (tp->tp_size != int_size &&
  441. (tp->tp_fund == CHAR || tp->tp_fund == SHORT)
  442. ) {
  443. C_lol(df->df_address);
  444. /* conversion(int_type, df->df_type); ???
  445. No, you can't do this on the stack! (CJ)
  446. */
  447. C_lal(df->df_address);
  448. C_sti(tp->tp_size);
  449. df->df_register = REG_NONE;
  450. }
  451. }
  452. code_expr(expr, val, code, tlbl, flbl)
  453. struct expr *expr;
  454. label tlbl, flbl;
  455. {
  456. /* code_expr() is the parser's interface to the expression code
  457. generator. If line number trace is wanted, it generates a
  458. lin instruction. EVAL() is called directly.
  459. */
  460. if (! options['L']) /* profiling */
  461. C_lin((arith)LineNumber);
  462. EVAL(expr, val, code, tlbl, flbl);
  463. }
  464. /* The FOR/WHILE/DO/SWITCH stacking mechanism:
  465. stack_stmt() has to be called at the entrance of a
  466. for, while, do or switch statement to indicate the
  467. EM labels where a subsequent break or continue causes
  468. the program to jump to.
  469. */
  470. static struct stmt_block *stmt_stack; /* top of statement stack */
  471. /* code_break() generates EM code needed at the occurrence of "break":
  472. it generates a branch instruction to the break label of the
  473. innermost statement in which break has a meaning.
  474. As "break" is legal in any of 'while', 'do', 'for' or 'switch',
  475. which are the only ones that are stacked, only the top of
  476. the stack is interesting.
  477. */
  478. code_break()
  479. {
  480. register struct stmt_block *stmt_block = stmt_stack;
  481. if (stmt_block)
  482. C_bra(stmt_block->st_break);
  483. else
  484. error("break not inside for, while, do or switch");
  485. }
  486. /* code_continue() generates EM code needed at the occurrence of
  487. "continue":
  488. it generates a branch instruction to the continue label of the
  489. innermost statement in which continue has a meaning.
  490. */
  491. code_continue()
  492. {
  493. register struct stmt_block *stmt_block = stmt_stack;
  494. while (stmt_block) {
  495. if (stmt_block->st_continue) {
  496. C_bra(stmt_block->st_continue);
  497. return;
  498. }
  499. stmt_block = stmt_block->next;
  500. }
  501. error("continue not inside for, while or do");
  502. }
  503. stack_stmt(break_label, cont_label)
  504. label break_label, cont_label;
  505. {
  506. register struct stmt_block *stmt_block = new_stmt_block();
  507. stmt_block->next = stmt_stack;
  508. stmt_block->st_break = break_label;
  509. stmt_block->st_continue = cont_label;
  510. stmt_stack = stmt_block;
  511. }
  512. unstack_stmt()
  513. {
  514. /* unstack_stmt() unstacks the data of a statement
  515. which may contain break or continue
  516. */
  517. register struct stmt_block *sbp = stmt_stack;
  518. stmt_stack = sbp->next;
  519. free_stmt_block(sbp);
  520. }
  521. static label l1;
  522. prc_entry(name)
  523. char *name;
  524. {
  525. if (options['p']) {
  526. C_df_dlb(l1 = data_label());
  527. C_rom_scon(name, (arith) (strlen(name) + 1));
  528. C_lae_dlb(l1, (arith) 0);
  529. C_cal("procentry");
  530. C_asp(pointer_size);
  531. }
  532. }
  533. prc_exit()
  534. {
  535. if (options['p']) {
  536. C_lae_dlb(l1, (arith) 0);
  537. C_cal("procexit");
  538. C_asp(pointer_size);
  539. }
  540. }