list.c 6.1 KB

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