compute.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  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. * Author: Hans van Staveren
  6. */
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include "assert.h"
  11. #include "param.h"
  12. #include "tables.h"
  13. #include "types.h"
  14. #include <cgg_cg.h>
  15. #include "data.h"
  16. #include "result.h"
  17. #include "glosym.h"
  18. #include "extern.h"
  19. #include "salloc.h"
  20. #include "utils.h"
  21. #include "regvar.h"
  22. #ifdef USE_TES
  23. #include "label.h"
  24. #endif
  25. #include "compute.h"
  26. #define LLEAF 01
  27. #define LDEF 02
  28. #define RLEAF 04
  29. #define RDEF 010
  30. #define LLDEF LLEAF|LDEF
  31. #define RLDEF RLEAF|RDEF
  32. char opdesc[] = {
  33. 0, /* EX_TOKFIELD */
  34. 0, /* EX_ARG */
  35. 0, /* EX_CON */
  36. 0, /* EX_ALLREG */
  37. LLDEF|RLDEF, /* EX_SAMESIGN */
  38. LLDEF|RLDEF, /* EX_SFIT */
  39. LLDEF|RLDEF, /* EX_UFIT */
  40. 0, /* EX_ROM */
  41. LLDEF|RLDEF, /* EX_NCPEQ */
  42. LLDEF|RLDEF, /* EX_SCPEQ */
  43. LLDEF|RLDEF, /* EX_RCPEQ */
  44. LLDEF|RLDEF, /* EX_NCPNE */
  45. LLDEF|RLDEF, /* EX_SCPNE */
  46. LLDEF|RLDEF, /* EX_RCPNE */
  47. LLDEF|RLDEF, /* EX_NCPGT */
  48. LLDEF|RLDEF, /* EX_NCPGE */
  49. LLDEF|RLDEF, /* EX_NCPLT */
  50. LLDEF|RLDEF, /* EX_NCPLE */
  51. LLDEF, /* EX_OR2 */
  52. LLDEF, /* EX_AND2 */
  53. LLDEF|RLDEF, /* EX_PLUS */
  54. LLDEF|RLDEF, /* EX_CAT */
  55. LLDEF|RLDEF, /* EX_MINUS */
  56. LLDEF|RLDEF, /* EX_TIMES */
  57. LLDEF|RLDEF, /* EX_DIVIDE */
  58. LLDEF|RLDEF, /* EX_MOD */
  59. LLDEF|RLDEF, /* EX_LSHIFT */
  60. LLDEF|RLDEF, /* EX_RSHIFT */
  61. LLDEF, /* EX_NOT */
  62. LLDEF, /* EX_COMP */
  63. 0, /* EX_COST */
  64. 0, /* EX_STRING */
  65. LLEAF, /* EX_DEFINED */
  66. 0, /* EX_SUBREG */
  67. LLDEF, /* EX_TOSTRING */
  68. LLDEF, /* EX_UMINUS */
  69. 0, /* EX_REG */
  70. 0, /* EX_LOWW */
  71. 0, /* EX_HIGHW */
  72. LLDEF, /* EX_INREG */
  73. LLDEF, /* EX_REGVAR */
  74. LLDEF|RLDEF, /* EX_OR */
  75. LLDEF|RLDEF, /* EX_XOR */
  76. LLDEF|RLDEF, /* EX_AND */
  77. 0, /* EX_ISROM */
  78. #ifdef USE_TES
  79. 0, /* EX_TOPELTSIZE */
  80. 0, /* EX_FALLTHROUGH */
  81. #endif
  82. };
  83. string mycat(string s1, string s2)
  84. {
  85. string s;
  86. if (s1==0 || *s1=='\0') return(s2);
  87. if (s2==0 || *s2=='\0') return(s1);
  88. s=salloc(strlen(s1)+strlen(s2)+1);
  89. strcpy(s,s1);
  90. strcat(s,"+");
  91. strcat(s,s2);
  92. return(s);
  93. }
  94. string mystrcpy(string s)
  95. {
  96. string r;
  97. r=salloc(strlen(s));
  98. strcpy(r,s);
  99. return(r);
  100. }
  101. char digstr[21][15];
  102. string tostring(word n)
  103. {
  104. char buf[25];
  105. if (n>=-20 && n<=20 && (n&1)==0) {
  106. if (digstr[((int)n>>1)+10][0]==0)
  107. sprintf(digstr[((int)n>>1)+10],WRD_FMT,n);
  108. return(digstr[((int)n>>1)+10]);
  109. }
  110. sprintf(buf,WRD_FMT,n);
  111. return(mystrcpy(buf));
  112. }
  113. void compute(node_p node, result_t *presult)
  114. {
  115. result_t leaf1,leaf2;
  116. token_p tp;
  117. int desc;
  118. long mask,tmp;
  119. int i,tmpreg;
  120. glosym_p gp;
  121. presult->e_typ = EV_UNDEF;
  122. desc=opdesc[node->ex_operator];
  123. if (desc&LLEAF) {
  124. compute(&enodes[node->ex_lnode], &leaf1);
  125. if (desc&LDEF && leaf1.e_typ==EV_UNDEF)
  126. return;
  127. }
  128. if (desc&RLEAF) {
  129. compute(&enodes[node->ex_rnode], &leaf2);
  130. if (desc&RDEF && leaf2.e_typ==EV_UNDEF)
  131. return;
  132. }
  133. presult->e_typ=EV_INT;
  134. switch(node->ex_operator) {
  135. default: assert(FALSE);
  136. case EX_TOKFIELD:
  137. if (node->ex_lnode==0)
  138. if (curtoken) tp = curtoken;
  139. else tp = &fakestack[stackheight-1];
  140. else tp = &fakestack[stackheight-node->ex_lnode];
  141. switch(presult->e_typ = tokens[tp->t_token].t_type[node->ex_rnode-1]) {
  142. default:
  143. assert(FALSE);
  144. case EV_INT:
  145. presult->e_v.e_con = tp->t_att[node->ex_rnode-1].aw;
  146. break;
  147. case EV_ADDR:
  148. presult->e_v.e_addr = tp->t_att[node->ex_rnode-1].aa;
  149. break;
  150. case EV_REG:
  151. presult->e_v.e_reg = tp->t_att[node->ex_rnode-1].ar;
  152. break;
  153. }
  154. return;
  155. case EX_ARG:
  156. *presult = dollar[node->ex_lnode-1];
  157. return;
  158. case EX_CON:
  159. presult->e_typ = EV_INT;
  160. presult->e_v.e_con = ((long) node->ex_rnode << 16) | ((long)node->ex_lnode&0xffff);
  161. return;
  162. case EX_REG:
  163. presult->e_typ = EV_REG;
  164. presult->e_v.e_reg = node->ex_lnode;
  165. return;
  166. case EX_ALLREG:
  167. presult->e_typ = EV_REG;
  168. presult->e_v.e_reg = allreg[node->ex_lnode-1];
  169. #if MAXMEMBERS!=0
  170. if (node->ex_rnode!=0)
  171. presult->e_v.e_reg = machregs[presult->e_v.e_reg].
  172. r_members[node->ex_rnode-1];
  173. #endif
  174. return;
  175. case EX_SAMESIGN:
  176. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  177. presult->e_typ = EV_INT;
  178. if (leaf1.e_v.e_con>=0)
  179. presult->e_v.e_con= leaf2.e_v.e_con>=0;
  180. else
  181. presult->e_v.e_con= leaf2.e_v.e_con<0;
  182. return;
  183. case EX_SFIT:
  184. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  185. mask = 0xFFFFFFFFL;
  186. for (i=0;i<leaf2.e_v.e_con-1;i++)
  187. mask &= ~(1<<i);
  188. tmp = leaf1.e_v.e_con&mask;
  189. presult->e_v.e_con = tmp==0||tmp==mask;
  190. return;
  191. case EX_UFIT:
  192. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  193. mask = 0xFFFFFFFFL;
  194. for (i=0;i<leaf2.e_v.e_con;i++)
  195. mask &= ~(1<<i);
  196. presult->e_v.e_con = (leaf1.e_v.e_con&mask)==0;
  197. return;
  198. case EX_ROM:
  199. assert(node->ex_rnode>=0 &&node->ex_rnode<MAXROM);
  200. leaf2=dollar[node->ex_lnode];
  201. presult->e_typ = EV_UNDEF;
  202. if (leaf2.e_typ != EV_ADDR)
  203. return;
  204. if (leaf2.e_v.e_addr.ea_off!=0)
  205. return;
  206. gp = lookglo(leaf2.e_v.e_addr.ea_str);
  207. if (gp == (glosym_p) 0)
  208. return;
  209. if ((gp->gl_rom[MAXROM]&(1<<node->ex_rnode))==0)
  210. return;
  211. presult->e_typ = EV_INT;
  212. presult->e_v.e_con = gp->gl_rom[node->ex_rnode];
  213. return;
  214. case EX_ISROM:
  215. leaf2=dollar[node->ex_lnode];
  216. if (leaf2.e_typ != EV_ADDR)
  217. presult->e_v.e_con = 0;
  218. else
  219. presult->e_v.e_con = lookglo(leaf2.e_v.e_addr.ea_str) != 0;
  220. return;
  221. case EX_LOWW:
  222. presult->e_v.e_con = saveemp[node->ex_lnode].em_u.em_loper&0xFFFF;
  223. return;
  224. case EX_HIGHW:
  225. presult->e_v.e_con = saveemp[node->ex_lnode].em_u.em_loper>>16;
  226. return;
  227. case EX_NCPEQ:
  228. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  229. presult->e_v.e_con = leaf1.e_v.e_con==leaf2.e_v.e_con;
  230. return;
  231. case EX_SCPEQ:
  232. assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR);
  233. presult->e_v.e_con =
  234. (strcmp(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str)==0 &&
  235. leaf1.e_v.e_addr.ea_off==leaf2.e_v.e_addr.ea_off);
  236. return;
  237. case EX_RCPEQ:
  238. assert(leaf1.e_typ == EV_REG && leaf2.e_typ == EV_REG);
  239. presult->e_v.e_con = leaf1.e_v.e_reg==leaf2.e_v.e_reg;
  240. return;
  241. case EX_NCPNE:
  242. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  243. presult->e_v.e_con = leaf1.e_v.e_con!=leaf2.e_v.e_con;
  244. return;
  245. case EX_SCPNE:
  246. assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR);
  247. presult->e_v.e_con =
  248. !(strcmp(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str)==0 &&
  249. leaf1.e_v.e_addr.ea_off==leaf2.e_v.e_addr.ea_off);
  250. return;
  251. case EX_RCPNE:
  252. assert(leaf1.e_typ == EV_REG && leaf2.e_typ == EV_REG);
  253. presult->e_v.e_con = leaf1.e_v.e_reg!=leaf2.e_v.e_reg;
  254. return;
  255. case EX_NCPGT:
  256. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  257. presult->e_v.e_con = leaf1.e_v.e_con>leaf2.e_v.e_con;
  258. return;
  259. case EX_NCPGE:
  260. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  261. presult->e_v.e_con = leaf1.e_v.e_con>=leaf2.e_v.e_con;
  262. return;
  263. case EX_NCPLT:
  264. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  265. presult->e_v.e_con = leaf1.e_v.e_con<leaf2.e_v.e_con;
  266. return;
  267. case EX_NCPLE:
  268. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  269. presult->e_v.e_con = leaf1.e_v.e_con<=leaf2.e_v.e_con;
  270. return;
  271. case EX_OR2:
  272. assert(leaf1.e_typ == EV_INT);
  273. if (leaf1.e_v.e_con==0) {
  274. compute(&enodes[node->ex_rnode], presult);
  275. }
  276. else *presult = leaf1;
  277. return;
  278. case EX_AND2:
  279. assert(leaf1.e_typ == EV_INT);
  280. if (leaf1.e_v.e_con!=0) {
  281. compute(&enodes[node->ex_rnode], presult);
  282. }
  283. else *presult = leaf1;
  284. return;
  285. case EX_PLUS:
  286. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  287. presult->e_v.e_con=leaf1.e_v.e_con+leaf2.e_v.e_con;
  288. return;
  289. case EX_CAT:
  290. assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR);
  291. presult->e_typ = EV_ADDR;
  292. presult->e_v.e_addr.ea_str = mycat(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str);
  293. presult->e_v.e_addr.ea_off = leaf1.e_v.e_addr.ea_off+leaf2.e_v.e_addr.ea_off;
  294. return;
  295. case EX_MINUS:
  296. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  297. presult->e_v.e_con = leaf1.e_v.e_con - leaf2.e_v.e_con;
  298. return;
  299. case EX_OR:
  300. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  301. presult->e_v.e_con = leaf1.e_v.e_con | leaf2.e_v.e_con;
  302. return;
  303. case EX_XOR:
  304. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  305. presult->e_v.e_con = leaf1.e_v.e_con ^ leaf2.e_v.e_con;
  306. return;
  307. case EX_AND:
  308. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  309. presult->e_v.e_con = leaf1.e_v.e_con & leaf2.e_v.e_con;
  310. return;
  311. case EX_TIMES:
  312. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  313. presult->e_v.e_con = leaf1.e_v.e_con * leaf2.e_v.e_con;
  314. return;
  315. case EX_DIVIDE:
  316. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  317. presult->e_v.e_con = leaf1.e_v.e_con / leaf2.e_v.e_con;
  318. return;
  319. case EX_MOD:
  320. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  321. presult->e_v.e_con = leaf1.e_v.e_con % leaf2.e_v.e_con;
  322. return;
  323. case EX_LSHIFT:
  324. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  325. presult->e_v.e_con = leaf1.e_v.e_con << leaf2.e_v.e_con;
  326. return;
  327. case EX_RSHIFT:
  328. assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
  329. presult->e_v.e_con = leaf1.e_v.e_con >> leaf2.e_v.e_con;
  330. return;
  331. case EX_NOT:
  332. assert(leaf1.e_typ == EV_INT);
  333. presult->e_v.e_con = !leaf1.e_v.e_con;
  334. return;
  335. case EX_COMP:
  336. assert(leaf1.e_typ == EV_INT);
  337. presult->e_v.e_con = ~leaf1.e_v.e_con;
  338. return;
  339. case EX_STRING:
  340. presult->e_typ = EV_ADDR;
  341. presult->e_v.e_addr.ea_str = codestrings[node->ex_lnode];
  342. presult->e_v.e_addr.ea_off = 0;
  343. return;
  344. case EX_DEFINED:
  345. presult->e_v.e_con=leaf1.e_typ!=EV_UNDEF;
  346. return;
  347. case EX_SUBREG:
  348. presult->e_typ = EV_REG;
  349. if (node->ex_lnode==0)
  350. if (curtoken) tp = curtoken;
  351. else tp = &fakestack[stackheight-1];
  352. else tp = &fakestack[stackheight-node->ex_lnode];
  353. assert(tp->t_token == -1);
  354. tmpreg= tp->t_att[0].ar;
  355. #if MAXMEMBERS!=0
  356. if (node->ex_rnode)
  357. tmpreg=machregs[tmpreg].r_members[node->ex_rnode-1];
  358. #endif
  359. presult->e_v.e_reg=tmpreg;
  360. return;
  361. case EX_TOSTRING:
  362. assert(leaf1.e_typ == EV_INT);
  363. presult->e_typ = EV_ADDR;
  364. presult->e_v.e_addr.ea_str = "";
  365. presult->e_v.e_addr.ea_off = leaf1.e_v.e_con;
  366. return;
  367. #ifdef REGVARS
  368. case EX_INREG:
  369. assert(leaf1.e_typ == EV_INT);
  370. presult->e_v.e_con = isregtyp((long) leaf1.e_v.e_con);
  371. return;
  372. case EX_REGVAR:
  373. assert(leaf1.e_typ == EV_INT);
  374. i = isregvar((long) leaf1.e_v.e_con);
  375. if (i<=0) {
  376. presult->e_typ = EV_UNDEF;
  377. return;
  378. }
  379. presult->e_typ = EV_REG;
  380. presult->e_v.e_reg=i;
  381. return;
  382. #endif
  383. case EX_UMINUS:
  384. assert(leaf1.e_typ == EV_INT);
  385. presult->e_v.e_con = -leaf1.e_v.e_con;
  386. return;
  387. #ifdef USE_TES
  388. case EX_TOPELTSIZE: /* Hans, new */
  389. { register label_p lbl;
  390. lbl = get_label(saveemp[node->ex_lnode].em_u.em_ioper);
  391. if (lbl != (label_p)0) {
  392. presult->e_v.e_con = lbl->lb_height;
  393. } else {
  394. presult->e_v.e_con = 0;
  395. }
  396. return;
  397. }
  398. case EX_FALLTHROUGH: /* Hans, new */
  399. { register label_p lbl;
  400. lbl = get_label(saveemp[node->ex_lnode].em_u.em_ioper);
  401. if (lbl != (label_p)0) {
  402. presult->e_v.e_con = lbl->lb_fallthrough;
  403. } else presult->e_v.e_con = 0;
  404. return;
  405. }
  406. #endif
  407. }
  408. }