subr.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  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. #include <stdlib.h>
  6. #include <string.h>
  7. #include "param.h"
  8. #include "reg.h"
  9. #include "lookup.h"
  10. #include "property.h"
  11. #include "expr.h"
  12. #include "set.h"
  13. #include "varinfo.h"
  14. #include "instruct.h"
  15. #include "token.h"
  16. #include "regvar.h"
  17. #include "error.h"
  18. #include "subr.h"
  19. #include <cgg_cg.h>
  20. #include "extern.h"
  21. #include "strlookup.h"
  22. #include "hall.h"
  23. void n_proc(char *name)
  24. {
  25. symbol *sy_p;
  26. extern int npatbytes;
  27. sy_p = lookup(name,symproc,newsymbol);
  28. sy_p->sy_value.syv_procoff = npatbytes + 1;
  29. }
  30. struct varinfo *make_erase(char *name)
  31. {
  32. expr_t e;
  33. struct varinfo *result;
  34. e = ident_expr(name);
  35. if (e.ex_typ != TYPREG)
  36. error("Register name required here");
  37. NEW(result,struct varinfo);
  38. result->vi_next = VI_NULL;
  39. result->vi_int[0] = e.ex_index;
  40. return(result);
  41. }
  42. void n_instr(char *name, char *asname, operand *oplist, struct varinfo *eraselist, struct varinfo *cost)
  43. {
  44. int instrno;
  45. int cc_count;
  46. instr_p ip;
  47. instrno = NEXT(ninstr,MAXINSTR,"Instructions");
  48. ip = &l_instr[instrno];
  49. ip->i_name = name;
  50. ip->i_asname = strlookup(asname!=0 ? asname : name);
  51. ip->i_nops = 0;
  52. ip->i_oplist = oplist;
  53. ip->i_erases = eraselist;
  54. if (cost==0) {
  55. ip->i_cost.ct_space = 0;
  56. ip->i_cost.ct_time = 0;
  57. } else {
  58. ip->i_cost.ct_space = cost->vi_int[0];
  59. ip->i_cost.ct_space = cost->vi_int[1];
  60. }
  61. for (cc_count=0; oplist!=0; oplist = oplist->o_next) {
  62. ip->i_nops++;
  63. if(oplist->o_adorn&AD_CC)
  64. cc_count++;
  65. }
  66. while (eraselist!=VI_NULL) {
  67. if (eraselist->vi_int[0] == -1 && cc_count)
  68. error("Instruction can't both set and break the condition codes");
  69. eraselist=eraselist->vi_next;
  70. }
  71. if (cc_count>1)
  72. error("No instruction can set condition codes more than once");
  73. }
  74. void n_set(char *name, int number)
  75. {
  76. symbol *sy_p;
  77. sy_p = lookup(name,symset,newsymbol);
  78. sy_p->sy_value.syv_setno = number;
  79. }
  80. void n_tok(char *name,struct varinfo *atts, int size, struct varinfo *cost, struct varinfo *format)
  81. {
  82. symbol *sy_p;
  83. token_p tp;
  84. struct varinfo *vip;
  85. int i;
  86. int tokno;
  87. int thistokensize;
  88. char formstr[50],smallstr[2];
  89. sy_p = lookup(name,symtok,newsymbol);
  90. NEW(tp,token_t);
  91. tokno = NEXT(ntokens,MAXTOKENS,"Tokens");
  92. sy_p->sy_value.syv_tokno = tokno;
  93. l_tokens[tokno] = tp;
  94. tp->tk_name = sy_p->sy_name;
  95. tp->tk_size = size;
  96. if (cost != 0) {
  97. tp->tk_cost.ct_space = cost->vi_int[0];
  98. tp->tk_cost.ct_time = cost->vi_int[1];
  99. } else {
  100. tp->tk_cost.ct_space = 0;
  101. tp->tk_cost.ct_time = 0;
  102. }
  103. for(i=0,vip=atts;i<MAXATT && vip!=0;i++,vip=vip->vi_next) {
  104. tp->tk_att[i].ta_type = vip->vi_int[0];
  105. tp->tk_att[i].ta_name = vip->vi_str[0];
  106. vip->vi_str[0]=0;
  107. }
  108. thistokensize=i;
  109. if (i>maxtokensize)
  110. maxtokensize=i;
  111. if (vip!=0)
  112. error("More then %d attributes, rest discarded",MAXATT);
  113. for(;i<MAXATT;i++)
  114. tp->tk_att[i].ta_type= -3;
  115. if (format!=0) {
  116. formstr[0] = 0;
  117. for (vip=format;vip!=0;vip=vip->vi_next) {
  118. if (vip->vi_int[0]==0)
  119. strcat(formstr,vip->vi_str[0]);
  120. else {
  121. for(i=0;i<thistokensize;i++) {
  122. if (strcmp(vip->vi_str[0],tp->tk_att[i].ta_name)==0) {
  123. smallstr[0] = i+1;
  124. smallstr[1] = 0;
  125. strcat(formstr,smallstr);
  126. break;
  127. }
  128. }
  129. if (i==thistokensize)
  130. error("%s not a known attribute",
  131. vip->vi_str[0]);
  132. }
  133. }
  134. tp->tk_format = strlookup(formstr);
  135. } else
  136. tp->tk_format = -1;
  137. }
  138. void checkprintformat(int n)
  139. {
  140. short *s;
  141. int i;
  142. extern set_t l_sets[];
  143. s= l_sets[n].set_val;
  144. for(i=nregs;i<nregs+ntokens;i++)
  145. if (BIT(s,i) && l_tokens[i-nregs]->tk_format<0)
  146. error("Token %s in set does not have printformat",
  147. l_tokens[i-nregs]->tk_name);
  148. }
  149. void n_prop(char *name, int size)
  150. {
  151. int propno;
  152. symbol *sp;
  153. propno = NEXT(nprops,MAXPROPS,"Properties");
  154. sp = lookup(name,symprop,newsymbol);
  155. sp->sy_value.syv_propno = propno;
  156. if (size <= 0) {
  157. error("Size of property must be >0");
  158. size = wordsize;
  159. }
  160. l_props[propno].pr_size = size;
  161. }
  162. void prophall(int n) {
  163. int i;
  164. short hallset[SETSIZE];
  165. if (n < 0) return;
  166. for(i=0;i<SETSIZE;i++)
  167. hallset[i] = i<SZOFSET(MAXREGS) ? l_props[n].pr_regset[i] : 0;
  168. nexthall(hallset);
  169. }
  170. int n_reg(char *name, char *printstring, int nmemb, int member1, int member2)
  171. {
  172. symbol *sy_p;
  173. reginfo *ri_p;
  174. int regno;
  175. sy_p = lookup(name,symreg,newsymbol);
  176. sy_p->sy_value.syv_regno = regno = NEXT(nregs,MAXREGS,"Number of registers");
  177. ri_p = &l_regs[regno];
  178. ri_p->ri_name = mystrcpy(name);
  179. ri_p->ri_repr = printstring!=0 ? mystrcpy(printstring) : ri_p->ri_name;
  180. ri_p->ri_memb[0] = member1;
  181. ri_p->ri_memb[1] = member2;
  182. if (nmemb>maxmembers)
  183. maxmembers=nmemb;
  184. return(regno);
  185. }
  186. void make_const()
  187. {
  188. wordsize = cmustbeset("EM_WSIZE");
  189. pointersize = cmustbeset("EM_PSIZE");
  190. }
  191. int cmustbeset(char *ident)
  192. {
  193. return(lookup(ident,symconst,mustexist)->sy_value.syv_cstval);
  194. }
  195. void n_const(char *ident, int val)
  196. {
  197. symbol *sy_p;
  198. sy_p = lookup(ident,symconst,newsymbol);
  199. sy_p->sy_value.syv_cstval = val;
  200. }
  201. void n_sconst(char *ident, char *val)
  202. {
  203. symbol *sy_p;
  204. sy_p = lookup(ident,symsconst,newsymbol);
  205. sy_p->sy_value.syv_stringno = strlookup(val);
  206. }
  207. void regline(varinfo *rl, varinfo *pl, int rv)
  208. {
  209. varinfo *rrl,*rpl;
  210. short *sp;
  211. reginfo *regp;
  212. int thissize;
  213. int propno;
  214. for(rrl=rl;rrl!=0;rrl=rrl->vi_next) {
  215. regp = &l_regs[rrl->vi_int[0]];
  216. thissize = 0;
  217. for(rpl=pl;rpl!=0;rpl=rpl->vi_next) {
  218. propno = rpl->vi_int[0];
  219. sp= l_props[propno].pr_regset;
  220. BIS(sp,rrl->vi_int[0]);
  221. if (thissize==0)
  222. thissize = l_props[propno].pr_size;
  223. else if (thissize!=-1 && thissize!=l_props[propno].pr_size)
  224. error("Register %s has no clear size",
  225. regp->ri_name);
  226. }
  227. regp->ri_size = thissize;
  228. regp->ri_class = regclass;
  229. regp->ri_rregvar = rv;
  230. if (rv>=0) {
  231. if (regp->ri_memb[0]!=0)
  232. error("Register variables may not have subregisters");
  233. rvused |= ANY_REGVAR;
  234. if (regp->ri_size == wordsize)
  235. rvused |= SL_REGVAR;
  236. else if (regp->ri_size == 2*wordsize)
  237. rvused |= DL_REGVAR;
  238. if (nregvar[rv]==0)
  239. rvsize[rv] = regp->ri_size;
  240. else if (rvsize[rv]!=regp->ri_size)
  241. error("All variables of one type must have the same size");
  242. NEXT(nregvar[rv],MAXREGVAR,"Register variable");
  243. rvnumbers[rv][nregvar[rv]-1] = rrl->vi_int[0];
  244. }
  245. }
  246. regclass++;
  247. }
  248. void setallreg(struct varinfo *vi)
  249. {
  250. nallreg=0;
  251. for(;vi!=0;vi=vi->vi_next) {
  252. if (vi->vi_int[0]<0)
  253. continue;
  254. allreg[nallreg++] = vi->vi_int[0];
  255. }
  256. }
  257. void freevi(struct varinfo *vip)
  258. {
  259. int i;
  260. if (vip==0)
  261. return;
  262. freevi(vip->vi_next);
  263. freevi(vip->vi_vi);
  264. for (i=0;i<VI_NSTR;i++)
  265. free((char *) vip->vi_str[i]);
  266. free(vip);
  267. }
  268. int myatoi(char *s)
  269. {
  270. int base=10;
  271. int sum=0;
  272. if (*s=='0') {
  273. base = 8;
  274. s++;
  275. if (*s=='x') {
  276. base=16;
  277. s++;
  278. }
  279. }
  280. for (;;) {
  281. switch (*s) {
  282. default: return(sum);
  283. case '8':
  284. case '9':
  285. if (base==8) error("Bad digit in octal number");
  286. case '0':
  287. case '1':
  288. case '2':
  289. case '3':
  290. case '4':
  291. case '5':
  292. case '6':
  293. case '7':
  294. sum = sum*base + *s++ - '0';
  295. break;
  296. case 'a':
  297. case 'b':
  298. case 'c':
  299. case 'd':
  300. case 'e':
  301. case 'f':
  302. if (base!=16) error("Hexletter in number not expected");
  303. sum = sum*base + 10 + *s++ - 'a';
  304. break;
  305. case 'A':
  306. case 'B':
  307. case 'C':
  308. case 'D':
  309. case 'E':
  310. case 'F':
  311. if (base!=16) error("Hexletter in number not expected");
  312. sum = sum*base + 10 + *s++ - 'A';
  313. break;
  314. }
  315. }
  316. }
  317. char *mystrcpy(char *s)
  318. {
  319. char *p;
  320. p=myalloc(strlen(s)+1);
  321. strcpy(p,s);
  322. return(p);
  323. }
  324. char *myalloc(int n)
  325. {
  326. char *p,*result;
  327. result=p=malloc(n);
  328. if (p== (char *) 0)
  329. fatal("Out of memory");
  330. do *p++=0; while (--n);
  331. return(result);
  332. }
  333. int chkincl(int value, int lwb, int upb)
  334. {
  335. if (value<lwb || value>upb)
  336. error("Number %d should have been between %d and %d",
  337. value,lwb,upb);
  338. return(value);
  339. }
  340. int subset(short *sp1, short *sp2, int setsize)
  341. {
  342. int i;
  343. for(i=0;i<setsize;i++)
  344. if ( (sp1[i] | sp2[i]) != sp2[i])
  345. return(0);
  346. return(1);
  347. }
  348. int vilength(struct varinfo *vip)
  349. {
  350. int l=0;
  351. while(vip!=0) {
  352. vip=vip->vi_next;
  353. l++;
  354. }
  355. return(l);
  356. }