amac2.clu 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. % AMAC2 CLU
  2. %
  3. % CLUMAC assembler: macro definitions
  4. m_pcall = proc (e: env);
  5. ref: wrd := get_wrd(e);
  6. m_args(e);
  7. reg, disp: int := tdlink(e, ref);
  8. put_xinst(e, MOVE, MR, reg, disp);
  9. put_xinst(e, XCT, 0, MR, _en_set);
  10. end m_pcall;
  11. m_force = proc (e: env);
  12. put_inst(e, PUSH, SP, 0, get_wrd(e));
  13. typreg(e, wrd$create(0, RR), get_wrd(e));
  14. put_xinst(e, LDB, N1, 0, _dtypbp);
  15. put_xinst(e, CAIE, N1, RR, 0);
  16. put_xinst(e, JSP, XR, 0, _badtyp);
  17. put_xinst(e, POP, SP, 0, RR);
  18. end m_force;
  19. m_xcall = proc (e: env);
  20. addr: wrd := get_wrd(e);
  21. num: int := get_number(e);
  22. m_args(e);
  23. if ~(wrd$iequal(addr, RR) cor wrd$iequal(addr, 0))
  24. then put_inst(e, MOVE, RR, 0, addr); end;
  25. put_xinst(e, HRRZ, MR, 0, RR);
  26. put_xinst(e, XCT, 0, MR, _en_set);
  27. end m_xcall;
  28. m_arrgen = proc (e: env);
  29. num: int := get_number(e);
  30. put_xinst(e, MOVEI, R1, SP, 2 - num);
  31. put_xinst(e, HRLI, R1, 0, 1 - num);
  32. put_xinst(e, JSP, XR, 0, _amake);
  33. put_xinst(e, HRRM, N1, RR, _ar_cod);
  34. put_xinst(e, SUBI, SP, 0, num);
  35. end m_arrgen;
  36. m_recgen = proc (e: env);
  37. sels: ai := ai$predict(1, 2);
  38. for sel: int in get_numbers(e) do
  39. ai$addh(sels, sel);
  40. end;
  41. num: int := ai$size(sels);
  42. put_xinst(e, MOVEI, N1, 0, num);
  43. put_xinst(e, HRLI, N1, 0, _tvec);
  44. alloc(e, wrd$create(0, num), N1);
  45. for sel: int in ai$elements(sels) do
  46. put_xinst(e, POP, SP, RR, sel);
  47. end;
  48. end m_recgen;
  49. m_typreg = proc (e: env);
  50. typreg(e, get_wrd(e), get_wrd(e));
  51. end m_typreg;
  52. typreg = proc (e: env, dst: wrd, desc: wrd);
  53. reg, disp: int := tdlink(e, desc);
  54. put_xinst(e, HRROI, R0, reg, disp);
  55. put_xinst(e, SKIPG, RR, R0, 0);
  56. put_xinst(e, JSP, XR, 0, _notype);
  57. if ~wrd$iequal(dst, RR)
  58. then put_inst(e, MOVEM, RR, 0, dst); end;
  59. end typreg;
  60. m_typarg = proc (e: env);
  61. dst: wrd := wrd$create(0, RR);
  62. for desc: wrd in get_wrds(e) do
  63. typreg(e, dst, desc);
  64. put_xinst(e, PUSH, SP, 0, RR);
  65. end;
  66. end m_typarg;
  67. m_gettyp = proc (e: env);
  68. reg: int := get_number(e);
  69. put_inst(e, HLRZ, reg, 0, get_wrd(e));
  70. put_xinst(e, ANDI, reg, 0, _typmsk);
  71. end m_gettyp;
  72. m_cvtup = proc (e: env);
  73. addr: wrd := get_wrd(e);
  74. end m_cvtup;
  75. m_cvtdown = proc (e: env);
  76. addr: wrd := get_wrd(e);
  77. end m_cvtdown;
  78. m_string = proc (e: env);
  79. name: str := get_symbol(e);
  80. ref: wrd := string_lit(e, get_literal(e));
  81. env$define(e, name, ref);
  82. end m_string;
  83. m_tdesc = proc (e: env);
  84. iname: str := get_symbol(e);
  85. xname: str := get_symbol(e);
  86. dvec: wrd, dflg, dtyp: int := tdchk(e);
  87. dstr: wrd := string_lit(e, xname);
  88. vec: aw := aw$[wrd$create(_tdrep, 5),
  89. wrd$create(0, 0),
  90. wrd$create(0, dflg + _tdc_td),
  91. dstr,
  92. dvec];
  93. env$define(e, iname, env$add_rlink(e, dtyp, vec));
  94. end m_tdesc;
  95. m_sdesc = proc (e: env);
  96. iname: str := get_symbol(e);
  97. xname: str := get_symbol(e);
  98. dvec: wrd, dflg, dtyp: int := tdchk(e);
  99. dstr: wrd := string_lit(e, xname);
  100. if wrd$iequal(dvec, 0)
  101. then dflg := _tdc_cp;
  102. dtyp := _tcpd;
  103. end;
  104. vec: aw := aw$[wrd$create(_tdrep, 5),
  105. wrd$create(0, 0),
  106. wrd$create(0, dflg + _tdc_sd),
  107. dstr,
  108. dvec];
  109. env$define(e, iname, env$add_rlink(e, dtyp, vec));
  110. end m_sdesc;
  111. m_ptdesc = proc (e: env);
  112. pidesc(e, _tdc_pt);
  113. end m_ptdesc;
  114. m_itdesc = proc (e: env);
  115. pidesc(e, _tdc_it);
  116. end m_itdesc;
  117. pidesc = proc (e: env, flg: int);
  118. iname: str := get_symbol(e);
  119. dv1: wrd, df1, dt1: int := tdchk(e);
  120. dv2: wrd, df2, dt2: int := tdchk(e);
  121. dv3: wrd, df3, dt3: int := tdchk(e);
  122. vec: aw := aw$[wrd$create(_tdrep, 7),
  123. wrd$create(0, 0),
  124. wrd$create(0, i_or(flg, i_or(df1, i_or(df2, df3)))),
  125. wrd$create(0, 0),
  126. dv1,
  127. dv2,
  128. dv3];
  129. if dt2 > dt1
  130. then dt1 := dt2; end;
  131. if dt3 > dt1
  132. then dt1 := dt3; end;
  133. env$define(e, iname, env$add_rlink(e, dt1, vec));
  134. end pidesc;
  135. m_edesc = proc (e: env);
  136. iname: str := get_symbol(e);
  137. xname: str := get_symbol(e);
  138. dvec: wrd, dflg, dtyp: int := tdchk(e);
  139. dstr: wrd := string_lit(e, xname);
  140. vec: aw := aw$[wrd$create(_tdrep, 5),
  141. wrd$create(0, 0),
  142. wrd$create(0, dflg + _tdc_ed),
  143. dstr,
  144. dvec];
  145. env$define(e, iname, env$add_rlink(e, dtyp, vec));
  146. end m_edesc;
  147. m_rtdesc = proc (e: env);
  148. iname: str := get_symbol(e);
  149. dvec: wrd, dflg: int, dtyp, drtn: wrd := pnchk(e);
  150. vec: aw := aw$[wrd$create(_tdrep, 6),
  151. wrd$create(0, 0),
  152. wrd$create(0, dflg + _tdc_rt),
  153. drtn,
  154. dtyp,
  155. dvec];
  156. env$define(e, iname, env$add_rlink(e, get_type(dflg), vec));
  157. end m_rtdesc;
  158. alloc = proc (e: env, size: wrd, reg: int);
  159. env$add_option(e, _prc_ni);
  160. put_inst(e, MOVNI, RR, 0, size);
  161. put_xinst(e, ADDB, RR, 0, _dmemhi);
  162. put_xinst(e, CAMG, RR, 0, _dstkhi);
  163. put_xinst(e, PUSHJ, SP, 0, _memout);
  164. put_xinst(e, MOVEM, reg, RR, 0);
  165. end alloc;
  166. refchk = proc (e: env, reg: int, src: wrd);
  167. put_inst(e, SKIPL, reg, 0, src);
  168. put_xinst(e, JSP, XR, 0, _notref);
  169. end refchk;
  170. repchk = proc (e: env, reg: int, typ: int);
  171. put_xinst(e, HLRZ, N0, reg, 0);
  172. put_xinst(e, CAIE, N0, 0, typ);
  173. put_xinst(e, JSP, XR, 0, _badrep);
  174. end repchk;
  175. m_cpdesc = proc (e: env);
  176. name: str := get_symbol(e);
  177. dstr: wrd := string_lit(e, get_symbol(e));
  178. pos: wrd := get_wrd(e);
  179. vec: aw := aw$[wrd$create(_tdrep, 5),
  180. wrd$create(0, 0),
  181. wrd$create(0, _tdc_pa + _tdc_cp),
  182. dstr,
  183. pos];
  184. env$define(e, name, env$add_rlink(e, _tcpd, vec));
  185. end m_cpdesc;
  186. m_ppdesc = proc (e: env);
  187. name: str := get_symbol(e);
  188. dstr: wrd := string_lit(e, get_symbol(e));
  189. pos: wrd := get_wrd(e);
  190. vec: aw := aw$[wrd$create(_tdrep, 5),
  191. wrd$create(0, 0),
  192. wrd$create(0, _tdc_pa + _tdc_pp),
  193. dstr,
  194. pos];
  195. env$define(e, name, env$add_rlink(e, _tppd, vec));
  196. end m_ppdesc;
  197. m_pdesc = proc (e: env);
  198. iname: str := get_symbol(e);
  199. dvec: wrd, dflg: int, dtyp, dstr: wrd := pnchk(e);
  200. vec: aw := aw$[wrd$create(_tdrep, 6),
  201. wrd$create(0, 0),
  202. wrd$create(0, dflg + _tdc_xr),
  203. dstr,
  204. dtyp,
  205. dvec];
  206. env$define(e, iname, env$add_rlink(e, get_type(dflg), vec));
  207. end m_pdesc;
  208. m_pcdesc = proc (e: env);
  209. iname: str := get_symbol(e);
  210. dvec: wrd, dflg: int, dtyp, dstr: wrd := pnchk(e);
  211. vec: aw := aw$[wrd$create(_tcrep, _pc_dat),
  212. wrd$create(JSP + XR*32, _linker),
  213. get_wrd(e),
  214. dstr,
  215. dtyp,
  216. dvec];
  217. env$define(e, iname, env$add_rlink(e, get_type(dflg), vec));
  218. end m_pcdesc;
  219. m_vargen = proc (e: env);
  220. var: str := get_symbol(e);
  221. disp: int := env$add_vinit(e, get_wrd(e));
  222. env$define(e, var, wrd$create(0, disp));
  223. end m_vargen;
  224. tdlink = proc (e: env, desc: wrd) returns (int, int);
  225. left, right: int := wrd$w2i(desc);
  226. left := i_and(left, _typmsk);
  227. if left = i_and(_tppd, _typmsk)
  228. then disp: int := env$add_plink(e, desc);
  229. put_xinst(e, HLRZ, R1, MR, _en_par);
  230. return(R1, disp);
  231. elseif left = i_and(_tcpd, _typmsk)
  232. then disp: int := env$add_clink(e, desc);
  233. put_xinst(e, HRRZ, R1, MR, _en_par);
  234. return(R1, disp);
  235. else return(LR, env$add_link(e, desc)); end;
  236. end tdlink;
  237. tdchk = proc (e: env) returns (wrd, int, int);
  238. dflg: int := 0;
  239. vec: aw := aw$[1: wrd$create(0, 0)];
  240. for w: wrd in get_wrds(e) do
  241. dflg := i_or(dflg, get_flag(w));
  242. aw$addh(vec, w);
  243. end;
  244. dref: wrd;
  245. num: int := aw$size(vec);
  246. if num > 1
  247. then vec[1] := wrd$create(_tdrep, num);
  248. dref := env$add_rlink(e, _tref, vec);
  249. else dref := vec[1];
  250. end;
  251. return(dref, dflg, get_type(dflg));
  252. end tdchk;
  253. pnchk = proc (e: env) returns (wrd, int, wrd, wrd);
  254. vec: aw := aw$predict(1, 2);
  255. for w: wrd in get_wrds(e) do
  256. aw$addh(vec, w);
  257. end;
  258. num: int := aw$size(vec);
  259. if num = 1
  260. then dstr: wrd := get_string(e, aw$bottom(vec));
  261. zero: wrd := wrd$create(0, 0);
  262. return(zero, 0, zero, dstr);
  263. end;
  264. dtyp: wrd := aw$reml(vec);
  265. dstr: wrd := get_string(e, aw$reml(vec));
  266. dflg: int := get_flag(dtyp);
  267. dref: wrd;
  268. if num > 2
  269. then aw$addl(vec, wrd$create(_tdrep, num - 1));
  270. dref := env$add_rlink(e, _tref, vec);
  271. else dref := wrd$create(0, 0);
  272. end;
  273. return(dref, dflg, dtyp, dstr);
  274. end pnchk;
  275. get_flag = proc (dtyp: wrd) returns (int);
  276. left, right: int := wrd$w2i(dtyp);
  277. left := i_and(left, _typmsk);
  278. if left = i_and(_tppd, _typmsk)
  279. then return(_tdc_pp);
  280. elseif left = i_and(_tcpd, _typmsk)
  281. then return(_tdc_cp);
  282. else return(0); end;
  283. end get_flag;
  284. get_type = proc (dflg: int) returns (int);
  285. if i_and(dflg, _tdc_pp) > 0
  286. then return(_tppd);
  287. elseif i_and(dflg, _tdc_cp) > 0
  288. then return(_tcpd);
  289. else return(_ttd); end;
  290. end get_type;
  291. get_string = proc (e: env, w: wrd) returns (wrd);
  292. ud: str := w.right_unknown;
  293. if ud = ""
  294. then env$err(e, "OOPS: a_word given to get_string is not an undef"); end;
  295. return(string_lit(e, ud));
  296. end get_string;
  297. string_lit = proc (e: env, s: str) returns (wrd);
  298. z: int := str$size(s);
  299. if z = 0
  300. then return(wrd$create(_str, _nullsd)); end;
  301. c: char := s[1];
  302. if c = '\033'
  303. then return(env$lookup(e, str$rest(s, 2))); end;
  304. if z = 1
  305. then return(wrd$create(_tstr, char$c2i(c))); end;
  306. if z = 4 cand c = '\\'
  307. then sum: int := 0;
  308. for i: int in int$from_to(0, 2) do
  309. sum := sum + char$c2i(s[4 - i]) * 8**i;
  310. end;
  311. return(wrd$create(_tstr, sum));
  312. end;
  313. len: int := (z + 11) / 6;
  314. vec: aw := aw$predict(1, len);
  315. aw$addh(vec, wrd$create(_tsrep, len));
  316. for i: int in int$from_to(0, len - 2) do
  317. aw$addh(vec, wrd$s2ascii(str$substr(s, 6 * i + 1, 6)));
  318. end;
  319. return(env$add_rlink(e, _str, vec));
  320. end string_lit;