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