source: mainline/uspace/app/pcc/arch/sparc64/code.c@ a7de7182

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a7de7182 was a7de7182, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 14 years ago

Added pcc source tree (contents of pcc-1.0.0.tgz)

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 * Copyright (c) 2008 David Crawshaw <david@zentus.com>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "pass1.h"
18
19void
20defloc(struct symtab *sp)
21{
22 static char *loctbl[] = { "text", "data", "rodata" };
23 static int lastloc = -1;
24 TWORD t;
25 char *n;
26 int s;
27
28 if (sp == NULL)
29 return;
30
31 t = sp->stype;
32 s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA;
33 if (s != lastloc)
34 printf("\n\t.section \".%s\"\n", loctbl[s]);
35 lastloc = s;
36 if (s == PROG)
37 return;
38
39 switch (DEUNSIGN(sp->stype)) {
40 case CHAR: s = 1;
41 case SHORT: s = 2;
42 case INT:
43 case UNSIGNED: s = 4;
44 default: s = 8;
45 }
46 printf("\t.align %d\n", s);
47
48 n = sp->soname ? sp->soname : sp->sname;
49 if (sp->sclass == EXTDEF)
50 printf("\t.global %s\n", n);
51 if (sp->slevel == 0) {
52 printf("\t.type %s,#object\n", n);
53 printf("\t.size %s," CONFMT "\n", n,
54 tsize(sp->stype, sp->sdf, sp->sap) / SZCHAR);
55 printf("%s:\n", n);
56 } else
57 printf(LABFMT ":\n", sp->soffset);
58}
59
60void
61efcode()
62{
63 /* XXX */
64}
65
66void
67bfcode(struct symtab **sp, int cnt)
68{
69 int i, off;
70 NODE *p, *q;
71 struct symtab *sym;
72
73 /* Process the first six arguments. */
74 for (i=0; i < cnt && i < 6; i++) {
75 sym = sp[i];
76 q = block(REG, NIL, NIL, sym->stype, sym->sdf, sym->sap);
77 q->n_rval = RETREG_PRE(sym->stype) + i;
78 p = tempnode(0, sym->stype, sym->sdf, sym->sap);
79 sym->soffset = regno(p);
80 sym->sflags |= STNODE;
81 p = buildtree(ASSIGN, p, q);
82 ecomp(p);
83 }
84
85 /* Process the remaining arguments. */
86 for (off = V9RESERVE; i < cnt; i++) {
87 sym = sp[i];
88 p = tempnode(0, sym->stype, sym->sdf, sym->sap);
89 off = ALIGN(off, (tlen(p) - 1));
90 sym->soffset = off * SZCHAR;
91 off += tlen(p);
92 p = buildtree(ASSIGN, p, nametree(sym));
93 sym->soffset = regno(p->n_left);
94 sym->sflags |= STNODE;
95 ecomp(p);
96 }
97}
98
99void
100bccode()
101{
102 SETOFF(autooff, SZINT);
103}
104
105void
106ejobcode(int flag)
107{
108}
109
110void
111bjobcode()
112{
113}
114
115/*
116 * The first six 64-bit arguments are saved in the registers O0 to O5,
117 * which become I0 to I5 after the "save" instruction moves the register
118 * window. Arguments 7 and up must be saved on the stack to %sp+BIAS+176.
119 *
120 * For a pretty picture, see Figure 3-16 in the SPARC Compliance Def 2.4.
121 */
122static NODE *
123moveargs(NODE *p, int *regp, int *stacksize)
124{
125 NODE *r, *q;
126
127 if (p->n_op == CM) {
128 p->n_left = moveargs(p->n_left, regp, stacksize);
129 r = p->n_right;
130 } else {
131 r = p;
132 }
133
134 /* XXX more than six FP args can and should be passed in registers. */
135 if (*regp > 5 && r->n_op != STARG) {
136 /* We are storing the stack offset in n_rval. */
137 r = block(FUNARG, r, NIL, r->n_type, r->n_df, r->n_ap);
138 /* Make sure we are appropriately aligned. */
139 *stacksize = ALIGN(*stacksize, (tlen(r) - 1));
140 r->n_rval = *stacksize;
141 *stacksize += tlen(r);
142 } else if (r->n_op == STARG)
143 cerror("op STARG in moveargs");
144 else {
145 q = block(REG, NIL, NIL, r->n_type, r->n_df, r->n_ap);
146
147 /*
148 * The first six non-FP arguments go in the registers O0 - O5.
149 * Float arguments are stored in %fp1, %fp3, ..., %fp29, %fp31.
150 * Double arguments are stored in %fp0, %fp2, ..., %fp28, %fp30.
151 * A non-fp argument still increments register, eg.
152 * test(int a, int b, float b)
153 * takes %o0, %o1, %fp5.
154 */
155 if (q->n_type == FLOAT)
156 q->n_rval = F0 + (*regp++ * 2) + 1;
157 else if (q->n_type == DOUBLE)
158 q->n_rval = D0 + *regp++;
159 else if (q->n_type == LDOUBLE)
160 cerror("long double support incomplete");
161 else
162 q->n_rval = O0 + (*regp)++;
163
164 r = buildtree(ASSIGN, q, r);
165 }
166
167 if (p->n_op == CM) {
168 p->n_right = r;
169 return p;
170 }
171
172 return r;
173}
174
175NODE *
176funcode(NODE *p)
177{
178 NODE *r, *l;
179 int reg = 0, stacksize = 0;
180
181 r = l = 0;
182
183 p->n_right = moveargs(p->n_right, &reg, &stacksize);
184
185 /*
186 * This is a particularly gross and inefficient way to handle
187 * argument overflows. First, we calculate how much stack space
188 * we need in moveargs(). Then we assign it by moving %sp, make
189 * the function call, and then move %sp back.
190 *
191 * What we should be doing is getting the maximum of all the needed
192 * stacksize values to the prologue and doing it all in the "save"
193 * instruction.
194 */
195 if (stacksize != 0) {
196 stacksize = V9STEP(stacksize); /* 16-bit alignment. */
197
198 r = block(REG, NIL, NIL, INT, 0, MKAP(INT));
199 r->n_lval = 0;
200 r->n_rval = SP;
201 r = block(MINUS, r, bcon(stacksize), INT, 0, MKAP(INT));
202
203 l = block(REG, NIL, NIL, INT, 0, MKAP(INT));
204 l->n_lval = 0;
205 l->n_rval = SP;
206 r = buildtree(ASSIGN, l, r);
207
208 p = buildtree(COMOP, r, p);
209
210 r = block(REG, NIL, NIL, INT, 0, MKAP(INT));
211 r->n_lval = 0;
212 r->n_rval = SP;
213 r = block(PLUS, r, bcon(stacksize), INT, 0, MKAP(INT));
214
215 l = block(REG, NIL, NIL, INT, 0, MKAP(INT));
216 l->n_lval = 0;
217 l->n_rval = SP;
218 r = buildtree(ASSIGN, l, r);
219
220 p = buildtree(COMOP, p, r);
221
222 }
223 return p;
224}
225
226int
227fldal(unsigned int t)
228{
229 uerror("illegal field type");
230 return ALINT;
231}
232
233void
234fldty(struct symtab *p)
235{
236}
237
238int
239mygenswitch(int num, TWORD type, struct swents **p, int n)
240{
241 return 0;
242}
Note: See TracBrowser for help on using the repository browser.