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(r);
115
		if(t >= 0) {
116
			n->op = OASHL;
117
			r->vconst = t;
118
			r->type = types[TINT];
119
		}
120
		t = vlog(l);
121
		if(t >= 0) {
122
			n->op = OASHL;
123
			n->left = r;
124
			n->right = l;
125
			r = l;
126
			l = n->left;
127
			r->vconst = t;
128
			r->type = types[TINT];
129
		}
130
		break;
131
 
132
	case OASLDIV:
133
		xcom(l);
134
		xcom(r);
135
		t = vlog(r);
136
		if(t >= 0) {
137
			n->op = OASLSHR;
138
			r->vconst = t;
139
			r->type = types[TINT];
140
		}
141
		break;
142
 
143
	case OLDIV:
144
		xcom(l);
145
		xcom(r);
146
		t = vlog(r);
147
		if(t >= 0) {
148
			n->op = OLSHR;
149
			r->vconst = t;
150
			r->type = types[TINT];
151
		}
152
		break;
153
 
154
	case OASLMOD:
155
		xcom(l);
156
		xcom(r);
157
		t = vlog(r);
158
		if(t >= 0) {
159
			n->op = OASAND;
160
			r->vconst--;
161
		}
162
		break;
163
 
164
	case OLMOD:
165
		xcom(l);
166
		xcom(r);
167
		t = vlog(r);
168
		if(t >= 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
 
184
	if(l != Z)
185
		n->complex = l->complex;
186
	if(r != Z) {
187
		if(r->complex == n->complex)
188
			n->complex = r->complex+1;
189
		else
190
		if(r->complex > n->complex)
191
			n->complex = r->complex;
192
	}
193
	if(n->complex == 0)
194
		n->complex++;
195
 
196
	if(com64(n))
197
		return;
198
 
199
	switch(n->op) {
200
	case OFUNC:
201
		n->complex = FNX;
202
		break;
203
 
204
	case OADD:
205
	case OXOR:
206
	case OAND:
207
	case OOR:
208
	case OEQ:
209
	case ONE:
210
		/*
211
		 * immediate operators, make const on right
212
		 */
213
		if(l->op == OCONST) {
214
			n->left = r;
215
			n->right = l;
216
		}
217
		break;
218
	}
219
}