compute.c 11 KB

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