desig.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. /* D E S I G N A T O R E V A L U A T I O N */
  2. /* Code generation for designators.
  3. This file contains some routines that generate code common to address
  4. as well as value computations, and leave a description in a "desig"
  5. structure. It also contains routines to load an address, load a value
  6. or perform a store.
  7. */
  8. #include "debug.h"
  9. #include <assert.h>
  10. #include <em.h>
  11. #include "LLlex.h"
  12. #include "def.h"
  13. #include "desig.h"
  14. #include "main.h"
  15. /* next line DEBUG */
  16. #include "idf.h"
  17. #include "node.h"
  18. #include "scope.h"
  19. #include "type.h"
  20. struct desig InitDesig = {DSG_INIT, 0, 0, NULLDEF, 0};
  21. struct withdesig *WithDesigs;
  22. STATIC int
  23. properly(ds, size, al)
  24. register struct desig *ds;
  25. arith size;
  26. {
  27. /* Check if it is allowed to load or store the value indicated
  28. by "ds" with LOI/STI.
  29. - if the size is not either a multiple or a dividor of the
  30. wordsize, then not.
  31. - if the alignment is at least "word" then OK.
  32. - if size is dividor of word_size and alignment >= size then OK.
  33. - otherwise check alignment of address. This can only be done
  34. with DSG_FIXED.
  35. */
  36. arith szmodword = size % word_size; /* 0 if multiple of wordsize */
  37. arith wordmodsz = word_size % size; /* 0 if dividor of wordsize */
  38. if( szmodword && wordmodsz ) return 0;
  39. if( al >= word_align ) return 1;
  40. if( szmodword && al >= szmodword ) return 1;
  41. return ds->dsg_kind == DSG_FIXED &&
  42. ((! szmodword && ds->dsg_offset % word_align == 0) ||
  43. (! wordmodsz && ds->dsg_offset % size == 0));
  44. }
  45. CodeCopy(lhs, rhs, sz, psize)
  46. register struct desig *lhs, *rhs;
  47. arith sz, *psize;
  48. {
  49. struct desig l, r;
  50. l = *lhs;
  51. r = *rhs;
  52. *psize -= sz;
  53. lhs->dsg_offset += sz;
  54. rhs->dsg_offset += sz;
  55. CodeAddress(&r);
  56. C_loi(sz);
  57. CodeAddress(&l);
  58. C_sti(sz);
  59. }
  60. CodeMove(rhs, left, rtp)
  61. register struct desig *rhs;
  62. register struct node *left;
  63. struct type *rtp;
  64. {
  65. struct desig dsl;
  66. register struct desig *lhs = &dsl;
  67. register struct type *ltp = left->nd_type;
  68. dsl = InitDesig;
  69. /* Generate code for an assignment. Testing of type
  70. compatibility and the like is already done.
  71. Go through some (considerable) trouble to see if
  72. a BLM can be generated.
  73. */
  74. switch( rhs->dsg_kind ) {
  75. case DSG_LOADED:
  76. CodeDesig(left, lhs);
  77. if( rtp->tp_fund == T_STRINGCONST ) {
  78. CodeAddress(lhs);
  79. C_blm(lhs->dsg_packed ? ltp->tp_psize : ltp->tp_size);
  80. return;
  81. }
  82. CodeStore(lhs, ltp);
  83. return;
  84. case DSG_PLOADED:
  85. case DSG_PFIXED:
  86. CodeAddress(rhs);
  87. CodeValue(rhs, rtp);
  88. CodeDStore(left);
  89. return;
  90. case DSG_FIXED: {
  91. arith tpsize;
  92. CodeDesig(left, lhs);
  93. tpsize = lhs->dsg_packed ? ltp->tp_psize : ltp->tp_size;
  94. if( lhs->dsg_kind == DSG_FIXED &&
  95. lhs->dsg_offset % word_size == rhs->dsg_offset % word_size
  96. ) {
  97. arith size = tpsize;
  98. if( size > 6 * word_size ) {
  99. /* Do a block move
  100. */
  101. struct desig l, r;
  102. l = *lhs;
  103. r = *rhs;
  104. CodeAddress(&r);
  105. CodeAddress(&l);
  106. C_blm(size);
  107. }
  108. else {
  109. register arith sz;
  110. for( sz = 2 * word_size; sz; sz -= word_size) {
  111. while( size >= sz )
  112. /* Then copy dwords, words.
  113. Depend on peephole optimizer
  114. */
  115. CodeCopy(lhs, rhs, sz, &size);
  116. }
  117. }
  118. return;
  119. }
  120. if( lhs->dsg_kind == DSG_PLOADED ||
  121. lhs->dsg_kind == DSG_INDEXED ) {
  122. CodeAddress(lhs);
  123. }
  124. }
  125. default:
  126. crash("(CodeMove)");
  127. /*NOTREACHED*/
  128. }
  129. }
  130. CodeValue(ds, tp)
  131. register struct desig *ds;
  132. register struct type *tp;
  133. {
  134. /* Generate code to load the value of the designator described
  135. in "ds"
  136. */
  137. arith size = ds->dsg_packed ? tp->tp_psize : tp->tp_size;
  138. int algn = ds->dsg_packed ? tp->tp_palign : tp->tp_align;
  139. switch( ds->dsg_kind ) {
  140. case DSG_LOADED:
  141. return;
  142. case DSG_FIXED:
  143. if( ds->dsg_offset % word_size == 0 ) {
  144. if ( size == word_size ) {
  145. if( ds->dsg_name )
  146. C_loe_dnam(ds->dsg_name, ds->dsg_offset);
  147. else
  148. C_lol(ds->dsg_offset);
  149. break;
  150. } else if ( size == word_size * 2) {
  151. if( ds->dsg_name )
  152. C_lde_dnam(ds->dsg_name, ds->dsg_offset);
  153. else
  154. C_ldl(ds->dsg_offset);
  155. break;
  156. }
  157. }
  158. /* Fall through */
  159. case DSG_PLOADED:
  160. case DSG_PFIXED:
  161. if( properly(ds, size, algn) ) {
  162. CodeAddress(ds);
  163. C_loi(size);
  164. break;
  165. }
  166. crash("(CodeValue)");
  167. break;
  168. case DSG_INDEXED:
  169. C_lar(word_size);
  170. break;
  171. default:
  172. crash("(CodeValue)");
  173. /*NOTREACHED*/
  174. }
  175. if (size < word_size && tp->tp_fund == T_SUBRANGE &&
  176. BaseType(tp)->tp_fund == T_INTEGER && tp->sub_lb < 0) {
  177. C_loc(size);
  178. C_loc(word_size);
  179. C_cii();
  180. }
  181. ds->dsg_kind = DSG_LOADED;
  182. }
  183. CodeStore(ds, tp)
  184. register struct desig *ds;
  185. register struct type *tp;
  186. {
  187. /* Generate code to store the value on the stack in the designator
  188. described in "ds"
  189. */
  190. struct desig save;
  191. arith size = ds->dsg_packed ? tp->tp_psize : tp->tp_size;
  192. int algn = ds->dsg_packed ? tp->tp_palign : tp->tp_align;
  193. save = *ds;
  194. switch( ds->dsg_kind ) {
  195. case DSG_FIXED:
  196. if( ds->dsg_offset % word_size == 0 ) {
  197. if ( size == word_size ) {
  198. if( ds->dsg_name )
  199. C_ste_dnam(ds->dsg_name, ds->dsg_offset);
  200. else
  201. C_stl(ds->dsg_offset);
  202. break;
  203. } else if ( size == word_size * 2) {
  204. if( ds->dsg_name )
  205. C_sde_dnam(ds->dsg_name, ds->dsg_offset);
  206. else
  207. C_sdl(ds->dsg_offset);
  208. break;
  209. }
  210. }
  211. /* Fall through */
  212. case DSG_PLOADED:
  213. case DSG_PFIXED:
  214. CodeAddress(&save);
  215. if( properly(ds, size, algn) ) {
  216. C_sti(size);
  217. break;
  218. }
  219. crash("(CodeStore)");
  220. break;
  221. case DSG_INDEXED:
  222. C_sar(word_size);
  223. break;
  224. default:
  225. crash("(CodeStore)");
  226. /*NOTREACHED*/
  227. }
  228. ds->dsg_kind = DSG_INIT;
  229. }
  230. CodeAddress(ds)
  231. register struct desig *ds;
  232. {
  233. /* Generate code to load the address of the designator described
  234. in "ds"
  235. */
  236. switch( ds->dsg_kind ) {
  237. case DSG_PLOADED:
  238. if( ds->dsg_offset )
  239. C_adp(ds->dsg_offset);
  240. break;
  241. case DSG_FIXED:
  242. if( ds->dsg_name ) {
  243. C_lae_dnam(ds->dsg_name, ds->dsg_offset);
  244. break;
  245. }
  246. C_lal(ds->dsg_offset);
  247. if( ds->dsg_def )
  248. ds->dsg_def->df_flags |= D_NOREG;
  249. break;
  250. case DSG_PFIXED:
  251. if ( word_size == pointer_size ) {
  252. if( ds->dsg_name )
  253. C_loe_dnam(ds->dsg_name, ds->dsg_offset);
  254. else
  255. C_lol(ds->dsg_offset);
  256. break;
  257. } else {
  258. if( ds->dsg_name )
  259. C_lde_dnam(ds->dsg_name, ds->dsg_offset);
  260. else
  261. C_ldl(ds->dsg_offset);
  262. break;
  263. }
  264. case DSG_INDEXED:
  265. C_aar(word_size);
  266. break;
  267. default:
  268. crash("(CodeAddress)");
  269. /*NOTREACHED*/
  270. }
  271. ds->dsg_offset = 0;
  272. ds->dsg_kind = DSG_PLOADED;
  273. }
  274. CodeFieldDesig(df, ds)
  275. register struct def *df;
  276. register struct desig *ds;
  277. {
  278. /* Generate code for a field designator. Only the code common for
  279. address as well as value computation is generated, and the
  280. resulting information on where to find the designator is placed
  281. in "ds". "df" indicates the definition of the field.
  282. */
  283. if( ds->dsg_kind == DSG_INIT ) {
  284. /* In a WITH statement. We must find the designator in the
  285. WITH statement, and act as if the field is a selection
  286. of this designator.
  287. So, first find the right WITH statement, which is the
  288. first one of the proper record type, which is
  289. recognized by its scope indication.
  290. */
  291. register struct withdesig *wds = WithDesigs;
  292. assert(wds != 0);
  293. while( wds->w_scope != df->df_scope ) {
  294. wds = wds->w_next;
  295. assert(wds != 0);
  296. }
  297. /* Found it. Now, act like it was a selection.
  298. */
  299. *ds = wds->w_desig;
  300. assert(ds->dsg_kind == DSG_PFIXED);
  301. }
  302. switch( ds->dsg_kind ) {
  303. case DSG_PLOADED:
  304. case DSG_FIXED:
  305. ds->dsg_offset += df->fld_off;
  306. break;
  307. case DSG_PFIXED:
  308. case DSG_INDEXED:
  309. CodeAddress(ds);
  310. ds->dsg_kind = DSG_PLOADED;
  311. ds->dsg_offset = df->fld_off;
  312. break;
  313. default:
  314. crash("(CodeFieldDesig)");
  315. }
  316. ds->dsg_packed = df->fld_flags & F_PACKED;
  317. }
  318. CodeVarDesig(df, ds)
  319. register struct def *df;
  320. register struct desig *ds;
  321. {
  322. /* Generate code for a variable represented by a "def" structure.
  323. Of course, there are numerous cases: the variable is local,
  324. it is a value parameter, it is a var parameter, it is one of
  325. those of an enclosing procedure, or it is global.
  326. */
  327. register struct scope *sc = df->df_scope;
  328. assert(ds->dsg_kind == DSG_INIT);
  329. if( df->var_name ) {
  330. /* this variable has been given a name, so it is global.
  331. It is directly accessible.
  332. */
  333. ds->dsg_name = df->var_name;
  334. ds->dsg_offset = 0;
  335. ds->dsg_kind = DSG_FIXED;
  336. return;
  337. }
  338. if( sc->sc_level != proclevel ) {
  339. /* the variable is local to a statically enclosing procedure.
  340. */
  341. assert(proclevel > sc->sc_level);
  342. df->df_flags |= D_NOREG;
  343. if( df->df_flags & (D_VARPAR|D_VALPAR) ) {
  344. /* value or var parameter
  345. */
  346. C_lxa((arith) (proclevel - sc->sc_level));
  347. if( (df->df_flags & D_VARPAR) ||
  348. IsConformantArray(df->df_type) ) {
  349. /* var parameter or conformant array.
  350. For conformant array's, the address is
  351. passed.
  352. */
  353. C_adp(df->var_off);
  354. C_loi(pointer_size);
  355. ds->dsg_offset = 0;
  356. ds->dsg_kind = DSG_PLOADED;
  357. return;
  358. }
  359. }
  360. else
  361. C_lxl((arith) (proclevel - sc->sc_level));
  362. ds->dsg_kind = DSG_PLOADED;
  363. ds->dsg_offset = df->var_off;
  364. return;
  365. }
  366. /* Now, finally, we have a local variable or a local parameter
  367. */
  368. if( (df->df_flags & D_VARPAR) || IsConformantArray(df->df_type) )
  369. /* a var parameter; address directly accessible. */
  370. ds->dsg_kind = DSG_PFIXED;
  371. else
  372. ds->dsg_kind = DSG_FIXED;
  373. ds->dsg_offset = df->var_off;
  374. ds->dsg_def = df;
  375. }
  376. CodeBoundDesig(df, ds)
  377. register struct def *df;
  378. register struct desig *ds;
  379. {
  380. /* Generate code for the lower- and upperbound of a conformant array */
  381. assert(ds->dsg_kind == DSG_INIT);
  382. if( df->df_scope->sc_level < proclevel ) {
  383. C_lxa((arith) (proclevel - df->df_scope->sc_level));
  384. C_lof(df->bnd_type->arr_cfdescr);
  385. if( df->df_kind == D_UBOUND ) {
  386. C_lxa((arith) (proclevel - df->df_scope->sc_level));
  387. C_lof(df->bnd_type->arr_cfdescr+word_size);
  388. C_adi(word_size);
  389. }
  390. }
  391. else {
  392. C_lol(df->bnd_type->arr_cfdescr);
  393. if( df->df_kind == D_UBOUND ) {
  394. C_lol(df->bnd_type->arr_cfdescr+word_size);
  395. C_adi(word_size);
  396. }
  397. }
  398. ds->dsg_kind = DSG_LOADED;
  399. }
  400. CodeFuncDesig(df, ds)
  401. register struct def *df;
  402. register struct desig *ds;
  403. {
  404. /* generate code to store the function result */
  405. if( df->df_scope->sc_level + 1 < proclevel ) {
  406. /* Assignment to function-identifier in the declaration-part of
  407. the function (i.e. in the statement-part of a nested function
  408. or procedure).
  409. */
  410. if( !options['R'] ) {
  411. C_loc((arith)1);
  412. C_lxl((arith) (proclevel - df->df_scope->sc_level - 1));
  413. C_adp(df->prc_bool);
  414. C_sti(int_size);
  415. }
  416. C_lxl((arith) (proclevel - df->df_scope->sc_level - 1));
  417. ds->dsg_kind = DSG_PLOADED;
  418. }
  419. else {
  420. /* Assignment to function-identifier in the statement-part of
  421. the function.
  422. */
  423. if( !options['R'] ) {
  424. C_loc((arith)1);
  425. C_stl(df->prc_bool);
  426. }
  427. ds->dsg_kind = DSG_FIXED;
  428. }
  429. assert(df->prc_res < 0);
  430. ds->dsg_offset = df->prc_res;
  431. }
  432. CodeDesig(nd, ds)
  433. register struct node *nd;
  434. register struct desig *ds;
  435. {
  436. /* Generate code for a designator. Use divide and conquer
  437. principle
  438. */
  439. register struct def *df;
  440. switch( nd->nd_class ) { /* Divide */
  441. case Def:
  442. df = nd->nd_def;
  443. switch( (int) df->df_kind ) {
  444. case D_FIELD:
  445. CodeFieldDesig(df, ds);
  446. break;
  447. case D_VARIABLE:
  448. CodeVarDesig(df, ds);
  449. break;
  450. case D_LBOUND:
  451. case D_UBOUND:
  452. CodeBoundDesig(df, ds);
  453. break;
  454. case D_FUNCTION:
  455. CodeFuncDesig(df, ds);
  456. break;
  457. default:
  458. crash("(CodeDesig) Def");
  459. }
  460. break;
  461. case LinkDef:
  462. assert(nd->nd_symb == '.');
  463. CodeDesig(nd->nd_left, ds);
  464. CodeFieldDesig(nd->nd_def, ds);
  465. break;
  466. case Arrsel: {
  467. struct type *tp;
  468. assert(nd->nd_symb == '[');
  469. CodeDesig(nd->nd_left, ds);
  470. CodeAddress(ds);
  471. CodePExpr(nd->nd_right);
  472. /* Now load address of descriptor
  473. */
  474. tp = nd->nd_left->nd_type;
  475. if( IsConformantArray(tp) ) {
  476. if( tp->arr_sclevel < proclevel ) {
  477. C_lxa((arith) (proclevel - tp->arr_sclevel));
  478. C_adp(tp->arr_cfdescr);
  479. }
  480. else
  481. C_lal(tp->arr_cfdescr);
  482. }
  483. else
  484. C_lae_dlb(tp->arr_ardescr, (arith) 0);
  485. if( options['A'] ) {
  486. C_cal("_rcka");
  487. }
  488. ds->dsg_kind = DSG_INDEXED;
  489. ds->dsg_packed = IsPacked(tp);
  490. break;
  491. }
  492. case Arrow:
  493. assert(nd->nd_symb == '^');
  494. if( nd->nd_right->nd_type->tp_fund == T_FILE ) {
  495. CodeDAddress(nd->nd_right);
  496. C_cal("_wdw");
  497. C_asp(pointer_size);
  498. C_lfr(pointer_size);
  499. ds->dsg_kind = DSG_PLOADED;
  500. ds->dsg_packed = 1;
  501. break;
  502. }
  503. CodeDesig(nd->nd_right, ds);
  504. switch(ds->dsg_kind) {
  505. case DSG_LOADED:
  506. ds->dsg_kind = DSG_PLOADED;
  507. break;
  508. case DSG_INDEXED:
  509. case DSG_PLOADED:
  510. case DSG_PFIXED:
  511. CodeValue(ds, nd->nd_right->nd_type);
  512. ds->dsg_kind = DSG_PLOADED;
  513. ds->dsg_offset = 0;
  514. break;
  515. case DSG_FIXED:
  516. ds->dsg_kind = DSG_PFIXED;
  517. break;
  518. default:
  519. crash("(CodeDesig) Uoper");
  520. }
  521. break;
  522. default:
  523. crash("(CodeDesig) class");
  524. }
  525. }