list.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #include "l.h"
  2. void
  3. listinit(void)
  4. {
  5. fmtinstall('A', Aconv);
  6. fmtinstall('C', Cconv);
  7. fmtinstall('D', Dconv);
  8. fmtinstall('P', Pconv);
  9. fmtinstall('S', Sconv);
  10. fmtinstall('N', Nconv);
  11. }
  12. void
  13. prasm(Prog *p)
  14. {
  15. print("%P\n", p);
  16. }
  17. int
  18. Pconv(Fmt *fp)
  19. {
  20. char str[STRINGSZ], *s;
  21. Prog *p;
  22. int a;
  23. p = va_arg(fp->args, Prog*);
  24. curp = p;
  25. a = p->as;
  26. switch(a) {
  27. default:
  28. s = str;
  29. s += sprint(s, "(%ld)", p->line);
  30. if(p->reg == NREG)
  31. sprint(s, " %A%C %D,%D",
  32. a, p->scond, &p->from, &p->to);
  33. else
  34. if(p->from.type != D_FREG)
  35. sprint(s, " %A%C %D,R%d,%D",
  36. a, p->scond, &p->from, p->reg, &p->to);
  37. else
  38. sprint(s, " %A%C %D,F%d,%D",
  39. a, p->scond, &p->from, p->reg, &p->to);
  40. break;
  41. case ASWPW:
  42. case ASWPBU:
  43. sprint(str, "(%ld) %A%C R%d,%D,%D",
  44. p->line, a, p->scond, p->reg, &p->from, &p->to);
  45. break;
  46. case ADATA:
  47. case AINIT:
  48. case ADYNT:
  49. sprint(str, "(%ld) %A%C %D/%d,%D",
  50. p->line, a, p->scond, &p->from, p->reg, &p->to);
  51. break;
  52. }
  53. return fmtstrcpy(fp, str);
  54. }
  55. int
  56. Aconv(Fmt *fp)
  57. {
  58. char *s;
  59. int a;
  60. a = va_arg(fp->args, int);
  61. s = "???";
  62. if(a >= AXXX && a < ALAST)
  63. s = anames[a];
  64. return fmtstrcpy(fp, s);
  65. }
  66. char* strcond[16] =
  67. {
  68. ".EQ",
  69. ".NE",
  70. ".HS",
  71. ".LO",
  72. ".MI",
  73. ".PL",
  74. ".VS",
  75. ".VC",
  76. ".HI",
  77. ".LS",
  78. ".GE",
  79. ".LT",
  80. ".GT",
  81. ".LE",
  82. "",
  83. ".NV"
  84. };
  85. int
  86. Cconv(Fmt *fp)
  87. {
  88. char s[20];
  89. int c;
  90. c = va_arg(fp->args, int);
  91. strcpy(s, strcond[c & C_SCOND]);
  92. if(c & C_SBIT)
  93. strcat(s, ".S");
  94. if(c & C_PBIT)
  95. strcat(s, ".P");
  96. if(c & C_WBIT)
  97. strcat(s, ".W");
  98. if(c & C_UBIT) /* ambiguous with FBIT */
  99. strcat(s, ".U");
  100. return fmtstrcpy(fp, s);
  101. }
  102. int
  103. Dconv(Fmt *fp)
  104. {
  105. char str[STRINGSZ];
  106. char *op;
  107. Adr *a;
  108. long v;
  109. a = va_arg(fp->args, Adr*);
  110. switch(a->type) {
  111. default:
  112. sprint(str, "GOK-type(%d)", a->type);
  113. break;
  114. case D_NONE:
  115. str[0] = 0;
  116. if(a->name != D_NONE || a->reg != NREG || a->sym != S)
  117. sprint(str, "%N(R%d)(NONE)", a, a->reg);
  118. break;
  119. case D_CONST:
  120. if(a->reg == NREG)
  121. sprint(str, "$%N", a);
  122. else
  123. sprint(str, "$%N(R%d)", a, a->reg);
  124. break;
  125. case D_SHIFT:
  126. v = a->offset;
  127. op = "<<>>->@>" + (((v>>5) & 3) << 1);
  128. if(v & (1<<4))
  129. sprint(str, "R%ld%c%cR%ld", v&15, op[0], op[1], (v>>8)&15);
  130. else
  131. sprint(str, "R%ld%c%c%ld", v&15, op[0], op[1], (v>>7)&31);
  132. if(a->reg != NREG)
  133. sprint(str+strlen(str), "(R%d)", a->reg);
  134. break;
  135. case D_OCONST:
  136. sprint(str, "$*$%N", a);
  137. if(a->reg != NREG)
  138. sprint(str, "%N(R%d)(CONST)", a, a->reg);
  139. break;
  140. case D_OREG:
  141. if(a->reg != NREG)
  142. sprint(str, "%N(R%d)", a, a->reg);
  143. else
  144. sprint(str, "%N", a);
  145. break;
  146. case D_REG:
  147. sprint(str, "R%d", a->reg);
  148. if(a->name != D_NONE || a->sym != S)
  149. sprint(str, "%N(R%d)(REG)", a, a->reg);
  150. break;
  151. case D_REGREG:
  152. sprint(str, "(R%d,R%d)", a->reg, (int)a->offset);
  153. if(a->name != D_NONE || a->sym != S)
  154. sprint(str, "%N(R%d)(REG)", a, a->reg);
  155. break;
  156. case D_FREG:
  157. sprint(str, "F%d", a->reg);
  158. if(a->name != D_NONE || a->sym != S)
  159. sprint(str, "%N(R%d)(REG)", a, a->reg);
  160. break;
  161. case D_PSR:
  162. switch(a->reg) {
  163. case 0:
  164. sprint(str, "CPSR");
  165. break;
  166. case 1:
  167. sprint(str, "SPSR");
  168. break;
  169. default:
  170. sprint(str, "PSR%d", a->reg);
  171. break;
  172. }
  173. if(a->name != D_NONE || a->sym != S)
  174. sprint(str, "%N(PSR%d)(REG)", a, a->reg);
  175. break;
  176. case D_FPCR:
  177. switch(a->reg){
  178. case 0:
  179. sprint(str, "FPSR");
  180. break;
  181. case 1:
  182. sprint(str, "FPCR");
  183. break;
  184. default:
  185. sprint(str, "FCR%d", a->reg);
  186. break;
  187. }
  188. if(a->name != D_NONE || a->sym != S)
  189. sprint(str, "%N(FCR%d)(REG)", a, a->reg);
  190. break;
  191. case D_BRANCH: /* botch */
  192. if(curp->cond != P) {
  193. v = curp->cond->pc;
  194. if(a->sym != S)
  195. sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
  196. else
  197. sprint(str, "%.5lux(BRANCH)", v);
  198. } else
  199. if(a->sym != S)
  200. sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
  201. else
  202. sprint(str, "%ld(APC)", a->offset);
  203. break;
  204. case D_FCONST:
  205. sprint(str, "$%e", ieeedtod(a->ieee));
  206. break;
  207. case D_SCONST:
  208. sprint(str, "$\"%S\"", a->sval);
  209. break;
  210. }
  211. return fmtstrcpy(fp, str);
  212. }
  213. int
  214. Nconv(Fmt *fp)
  215. {
  216. char str[STRINGSZ];
  217. Adr *a;
  218. Sym *s;
  219. a = va_arg(fp->args, Adr*);
  220. s = a->sym;
  221. switch(a->name) {
  222. default:
  223. sprint(str, "GOK-name(%d)", a->name);
  224. break;
  225. case D_NONE:
  226. sprint(str, "%ld", a->offset);
  227. break;
  228. case D_EXTERN:
  229. if(s == S)
  230. sprint(str, "%ld(SB)", a->offset);
  231. else
  232. sprint(str, "%s+%ld(SB)", s->name, a->offset);
  233. break;
  234. case D_STATIC:
  235. if(s == S)
  236. sprint(str, "<>+%ld(SB)", a->offset);
  237. else
  238. sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
  239. break;
  240. case D_AUTO:
  241. if(s == S)
  242. sprint(str, "%ld(SP)", a->offset);
  243. else
  244. sprint(str, "%s-%ld(SP)", s->name, -a->offset);
  245. break;
  246. case D_PARAM:
  247. if(s == S)
  248. sprint(str, "%ld(FP)", a->offset);
  249. else
  250. sprint(str, "%s+%ld(FP)", s->name, a->offset);
  251. break;
  252. }
  253. return fmtstrcpy(fp, str);
  254. }
  255. int
  256. Sconv(Fmt *fp)
  257. {
  258. int i, c;
  259. char str[STRINGSZ], *p, *a;
  260. a = va_arg(fp->args, char*);
  261. p = str;
  262. for(i=0; i<sizeof(long); i++) {
  263. c = a[i] & 0xff;
  264. if(c >= 'a' && c <= 'z' ||
  265. c >= 'A' && c <= 'Z' ||
  266. c >= '0' && c <= '9' ||
  267. c == ' ' || c == '%') {
  268. *p++ = c;
  269. continue;
  270. }
  271. *p++ = '\\';
  272. switch(c) {
  273. case 0:
  274. *p++ = 'z';
  275. continue;
  276. case '\\':
  277. case '"':
  278. *p++ = c;
  279. continue;
  280. case '\n':
  281. *p++ = 'n';
  282. continue;
  283. case '\t':
  284. *p++ = 't';
  285. continue;
  286. }
  287. *p++ = (c>>6) + '0';
  288. *p++ = ((c>>3) & 7) + '0';
  289. *p++ = (c & 7) + '0';
  290. }
  291. *p = 0;
  292. return fmtstrcpy(fp, str);
  293. }
  294. void
  295. diag(char *fmt, ...)
  296. {
  297. char buf[STRINGSZ], *tn;
  298. va_list arg;
  299. tn = "??none??";
  300. if(curtext != P && curtext->from.sym != S)
  301. tn = curtext->from.sym->name;
  302. va_start(arg, fmt);
  303. vseprint(buf, buf+sizeof(buf), fmt, arg);
  304. va_end(arg);
  305. print("%s: %s\n", tn, buf);
  306. nerrors++;
  307. if(nerrors > 10) {
  308. print("too many errors\n");
  309. errorexit();
  310. }
  311. }