Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110623134125

Diff

Diff from 1.66 to:

Annotations

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

Annotated File View

ragge
1.66
1 /*      $Id: code.c,v 1.66 2011/06/23 13:41:25 ragge 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
ragge
1.66
32
33 /*
34  * Print out assembler segment name.
35  */
36 void
37 setseg(int segchar *name)
38 {
39         switch (seg) {
40         case PROGname = ".text"break;
41         case DATA:
42         case LDATAname = ".data"break;
43         case STRNG:
44         case RDATAname = ".section .rodata"break;
45         case UDATAbreak;
46         case PICLDATA:
47         case PICDATAname = ".section .data.rel.rw,\"aw\",@progbits"break;
48         case PICRDATAname = ".section .data.rel.ro,\"aw\",@progbits"break;
49         case TLSDATAname = ".section .tdata,\"awT\",@progbits"break;
50         case TLSUDATAname = ".section .tbss,\"awT\",@nobits"break;
51         case CTORSname = ".section\t.ctors,\"aw\",@progbits"break;
52         case DTORSname = ".section\t.dtors,\"aw\",@progbits"break;
53         case NMSEG
54                 printf("\t.section %s,\"aw\",@progbits\n"name);
55                 return;
56         }
57         printf("\t%s\n"name);
58 }
gmcgarry
1.28
59
ragge
1.1
60 /*
ragge
1.65
61  * Print out assembler segment name.
ragge
1.1
62  */
63 void
ragge
1.65
64 setseg(int segchar *name)
ragge
1.1
65 {
ragge
1.65
66         switch (seg) {
67         case PROGname = ".text"break;
68         case DATA:
69         case LDATAname = ".data"break;
70         case UDATAbreak;
gmcgarry
1.57
71 #ifdef MACHOABI
ragge
1.65
72         case PICLDATA:
73         case PICDATAname = ".section .data.rel.rw,\"aw\""break;
74         case PICRDATAname = ".section .data.rel.ro,\"aw\""break;
75         case STRNGname = ".cstring"break;
76         case RDATAname = ".const_data"break;
77 #else
78         case PICLDATAname = ".section .data.rel.local,\"aw\",@progbits";break;
79         case PICDATAname = ".section .data.rel.rw,\"aw\",@progbits"break;
80         case PICRDATAname = ".section .data.rel.ro,\"aw\",@progbits"break;
81         case STRNG:
82 #ifdef AOUTABI
83         case RDATAname = ".data"break;
gmcgarry
1.57
84 #else
ragge
1.65
85         case RDATAname = ".section .rodata"break;
gmcgarry
1.57
86 #endif
87 #endif
ragge
1.65
88         case TLSDATAname = ".section .tdata,\"awT\",@progbits"break;
89         case TLSUDATAname = ".section .tbss,\"awT\",@nobits"break;
90         case CTORSname = ".section\t.ctors,\"aw\",@progbits"break;
91         case DTORSname = ".section\t.dtors,\"aw\",@progbits"break;
92         case NMSEG
93                 printf("\t.section %s,\"aw\",@progbits\n"name);
94                 return;
ragge
1.53
95         }
ragge
1.65
96         printf("\t%s\n"name);
97 }
98
gmcgarry
1.57
99 #ifdef MACHOABI
ragge
1.65
100 void
101 defalign(int al)
102 {
103         printf("\t.align %d\n"ispow2(al/ALCHAR));
104 }
gmcgarry
1.57
105 #endif
ragge
1.65
106
107 /*
108  * Define everything needed to print out some data (or text).
109  * This means segment, alignment, visibility, etc.
110  */
111 void
112 defloc(struct symtab *sp)
113 {
114         char *name;
115
116         if ((name = sp->soname) == NULL)
117                 name = exname(sp->sname);
118         if (sp->sclass == EXTDEF) {
ragge
1.41
119                 printf("        .globl %s\n"name);
gmcgarry
1.30
120 #if defined(ELFABI)
mickey
1.49
121                 printf("\t.type %s,@%s\n"name,
ragge
1.65
122                     ISFTN(sp->stype)? "function" : "object");
gmcgarry
1.30
123 #endif
mickey
1.49
124         }
ragge
1.58
125 #if defined(ELFABI)
ragge
1.65
126         if (!ISFTN(sp->stype)) {
ragge
1.58
127                 if (sp->slevel == 0)
128                         printf("\t.size %s,%d\n"name,
ragge
1.65
129                             (int)tsize(sp->stypesp->sdfsp->sap)/SZCHAR);
ragge
1.58
130                 else
131                         printf("\t.size " LABFMT ",%d\n"sp->soffset,
ragge
1.65
132                             (int)tsize(sp->stypesp->sdfsp->sap)/SZCHAR);
ragge
1.58
133         }
134 #endif
ragge
1.24
135         if (sp->slevel == 0)
ragge
1.41
136                 printf("%s:\n"name);
ragge
1.24
137         else
138                 printf(LABFMT ":\n"sp->soffset);
ragge
1.6
139 }
140
141 /*
ragge
1.1
142  * code for the end of a function
ragge
1.4
143  * deals with struct return here
ragge
1.1
144  */
145 void
146 efcode()
147 {
ragge
1.16
148         extern int gotnr;
ragge
1.4
149         NODE *p, *q;
150
ragge
1.16
151         gotnr = 0;      /* new number for next fun */
ragge
1.4
152         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
153                 return;
ragge
1.48
154 #if defined(os_openbsd)
155         /* struct return for small structs */
ragge
1.56
156         int sz = tsize(BTYPE(cftnsp->stype), cftnsp->sdfcftnsp->sap);
ragge
1.48
157         if (sz == SZCHAR || sz == SZSHORT || sz == SZINT || sz == SZLONGLONG) {
158                 /* Pointer to struct in eax */
159                 if (sz == SZLONGLONG) {
ragge
1.60
160                         q = block(OREGNILNILINT00);
ragge
1.48
161                         q->n_lval = 4;
ragge
1.60
162                         p = block(REGNILNILINT00);
ragge
1.48
163                         p->n_rval = EDX;
164                         ecomp(buildtree(ASSIGNpq));
165                 }
166                 if (sz < SZSHORTsz = CHAR;
167                 else if (sz > SZSHORTsz = INT;
168                 else sz = SHORT;
ragge
1.60
169                 q = block(OREGNILNILsz00);
170                 p = block(REGNILNILsz00);
ragge
1.48
171                 ecomp(buildtree(ASSIGNpq));
172                 return;
173         }
174 #endif
ragge
1.18
175         /* Create struct assignment */
ragge
1.56
176         q = block(OREGNILNILPTR+STRTY0cftnsp->sap);
ragge
1.4
177         q->n_rval = EBP;
178         q->n_lval = 8/* return buffer offset */
ragge
1.18
179         q = buildtree(UMULqNIL);
ragge
1.56
180         p = block(REGNILNILPTR+STRTY0cftnsp->sap);
ragge
1.18
181         p = buildtree(UMULpNIL);
182         p = buildtree(ASSIGNqp);
183         ecomp(p);
ragge
1.55
184
185         /* put hidden arg in eax on return */
ragge
1.60
186         q = block(OREGNILNILINT00);
ragge
1.55
187         regno(q) = FPREG;
188         q->n_lval = 8;
ragge
1.60
189         p = block(REGNILNILINT00);
ragge
1.55
190         regno(p) = EAX;
191         ecomp(buildtree(ASSIGNpq));
ragge
1.1
192 }
193
194 /*
195  * code for the beginning of a function; a is an array of
ragge
1.2
196  * indices in symtab for the arguments; n is the number
ragge
1.1
197  */
198 void
ragge
1.17
199 bfcode(struct symtab **spint cnt)
ragge
1.1
200 {
gmcgarry
1.30
201         extern int argstacksize;
ragge
1.29
202         struct symtab *sp2;
ragge
1.17
203         extern int gotnr;
204         NODE *n, *p;
ragge
1.4
205         int i;
206
ragge
1.17
207         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
208                 /* Function returns struct, adjust arg offset */
ragge
1.48
209 #if defined(os_openbsd)
210                 /* OpenBSD uses non-standard return for small structs */
ragge
1.56
211                 int sz = tsize(BTYPE(cftnsp->stype), cftnsp->sdfcftnsp->sap);
ragge
1.48
212                 if (sz != SZCHAR && sz != SZSHORT &&
213                     sz != SZINT && sz != SZLONGLONG)
214 #endif
215                         for (i = 0i < cnti++) 
216                                 sp[i]->soffset += SZPOINT(INT);
ragge
1.17
217         }
gmcgarry
1.30
218
ragge
1.52
219 #ifdef GCC_COMPAT
ragge
1.56
220         if (attr_find(cftnsp->sapGCC_ATYP_STDCALL) != NULL)
ragge
1.52
221                 cftnsp->sflags |= SSTDCALL;
222 #endif
223
gmcgarry
1.30
224         /*
ragge
1.52
225          * Count the arguments
gmcgarry
1.30
226          */
227         argstacksize = 0;
228         if (cftnsp->sflags & SSTDCALL) {
ragge
1.52
229 #ifdef os_win32
230
gmcgarry
1.45
231                 char buf[256];
ragge
1.41
232                 char *name;
ragge
1.52
233 #endif
234
gmcgarry
1.30
235                 for (i = 0i < cnti++) {
236                         TWORD t = sp[i]->stype;
237                         if (t == STRTY || t == UNIONTY)
ragge
1.39
238                                 argstacksize +=
ragge
1.56
239                                     tsize(tsp[i]->sdfsp[i]->sap);
gmcgarry
1.30
240                         else
241                                 argstacksize += szty(t) * SZINT / SZCHAR;
242                 }
ragge
1.52
243 #ifdef os_win32
244                 /*
245                  * mangle name in symbol table as a callee.
246                  */
ragge
1.41
247                 if ((name = cftnsp->soname) == NULL)
gmcgarry
1.47
248                         name = exname(cftnsp->sname);
gmcgarry
1.45
249                 snprintf(buf256"%s@%d"nameargstacksize);
gmcgarry
1.47
250                 cftnsp->soname = addname(buf);
ragge
1.52
251 #endif
gmcgarry
1.30
252         }
253
ragge
1.17
254         if (kflag) {
gmcgarry
1.44
255 #define STL     200
ragge
1.34
256                 char *str = inlalloc(STL);
257 #if !defined(MACHOABI)
258                 int l = getlab();
gmcgarry
1.44
259 #else
260                 char *name;
ragge
1.34
261 #endif
262
263                 /* Generate extended assembler for PIC prolog */
ragge
1.60
264                 p = tempnode(0INT00);
ragge
1.22
265                 gotnr = regno(p);
ragge
1.60
266                 p = block(XARGpNILINT00);
ragge
1.34
267                 p->n_name = "=g";
ragge
1.60
268                 p = block(XASMpbcon(0), INT00);
gmcgarry
1.44
269
ragge
1.34
270 #if defined(MACHOABI)
gmcgarry
1.44
271                 if ((name = cftnsp->soname) == NULL)
272                         name = cftnsp->sname;
ragge
1.34
273                 if (snprintf(strSTL"call L%s$pb\nL%s$pb:\n\tpopl %%0\n",
gmcgarry
1.44
274                     namename) >= STL)
ragge
1.34
275                         cerror("bfcode");
276 #else
277                 if (snprintf(strSTL,
278                     "call " LABFMT "\n" LABFMT ":\n     popl %%0\n"
279                     "   addl $_GLOBAL_OFFSET_TABLE_+[.-" LABFMT "], %%0\n",
280                     lll) >= STL)
281                         cerror("bfcode");
282 #endif
283                 p->n_name = str;
284                 p->n_right->n_type = STRTY;
285                 ecomp(p);
ragge
1.17
286         }
287         if (xtemps == 0)
ragge
1.4
288                 return;
ragge
1.17
289
290         /* put arguments in temporaries */
291         for (i = 0i < cnti++) {
292                 if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY ||
293                     cisreg(sp[i]->stype) == 0)
294                         continue;
ragge
1.33
295                 if (cqual(sp[i]->stypesp[i]->squal) & VOL)
296                         continue;
ragge
1.29
297                 sp2 = sp[i];
ragge
1.56
298                 n = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->sap);
ragge
1.29
299                 n = buildtree(ASSIGNnnametree(sp2));
ragge
1.22
300                 sp[i]->soffset = regno(n->n_left);
ragge
1.17
301                 sp[i]->sflags |= STNODE;
302                 ecomp(n);
303         }
ragge
1.1
304 }
305
306
gmcgarry
1.28
307 #if defined(MACHOABI)
308 struct stub stublist;
309 struct stub nlplist;
310 #endif
311
ragge
1.1
312 /* called just before final exit */
313 /* flag is 1 if errors, 0 if none */
314 void
315 ejobcode(int flag )
316 {
gmcgarry
1.28
317 #if defined(MACHOABI)
318         /*
319          * iterate over the stublist and output the PIC stubs
320 `        */
321         if (kflag) {
322                 struct stub *p;
323
324                 DLIST_FOREACH(p, &stublistlink) {
325                         printf("\t.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5\n");
326                         printf("L%s$stub:\n"p->name);
pantzer
1.42
327                         printf("\t.indirect_symbol %s\n"p->name);
gmcgarry
1.28
328                         printf("\thlt ; hlt ; hlt ; hlt ; hlt\n");
329                         printf("\t.subsections_via_symbols\n");
330                 }
331
332                 printf("\t.section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
333                 DLIST_FOREACH(p, &nlplistlink) {
334                         printf("L%s$non_lazy_ptr:\n"p->name);
pantzer
1.42
335                         printf("\t.indirect_symbol %s\n"p->name);
gmcgarry
1.28
336                         printf("\t.long 0\n");
337                 }
338
339         }
340 #endif
341
plunky
1.62
342         printf("\t.ident \"PCC: %s\"\n"VERSSTR);
ragge
1.1
343 }
344
pj
1.8
345 void
346 bjobcode()
347 {
ragge
1.64
348 #ifdef os_sunos
349         astypnames[SHORT] = astypnames[USHORT] = "\t.2byte";
350 #endif
351         astypnames[INT] = astypnames[UNSIGNED] = "\t.long";
gmcgarry
1.28
352 #if defined(MACHOABI)
353         DLIST_INIT(&stublistlink);
354         DLIST_INIT(&nlplistlink);
355 #endif
pj
1.8
356 }
357
ragge
1.1
358 /*
ragge
1.17
359  * Called with a function call with arguments as argument.
360  * This is done early in buildtree() and only done once.
361  * Returns p.
362  */
363 NODE *
364 funcode(NODE *p)
365 {
366         extern int gotnr;
367         NODE *r, *l;
368
369         /* Fix function call arguments. On x86, just add funarg */
370         for (r = p->n_rightr->n_op == CMr = r->n_left) {
371                 if (r->n_right->n_op != STARG)
372                         r->n_right = block(FUNARGr->n_rightNIL,
373                             r->n_right->n_typer->n_right->n_df,
ragge
1.56
374                             r->n_right->n_ap);
ragge
1.17
375         }
376         if (r->n_op != STARG) {
377                 l = talloc();
378                 *l = *r;
379                 r->n_op = FUNARG;
380                 r->n_left = l;
381                 r->n_type = l->n_type;
382         }
383         if (kflag == 0)
384                 return p;
gmcgarry
1.28
385 #if defined(ELFABI)
ragge
1.17
386         /* Create an ASSIGN node for ebx */
ragge
1.60
387         l = block(REGNILNILINT00);
ragge
1.17
388         l->n_rval = EBX;
ragge
1.60
389         l = buildtree(ASSIGNltempnode(gotnrINT00));
ragge
1.17
390         if (p->n_right->n_op != CM) {
ragge
1.60
391                 p->n_right = block(CMlp->n_rightINT00);
ragge
1.17
392         } else {
393                 for (r = p->n_rightr->n_left->n_op == CMr = r->n_left)
394                         ;
ragge
1.60
395                 r->n_left = block(CMlr->n_leftINT00);
ragge
1.17
396         }
gmcgarry
1.28
397 #endif
ragge
1.17
398         return p;
399 }
400
ragge
1.1
401 /* fix up type of field p */
402 void
403 fldty(struct symtab *p)
404 {
405 }
406
stefan
1.19
407 /*
ragge
1.1
408  * XXX - fix genswitch.
409  */
stefan
1.19
410 int
411 mygenswitch(int numTWORD typestruct swents **pint n)
ragge
1.1
412 {
stefan
1.19
413         return 0;
ragge
1.1
414 }
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-10-31 18:06 +0100