asm.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include "limbo.h"
  2. void
  3. asmentry(Decl *e)
  4. {
  5. if(e == nil)
  6. return;
  7. Bprint(bout, "\tentry\t%ld, %d\n", e->pc->pc, e->desc->id);
  8. }
  9. void
  10. asmmod(Decl *m)
  11. {
  12. Bprint(bout, "\tmodule\t");
  13. Bprint(bout, "%s\n", m->sym->name);
  14. for(m = m->ty->tof->ids; m != nil; m = m->next){
  15. switch(m->store){
  16. case Dglobal:
  17. Bprint(bout, "\tlink\t-1,-1,0x%lux,\".mp\"\n", sign(m));
  18. break;
  19. case Dfn:
  20. Bprint(bout, "\tlink\t%d,%ld,0x%lux,\"",
  21. m->desc->id, m->pc->pc, sign(m));
  22. if(m->dot->ty->kind == Tadt)
  23. Bprint(bout, "%s.", m->dot->sym->name);
  24. Bprint(bout, "%s\"\n", m->sym->name);
  25. break;
  26. }
  27. }
  28. }
  29. #define NAMELEN 64
  30. void
  31. asmpath(void)
  32. {
  33. char name[8*NAMELEN], *sp;
  34. sp = srcpath(name, 8*NAMELEN);
  35. Bprint(bout, "\tsource\t\"%s\"\n", sp);
  36. }
  37. void
  38. asmdesc(Desc *d)
  39. {
  40. uchar *m, *e;
  41. for(; d != nil; d = d->next){
  42. Bprint(bout, "\tdesc\t$%d,%lud,\"", d->id, d->size);
  43. e = d->map + d->nmap;
  44. for(m = d->map; m < e; m++)
  45. Bprint(bout, "%.2x", *m);
  46. Bprint(bout, "\"\n");
  47. }
  48. }
  49. void
  50. asmvar(long size, Decl *d)
  51. {
  52. Bprint(bout, "\tvar\t@mp,%ld\n", size);
  53. for(; d != nil; d = d->next)
  54. if(d->store == Dglobal && d->init != nil)
  55. asminitializer(d->offset, d->init);
  56. }
  57. void
  58. asmldt(long size, Decl *d)
  59. {
  60. Bprint(bout, "\tldts\t@ldt,%ld\n", size);
  61. for(; d != nil; d = d->next)
  62. if(d->store == Dglobal && d->init != nil)
  63. asminitializer(d->offset, d->init);
  64. }
  65. void
  66. asminitializer(long offset, Node *n)
  67. {
  68. Node *elem, *wild;
  69. Case *c;
  70. Label *lab;
  71. Decl *id;
  72. ulong dv[2];
  73. long e, last, esz, dotlen, idlen;
  74. int i;
  75. switch(n->ty->kind){
  76. case Tbyte:
  77. Bprint(bout, "\tbyte\t@mp+%ld,%ld\n", offset, (long)n->val & 0xff);
  78. break;
  79. case Tint:
  80. case Tfix:
  81. Bprint(bout, "\tword\t@mp+%ld,%ld\n", offset, (long)n->val);
  82. break;
  83. case Tbig:
  84. Bprint(bout, "\tlong\t@mp+%ld,%lld # %.16llux\n", offset, n->val, n->val);
  85. break;
  86. case Tstring:
  87. asmstring(offset, n->decl->sym);
  88. break;
  89. case Treal:
  90. dtocanon(n->rval, dv);
  91. Bprint(bout, "\treal\t@mp+%ld,%g # %.8lux%.8lux\n", offset, n->rval, dv[0], dv[1]);
  92. break;
  93. case Tadt:
  94. case Tadtpick:
  95. case Ttuple:
  96. id = n->ty->ids;
  97. for(n = n->left; n != nil; n = n->right){
  98. asminitializer(offset + id->offset, n->left);
  99. id = id->next;
  100. }
  101. break;
  102. case Tcase:
  103. c = n->ty->cse;
  104. Bprint(bout, "\tword\t@mp+%ld,%d", offset, c->nlab);
  105. for(i = 0; i < c->nlab; i++){
  106. lab = &c->labs[i];
  107. Bprint(bout, ",%ld,%ld,%ld", (long)lab->start->val, (long)lab->stop->val+1, lab->inst->pc);
  108. }
  109. Bprint(bout, ",%ld\n", c->iwild ? c->iwild->pc : -1);
  110. break;
  111. case Tcasel:
  112. c = n->ty->cse;
  113. Bprint(bout, "\tword\t@mp+%ld,%d", offset, c->nlab);
  114. for(i = 0; i < c->nlab; i++){
  115. lab = &c->labs[i];
  116. Bprint(bout, ",%lld,%lld,%ld", lab->start->val, lab->stop->val+1, lab->inst->pc);
  117. }
  118. Bprint(bout, ",%ld\n", c->iwild ? c->iwild->pc : -1);
  119. break;
  120. case Tcasec:
  121. c = n->ty->cse;
  122. Bprint(bout, "\tword\t@mp+%ld,%d\n", offset, c->nlab);
  123. offset += IBY2WD;
  124. for(i = 0; i < c->nlab; i++){
  125. lab = &c->labs[i];
  126. asmstring(offset, lab->start->decl->sym);
  127. offset += IBY2WD;
  128. if(lab->stop != lab->start)
  129. asmstring(offset, lab->stop->decl->sym);
  130. offset += IBY2WD;
  131. Bprint(bout, "\tword\t@mp+%ld,%ld\n", offset, lab->inst->pc);
  132. offset += IBY2WD;
  133. }
  134. Bprint(bout, "\tword\t@mp+%ld,%ld\n", offset, c->iwild ? c->iwild->pc : -1);
  135. break;
  136. case Tgoto:
  137. c = n->ty->cse;
  138. Bprint(bout, "\tword\t@mp+%ld", offset);
  139. Bprint(bout, ",%ld", n->ty->size/IBY2WD-1);
  140. for(i = 0; i < c->nlab; i++)
  141. Bprint(bout, ",%ld", c->labs[i].inst->pc);
  142. if(c->iwild != nil)
  143. Bprint(bout, ",%ld", c->iwild->pc);
  144. Bprint(bout, "\n");
  145. break;
  146. case Tany:
  147. break;
  148. case Tarray:
  149. Bprint(bout, "\tarray\t@mp+%ld,$%d,%ld\n", offset, n->ty->tof->decl->desc->id, (long)n->left->val);
  150. if(n->right == nil)
  151. break;
  152. Bprint(bout, "\tindir\t@mp+%ld,0\n", offset);
  153. c = n->right->ty->cse;
  154. wild = nil;
  155. if(c->wild != nil)
  156. wild = c->wild->right;
  157. last = 0;
  158. esz = n->ty->tof->size;
  159. for(i = 0; i < c->nlab; i++){
  160. e = c->labs[i].start->val;
  161. if(wild != nil){
  162. for(; last < e; last++)
  163. asminitializer(esz * last, wild);
  164. }
  165. last = e;
  166. e = c->labs[i].stop->val;
  167. elem = c->labs[i].node->right;
  168. for(; last <= e; last++)
  169. asminitializer(esz * last, elem);
  170. }
  171. if(wild != nil)
  172. for(e = n->left->val; last < e; last++)
  173. asminitializer(esz * last, wild);
  174. Bprint(bout, "\tapop\n");
  175. break;
  176. case Tiface:
  177. if(LDT)
  178. Bprint(bout, "\tword\t@ldt+%ld,%ld\n", offset, (long)n->val);
  179. else
  180. Bprint(bout, "\tword\t@mp+%ld,%ld\n", offset, (long)n->val);
  181. offset += IBY2WD;
  182. for(id = n->decl->ty->ids; id != nil; id = id->next){
  183. offset = align(offset, IBY2WD);
  184. if(LDT)
  185. Bprint(bout, "\text\t@ldt+%ld,0x%lux,\"", offset, sign(id));
  186. else
  187. Bprint(bout, "\text\t@mp+%ld,0x%lux,\"", offset, sign(id));
  188. dotlen = 0;
  189. idlen = id->sym->len + 1;
  190. if(id->dot->ty->kind == Tadt){
  191. dotlen = id->dot->sym->len + 1;
  192. Bprint(bout, "%s.", id->dot->sym->name);
  193. }
  194. Bprint(bout, "%s\"\n", id->sym->name);
  195. offset += idlen + dotlen + IBY2WD;
  196. }
  197. break;
  198. default:
  199. nerror(n, "can't asm global %n", n);
  200. break;
  201. }
  202. }
  203. void
  204. asmexc(Except *es)
  205. {
  206. int i, o, n, id;
  207. Decl *d;
  208. Except *e;
  209. Case *c;
  210. Label *lab;
  211. n = 0;
  212. for(e = es; e != nil; e = e->next)
  213. n++;
  214. Bprint(bout, "\texceptions\t%d\n", n);
  215. for(e = es; e != nil; e = e->next){
  216. if(!e->p1->reach && !e->p2->reach)
  217. continue;
  218. c = e->c;
  219. o = e->d->offset;
  220. if(e->desc != nil)
  221. id = e->desc->id;
  222. else
  223. id = -1;
  224. Bprint(bout, "\texception\t%ld, %ld, %d, %d, %d, %d\n", getpc(e->p1), getpc(e->p2), o, id, c->nlab, e->ne);
  225. for(i = 0; i < c->nlab; i++){
  226. lab = &c->labs[i];
  227. d = lab->start->decl;
  228. if(lab->start->ty->kind == Texception)
  229. d = d->init->decl;
  230. Bprint(bout, "\texctab\t\"%s\", %ld\n", d->sym->name, lab->inst->pc);
  231. }
  232. if(c->iwild == nil)
  233. Bprint(bout, "\texctab\t*, %d\n", -1);
  234. else
  235. Bprint(bout, "\texctab\t*, %ld\n", c->iwild->pc);
  236. }
  237. }
  238. void
  239. asmstring(long offset, Sym *sym)
  240. {
  241. char *s, *se;
  242. int c;
  243. Bprint(bout, "\tstring\t@mp+%ld,\"", offset);
  244. s = sym->name;
  245. se = s + sym->len;
  246. for(; s < se; s++){
  247. c = *s;
  248. if(c == '\n')
  249. Bwrite(bout, "\\n", 2);
  250. else if(c == '\0')
  251. Bwrite(bout, "\\z", 2);
  252. else if(c == '"')
  253. Bwrite(bout, "\\\"", 2);
  254. else if(c == '\\')
  255. Bwrite(bout, "\\\\", 2);
  256. else
  257. Bputc(bout, c);
  258. }
  259. Bprint(bout, "\"\n");
  260. }
  261. void
  262. asminst(Inst *in)
  263. {
  264. for(; in != nil; in = in->next){
  265. if(in->op == INOOP)
  266. continue;
  267. if(in->pc % 10 == 0)
  268. Bprint(bout, "#%ld\n", in->pc);
  269. Bprint(bout, "%I\n", in);
  270. }
  271. }