source: mainline/uspace/app/pcc/arch/i386/order.c@ 9d58539

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9d58539 was 9d58539, checked in by Prutkov Alex <prutkov.alex@…>, 13 years ago

Fixed unix permissions for all files

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/* $Id: order.c,v 1.59 2011/01/29 09:55:29 ragge Exp $ */
2/*
3 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29
30# include "pass2.h"
31
32#include <string.h>
33
34int canaddr(NODE *);
35
36/* is it legal to make an OREG or NAME entry which has an
37 * offset of off, (from a register of r), if the
38 * resulting thing had type t */
39int
40notoff(TWORD t, int r, CONSZ off, char *cp)
41{
42 return(0); /* YES */
43}
44
45/*
46 * Turn a UMUL-referenced node into OREG.
47 * Be careful about register classes, this is a place where classes change.
48 */
49void
50offstar(NODE *p, int shape)
51{
52 NODE *r;
53
54 if (x2debug)
55 printf("offstar(%p)\n", p);
56
57 if (isreg(p))
58 return; /* Is already OREG */
59
60 r = p->n_right;
61 if( p->n_op == PLUS || p->n_op == MINUS ){
62 if( r->n_op == ICON ){
63 if (isreg(p->n_left) == 0)
64 (void)geninsn(p->n_left, INAREG);
65 /* Converted in ormake() */
66 return;
67 }
68 if (r->n_op == LS && r->n_right->n_op == ICON &&
69 r->n_right->n_lval == 2 && p->n_op == PLUS) {
70 if (isreg(p->n_left) == 0)
71 (void)geninsn(p->n_left, INAREG);
72 if (isreg(r->n_left) == 0)
73 (void)geninsn(r->n_left, INAREG);
74 return;
75 }
76 }
77 (void)geninsn(p, INAREG);
78}
79
80/*
81 * Do the actual conversion of offstar-found OREGs into real OREGs.
82 */
83void
84myormake(NODE *q)
85{
86 NODE *p, *r;
87
88 if (x2debug)
89 printf("myormake(%p)\n", q);
90
91 p = q->n_left;
92 if (p->n_op == PLUS && (r = p->n_right)->n_op == LS &&
93 r->n_right->n_op == ICON && r->n_right->n_lval == 2 &&
94 p->n_left->n_op == REG && r->n_left->n_op == REG) {
95 q->n_op = OREG;
96 q->n_lval = 0;
97 q->n_rval = R2PACK(p->n_left->n_rval, r->n_left->n_rval, 0);
98 tfree(p);
99 }
100}
101
102/*
103 * Shape matches for UMUL. Cooperates with offstar().
104 */
105int
106shumul(NODE *p, int shape)
107{
108
109 if (x2debug)
110 printf("shumul(%p)\n", p);
111
112 /* Turns currently anything into OREG on x86 */
113 if (shape & SOREG)
114 return SROREG;
115 return SRNOPE;
116}
117
118/*
119 * Rewrite operations on binary operators (like +, -, etc...).
120 * Called as a result of table lookup.
121 */
122int
123setbin(NODE *p)
124{
125
126 if (x2debug)
127 printf("setbin(%p)\n", p);
128 return 0;
129
130}
131
132/* setup for assignment operator */
133int
134setasg(NODE *p, int cookie)
135{
136 if (x2debug)
137 printf("setasg(%p)\n", p);
138 return(0);
139}
140
141/* setup for unary operator */
142int
143setuni(NODE *p, int cookie)
144{
145 return 0;
146}
147
148/*
149 * Special handling of some instruction register allocation.
150 */
151struct rspecial *
152nspecial(struct optab *q)
153{
154 switch (q->op) {
155 case OPLOG:
156 {
157 static struct rspecial s[] = { { NEVER, EAX }, { 0 } };
158 return s;
159 }
160
161 case STASG:
162 {
163 static struct rspecial s[] = {
164 { NEVER, EDI },
165 { NRIGHT, ESI }, { NOLEFT, ESI },
166 { NOLEFT, ECX }, { NORIGHT, ECX },
167 { NEVER, ECX }, { 0 } };
168 return s;
169 }
170
171 case STARG:
172 {
173 static struct rspecial s[] = {
174 { NEVER, EAX }, { NEVER, EDX },
175 { NEVER, ECX }, { 0 } };
176 return s;
177 }
178
179 case SCONV:
180 if ((q->ltype & (TINT|TUNSIGNED|TSHORT|TUSHORT)) &&
181 q->rtype == (TCHAR|TUCHAR)) {
182 static struct rspecial s[] = {
183 { NOLEFT, ESI }, { NOLEFT, EDI }, { 0 } };
184 return s;
185 } else if ((q->ltype & TINT) &&
186 q->rtype == (TLONGLONG|TULONGLONG)) {
187 static struct rspecial s[] = {
188 { NLEFT, EAX }, { NRES, EAXEDX },
189 { NEVER, EAX }, { NEVER, EDX }, { 0 } };
190 return s;
191 } else if (q->ltype == TSHORT &&
192 q->rtype == (TLONGLONG|TULONGLONG)) {
193 static struct rspecial s[] = {
194 { NRES, EAXEDX },
195 { NEVER, EAX }, { NEVER, EDX }, { 0 } };
196 return s;
197 } else if (q->ltype == TCHAR &&
198 q->rtype == (TLONGLONG|TULONGLONG)) {
199 static struct rspecial s[] = {
200 { NRES, EAXEDX },
201 { NEVER, EAX }, { NEVER, EDX }, { 0 } };
202 return s;
203 }
204 break;
205 case DIV:
206 if (q->lshape == SBREG) {
207 static struct rspecial s[] = {
208 { NEVER, AL }, { NEVER, AH },
209 { NLEFT, AL }, { NRES, AL },
210 { NORIGHT, AH }, { NORIGHT, AL }, { 0 } };
211 return s;
212 } else if (q->lshape == SAREG) {
213 static struct rspecial s[] = {
214 { NEVER, EAX }, { NEVER, EDX },
215 { NLEFT, EAX }, { NRES, EAX },
216 { NORIGHT, EDX }, { NORIGHT, EAX }, { 0 } };
217 return s;
218 } else if (q->lshape & SCREG) {
219 static struct rspecial s[] = {
220 { NEVER, EAX }, { NEVER, EDX },
221 { NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
222 return s;
223 }
224 break;
225 case MOD:
226 if (q->lshape == SBREG) {
227 static struct rspecial s[] = {
228 { NEVER, AL }, { NEVER, AH },
229 { NLEFT, AL }, { NRES, AH },
230 { NORIGHT, AH }, { NORIGHT, AL }, { 0 } };
231 return s;
232 } else if (q->lshape == SAREG) {
233 static struct rspecial s[] = {
234 { NEVER, EAX }, { NEVER, EDX },
235 { NLEFT, EAX }, { NRES, EDX },
236 { NORIGHT, EDX }, { NORIGHT, EAX }, { 0 } };
237 return s;
238 } else if (q->lshape & SCREG) {
239 static struct rspecial s[] = {
240 { NEVER, EAX }, { NEVER, EDX },
241 { NEVER, ECX }, { NRES, EAXEDX }, { 0 } };
242 return s;
243 }
244 break;
245 case MUL:
246 if (q->lshape == SBREG) {
247 static struct rspecial s[] = {
248 { NEVER, AL }, { NEVER, AH },
249 { NLEFT, AL }, { NRES, AL }, { 0 } };
250 return s;
251 } else if (q->lshape & SCREG) {
252 static struct rspecial s[] = {
253 { NLEFT, EAXEDX }, { NRIGHT, ECXESI },
254 { NEVER, ESI }, { NRES, EAXEDX }, { 0 } };
255 return s;
256 }
257 break;
258 case LS:
259 case RS:
260 if (q->visit & (INAREG|INBREG)) {
261 static struct rspecial s[] = {
262 { NRIGHT, CL }, { NOLEFT, ECX }, { 0 } };
263 return s;
264 } else if (q->visit & INCREG) {
265 static struct rspecial s[] = {
266 { NLEFT, EAXEDX }, { NRIGHT, CL },
267 { NRES, EAXEDX }, { 0 } };
268 return s;
269 }
270 break;
271
272 default:
273 break;
274 }
275 comperr("nspecial entry %d", q - table);
276 return 0; /* XXX gcc */
277}
278
279/*
280 * Set evaluation order of a binary node if it differs from default.
281 */
282int
283setorder(NODE *p)
284{
285 return 0; /* nothing differs on x86 */
286}
287
288/*
289 * set registers in calling conventions live.
290 */
291int *
292livecall(NODE *p)
293{
294 static int r[] = { EAX, EBX, -1 };
295 int off = 1;
296
297#ifdef TLS
298 if (p->n_left->n_op == ICON &&
299 strcmp(p->n_left->n_name, "___tls_get_addr@PLT") == 0)
300 off--;
301#endif
302
303 return kflag ? &r[off] : &r[2];
304}
305
306/*
307 * Signal whether the instruction is acceptable for this target.
308 */
309int
310acceptable(struct optab *op)
311{
312 return 1;
313}
Note: See TracBrowser for help on using the repository browser.