list.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. #define EXTERN
  2. #include "gc.h"
  3. void
  4. listinit(void)
  5. {
  6. fmtinstall('A', Aconv);
  7. fmtinstall('P', Pconv);
  8. fmtinstall('S', Sconv);
  9. fmtinstall('N', Nconv);
  10. fmtinstall('B', Bconv);
  11. fmtinstall('D', Dconv);
  12. fmtinstall('R', Rconv);
  13. }
  14. int
  15. Bconv(Fmt *fp)
  16. {
  17. char str[STRINGSZ], ss[STRINGSZ], *s;
  18. Bits bits;
  19. int i;
  20. str[0] = 0;
  21. bits = va_arg(fp->args, Bits);
  22. while(bany(&bits)) {
  23. i = bnum(bits);
  24. if(str[0])
  25. strcat(str, " ");
  26. if(var[i].sym == S) {
  27. sprint(ss, "$%ld", var[i].offset);
  28. s = ss;
  29. } else
  30. s = var[i].sym->name;
  31. if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
  32. break;
  33. strcat(str, s);
  34. bits.b[i/32] &= ~(1L << (i%32));
  35. }
  36. return fmtstrcpy(fp, str);
  37. }
  38. char *extra [] = {
  39. ".EQ", ".NE", ".CS", ".CC",
  40. ".MI", ".PL", ".VS", ".VC",
  41. ".HI", ".LS", ".GE", ".LT",
  42. ".GT", ".LE", "", ".NV",
  43. };
  44. int
  45. Pconv(Fmt *fp)
  46. {
  47. char str[STRINGSZ], sc[20];
  48. Prog *p;
  49. int a, s;
  50. p = va_arg(fp->args, Prog*);
  51. a = p->as;
  52. s = p->scond;
  53. strcpy(sc, extra[s & C_SCOND]);
  54. if(s & C_SBIT)
  55. strcat(sc, ".S");
  56. if(s & C_PBIT)
  57. strcat(sc, ".P");
  58. if(s & C_WBIT)
  59. strcat(sc, ".W");
  60. if(s & C_UBIT) /* ambiguous with FBIT */
  61. strcat(sc, ".U");
  62. if(a == AMOVM) {
  63. if(p->from.type == D_CONST)
  64. sprint(str, " %A%s %R,%D", a, sc, &p->from, &p->to);
  65. else
  66. if(p->to.type == D_CONST)
  67. sprint(str, " %A%s %D,%R", a, sc, &p->from, &p->to);
  68. else
  69. sprint(str, " %A%s %D,%D", a, sc, &p->from, &p->to);
  70. } else
  71. if(a == ADATA)
  72. sprint(str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
  73. else
  74. if(p->as == ATEXT)
  75. sprint(str, " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
  76. else
  77. if(p->reg == NREG)
  78. sprint(str, " %A%s %D,%D", a, sc, &p->from, &p->to);
  79. else
  80. if(p->from.type != D_FREG)
  81. sprint(str, " %A%s %D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
  82. else
  83. sprint(str, " %A%s %D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
  84. return fmtstrcpy(fp, str);
  85. }
  86. int
  87. Aconv(Fmt *fp)
  88. {
  89. char *s;
  90. int a;
  91. a = va_arg(fp->args, int);
  92. s = "???";
  93. if(a >= AXXX && a < ALAST)
  94. s = anames[a];
  95. return fmtstrcpy(fp, s);
  96. }
  97. int
  98. Dconv(Fmt *fp)
  99. {
  100. char str[STRINGSZ];
  101. Adr *a;
  102. char *op;
  103. int v;
  104. a = va_arg(fp->args, Adr*);
  105. switch(a->type) {
  106. default:
  107. sprint(str, "GOK-type(%d)", a->type);
  108. break;
  109. case D_NONE:
  110. str[0] = 0;
  111. if(a->name != D_NONE || a->reg != NREG || a->sym != S)
  112. sprint(str, "%N(R%d)(NONE)", a, a->reg);
  113. break;
  114. case D_CONST:
  115. if(a->reg != NREG)
  116. sprint(str, "$%N(R%d)", a, a->reg);
  117. else
  118. sprint(str, "$%N", a);
  119. break;
  120. case D_SHIFT:
  121. v = a->offset;
  122. op = "<<>>->@>" + (((v>>5) & 3) << 1);
  123. if(v & (1<<4))
  124. sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
  125. else
  126. sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
  127. if(a->reg != NREG)
  128. sprint(str+strlen(str), "(R%d)", a->reg);
  129. break;
  130. case D_OREG:
  131. if(a->reg != NREG)
  132. sprint(str, "%N(R%d)", a, a->reg);
  133. else
  134. sprint(str, "%N", a);
  135. break;
  136. case D_REG:
  137. sprint(str, "R%d", a->reg);
  138. if(a->name != D_NONE || a->sym != S)
  139. sprint(str, "%N(R%d)(REG)", a, a->reg);
  140. break;
  141. case D_FREG:
  142. sprint(str, "F%d", a->reg);
  143. if(a->name != D_NONE || a->sym != S)
  144. sprint(str, "%N(R%d)(REG)", a, a->reg);
  145. break;
  146. case D_PSR:
  147. sprint(str, "PSR");
  148. if(a->name != D_NONE || a->sym != S)
  149. sprint(str, "%N(PSR)(REG)", a);
  150. break;
  151. case D_BRANCH:
  152. sprint(str, "%ld(PC)", a->offset-pc);
  153. break;
  154. case D_FCONST:
  155. sprint(str, "$%.17e", a->dval);
  156. break;
  157. case D_SCONST:
  158. sprint(str, "$\"%S\"", a->sval);
  159. break;
  160. }
  161. return fmtstrcpy(fp, str);
  162. }
  163. int
  164. Rconv(Fmt *fp)
  165. {
  166. char str[STRINGSZ];
  167. Adr *a;
  168. int i, v;
  169. a = va_arg(fp->args, Adr*);
  170. sprint(str, "GOK-reglist");
  171. switch(a->type) {
  172. case D_CONST:
  173. if(a->reg != NREG)
  174. break;
  175. if(a->sym != S)
  176. break;
  177. v = a->offset;
  178. strcpy(str, "");
  179. for(i=0; i<NREG; i++) {
  180. if(v & (1<<i)) {
  181. if(str[0] == 0)
  182. strcat(str, "[R");
  183. else
  184. strcat(str, ",R");
  185. sprint(strchr(str, 0), "%d", i);
  186. }
  187. }
  188. strcat(str, "]");
  189. }
  190. return fmtstrcpy(fp, str);
  191. }
  192. int
  193. Sconv(Fmt *fp)
  194. {
  195. int i, c;
  196. char str[STRINGSZ], *p, *a;
  197. a = va_arg(fp->args, char*);
  198. p = str;
  199. for(i=0; i<NSNAME; i++) {
  200. c = a[i] & 0xff;
  201. if(c >= 'a' && c <= 'z' ||
  202. c >= 'A' && c <= 'Z' ||
  203. c >= '0' && c <= '9' ||
  204. c == ' ' || c == '%') {
  205. *p++ = c;
  206. continue;
  207. }
  208. *p++ = '\\';
  209. switch(c) {
  210. case 0:
  211. *p++ = 'z';
  212. continue;
  213. case '\\':
  214. case '"':
  215. *p++ = c;
  216. continue;
  217. case '\n':
  218. *p++ = 'n';
  219. continue;
  220. case '\t':
  221. *p++ = 't';
  222. continue;
  223. case '\r':
  224. *p++ = 'r';
  225. continue;
  226. case '\f':
  227. *p++ = 'f';
  228. continue;
  229. }
  230. *p++ = (c>>6) + '0';
  231. *p++ = ((c>>3) & 7) + '0';
  232. *p++ = (c & 7) + '0';
  233. }
  234. *p = 0;
  235. return fmtstrcpy(fp, str);
  236. }
  237. int
  238. Nconv(Fmt *fp)
  239. {
  240. char str[STRINGSZ];
  241. Adr *a;
  242. Sym *s;
  243. a = va_arg(fp->args, Adr*);
  244. s = a->sym;
  245. if(s == S) {
  246. sprint(str, "%ld", a->offset);
  247. goto out;
  248. }
  249. switch(a->name) {
  250. default:
  251. sprint(str, "GOK-name(%d)", a->name);
  252. break;
  253. case D_NONE:
  254. sprint(str, "%ld", a->offset);
  255. break;
  256. case D_EXTERN:
  257. sprint(str, "%s+%ld(SB)", s->name, a->offset);
  258. break;
  259. case D_STATIC:
  260. sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
  261. break;
  262. case D_AUTO:
  263. sprint(str, "%s-%ld(SP)", s->name, -a->offset);
  264. break;
  265. case D_PARAM:
  266. sprint(str, "%s+%ld(FP)", s->name, a->offset);
  267. break;
  268. }
  269. out:
  270. return fmtstrcpy(fp, str);
  271. }