subr.c 8.1 KB

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