OLD | NEW |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // "Portable" code generation. | 5 // "Portable" code generation. |
6 // Compiled separately for 5g, 6g, and 8g, so allowed to use gg.h, opt.h. | 6 // Compiled separately for 5g, 6g, and 8g, so allowed to use gg.h, opt.h. |
7 // Must code to the intersection of the three back ends. | 7 // Must code to the intersection of the three back ends. |
8 | 8 |
9 #include <u.h> | 9 #include <u.h> |
10 #include <libc.h> | 10 #include <libc.h> |
11 #include "md5.h" | 11 #include "md5.h" |
12 #include "gg.h" | 12 #include "gg.h" |
13 #include "opt.h" | 13 #include "opt.h" |
14 #include "../../runtime/funcdata.h" | 14 #include "../../runtime/funcdata.h" |
15 | 15 |
16 static void allocauto(Prog* p); | 16 static void allocauto(Prog* p); |
| 17 static void emitptrargsmap(void); |
17 | 18 |
18 static Sym* | 19 static Sym* |
19 makefuncdatasym(char *namefmt, int64 funcdatakind) | 20 makefuncdatasym(char *namefmt, int64 funcdatakind) |
20 { | 21 { |
21 Node nod; | 22 Node nod; |
22 Node *pnod; | 23 Node *pnod; |
23 Sym *sym; | 24 Sym *sym; |
24 static int32 nsym; | 25 static int32 nsym; |
25 | 26 |
26 snprint(namebuf, sizeof(namebuf), namefmt, nsym++); | 27 snprint(namebuf, sizeof(namebuf), namefmt, nsym++); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 newproc = sysfunc("newproc"); | 167 newproc = sysfunc("newproc"); |
167 deferproc = sysfunc("deferproc"); | 168 deferproc = sysfunc("deferproc"); |
168 deferreturn = sysfunc("deferreturn"); | 169 deferreturn = sysfunc("deferreturn"); |
169 panicindex = sysfunc("panicindex"); | 170 panicindex = sysfunc("panicindex"); |
170 panicslice = sysfunc("panicslice"); | 171 panicslice = sysfunc("panicslice"); |
171 throwreturn = sysfunc("throwreturn"); | 172 throwreturn = sysfunc("throwreturn"); |
172 } | 173 } |
173 | 174 |
174 lno = setlineno(fn); | 175 lno = setlineno(fn); |
175 | 176 |
| 177 curfn = fn; |
| 178 dowidth(curfn->type); |
| 179 |
176 if(fn->nbody == nil) { | 180 if(fn->nbody == nil) { |
177 » » if(pure_go || strncmp(fn->nname->sym->name, "init·", 6) == 0) | 181 » » if(pure_go || strncmp(fn->nname->sym->name, "init·", 6) == 0) { |
178 yyerror("missing function body", fn); | 182 yyerror("missing function body", fn); |
| 183 goto ret; |
| 184 } |
| 185 if(debug['A']) |
| 186 goto ret; |
| 187 emitptrargsmap(); |
179 goto ret; | 188 goto ret; |
180 } | 189 } |
181 | 190 |
182 saveerrors(); | 191 saveerrors(); |
183 | 192 |
184 // set up domain for labels | 193 // set up domain for labels |
185 clearlabels(); | 194 clearlabels(); |
186 | 195 |
187 curfn = fn; | |
188 dowidth(curfn->type); | |
189 | |
190 if(curfn->type->outnamed) { | 196 if(curfn->type->outnamed) { |
191 // add clearing of the output parameters | 197 // add clearing of the output parameters |
192 t = structfirst(&save, getoutarg(curfn->type)); | 198 t = structfirst(&save, getoutarg(curfn->type)); |
193 while(t != T) { | 199 while(t != T) { |
194 if(t->nname != N) { | 200 if(t->nname != N) { |
195 n = nod(OAS, t->nname, N); | 201 n = nod(OAS, t->nname, N); |
196 typecheck(&n, Etop); | 202 typecheck(&n, Etop); |
197 curfn->nbody = concat(list1(n), curfn->nbody); | 203 curfn->nbody = concat(list1(n), curfn->nbody); |
198 } | 204 } |
199 t = structnext(&save); | 205 t = structnext(&save); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 | 328 |
323 if(0) | 329 if(0) |
324 frame(0); | 330 frame(0); |
325 | 331 |
326 // Remove leftover instrumentation from the instruction stream. | 332 // Remove leftover instrumentation from the instruction stream. |
327 removevardef(ptxt); | 333 removevardef(ptxt); |
328 ret: | 334 ret: |
329 lineno = lno; | 335 lineno = lno; |
330 } | 336 } |
331 | 337 |
| 338 static void |
| 339 emitptrargsmap(void) |
| 340 { |
| 341 int nptr, nbitmap, j, off; |
| 342 vlong xoffset; |
| 343 Bvec *bv; |
| 344 Sym *sym; |
| 345 ········ |
| 346 sym = lookup(smprint("%s.args_stackmap", curfn->nname->sym->name)); |
| 347 |
| 348 nptr = curfn->type->argwid / widthptr; |
| 349 bv = bvalloc(nptr*2); |
| 350 nbitmap = 1; |
| 351 if(curfn->type->outtuple > 0) |
| 352 nbitmap = 2; |
| 353 off = duint32(sym, 0, nbitmap); |
| 354 off = duint32(sym, off, bv->n); |
| 355 if(curfn->type->thistuple > 0) { |
| 356 xoffset = 0; |
| 357 twobitwalktype1(getthisx(curfn->type), &xoffset, bv); |
| 358 } |
| 359 if(curfn->type->intuple > 0) { |
| 360 xoffset = 0; |
| 361 twobitwalktype1(getinargx(curfn->type), &xoffset, bv); |
| 362 } |
| 363 for(j = 0; j < bv->n; j += 32) |
| 364 off = duint32(sym, off, bv->b[j/32]); |
| 365 if(curfn->type->outtuple > 0) { |
| 366 xoffset = 0; |
| 367 twobitwalktype1(getoutargx(curfn->type), &xoffset, bv); |
| 368 for(j = 0; j < bv->n; j += 32) |
| 369 off = duint32(sym, off, bv->b[j/32]); |
| 370 } |
| 371 ggloblsym(sym, off, RODATA); |
| 372 free(bv); |
| 373 } |
| 374 |
332 // Sort the list of stack variables. Autos after anything else, | 375 // Sort the list of stack variables. Autos after anything else, |
333 // within autos, unused after used, within used, things with | 376 // within autos, unused after used, within used, things with |
334 // pointers first, zeroed things first, and then decreasing size. | 377 // pointers first, zeroed things first, and then decreasing size. |
335 // Because autos are laid out in decreasing addresses | 378 // Because autos are laid out in decreasing addresses |
336 // on the stack, pointers first, zeroed things first and decreasing size | 379 // on the stack, pointers first, zeroed things first and decreasing size |
337 // really means, in memory, things with pointers needing zeroing at | 380 // really means, in memory, things with pointers needing zeroing at |
338 // the top of the stack and increasing in size. | 381 // the top of the stack and increasing in size. |
339 // Non-autos sort on offset. | 382 // Non-autos sort on offset. |
340 static int | 383 static int |
341 cmpstackvar(Node *a, Node *b) | 384 cmpstackvar(Node *a, Node *b) |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 } | 530 } |
488 if(((thechar == '5' || thechar == '9') && n->op != OREGISTER) || !n->add
able || n->op == OLITERAL) { | 531 if(((thechar == '5' || thechar == '9') && n->op != OREGISTER) || !n->add
able || n->op == OLITERAL) { |
489 regalloc(®, types[tptr], n); | 532 regalloc(®, types[tptr], n); |
490 cgen(n, ®); | 533 cgen(n, ®); |
491 gins(ACHECKNIL, ®, N); | 534 gins(ACHECKNIL, ®, N); |
492 regfree(®); | 535 regfree(®); |
493 return; | 536 return; |
494 } | 537 } |
495 gins(ACHECKNIL, n, N); | 538 gins(ACHECKNIL, n, N); |
496 } | 539 } |
OLD | NEW |