Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.68 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/arch/i386/code.c

Annotated File View

plunky
1.68
1 /*      $Id: code.c,v 1.68 2012/04/22 21:07:40 plunky Exp $     */
ragge
1.1
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29
30 # include "pass1.h"
31
32 /*
ragge
1.65
33  * Print out assembler segment name.
ragge
1.1
34  */
35 void
ragge
1.65
36 setseg(int segchar *name)
ragge
1.1
37 {
ragge
1.65
38         switch (seg) {
39         case PROGname = ".text"break;
40         case DATA:
41         case LDATAname = ".data"break;
42         case UDATAbreak;
gmcgarry
1.57
43 #ifdef MACHOABI
ragge
1.65
44         case PICLDATA:
45         case PICDATAname = ".section .data.rel.rw,\"aw\""break;
46         case PICRDATAname = ".section .data.rel.ro,\"aw\""break;
47         case STRNGname = ".cstring"break;
48         case RDATAname = ".const_data"break;
49 #else
50         case PICLDATAname = ".section .data.rel.local,\"aw\",@progbits";break;
51         case PICDATAname = ".section .data.rel.rw,\"aw\",@progbits"break;
52         case PICRDATAname = ".section .data.rel.ro,\"aw\",@progbits"break;
53         case STRNG:
54 #ifdef AOUTABI
55         case RDATAname = ".data"break;
gmcgarry
1.57
56 #else
ragge
1.65
57         case RDATAname = ".section .rodata"break;
gmcgarry
1.57
58 #endif
59 #endif
ragge
1.65
60         case TLSDATAname = ".section .tdata,\"awT\",@progbits"break;
61         case TLSUDATAname = ".section .tbss,\"awT\",@nobits"break;
62         case CTORSname = ".section\t.ctors,\"aw\",@progbits"break;
63         case DTORSname = ".section\t.dtors,\"aw\",@progbits"break;
64         case NMSEG
65                 printf("\t.section %s,\"aw\",@progbits\n"name);
66                 return;
ragge
1.53
67         }
ragge
1.65
68         printf("\t%s\n"name);
69 }
70
gmcgarry
1.57
71 #ifdef MACHOABI
ragge
1.65
72 void
73 defalign(int al)
74 {
75         printf("\t.align %d\n"ispow2(al/ALCHAR));
76 }
gmcgarry
1.57
77 #endif
ragge
1.65
78
79 /*
80  * Define everything needed to print out some data (or text).
81  * This means segment, alignment, visibility, etc.
82  */
83 void
84 defloc(struct symtab *sp)
85 {
86         char *name;
87
88         if ((name = sp->soname) == NULL)
89                 name = exname(sp->sname);
90         if (sp->sclass == EXTDEF) {
ragge
1.41
91                 printf("        .globl %s\n"name);
gmcgarry
1.30
92 #if defined(ELFABI)
mickey
1.49
93                 printf("\t.type %s,@%s\n"name,
ragge
1.65
94                     ISFTN(sp->stype)? "function" : "object");
gmcgarry
1.30
95 #endif
mickey
1.49
96         }
ragge
1.58
97 #if defined(ELFABI)
ragge
1.65
98         if (!ISFTN(sp->stype)) {
ragge
1.58
99                 if (sp->slevel == 0)
100                         printf("\t.size %s,%d\n"name,
ragge
1.65
101                             (int)tsize(sp->stypesp->sdfsp->sap)/SZCHAR);
ragge
1.58
102                 else
103                         printf("\t.size " LABFMT ",%d\n"sp->soffset,
ragge
1.65
104                             (int)tsize(sp->stypesp->sdfsp->sap)/SZCHAR);
ragge
1.58
105         }
106 #endif
ragge
1.24
107         if (sp->slevel == 0)
ragge
1.41
108                 printf("%s:\n"name);
ragge
1.24
109         else
110                 printf(LABFMT ":\n"sp->soffset);
ragge
1.6
111 }
112
113 /*
ragge
1.1
114  * code for the end of a function
ragge
1.4
115  * deals with struct return here
ragge
1.1
116  */
117 void
plunky
1.68
118 efcode(void)
ragge
1.1
119 {
ragge
1.16
120         extern int gotnr;
ragge
1.4
121         NODE *p, *q;
122
ragge
1.16
123         gotnr = 0;      /* new number for next fun */
ragge
1.4
124         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
125                 return;
ragge
1.48
126 #if defined(os_openbsd)
127         /* struct return for small structs */
ragge
1.56
128         int sz = tsize(BTYPE(cftnsp->stype), cftnsp->sdfcftnsp->sap);
ragge
1.48
129         if (sz == SZCHAR || sz == SZSHORT || sz == SZINT || sz == SZLONGLONG) {
130                 /* Pointer to struct in eax */
131                 if (sz == SZLONGLONG) {
ragge
1.60
132                         q = block(OREGNILNILINT00);
ragge
1.48
133                         q->n_lval = 4;
ragge
1.60
134                         p = block(REGNILNILINT00);
ragge
1.48
135                         p->n_rval = EDX;
136                         ecomp(buildtree(ASSIGNpq));
137                 }
138                 if (sz < SZSHORTsz = CHAR;
139                 else if (sz > SZSHORTsz = INT;
140                 else sz = SHORT;
ragge
1.60
141                 q = block(OREGNILNILsz00);
142                 p = block(REGNILNILsz00);
ragge
1.48
143                 ecomp(buildtree(ASSIGNpq));
144                 return;
145         }
146 #endif
ragge
1.18
147         /* Create struct assignment */
ragge
1.56
148         q = block(OREGNILNILPTR+STRTY0cftnsp->sap);
ragge
1.4
149         q->n_rval = EBP;
150         q->n_lval = 8/* return buffer offset */
ragge
1.18
151         q = buildtree(UMULqNIL);
ragge
1.56
152         p = block(REGNILNILPTR+STRTY0cftnsp->sap);
ragge
1.18
153         p = buildtree(UMULpNIL);
154         p = buildtree(ASSIGNqp);
155         ecomp(p);
ragge
1.55
156
157         /* put hidden arg in eax on return */
ragge
1.60
158         q = block(OREGNILNILINT00);
ragge
1.55
159         regno(q) = FPREG;
160         q->n_lval = 8;
ragge
1.60
161         p = block(REGNILNILINT00);
ragge
1.55
162         regno(p) = EAX;
163         ecomp(buildtree(ASSIGNpq));
ragge
1.1
164 }
165
166 /*
167  * code for the beginning of a function; a is an array of
ragge
1.2
168  * indices in symtab for the arguments; n is the number
ragge
1.1
169  */
170 void
ragge
1.17
171 bfcode(struct symtab **spint cnt)
ragge
1.1
172 {
gmcgarry
1.30
173         extern int argstacksize;
ragge
1.29
174         struct symtab *sp2;
ragge
1.17
175         extern int gotnr;
176         NODE *n, *p;
ragge
1.4
177         int i;
178
ragge
1.17
179         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
180                 /* Function returns struct, adjust arg offset */
ragge
1.48
181 #if defined(os_openbsd)
182                 /* OpenBSD uses non-standard return for small structs */
ragge
1.56
183                 int sz = tsize(BTYPE(cftnsp->stype), cftnsp->sdfcftnsp->sap);
ragge
1.48
184                 if (sz != SZCHAR && sz != SZSHORT &&
185                     sz != SZINT && sz != SZLONGLONG)
186 #endif
187                         for (i = 0i < cnti++) 
188                                 sp[i]->soffset += SZPOINT(INT);
ragge
1.17
189         }
gmcgarry
1.30
190
ragge
1.52
191 #ifdef GCC_COMPAT
ragge
1.56
192         if (attr_find(cftnsp->sapGCC_ATYP_STDCALL) != NULL)
ragge
1.52
193                 cftnsp->sflags |= SSTDCALL;
194 #endif
195
gmcgarry
1.30
196         /*
ragge
1.52
197          * Count the arguments
gmcgarry
1.30
198          */
199         argstacksize = 0;
200         if (cftnsp->sflags & SSTDCALL) {
ragge
1.52
201 #ifdef os_win32
202
gmcgarry
1.45
203                 char buf[256];
ragge
1.41
204                 char *name;
ragge
1.52
205 #endif
206
gmcgarry
1.30
207                 for (i = 0i < cnti++) {
208                         TWORD t = sp[i]->stype;
209                         if (t == STRTY || t == UNIONTY)
ragge
1.39
210                                 argstacksize +=
ragge
1.56
211                                     tsize(tsp[i]->sdfsp[i]->sap);
gmcgarry
1.30
212                         else
213                                 argstacksize += szty(t) * SZINT / SZCHAR;
214                 }
ragge
1.52
215 #ifdef os_win32
216                 /*
217                  * mangle name in symbol table as a callee.
218                  */
ragge
1.41
219                 if ((name = cftnsp->soname) == NULL)
gmcgarry
1.47
220                         name = exname(cftnsp->sname);
gmcgarry
1.45
221                 snprintf(buf256"%s@%d"nameargstacksize);
gmcgarry
1.47
222                 cftnsp->soname = addname(buf);
ragge
1.52
223 #endif
gmcgarry
1.30
224         }
225
ragge
1.17
226         if (kflag) {
gmcgarry
1.44
227 #define STL     200
ragge
1.34
228                 char *str = inlalloc(STL);
229 #if !defined(MACHOABI)
230                 int l = getlab();
gmcgarry
1.44
231 #else
232                 char *name;
ragge
1.34
233 #endif
234
235                 /* Generate extended assembler for PIC prolog */
ragge
1.60
236                 p = tempnode(0INT00);
ragge
1.22
237                 gotnr = regno(p);
ragge
1.60
238                 p = block(XARGpNILINT00);
ragge
1.34
239                 p->n_name = "=g";
ragge
1.60
240                 p = block(XASMpbcon(0), INT00);
gmcgarry
1.44
241
ragge
1.34
242 #if defined(MACHOABI)
gmcgarry
1.44
243                 if ((name = cftnsp->soname) == NULL)
244                         name = cftnsp->sname;
ragge
1.34
245                 if (snprintf(strSTL"call L%s$pb\nL%s$pb:\n\tpopl %%0\n",
gmcgarry
1.44
246                     namename) >= STL)
ragge
1.34
247                         cerror("bfcode");
248 #else
249                 if (snprintf(strSTL,
250                     "call " LABFMT "\n" LABFMT ":\n     popl %%0\n"
251                     "   addl $_GLOBAL_OFFSET_TABLE_+[.-" LABFMT "], %%0\n",
252                     lll) >= STL)
253                         cerror("bfcode");
254 #endif
255                 p->n_name = str;
256                 p->n_right->n_type = STRTY;
257                 ecomp(p);
ragge
1.17
258         }
259         if (xtemps == 0)
ragge
1.4
260                 return;
ragge
1.17
261
262         /* put arguments in temporaries */
263         for (i = 0i < cnti++) {
264                 if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY ||
265                     cisreg(sp[i]->stype) == 0)
266                         continue;
ragge
1.33
267                 if (cqual(sp[i]->stypesp[i]->squal) & VOL)
268                         continue;
ragge
1.29
269                 sp2 = sp[i];
ragge
1.56
270                 n = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->sap);
ragge
1.29
271                 n = buildtree(ASSIGNnnametree(sp2));
ragge
1.22
272                 sp[i]->soffset = regno(n->n_left);
ragge
1.17
273                 sp[i]->sflags |= STNODE;
274                 ecomp(n);
275         }
ragge
1.1
276 }
277
278
gmcgarry
1.28
279 #if defined(MACHOABI)
280 struct stub stublist;
281 struct stub nlplist;
282 #endif
283
ragge
1.1
284 /* called just before final exit */
285 /* flag is 1 if errors, 0 if none */
286 void
plunky
1.68
287 ejobcode(int flag)
ragge
1.1
288 {
gmcgarry
1.28
289 #if defined(MACHOABI)
290         /*
291          * iterate over the stublist and output the PIC stubs
292 `        */
293         if (kflag) {
294                 struct stub *p;
295
296                 DLIST_FOREACH(p, &stublistlink) {
297                         printf("\t.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5\n");
298                         printf("L%s$stub:\n"p->name);
pantzer
1.42
299                         printf("\t.indirect_symbol %s\n"p->name);
gmcgarry
1.28
300                         printf("\thlt ; hlt ; hlt ; hlt ; hlt\n");
301                         printf("\t.subsections_via_symbols\n");
302                 }
303
304                 printf("\t.section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
305                 DLIST_FOREACH(p, &nlplistlink) {
306                         printf("L%s$non_lazy_ptr:\n"p->name);
pantzer
1.42
307                         printf("\t.indirect_symbol %s\n"p->name);
gmcgarry
1.28
308                         printf("\t.long 0\n");
309                 }
310
311         }
312 #endif
313
plunky
1.62
314         printf("\t.ident \"PCC: %s\"\n"VERSSTR);
ragge
1.1
315 }
316
pj
1.8
317 void
plunky
1.68
318 bjobcode(void)
pj
1.8
319 {
ragge
1.64
320 #ifdef os_sunos
321         astypnames[SHORT] = astypnames[USHORT] = "\t.2byte";
322 #endif
323         astypnames[INT] = astypnames[UNSIGNED] = "\t.long";
gmcgarry
1.28
324 #if defined(MACHOABI)
325         DLIST_INIT(&stublistlink);
326         DLIST_INIT(&nlplistlink);
327 #endif
pj
1.8
328 }
329
ragge
1.1
330 /*
ragge
1.17
331  * Called with a function call with arguments as argument.
332  * This is done early in buildtree() and only done once.
333  * Returns p.
334  */
335 NODE *
336 funcode(NODE *p)
337 {
338         extern int gotnr;
339         NODE *r, *l;
340
341         /* Fix function call arguments. On x86, just add funarg */
342         for (r = p->n_rightr->n_op == CMr = r->n_left) {
343                 if (r->n_right->n_op != STARG)
344                         r->n_right = block(FUNARGr->n_rightNIL,
345                             r->n_right->n_typer->n_right->n_df,
ragge
1.56
346                             r->n_right->n_ap);
ragge
1.17
347         }
348         if (r->n_op != STARG) {
349                 l = talloc();
350                 *l = *r;
351                 r->n_op = FUNARG;
352                 r->n_left = l;
353                 r->n_type = l->n_type;
354         }
355         if (kflag == 0)
356                 return p;
gmcgarry
1.28
357 #if defined(ELFABI)
ragge
1.17
358         /* Create an ASSIGN node for ebx */
ragge
1.60
359         l = block(REGNILNILINT00);
ragge
1.17
360         l->n_rval = EBX;
ragge
1.60
361         l = buildtree(ASSIGNltempnode(gotnrINT00));
ragge
1.17
362         if (p->n_right->n_op != CM) {
ragge
1.60
363                 p->n_right = block(CMlp->n_rightINT00);
ragge
1.17
364         } else {
365                 for (r = p->n_rightr->n_left->n_op == CMr = r->n_left)
366                         ;
ragge
1.60
367                 r->n_left = block(CMlr->n_leftINT00);
ragge
1.17
368         }
gmcgarry
1.28
369 #endif
ragge
1.17
370         return p;
371 }
372
ragge
1.1
373 /* fix up type of field p */
374 void
375 fldty(struct symtab *p)
376 {
377 }
378
stefan
1.19
379 /*
ragge
1.1
380  * XXX - fix genswitch.
381  */
stefan
1.19
382 int
383 mygenswitch(int numTWORD typestruct swents **pint n)
ragge
1.1
384 {
stefan
1.19
385         return 0;
ragge
1.1
386 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-08-31 02:15 +0200