source: mainline/uspace/app/pcc/arch/vax/local.c@ a837544

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a837544 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: 11.6 KB
Line 
1/* $Id: local.c,v 1.10 2011/01/21 21:47:59 ragge Exp $ */
2/*
3 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * Redistributions of source code and documentation must retain the above
10 * copyright notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditionsand the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed or owned by Caldera
17 * International, Inc.
18 * Neither the name of Caldera International, Inc. nor the names of other
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
21 *
22 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
23 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
27 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36# include "pass1.h"
37
38/* this file contains code which is dependent on the target machine */
39
40#if 0
41NODE *
42cast( p, t ) register NODE *p; TWORD t; {
43 /* cast node p to type t */
44
45 p = buildtree( CAST, block( NAME, NIL, NIL, t, 0, (int)t ), p );
46 p->left->op = FREE;
47 p->op = FREE;
48 return( p->right );
49 }
50#endif
51
52NODE *
53clocal(p) NODE *p; {
54
55 /* this is called to do local transformations on
56 an expression tree preparitory to its being
57 written out in intermediate code.
58 */
59
60 /* the major essential job is rewriting the
61 automatic variables and arguments in terms of
62 REG and OREG nodes */
63 /* conversion ops which are not necessary are also clobbered here */
64 /* in addition, any special features (such as rewriting
65 exclusive or) are easily handled here as well */
66
67 register struct symtab *q;
68 register NODE *r;
69 register int o;
70 register int m, ml;
71
72 switch( o = p->n_op ){
73
74 case NAME:
75 if((q = p->n_sp) == 0 ) { /* already processed; ignore... */
76 return(p);
77 }
78 switch( q->sclass ){
79
80 case AUTO:
81 case PARAM:
82 /* fake up a structure reference */
83 r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 );
84 r->n_lval = 0;
85 r->n_rval = (q->sclass==AUTO?STKREG:ARGREG);
86 p = stref( block( STREF, r, p, 0, 0, 0 ) );
87 break;
88
89 case STATIC:
90 if( q->slevel == 0 ) break;
91 p->n_lval = 0;
92 p->n_rval = -q->soffset;
93 break;
94
95 case REGISTER:
96 p->n_op = REG;
97 p->n_lval = 0;
98 p->n_rval = q->soffset;
99 break;
100
101 }
102 break;
103
104 case PCONV:
105 /* do pointer conversions for char and longs */
106 ml = p->n_left->n_type;
107 if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->n_left->n_op != ICON ) break;
108
109 /* pointers all have the same representation; the type is inherited */
110
111 inherit:
112 p->n_left->n_type = p->n_type;
113 p->n_left->n_df = p->n_df;
114 p->n_left->n_sue = p->n_sue;
115 r = p->n_left;
116 nfree(p);
117 return( r );
118
119 case SCONV:
120 m = (p->n_type == FLOAT || p->n_type == DOUBLE );
121 ml = (p->n_left->n_type == FLOAT || p->n_left->n_type == DOUBLE );
122 if( m != ml ) break;
123
124 /* now, look for conversions downwards */
125
126 m = p->n_type;
127 ml = p->n_left->n_type;
128 if( p->n_left->n_op == ICON ){ /* simulate the conversion here */
129 CONSZ val;
130 val = p->n_left->n_lval;
131 switch( m ){
132 case CHAR:
133 p->n_left->n_lval = (char) val;
134 break;
135 case UCHAR:
136 p->n_left->n_lval = val & 0XFF;
137 break;
138 case USHORT:
139 p->n_left->n_lval = val & 0XFFFFL;
140 break;
141 case SHORT:
142 p->n_left->n_lval = (short)val;
143 break;
144 case UNSIGNED:
145 p->n_left->n_lval = val & 0xFFFFFFFFL;
146 break;
147 case INT:
148 p->n_left->n_lval = (int)val;
149 break;
150 }
151 p->n_left->n_type = m;
152 }
153 else {
154 /* meaningful ones are conversion of int to char, int to short,
155 and short to char, and unsigned version of them */
156 if( m==CHAR || m==UCHAR ){
157 if( ml!=CHAR && ml!= UCHAR ) break;
158 }
159 else if( m==SHORT || m==USHORT ){
160 if( ml!=CHAR && ml!=UCHAR && ml!=SHORT && ml!=USHORT ) break;
161 }
162 }
163
164 /* clobber conversion */
165 if( tlen(p) == tlen(p->n_left) ) goto inherit;
166 r = p->n_left;
167 nfree(p);
168 return( r ); /* conversion gets clobbered */
169
170 case PVCONV:
171 case PMCONV:
172 if( p->n_right->n_op != ICON ) cerror( "bad conversion", 0);
173 r = buildtree( o==PMCONV?MUL:DIV, p->n_left, p->n_right);
174 nfree(p);
175 return r;
176
177 case RS:
178 case RSEQ:
179 /* convert >> to << with negative shift count */
180 /* only if type of left operand is not unsigned */
181 if( ISUNSIGNED(p->n_left->n_type) ) break;
182 p->n_right = buildtree( UMINUS, p->n_right, NIL );
183 if( p->n_op == RS ) p->n_op = LS;
184 else p->n_op = LSEQ;
185 break;
186
187 case FORCE:
188 p->n_op = ASSIGN;
189 p->n_right = p->n_left;
190 p->n_left = block(REG, NIL, NIL, p->n_type, 0, MKSUE(INT));
191 p->n_left->n_rval = p->n_left->n_type == BOOL ?
192 RETREG(CHAR) : RETREG(p->n_type);
193 break;
194
195 case STCALL:
196 case CALL:
197 /* Fix function call arguments. On vax, just add funarg */
198 for (r = p->n_right; r->n_op == CM; r = r->n_left) {
199 if (r->n_right->n_op != STARG &&
200 r->n_right->n_op != FUNARG)
201 r->n_right = block(FUNARG, r->n_right, NIL,
202 r->n_right->n_type, r->n_right->n_df,
203 r->n_right->n_sue);
204 }
205 if (r->n_op != STARG && r->n_op != FUNARG) {
206 NODE *l = talloc();
207 *l = *r;
208 r->n_op = FUNARG; r->n_left = l; r->n_type = l->n_type;
209 }
210 break;
211 }
212
213 return(p);
214}
215
216void
217myp2tree(NODE *p)
218{
219 struct symtab *sp;
220 int o = p->n_op, i;
221
222 if (o != FCON)
223 return;
224
225 sp = inlalloc(sizeof(struct symtab));
226 sp->sclass = STATIC;
227 sp->ssue = MKSUE(p->n_type);
228 sp->slevel = 1; /* fake numeric label */
229 sp->soffset = getlab();
230 sp->sflags = 0;
231 sp->stype = p->n_type;
232 sp->squal = (CON >> TSHIFT);
233
234 defloc(sp);
235 ninval(0, sp->ssue->suesize, p);
236
237 p->n_op = NAME;
238 p->n_lval = 0;
239 p->n_sp = sp;
240
241}
242
243/*
244 * Can we take & of a NAME?
245 */
246int
247andable(NODE *p)
248{
249
250 if ((p->n_type & ~BTMASK) == FTN)
251 return 1; /* functions are called by name */
252 return 0; /* Delay name reference to table, for PIC code generation */
253}
254
255void
256cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */
257 autooff = AUTOINIT;
258 }
259
260int
261cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */
262 return(1); /* all are now */
263 }
264
265NODE *
266offcon(OFFSZ off, TWORD t, union dimfun *d, struct suedef *sue)
267{
268
269 /* return a node, for structure references, which is suitable for
270 being added to a pointer of type t, in order to be off bits offset
271 into a structure */
272
273 register NODE *p;
274
275 /* t, d, and s are the type, dimension offset, and sizeoffset */
276 /* in general they are necessary for offcon, but not on H'well */
277
278 p = bcon(0);
279 p->n_lval = off/SZCHAR;
280 return(p);
281
282 }
283
284void
285spalloc(NODE *t, NODE *p, OFFSZ off)
286{
287 cerror("spalloc");
288}
289
290static int inbits, inval;
291
292/*
293 * set fsz bits in sequence to zero.
294 */
295void
296zbits(OFFSZ off, int fsz)
297{
298 int m;
299
300 if (idebug)
301 printf("zbits off %lld, fsz %d inbits %d\n", off, fsz, inbits);
302 if ((m = (inbits % SZCHAR))) {
303 m = SZCHAR - m;
304 if (fsz < m) {
305 inbits += fsz;
306 return;
307 } else {
308 fsz -= m;
309 printf("\t.byte %d\n", inval);
310 inval = inbits = 0;
311 }
312 }
313 if (fsz >= SZCHAR) {
314 printf("\t.space %d\n", fsz/SZCHAR);
315 fsz -= (fsz/SZCHAR) * SZCHAR;
316 }
317 if (fsz) {
318 inval = 0;
319 inbits = fsz;
320 }
321}
322
323/*
324 * Initialize a bitfield.
325 */
326void
327infld(CONSZ off, int fsz, CONSZ val)
328{
329 if (idebug)
330 printf("infld off %lld, fsz %d, val %lld inbits %d\n",
331 off, fsz, val, inbits);
332 val &= ((CONSZ)1 << fsz)-1;
333 while (fsz + inbits >= SZCHAR) {
334 inval |= (val << inbits);
335 printf("\t.byte %d\n", inval & 255);
336 fsz -= (SZCHAR - inbits);
337 val >>= (SZCHAR - inbits);
338 inval = inbits = 0;
339 }
340 if (fsz) {
341 inval |= (val << inbits);
342 inbits += fsz;
343 }
344}
345
346
347char *
348exname( p ) char *p; {
349 /* make a name look like an external name in the local machine */
350 /* vad is elf now */
351 if (p == NULL)
352 return "";
353 return( p );
354 }
355
356TWORD
357ctype(TWORD type ){ /* map types which are not defined on the local machine */
358 switch( BTYPE(type) ){
359
360 case LONG:
361 MODTYPE(type,INT);
362 break;
363
364 case ULONG:
365 MODTYPE(type,UNSIGNED);
366 break;
367
368 case LDOUBLE: /* for now */
369 MODTYPE(type,DOUBLE);
370 }
371 return( type );
372 }
373
374void
375calldec(NODE *p, NODE *q)
376{
377}
378
379void
380extdec(struct symtab *q)
381{
382}
383
384void
385commdec( struct symtab *q ){ /* make a common declaration for id, if reasonable */
386 OFFSZ off;
387
388 printf( " .comm %s,", q->soname ? q->soname : exname( q->sname ) );
389 off = tsize( q->stype, q->sdf, q->ssue );
390 printf( CONFMT, off/SZCHAR );
391 printf( "\n" );
392 }
393
394/* make a local common declaration for id, if reasonable */
395void
396lcommdec(struct symtab *q)
397{
398 int off;
399
400 off = tsize(q->stype, q->sdf, q->ssue);
401 off = (off+(SZCHAR-1))/SZCHAR;
402 if (q->slevel == 0)
403 printf(" .lcomm %s,0%o\n", q->soname ? q->soname : exname(q->sname), off);
404 else
405 printf(" .lcomm " LABFMT ",0%o\n", q->soffset, off);
406}
407
408
409static char *loctbl[] = { "text", "data", "section .rodata", "section .rodata" };
410
411void
412setloc1(int locc)
413{
414 if (locc == lastloc)
415 return;
416 lastloc = locc;
417 printf(" .%s\n", loctbl[locc]);
418}
419
420/*
421 * print out a constant node, may be associated with a label.
422 * Do not free the node after use.
423 * off is bit offset from the beginning of the aggregate
424 * fsz is the number of bits this is referring to
425 * XXX - floating point constants may be wrong if cross-compiling.
426 */
427void
428ninval(CONSZ off, int fsz, NODE *p)
429{
430 union { float f; double d; long double l; int i[3]; } u;
431 struct symtab *q;
432 TWORD t;
433
434 t = p->n_type;
435 if (t > BTMASK)
436 t = INT; /* pointer */
437
438 if (p->n_op != ICON && p->n_op != FCON)
439 cerror("ninval: init node not constant");
440
441 if (p->n_op == ICON && p->n_sp != NULL && DEUNSIGN(t) != INT)
442 uerror("element not constant");
443
444 switch (t) {
445 case LONGLONG:
446 case ULONGLONG:
447 printf("\t.long 0x%x", (int)p->n_lval);
448 printf("\t.long 0x%x", (int)(p->n_lval >> 32));
449 break;
450 case INT:
451 case UNSIGNED:
452 printf("\t.long 0x%x", (int)p->n_lval);
453 if ((q = p->n_sp) != NULL) {
454 if ((q->sclass == STATIC && q->slevel > 0)) {
455 printf("+" LABFMT, q->soffset);
456 } else
457 printf("+%s", q->soname ? q->soname : exname(q->sname));
458 }
459 printf("\n");
460 break;
461 case SHORT:
462 case USHORT:
463 printf("\t.short 0x%x\n", (int)p->n_lval & 0xffff);
464 break;
465 case BOOL:
466 if (p->n_lval > 1)
467 p->n_lval = p->n_lval != 0;
468 /* FALLTHROUGH */
469 case CHAR:
470 case UCHAR:
471 printf("\t.byte %d\n", (int)p->n_lval & 0xff);
472 break;
473 case LDOUBLE:
474 u.i[2] = 0;
475 u.l = (long double)p->n_dcon;
476 printf("\t.long\t0x%x,0x%x,0x%x\n", u.i[0], u.i[1], u.i[2]);
477 break;
478 case DOUBLE:
479 u.d = (double)p->n_dcon;
480 printf("\t.long\t0x%x,0x%x\n", u.i[0], u.i[1]);
481 break;
482 case FLOAT:
483 u.f = (float)p->n_dcon;
484 printf("\t.long\t0x%x\n", u.i[0]);
485 break;
486 default:
487 cerror("ninval");
488 }
489
490}
491/*
492 * Give target the opportunity of handling pragmas.
493 */
494int
495mypragma(char *str)
496{
497 return 0;
498}
499
500/*
501 * Called when a identifier has been declared, to give target last word.
502 */
503void
504fixdef(struct symtab *sp)
505{
506}
507
508void
509pass1_lastchance(struct interpass *ip)
510{
511}
Note: See TracBrowser for help on using the repository browser.