Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20110605085442

Diff

Diff from 1.18 to:

Annotations

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

Annotated File View

plunky
1.18
1 /*      $Id: code.c,v 1.18 2011/06/05 08:54:42 plunky Exp $     */
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
21 void
22 defloc(struct symtab *sp)
23 {
david
1.3
24         static char *loctbl[] = { "text""data""rodata" };
david
1.1
25         static int lastloc = -1;
26         TWORD t;
ragge
1.12
27         char *n;
david
1.1
28         int s;
29
ragge
1.13
30         if (sp == NULL)
31                 return;
32
david
1.1
33         t = sp->stype;
34         s = ISFTN(t) ? PROG : ISCON(cqual(tsp->squal)) ? RDATA : DATA;
david
1.3
35         if (s != lastloc)
36                 printf("\n\t.section \".%s\"\n"loctbl[s]);
37         lastloc = s;
david
1.1
38         if (s == PROG)
39                 return;
david
1.6
40
41         switch (DEUNSIGN(sp->stype)) {
42                 case CHAR:      s = 1;
43                 case SHORT:     s = 2;
44                 case INT:
45                 case UNSIGNED:  s = 4;
46                 default:        s = 8;
47         }
48         printf("\t.align %d\n"s);
49
ragge
1.12
50         n = sp->soname ? sp->soname : sp->sname;
david
1.1
51         if (sp->sclass == EXTDEF)
ragge
1.12
52                 printf("\t.global %s\n"n);
david
1.5
53         if (sp->slevel == 0) {
ragge
1.12
54                 printf("\t.type %s,#object\n"n);
55                 printf("\t.size %s," CONFMT "\n"n,
ragge
1.14
56                         tsize(sp->stypesp->sdfsp->sap) / SZCHAR);
ragge
1.12
57                 printf("%s:\n"n);
david
1.5
58         } else
david
1.1
59                 printf(LABFMT ":\n"sp->soffset);
60 }
61
62 void
63 efcode()
64 {
65         /* XXX */
66 }
67
68 void
69 bfcode(struct symtab **spint cnt)
70 {
david
1.8
71         int ioff;
david
1.2
72         NODE *p, *q;
73         struct symtab *sym;
74
david
1.8
75         /* Process the first six arguments. */
david
1.10
76         for (i=0i < cnt && i < 6i++) {
david
1.2
77                 sym = sp[i];
ragge
1.14
78                 q = block(REGNILNILsym->stypesym->sdfsym->sap);
david
1.10
79                 q->n_rval = RETREG_PRE(sym->stype) + i;
ragge
1.14
80                 p = tempnode(0sym->stypesym->sdfsym->sap);
david
1.2
81                 sym->soffset = regno(p);
82                 sym->sflags |= STNODE;
83                 p = buildtree(ASSIGNpq);
84                 ecomp(p);
85         }
86
david
1.8
87         /* Process the remaining arguments. */
88         for (off = V9RESERVEi < cnti++) {
89                 sym = sp[i];
ragge
1.14
90                 p = tempnode(0sym->stypesym->sdfsym->sap);
david
1.8
91                 off = ALIGN(off, (tlen(p) - 1));
92                 sym->soffset = off * SZCHAR;
93                 off += tlen(p);
ragge
1.11
94                 p = buildtree(ASSIGNpnametree(sym));
david
1.8
95                 sym->soffset = regno(p->n_left);
96                 sym->sflags |= STNODE;
97                 ecomp(p);
98         }
david
1.1
99 }
100
101 void
102 ejobcode(int flag)
103 {
104 }
105
106 void
107 bjobcode()
108 {
109 }
110
david
1.7
111 /*
112  * The first six 64-bit arguments are saved in the registers O0 to O5,
113  * which become I0 to I5 after the "save" instruction moves the register
114  * window. Arguments 7 and up must be saved on the stack to %sp+BIAS+176.
115  *
116  * For a pretty picture, see Figure 3-16 in the SPARC Compliance Def 2.4.
117  */
david
1.2
118 static NODE *
david
1.7
119 moveargs(NODE *pint *regpint *stacksize)
david
1.2
120 {
121         NODE *r, *q;
122
123         if (p->n_op == CM) {
david
1.7
124                 p->n_left = moveargs(p->n_leftregpstacksize);
david
1.2
125                 r = p->n_right;
126         } else {
127                 r = p;
128         }
129
david
1.9
130         /* XXX more than six FP args can and should be passed in registers. */
david
1.10
131         if (*regp > 5 && r->n_op != STARG) {
david
1.8
132                 /* We are storing the stack offset in n_rval. */
ragge
1.14
133                 r = block(FUNARGrNILr->n_typer->n_dfr->n_ap);
david
1.8
134                 /* Make sure we are appropriately aligned. */
135                 *stacksize = ALIGN(*stacksize, (tlen(r) - 1));
136                 r->n_rval = *stacksize;
david
1.7
137                 *stacksize += tlen(r);
138         } else if (r->n_op == STARG)
david
1.2
139                 cerror("op STARG in moveargs");
140         else {
ragge
1.14
141                 q = block(REGNILNILr->n_typer->n_dfr->n_ap);
david
1.9
142
143                 /*
144                  * The first six non-FP arguments go in the registers O0 - O5.
145                  * Float arguments are stored in %fp1, %fp3, ..., %fp29, %fp31.
146                  * Double arguments are stored in %fp0, %fp2, ..., %fp28, %fp30.
147                  * A non-fp argument still increments register, eg.
148                  *     test(int a, int b, float b)
149                  * takes %o0, %o1, %fp5.
150                  */
151                 if (q->n_type == FLOAT)
david
1.10
152                         q->n_rval = F0 + (*regp++ * 2) + 1;
david
1.9
153                 else if (q->n_type == DOUBLE)
david
1.10
154                         q->n_rval = D0 + *regp++;
david
1.9
155                 else if (q->n_type == LDOUBLE)
156                         cerror("long double support incomplete");
157                 else
david
1.10
158                         q->n_rval = O0 + (*regp)++;
david
1.9
159
david
1.2
160                 r = buildtree(ASSIGNqr);
161         }
162
163         if (p->n_op == CM) {
164                 p->n_right = r;
165                 return p;
166         }
167
168         return r;
169 }
170
david
1.1
171 NODE *
172 funcode(NODE *p)
173 {
david
1.7
174         NODE *r, *l;
david
1.10
175         int reg = 0stacksize = 0;
david
1.7
176
177         r = l = 0;
178
179         p->n_right = moveargs(p->n_right, &reg, &stacksize);
180
181         /*
182          * This is a particularly gross and inefficient way to handle
183          * argument overflows. First, we calculate how much stack space
184          * we need in moveargs(). Then we assign it by moving %sp, make
185          * the function call, and then move %sp back.
186          *
187          * What we should be doing is getting the maximum of all the needed
188          * stacksize values to the prologue and doing it all in the "save"
189          * instruction.
190          */
191         if (stacksize != 0) {
192                 stacksize = V9STEP(stacksize); /* 16-bit alignment. */
193
ragge
1.15
194                 r = block(REGNILNILINT00);
david
1.7
195                 r->n_lval = 0;
196                 r->n_rval = SP;
ragge
1.15
197                 r = block(MINUSrbcon(stacksize), INT00);
david
1.7
198
ragge
1.15
199                 l = block(REGNILNILINT00);
david
1.7
200                 l->n_lval = 0;
201                 l->n_rval = SP;
202                 r = buildtree(ASSIGNlr);
203
204                 p = buildtree(COMOPrp);
205
ragge
1.15
206                 r = block(REGNILNILINT00);
david
1.7
207                 r->n_lval = 0;
208                 r->n_rval = SP;
ragge
1.15
209                 r = block(PLUSrbcon(stacksize), INT00);
david
1.7
210
ragge
1.15
211                 l = block(REGNILNILINT00);
david
1.7
212                 l->n_lval = 0;
213                 l->n_rval = SP;
214                 r = buildtree(ASSIGNlr);
215
216                 p = buildtree(COMOPpr);
217
218         }
david
1.1
219         return p;
220 }
221
222 void
223 fldty(struct symtab *p)
224 {
225 }
226
227 int
228 mygenswitch(int numTWORD typestruct swents **pint n)
229 {
230         return 0;
231 }
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 11:37 +0100