Subversion Repositories planix.SVN

Rev

Details | 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 t;
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 OASLMUL:
99
	case OASMUL:
100
		xcom(l);
101
		xcom(r);
102
		t = vlog(r);
103
		if(t >= 0) {
104
			n->op = OASASHL;
105
			r->vconst = t;
106
			r->type = types[TINT];
107
		}
108
		break;
109
 
110
	case OMUL:
111
	case OLMUL:
112
		xcom(l);
113
		xcom(r);
114
		t = vlog(l);
115
		if(t >= 0) {
116
			n->left = r;
117
			n->right = l;
118
			l = r;
119
			r = n->right;
120
		}
121
		t = vlog(r);
122
		if(t >= 0) {
123
			n->op = OASHL;
124
			r->vconst = t;
125
			r->type = types[TINT];
126
			simplifyshift(n);
127
		}
128
		break;
129
 
130
	case OASLDIV:
131
		xcom(l);
132
		xcom(r);
133
		t = vlog(r);
134
		if(t >= 0) {
135
			n->op = OASLSHR;
136
			r->vconst = t;
137
			r->type = types[TINT];
138
		}
139
		break;
140
 
141
	case OLDIV:
142
		xcom(l);
143
		xcom(r);
144
		t = vlog(r);
145
		if(t >= 0) {
146
			n->op = OLSHR;
147
			r->vconst = t;
148
			r->type = types[TINT];
149
			simplifyshift(n);
150
		}
151
		break;
152
 
153
	case OASLMOD:
154
		xcom(l);
155
		xcom(r);
156
		t = vlog(r);
157
		if(t >= 0) {
158
			n->op = OASAND;
159
			r->vconst--;
160
		}
161
		break;
162
 
163
	case OLMOD:
164
		xcom(l);
165
		xcom(r);
166
		t = vlog(r);
167
		if(t >= 0) {
168
			n->op = OAND;
169
			r->vconst--;
170
		}
171
		break;
172
 
173
	case OLSHR:
174
	case OASHL:
175
	case OASHR:
176
		xcom(l);
177
		xcom(r);
178
		simplifyshift(n);
179
		break;
180
 
181
	default:
182
		if(l != Z)
183
			xcom(l);
184
		if(r != Z)
185
			xcom(r);
186
		break;
187
	}
188
	if(n->addable >= 10)
189
		return;
190
 
191
	if(l != Z)
192
		n->complex = l->complex;
193
	if(r != Z) {
194
		if(r->complex == n->complex)
195
			n->complex = r->complex+1;
196
		else
197
		if(r->complex > n->complex)
198
			n->complex = r->complex;
199
	}
200
	if(n->complex == 0)
201
		n->complex++;
202
 
203
	if(com64(n))
204
		return;
205
 
206
	switch(n->op) {
207
	case OFUNC:
208
		n->complex = FNX;
209
		break;
210
 
211
	case OADD:
212
	case OXOR:
213
	case OAND:
214
	case OOR:
215
	case OEQ:
216
	case ONE:
217
		/*
218
		 * immediate operators, make const on right
219
		 */
220
		if(l->op == OCONST) {
221
			n->left = r;
222
			n->right = l;
223
		}
224
		break;
225
	}
226
}
227