Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110623134125

Diff

Diff from 1.20 to:

Annotations

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

Annotated File View

ragge
1.20
1 /*      $Id: code.c,v 1.20 2011/06/23 13:41:25 ragge Exp $      */
plunky
1.18
2
david
1.1
3 /*
4  * Copyright (c) 2008 David Crawshaw <david@zentus.com>
5  * 
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  * 
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #include "pass1.h"
20
ragge
1.20
21 /*
22  * Print out assembler segment name.
23  */
24 void
25 setseg(int segchar *name)
26 {
27         switch (seg) {
28         case PROGname = ".text"break;
29         case DATA:
30         case LDATAname = ".data"break;
31         case STRNG:
32         case RDATAname = ".section .rodata"break;
33         case UDATAbreak;
34         case PICLDATA:
35         case PICDATA:
36         case PICRDATA:
37         case TLSDATA:
38         case TLSUDATA:
39         case CTORS:
40         case DTORS:
41                 uerror("FIXME: unknown section");
42         case NMSEG
43                 printf("\t.section %s,\"aw\",@progbits\n"name);
44                 return;
45         }
46         printf("\t%s\n"name);
47 }
48
49
david
1.1
50 void
51 defloc(struct symtab *sp)
52 {
53         TWORD t;
ragge
1.20
54         char *name;
david
1.1
55
ragge
1.20
56         t = sp->stype;
ragge
1.13
57
ragge
1.20
58         if ((name = sp->soname) == NULL)
59                 name = exname(sp->sname);
david
1.6
60
ragge
1.20
61         if (!ISFTN(t)) {
62                 printf("\t.type %s,#object\n"name);
63                 printf("\t.size %s," CONFMT "\n"name,
64                         tsize(sp->stypesp->sdfsp->sap) / SZCHAR);
david
1.6
65         }
david
1.1
66         if (sp->sclass == EXTDEF)
ragge
1.20
67                 printf("\t.global %s\n"name);
david
1.5
68         if (sp->slevel == 0) {
ragge
1.20
69                 printf("%s:\n"name);
david
1.5
70         } else
david
1.1
71                 printf(LABFMT ":\n"sp->soffset);
72 }
73
74 void
75 efcode()
76 {
77         /* XXX */
78 }
79
80 void
81 bfcode(struct symtab **spint cnt)
82 {
david
1.8
83         int ioff;
david
1.2
84         NODE *p, *q;
85         struct symtab *sym;
86
david
1.8
87         /* Process the first six arguments. */
david
1.10
88         for (i=0i < cnt && i < 6i++) {
david
1.2
89                 sym = sp[i];
ragge
1.14
90                 q = block(REGNILNILsym->stypesym->sdfsym->sap);
david
1.10
91                 q->n_rval = RETREG_PRE(sym->stype) + i;
ragge
1.14
92                 p = tempnode(0sym->stypesym->sdfsym->sap);
david
1.2
93                 sym->soffset = regno(p);
94                 sym->sflags |= STNODE;
95                 p = buildtree(ASSIGNpq);
96                 ecomp(p);
97         }
98
david
1.8
99         /* Process the remaining arguments. */
100         for (off = V9RESERVEi < cnti++) {
101                 sym = sp[i];
ragge
1.14
102                 p = tempnode(0sym->stypesym->sdfsym->sap);
david
1.8
103                 off = ALIGN(off, (tlen(p) - 1));
104                 sym->soffset = off * SZCHAR;
105                 off += tlen(p);
ragge
1.11
106                 p = buildtree(ASSIGNpnametree(sym));
david
1.8
107                 sym->soffset = regno(p->n_left);
108                 sym->sflags |= STNODE;
109                 ecomp(p);
110         }
david
1.1
111 }
112
113 void
114 ejobcode(int flag)
115 {
116 }
117
118 void
119 bjobcode()
120 {
ragge
1.19
121         astypnames[USHORT] = astypnames[SHORT] = "\t.half";
122         astypnames[INT] = astypnames[UNSIGNED] = "\t.long";
123         astypnames[LONG] = astypnames[ULONG] = 
124             astypnames[LONGLONG] = astypnames[ULONGLONG] = "\t.xword";
david
1.1
125 }
126
david
1.7
127 /*
128  * The first six 64-bit arguments are saved in the registers O0 to O5,
129  * which become I0 to I5 after the "save" instruction moves the register
130  * window. Arguments 7 and up must be saved on the stack to %sp+BIAS+176.
131  *
132  * For a pretty picture, see Figure 3-16 in the SPARC Compliance Def 2.4.
133  */
david
1.2
134 static NODE *
david
1.7
135 moveargs(NODE *pint *regpint *stacksize)
david
1.2
136 {
137         NODE *r, *q;
138
139         if (p->n_op == CM) {
david
1.7
140                 p->n_left = moveargs(p->n_leftregpstacksize);
david
1.2
141                 r = p->n_right;
142         } else {
143                 r = p;
144         }
145
david
1.9
146         /* XXX more than six FP args can and should be passed in registers. */
david
1.10
147         if (*regp > 5 && r->n_op != STARG) {
david
1.8
148                 /* We are storing the stack offset in n_rval. */
ragge
1.14
149                 r = block(FUNARGrNILr->n_typer->n_dfr->n_ap);
david
1.8
150                 /* Make sure we are appropriately aligned. */
151                 *stacksize = ALIGN(*stacksize, (tlen(r) - 1));
152                 r->n_rval = *stacksize;
david
1.7
153                 *stacksize += tlen(r);
154         } else if (r->n_op == STARG)
david
1.2
155                 cerror("op STARG in moveargs");
156         else {
ragge
1.14
157                 q = block(REGNILNILr->n_typer->n_dfr->n_ap);
david
1.9
158
159                 /*
160                  * The first six non-FP arguments go in the registers O0 - O5.
161                  * Float arguments are stored in %fp1, %fp3, ..., %fp29, %fp31.
162                  * Double arguments are stored in %fp0, %fp2, ..., %fp28, %fp30.
163                  * A non-fp argument still increments register, eg.
164                  *     test(int a, int b, float b)
165                  * takes %o0, %o1, %fp5.
166                  */
167                 if (q->n_type == FLOAT)
david
1.10
168                         q->n_rval = F0 + (*regp++ * 2) + 1;
david
1.9
169                 else if (q->n_type == DOUBLE)
david
1.10
170                         q->n_rval = D0 + *regp++;
david
1.9
171                 else if (q->n_type == LDOUBLE)
172                         cerror("long double support incomplete");
173                 else
david
1.10
174                         q->n_rval = O0 + (*regp)++;
david
1.9
175
david
1.2
176                 r = buildtree(ASSIGNqr);
177         }
178
179         if (p->n_op == CM) {
180                 p->n_right = r;
181                 return p;
182         }
183
184         return r;
185 }
186
david
1.1
187 NODE *
188 funcode(NODE *p)
189 {
david
1.7
190         NODE *r, *l;
david
1.10
191         int reg = 0stacksize = 0;
david
1.7
192
193         r = l = 0;
194
195         p->n_right = moveargs(p->n_right, &reg, &stacksize);
196
197         /*
198          * This is a particularly gross and inefficient way to handle
199          * argument overflows. First, we calculate how much stack space
200          * we need in moveargs(). Then we assign it by moving %sp, make
201          * the function call, and then move %sp back.
202          *
203          * What we should be doing is getting the maximum of all the needed
204          * stacksize values to the prologue and doing it all in the "save"
205          * instruction.
206          */
207         if (stacksize != 0) {
208                 stacksize = V9STEP(stacksize); /* 16-bit alignment. */
209
ragge
1.15
210                 r = block(REGNILNILINT00);
david
1.7
211                 r->n_lval = 0;
212                 r->n_rval = SP;
ragge
1.15
213                 r = block(MINUSrbcon(stacksize), INT00);
david
1.7
214
ragge
1.15
215                 l = block(REGNILNILINT00);
david
1.7
216                 l->n_lval = 0;
217                 l->n_rval = SP;
218                 r = buildtree(ASSIGNlr);
219
220                 p = buildtree(COMOPrp);
221
ragge
1.15
222                 r = block(REGNILNILINT00);
david
1.7
223                 r->n_lval = 0;
224                 r->n_rval = SP;
ragge
1.15
225                 r = block(PLUSrbcon(stacksize), INT00);
david
1.7
226
ragge
1.15
227                 l = block(REGNILNILINT00);
david
1.7
228                 l->n_lval = 0;
229                 l->n_rval = SP;
230                 r = buildtree(ASSIGNlr);
231
232                 p = buildtree(COMOPpr);
233
234         }
david
1.1
235         return p;
236 }
237
238 void
239 fldty(struct symtab *p)
240 {
241 }
242
243 int
244 mygenswitch(int numTWORD typestruct swents **pint n)
245 {
246         return 0;
247 }
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-09-01 20:39 +0200