Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "gc.h"
2
 
3
void
4
noretval(int n)
5
{
6
 
7
	if(n & 1) {
8
		gins(ANOP, Z, Z);
9
		p->to.type = D_REG;
10
		p->to.reg = REGRET;
11
	}
12
	if(n & 2) {
13
		gins(ANOP, Z, Z);
14
		p->to.type = D_FREG;
15
		p->to.reg = FREGRET;
16
	}
17
}
18
 
19
/*
20
 *	calculate addressability as follows
21
 *		CONST ==> 20		$value
22
 *		NAME ==> 10		name
23
 *		REGISTER ==> 11		register
24
 *		INDREG ==> 12		*[(reg)+offset]
25
 *		&10 ==> 2		$name
26
 *		ADD(2, 20) ==> 2	$name+offset
27
 *		ADD(3, 20) ==> 3	$(reg)+offset
28
 *		&12 ==> 3		$(reg)+offset
29
 *		*11 ==> 11		??
30
 *		*2 ==> 10		name
31
 *		*3 ==> 12		*(reg)+offset
32
 *	calculate complexity (number of registers)
33
 */
34
void
35
xcom(Node *n)
36
{
37
	Node *l, *r;
38
	int v;
39
 
40
	if(n == Z)
41
		return;
42
	l = n->left;
43
	r = n->right;
44
	n->addable = 0;
45
	n->complex = 0;
46
	switch(n->op) {
47
	case OCONST:
48
		n->addable = 20;
49
		return;
50
 
51
	case OREGISTER:
52
		n->addable = 11;
53
		return;
54
 
55
	case OINDREG:
56
		n->addable = 12;
57
		return;
58
 
59
	case ONAME:
60
		n->addable = 10;
61
		return;
62
 
63
	case OADDR:
64
		xcom(l);
65
		if(l->addable == 10)
66
			n->addable = 2;
67
		if(l->addable == 12)
68
			n->addable = 3;
69
		break;
70
 
71
	case OIND:
72
		xcom(l);
73
		if(l->addable == 11)
74
			n->addable = 12;
75
		if(l->addable == 3)
76
			n->addable = 12;
77
		if(l->addable == 2)
78
			n->addable = 10;
79
		break;
80
 
81
	case OADD:
82
		xcom(l);
83
		xcom(r);
84
		if(l->addable == 20) {
85
			if(r->addable == 2)
86
				n->addable = 2;
87
			if(r->addable == 3)
88
				n->addable = 3;
89
		}
90
		if(r->addable == 20) {
91
			if(l->addable == 2)
92
				n->addable = 2;
93
			if(l->addable == 3)
94
				n->addable = 3;
95
		}
96
		break;
97
 
98
	case OASMUL:
99
	case OASLMUL:
100
		xcom(l);
101
		xcom(r);
102
		v = vlog(r);
103
		if(v >= 0) {
104
			n->op = OASASHL;
105
			r->vconst = v;
106
			r->type = types[TINT];
107
		}
108
		break;
109
 
110
	case OMUL:
111
	case OLMUL:
112
		xcom(l);
113
		xcom(r);
114
		v = vlog(r);
115
		if(v >= 0) {
116
			n->op = OASHL;
117
			r->vconst = v;
118
			r->type = types[TINT];
119
		}
120
		v = vlog(l);
121
		if(v >= 0) {
122
			n->op = OASHL;
123
			n->left = r;
124
			n->right = l;
125
			r = l;
126
			l = n->left;
127
			r->vconst = v;
128
			r->type = types[TINT];
129
		}
130
		break;
131
 
132
	case OASLDIV:
133
		xcom(l);
134
		xcom(r);
135
		v = vlog(r);
136
		if(v >= 0) {
137
			n->op = OASLSHR;
138
			r->vconst = v;
139
			r->type = types[TINT];
140
		}
141
		break;
142
 
143
	case OLDIV:
144
		xcom(l);
145
		xcom(r);
146
		v = vlog(r);
147
		if(v >= 0) {
148
			n->op = OLSHR;
149
			r->vconst = v;
150
			r->type = types[TINT];
151
		}
152
		break;
153
 
154
	case OASLMOD:
155
		xcom(l);
156
		xcom(r);
157
		v = vlog(r);
158
		if(v >= 0) {
159
			n->op = OASAND;
160
			r->vconst--;
161
		}
162
		break;
163
 
164
	case OLMOD:
165
		xcom(l);
166
		xcom(r);
167
		v = vlog(r);
168
		if(v >= 0) {
169
			n->op = OAND;
170
			r->vconst--;
171
		}
172
		break;
173
 
174
	default:
175
		if(l != Z)
176
			xcom(l);
177
		if(r != Z)
178
			xcom(r);
179
		break;
180
	}
181
	if(n->addable >= 10)
182
		return;
183
	if(l != Z)
184
		n->complex = l->complex;
185
	if(r != Z) {
186
		if(r->complex == n->complex)
187
			n->complex = r->complex+1;
188
		else
189
		if(r->complex > n->complex)
190
			n->complex = r->complex;
191
	}
192
	if(n->complex == 0)
193
		n->complex++;
194
 
195
	if(com64(n))
196
		return;
197
 
198
	switch(n->op) {
199
 
200
	case OFUNC:
201
		n->complex = FNX;
202
		break;
203
 
204
	case OEQ:
205
	case ONE:
206
	case OLE:
207
	case OLT:
208
	case OGE:
209
	case OGT:
210
	case OHI:
211
	case OHS:
212
	case OLO:
213
	case OLS:
214
		/*
215
		 * immediate operators, make const on right
216
		 */
217
		if(l->op == OCONST) {
218
			n->left = r;
219
			n->right = l;
220
			n->op = invrel[relindex(n->op)];
221
		}
222
		break;
223
 
224
	case OADD:
225
	case OXOR:
226
	case OAND:
227
	case OOR:
228
		/*
229
		 * immediate operators, make const on right
230
		 */
231
		if(l->op == OCONST) {
232
			n->left = r;
233
			n->right = l;
234
		}
235
		break;
236
	}
237
}
238