2 * Copyright (c) 2008 David Crawshaw <david@zentus.com>
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.
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.
33 printf("clocal in: %p, %s\n", p
, copst(op
));
41 if (sp
->sclass
== PARAM
|| sp
->sclass
== AUTO
) {
43 * Use a fake structure reference to
44 * write out frame pointer offsets.
46 l
= block(REG
, NIL
, NIL
, PTR
+STRTY
, 0, 0);
50 p
= stref(block(STREF
, l
, r
, 0, 0, 0));
53 case PCONV
: /* Remove what PCONVs we can. */
57 if (l
->n_op
== ICON
|| (ISPTR(p
->n_type
) && ISPTR(l
->n_type
))) {
58 l
->n_type
= p
->n_type
;
59 l
->n_qual
= p
->n_qual
;
68 /* Remove redundant conversions. */
69 if ((p
->n_type
& TMASK
) == 0 && (l
->n_type
& TMASK
) == 0 &&
70 btattr
[p
->n_type
].atypsz
== btattr
[l
->n_type
].atypsz
&&
71 p
->n_type
!= FLOAT
&& p
->n_type
!= DOUBLE
&&
72 l
->n_type
!= FLOAT
&& l
->n_type
!= DOUBLE
&&
73 l
->n_type
!= DOUBLE
&& p
->n_type
!= LDOUBLE
) {
74 if (l
->n_op
== NAME
|| l
->n_op
== UMUL
||
76 l
->n_type
= p
->n_type
;
83 /* Convert floating point to int before to char or short. */
84 if ((l
->n_type
== FLOAT
|| l
->n_type
== DOUBLE
|| l
->n_type
== LDOUBLE
)
85 && (DEUNSIGN(p
->n_type
) == CHAR
|| DEUNSIGN(p
->n_type
) == SHORT
)) {
86 p
= block(SCONV
, p
, NIL
, p
->n_type
, p
->n_df
, p
->n_ap
);
87 p
->n_left
->n_type
= INT
;
91 /* Transform constants now. */
95 if (ISPTR(p
->n_type
)) {
96 l
->n_type
= p
->n_type
;
103 case BOOL
: l
->n_lval
= (l
->n_lval
!= 0); break;
104 case CHAR
: l
->n_lval
= (char)l
->n_lval
; break;
105 case UCHAR
: l
->n_lval
= l
->n_lval
& 0377; break;
106 case SHORT
: l
->n_lval
= (short)l
->n_lval
; break;
107 case USHORT
: l
->n_lval
= l
->n_lval
& 0177777; break;
108 case UNSIGNED
: l
->n_lval
= l
->n_lval
& 0xffffffff; break;
109 case INT
: l
->n_lval
= (int)l
->n_lval
; break;
111 case ULONGLONG
: l
->n_lval
= l
->n_lval
; break;
113 case LONGLONG
: l
->n_lval
= (long long)l
->n_lval
; break;
118 l
->n_dcon
= l
->n_lval
;
123 cerror("sconv type unknown %d", p
->n_type
);
126 l
->n_type
= p
->n_type
;
134 cerror("converting bad type");
136 p
= buildtree(op
== PMCONV
? MUL
: DIV
, l
, r
);
140 /* Put attached value into the return register. */
142 p
->n_right
= p
->n_left
;
143 p
->n_left
= block(REG
, NIL
, NIL
, p
->n_type
, 0, MKAP(INT
));
144 p
->n_left
->n_rval
= RETREG_PRE(p
->n_type
);
150 printf("clocal out: %p, %s\n", p
, copst(op
));
166 sp
= tmpalloc(sizeof(struct symtab
));
169 sp
->soffset
= getlab();
171 sp
->stype
= p
->n_type
;
172 sp
->squal
= (CON
>> TSHIFT
);
175 ninval(0, btattr
[p
->n_type
].atypsz
, p
);
197 /* SPARCv9 registers are all 64-bits wide. */
202 offcon(OFFSZ off
, TWORD t
, union dimfun
*d
, struct attr
*ap
)
204 return bcon(off
/ SZCHAR
);
208 spalloc(NODE
*t
, NODE
*p
, OFFSZ off
)
213 instring(struct symtab
*sp
)
220 printf("\t.ascii \"");
221 for (s
= str
; *s
!= 0; ) {
225 fwrite(str
, 1, s
- str
, stdout
);
226 printf("\"\n\t.ascii \"");
230 fwrite(str
, 1, s
- str
, stdout
);
235 zbits(OFFSZ off
, int fsz
)
240 infld(CONSZ off
, int fsz
, CONSZ val
)
245 ninval(CONSZ off
, int fsz
, NODE
*p
)
249 union { float f
; double d
; int i
; long long l
; } u
;
257 if (p
->n_op
!= ICON
&& p
->n_op
!= FCON
)
258 cerror("ninval: not a constant");
259 if (p
->n_op
== ICON
&& sp
!= NULL
&& DEUNSIGN(t
) != LONGLONG
)
260 cerror("ninval: not constant");
265 printf("\t.byte %d\n", (int)p
->n_lval
& 0xff);
269 printf("\t.half %d\n", (int)p
->n_lval
&0xffff);
272 p
->n_lval
= (p
->n_lval
!= 0); /* FALLTHROUGH */
275 printf("\t.long " CONFMT
"\n", p
->n_lval
);
281 printf("\t.xword %lld", p
->n_lval
);
283 if (sp
->sclass
== STATIC
&& sp
->slevel
> 0)
284 printf("+" LABFMT
, sp
->soffset
);
286 printf("+%s", sp
->soname
?
287 sp
->soname
: exname(sp
->sname
));
292 u
.f
= (float)p
->n_dcon
;
293 printf("\t.long %d\n", u
.i
);
296 u
.d
= (double)p
->n_dcon
;
297 printf("\t.xword %lld\n", u
.l
);
315 calldec(NODE
*p
, NODE
*q
)
320 extdec(struct symtab
*q
)
325 defzero(struct symtab
*sp
)
327 int off
= (tsize(sp
->stype
, sp
->sdf
, sp
->sap
) + SZCHAR
- 1) / SZCHAR
;
330 printf("%s,%d\n", sp
->soname
? sp
->soname
: exname(sp
->sname
), off
);
332 printf(LABFMT
",%d\n", sp
->soffset
, off
);
342 fixdef(struct symtab
*sp
)
347 pass1_lastchance(struct interpass
*ip
)