LEFT | RIGHT |
(no file at all) | |
1 // Inferno utils/6c/sgen.c | 1 // Inferno utils/6c/sgen.c |
2 // http://code.google.com/p/inferno-os/source/browse/utils/6c/sgen.c | 2 // http://code.google.com/p/inferno-os/source/browse/utils/6c/sgen.c |
3 // | 3 // |
4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. | 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. |
5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) |
6 // Portions Copyright © 1997-1999 Vita Nuova Limited | 6 // Portions Copyright © 1997-1999 Vita Nuova Limited |
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com) | 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com) |
8 // Portions Copyright © 2004,2006 Bruce Ellis | 8 // Portions Copyright © 2004,2006 Bruce Ellis |
9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) |
10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 memset(&nod, 0, sizeof nod); | 49 memset(&nod, 0, sizeof nod); |
50 nod.op = ONAME; | 50 nod.op = ONAME; |
51 nod.sym = sym; | 51 nod.sym = sym; |
52 nod.class = CSTATIC; | 52 nod.class = CSTATIC; |
53 gins(AFUNCDATA, nodconst(funcdatakind), &nod); | 53 gins(AFUNCDATA, nodconst(funcdatakind), &nod); |
54 linksym(sym)->type = SRODATA; | 54 linksym(sym)->type = SRODATA; |
55 return sym; | 55 return sym; |
56 } | 56 } |
57 | 57 |
58 int | 58 int |
59 hasdotdotdot(void) | 59 hasdotdotdot(Type *t) |
60 { | 60 { |
61 » Type *t; | 61 » for(t=t->down; t!=T; t=t->down) |
62 | |
63 » for(t=thisfn->down; t!=T; t=t->down) | |
64 if(t->etype == TDOT) | 62 if(t->etype == TDOT) |
65 return 1; | 63 return 1; |
66 return 0; | 64 return 0; |
67 } | 65 } |
68 | 66 |
69 vlong | 67 vlong |
70 argsize(void) | 68 argsize(int doret) |
71 { | 69 { |
72 Type *t; | 70 Type *t; |
73 int32 s; | 71 int32 s; |
74 | 72 |
75 //print("t=%T\n", thisfn); | 73 //print("t=%T\n", thisfn); |
76 » s = align(0, thisfn->link, Aarg0, nil); | 74 » s = 0; |
| 75 » if(hasdotdotdot(thisfn)) |
| 76 » » s = align(s, thisfn->link, Aarg0, nil); |
77 for(t=thisfn->down; t!=T; t=t->down) { | 77 for(t=thisfn->down; t!=T; t=t->down) { |
78 switch(t->etype) { | 78 switch(t->etype) { |
79 case TVOID: | 79 case TVOID: |
80 break; | 80 break; |
81 case TDOT: | 81 case TDOT: |
82 if((textflag & NOSPLIT) == 0) | 82 if((textflag & NOSPLIT) == 0) |
83 yyerror("function takes ... without textflag NOS
PLIT"); | 83 yyerror("function takes ... without textflag NOS
PLIT"); |
84 return ArgsSizeUnknown; | 84 return ArgsSizeUnknown; |
85 default: | 85 default: |
86 s = align(s, t, Aarg1, nil); | 86 s = align(s, t, Aarg1, nil); |
87 s = align(s, t, Aarg2, nil); | 87 s = align(s, t, Aarg2, nil); |
88 break; | 88 break; |
89 } | 89 } |
90 //print(" %d %T\n", s, t); | 90 //print(" %d %T\n", s, t); |
91 } | 91 } |
92 if(thechar == '6' || thechar == '9') | 92 if(thechar == '6' || thechar == '9') |
93 s = (s+7) & ~7; | 93 s = (s+7) & ~7; |
94 else | 94 else |
95 s = (s+3) & ~3; | 95 s = (s+3) & ~3; |
| 96 if(doret && thisfn->link->etype != TVOID) { |
| 97 s = align(s, thisfn->link, Aarg1, nil); |
| 98 s = align(s, thisfn->link, Aarg2, nil); |
| 99 if(thechar == '6') |
| 100 s = (s+7) & ~7; |
| 101 else |
| 102 s = (s+3) & ~3; |
| 103 } |
96 return s; | 104 return s; |
97 } | 105 } |
98 | 106 |
99 void | 107 void |
100 codgen(Node *n, Node *nn) | 108 codgen(Node *n, Node *nn) |
101 { | 109 { |
102 Prog *sp; | 110 Prog *sp; |
103 Node *n1, nod, nod1; | 111 Node *n1, nod, nod1; |
104 Sym *gcargs; | 112 Sym *gcargs; |
105 Sym *gclocals; | 113 Sym *gclocals; |
(...skipping 10 matching lines...) Expand all Loading... |
116 if(n1 == Z) { | 124 if(n1 == Z) { |
117 diag(nn, "can't find function name"); | 125 diag(nn, "can't find function name"); |
118 return; | 126 return; |
119 } | 127 } |
120 if(n1->op == ONAME) | 128 if(n1->op == ONAME) |
121 break; | 129 break; |
122 } | 130 } |
123 nearln = nn->lineno; | 131 nearln = nn->lineno; |
124 | 132 |
125 p = gtext(n1->sym, stkoff); | 133 p = gtext(n1->sym, stkoff); |
| 134 p->from.sym->cfunc = 1; |
126 sp = p; | 135 sp = p; |
127 | 136 |
128 /* | 137 /* |
129 * generate funcdata symbol for this function. | 138 * generate funcdata symbol for this function. |
130 * data is filled in at the end of codgen(). | 139 * data is filled in at the end of codgen(). |
131 */ | 140 */ |
132 » isvarargs = hasdotdotdot(); | 141 » isvarargs = hasdotdotdot(thisfn); |
133 gcargs = nil; | 142 gcargs = nil; |
134 if(!isvarargs) | 143 if(!isvarargs) |
135 gcargs = makefuncdatasym("gcargs·%d", FUNCDATA_ArgsPointerMaps); | 144 gcargs = makefuncdatasym("gcargs·%d", FUNCDATA_ArgsPointerMaps); |
136 gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps); | 145 gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps); |
137 | 146 |
138 /* | 147 /* |
139 * isolate first argument | 148 * isolate first argument |
140 */ | 149 */ |
141 if(REGARG >= 0) { | 150 if(REGARG >= 0) { |
142 if(typesuv[thisfn->link->etype]) { | 151 if(typesuv[thisfn->link->etype]) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 lastp = sp; | 214 lastp = sp; |
206 pc = spc; | 215 pc = spc; |
207 sp->link = nil; | 216 sp->link = nil; |
208 suppress--; | 217 suppress--; |
209 warnreach = owarn; | 218 warnreach = owarn; |
210 } | 219 } |
211 | 220 |
212 void | 221 void |
213 gen(Node *n) | 222 gen(Node *n) |
214 { | 223 { |
215 » Node *l, nod; | 224 » Node *l, nod, nod1; |
216 Prog *sp, *spc, *spb; | 225 Prog *sp, *spc, *spb; |
217 Case *cn; | 226 Case *cn; |
218 long sbc, scc; | 227 long sbc, scc; |
219 int snbreak, sncontin; | 228 int snbreak, sncontin; |
220 int f, o, oldreach; | 229 int f, o, oldreach; |
221 | 230 |
222 loop: | 231 loop: |
223 if(n == Z) | 232 if(n == Z) |
224 return; | 233 return; |
225 nearln = n->lineno; | 234 nearln = n->lineno; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 warnreach = !suppress; | 275 warnreach = !suppress; |
267 complex(n); | 276 complex(n); |
268 if(n->type == T) | 277 if(n->type == T) |
269 break; | 278 break; |
270 l = n->left; | 279 l = n->left; |
271 if(l == Z) { | 280 if(l == Z) { |
272 noretval(3); | 281 noretval(3); |
273 gbranch(ORETURN); | 282 gbranch(ORETURN); |
274 break; | 283 break; |
275 } | 284 } |
| 285 if(typecmplx[n->type->etype] && !hasdotdotdot(thisfn)) { |
| 286 regret(&nod, n, thisfn, 2); |
| 287 sugen(l, &nod, n->type->width); |
| 288 noretval(3); |
| 289 gbranch(ORETURN); |
| 290 break; |
| 291 } |
276 if(typecmplx[n->type->etype]) { | 292 if(typecmplx[n->type->etype]) { |
277 sugen(l, nodret, n->type->width); | 293 sugen(l, nodret, n->type->width); |
278 noretval(3); | 294 noretval(3); |
279 gbranch(ORETURN); | 295 gbranch(ORETURN); |
280 break; | 296 break; |
281 } | 297 } |
282 » » regret(&nod, n); | 298 » » regret(&nod1, n, thisfn, 2); |
| 299 » » nod = nod1; |
| 300 » » if(nod.op != OREGISTER) |
| 301 » » » regalloc(&nod, n, Z); |
283 cgen(l, &nod); | 302 cgen(l, &nod); |
| 303 if(nod1.op != OREGISTER) |
| 304 gmove(&nod, &nod1); |
284 regfree(&nod); | 305 regfree(&nod); |
285 if(typefd[n->type->etype]) | 306 if(typefd[n->type->etype]) |
286 noretval(1); | 307 noretval(1); |
287 else | 308 else |
288 noretval(2); | 309 noretval(2); |
289 gbranch(ORETURN); | 310 gbranch(ORETURN); |
290 break; | 311 break; |
291 | 312 |
292 case OLABEL: | 313 case OLABEL: |
293 canreach = 1; | 314 canreach = 1; |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 Type *t; | 743 Type *t; |
723 int32 i; | 744 int32 i; |
724 int32 argbytes; | 745 int32 argbytes; |
725 int32 symoffset, argoffset; | 746 int32 symoffset, argoffset; |
726 | 747 |
727 // Dump the length of the bitmap array. This value is always one for | 748 // Dump the length of the bitmap array. This value is always one for |
728 // functions written in C. | 749 // functions written in C. |
729 symoffset = 0; | 750 symoffset = 0; |
730 gextern(sym, nodconst(1), symoffset, 4); | 751 gextern(sym, nodconst(1), symoffset, 4); |
731 symoffset += 4; | 752 symoffset += 4; |
732 » argbytes = (argsize() + ewidth[TIND] - 1); | 753 » argbytes = (argsize(1) + ewidth[TIND] - 1); |
733 bv = bvalloc((argbytes / ewidth[TIND]) * BitsPerPointer); | 754 bv = bvalloc((argbytes / ewidth[TIND]) * BitsPerPointer); |
734 » argoffset = align(0, fn->link, Aarg0, nil); | 755 » argoffset = 0; |
| 756 » if(hasdotdotdot(thisfn)) |
| 757 » » argoffset = align(0, fn->link, Aarg0, nil); |
735 if(argoffset > 0) { | 758 if(argoffset > 0) { |
736 // The C calling convention returns structs by copying them to a | 759 // The C calling convention returns structs by copying them to a |
737 // location pointed to by a hidden first argument. This first | 760 // location pointed to by a hidden first argument. This first |
738 // argument is a pointer. | 761 // argument is a pointer. |
739 if(argoffset != ewidth[TIND]) | 762 if(argoffset != ewidth[TIND]) |
740 yyerror("passbyptr arg not the right size"); | 763 yyerror("passbyptr arg not the right size"); |
741 bvset(bv, 1); // 2 = live ptr | 764 bvset(bv, 1); // 2 = live ptr |
742 } | 765 } |
743 for(t = fn->down; t != T; t = t->down) { | 766 for(t = fn->down; t != T; t = t->down) { |
744 if(t->etype == TVOID) | 767 if(t->etype == TVOID) |
745 continue; | 768 continue; |
746 argoffset = align(argoffset, t, Aarg1, nil); | 769 argoffset = align(argoffset, t, Aarg1, nil); |
747 walktype1(t, argoffset, bv, 1); | 770 walktype1(t, argoffset, bv, 1); |
748 argoffset = align(argoffset, t, Aarg2, nil); | 771 argoffset = align(argoffset, t, Aarg2, nil); |
749 } | 772 } |
750 // Dump the length of the bitmap. | 773 // Dump the length of the bitmap. |
751 gextern(sym, nodconst(bv->n), symoffset, 4); | 774 gextern(sym, nodconst(bv->n), symoffset, 4); |
752 symoffset += 4; | 775 symoffset += 4; |
753 // Dump the words of the bitmap. | 776 // Dump the words of the bitmap. |
754 for(i = 0; i < bv->n; i += 32) { | 777 for(i = 0; i < bv->n; i += 32) { |
755 gextern(sym, nodconst(bv->b[i/32]), symoffset, 4); | 778 gextern(sym, nodconst(bv->b[i/32]), symoffset, 4); |
756 symoffset += 4; | 779 symoffset += 4; |
757 } | 780 } |
758 free(bv); | 781 free(bv); |
759 // Finalize the gc symbol. | 782 // Finalize the gc symbol. |
760 sym->type = typ(0, T); | 783 sym->type = typ(0, T); |
761 sym->type->width = symoffset; | 784 sym->type->width = symoffset; |
762 } | 785 } |
LEFT | RIGHT |