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 "l.h"
2
 
3
void
4
listinit(void)
5
{
6
 
7
	fmtinstall('A', Aconv);
8
	fmtinstall('C', Cconv);
9
	fmtinstall('D', Dconv);
10
	fmtinstall('P', Pconv);
11
	fmtinstall('S', Sconv);
12
	fmtinstall('N', Nconv);
13
}
14
 
15
void
16
prasm(Prog *p)
17
{
18
	print("%P\n", p);
19
}
20
 
21
int
22
Pconv(Fmt *fp)
23
{
24
	char str[STRINGSZ], *s;
25
	Prog *p;
26
	int a;
27
 
28
	p = va_arg(fp->args, Prog*);
29
	curp = p;
30
	a = p->as;
31
	switch(a) {
32
	default:
33
		s = str;
34
		s += sprint(s, "(%ld)", p->line);
35
		if(p->reg == NREG)
36
			sprint(s, "	%A%C	%D,%D",
37
				a, p->scond, &p->from, &p->to);
38
		else
39
		if(p->from.type != D_FREG)
40
			sprint(s, "	%A%C	%D,R%d,%D",
41
				a, p->scond, &p->from, p->reg, &p->to);
42
		else
43
			sprint(s, "	%A%C	%D,F%d,%D",
44
				a, p->scond, &p->from, p->reg, &p->to);
45
		break;
46
 
47
	case ASWPW:
48
	case ASWPBU:
49
		sprint(str, "(%ld)	%A%C	R%d,%D,%D",
50
			p->line, a, p->scond, p->reg, &p->from, &p->to);
51
		break;
52
 
53
	case ADATA:
54
	case AINIT:
55
	case ADYNT:
56
		sprint(str, "(%ld)	%A%C	%D/%d,%D",
57
			p->line, a, p->scond, &p->from, p->reg, &p->to);
58
		break;
59
	}
60
	return fmtstrcpy(fp, str);
61
}
62
 
63
int
64
Aconv(Fmt *fp)
65
{
66
	char *s;
67
	int a;
68
 
69
	a = va_arg(fp->args, int);
70
	s = "???";
71
	if(a >= AXXX && a < ALAST)
72
		s = anames[a];
73
	return fmtstrcpy(fp, s);
74
}
75
 
76
char*	strcond[16] =
77
{
78
	".EQ",
79
	".NE",
80
	".HS",
81
	".LO",
82
	".MI",
83
	".PL",
84
	".VS",
85
	".VC",
86
	".HI",
87
	".LS",
88
	".GE",
89
	".LT",
90
	".GT",
91
	".LE",
92
	"",
93
	".NV"
94
};
95
 
96
int
97
Cconv(Fmt *fp)
98
{
99
	char s[20];
100
	int c;
101
 
102
	c = va_arg(fp->args, int);
103
	strcpy(s, strcond[c & C_SCOND]);
104
	if(c & C_SBIT)
105
		strcat(s, ".S");
106
	if(c & C_PBIT)
107
		strcat(s, ".P");
108
	if(c & C_WBIT)
109
		strcat(s, ".W");
110
	if(c & C_UBIT)		/* ambiguous with FBIT */
111
		strcat(s, ".U");
112
	return fmtstrcpy(fp, s);
113
}
114
 
115
int
116
Dconv(Fmt *fp)
117
{
118
	char str[STRINGSZ];
119
	char *op;
120
	Adr *a;
121
	long v;
122
 
123
	a = va_arg(fp->args, Adr*);
124
	switch(a->type) {
125
 
126
	default:
127
		sprint(str, "GOK-type(%d)", a->type);
128
		break;
129
 
130
	case D_NONE:
131
		str[0] = 0;
132
		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
133
			sprint(str, "%N(R%d)(NONE)", a, a->reg);
134
		break;
135
 
136
	case D_CONST:
137
		if(a->reg == NREG)
138
			sprint(str, "$%N", a);
139
		else
140
			sprint(str, "$%N(R%d)", a, a->reg);
141
		break;
142
 
143
	case D_SHIFT:
144
		v = a->offset;
145
		op = "<<>>->@>" + (((v>>5) & 3) << 1);
146
		if(v & (1<<4))
147
			sprint(str, "R%ld%c%cR%ld", v&15, op[0], op[1], (v>>8)&15);
148
		else
149
			sprint(str, "R%ld%c%c%ld", v&15, op[0], op[1], (v>>7)&31);
150
		if(a->reg != NREG)
151
			sprint(str+strlen(str), "(R%d)", a->reg);
152
		break;
153
 
154
	case D_OCONST:
155
		sprint(str, "$*$%N", a);
156
		if(a->reg != NREG)
157
			sprint(str, "%N(R%d)(CONST)", a, a->reg);
158
		break;
159
 
160
	case D_OREG:
161
		if(a->reg != NREG)
162
			sprint(str, "%N(R%d)", a, a->reg);
163
		else
164
			sprint(str, "%N", a);
165
		break;
166
 
167
	case D_REG:
168
		sprint(str, "R%d", a->reg);
169
		if(a->name != D_NONE || a->sym != S)
170
			sprint(str, "%N(R%d)(REG)", a, a->reg);
171
		break;
172
 
173
	case D_REGREG:
174
		sprint(str, "(R%d,R%d)", a->reg, (int)a->offset);
175
		if(a->name != D_NONE || a->sym != S)
176
			sprint(str, "%N(R%d)(REG)", a, a->reg);
177
		break;
178
 
179
	case D_FREG:
180
		sprint(str, "F%d", a->reg);
181
		if(a->name != D_NONE || a->sym != S)
182
			sprint(str, "%N(R%d)(REG)", a, a->reg);
183
		break;
184
 
185
	case D_PSR:
186
		switch(a->reg) {
187
		case 0:
188
			sprint(str, "CPSR");
189
			break;
190
		case 1:
191
			sprint(str, "SPSR");
192
			break;
193
		default:
194
			sprint(str, "PSR%d", a->reg);
195
			break;
196
		}
197
		if(a->name != D_NONE || a->sym != S)
198
			sprint(str, "%N(PSR%d)(REG)", a, a->reg);
199
		break;
200
 
201
	case D_FPCR:
202
		switch(a->reg){
203
		case 0:
204
			sprint(str, "FPSR");
205
			break;
206
		case 1:
207
			sprint(str, "FPCR");
208
			break;
209
		default:
210
			sprint(str, "FCR%d", a->reg);
211
			break;
212
		}
213
		if(a->name != D_NONE || a->sym != S)
214
			sprint(str, "%N(FCR%d)(REG)", a, a->reg);
215
 
216
		break;
217
 
218
	case D_BRANCH:	/* botch */
219
		if(curp->cond != P) {
220
			v = curp->cond->pc;
221
			if(a->sym != S)
222
				sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
223
			else
224
				sprint(str, "%.5lux(BRANCH)", v);
225
		} else
226
			if(a->sym != S)
227
				sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
228
			else
229
				sprint(str, "%ld(APC)", a->offset);
230
		break;
231
 
232
	case D_FCONST:
233
		sprint(str, "$%e", ieeedtod(a->ieee));
234
		break;
235
 
236
	case D_SCONST:
237
		sprint(str, "$\"%S\"", a->sval);
238
		break;
239
	}
240
	return fmtstrcpy(fp, str);
241
}
242
 
243
int
244
Nconv(Fmt *fp)
245
{
246
	char str[STRINGSZ];
247
	Adr *a;
248
	Sym *s;
249
 
250
	a = va_arg(fp->args, Adr*);
251
	s = a->sym;
252
	switch(a->name) {
253
	default:
254
		sprint(str, "GOK-name(%d)", a->name);
255
		break;
256
 
257
	case D_NONE:
258
		sprint(str, "%ld", a->offset);
259
		break;
260
 
261
	case D_EXTERN:
262
		if(s == S)
263
			sprint(str, "%ld(SB)", a->offset);
264
		else
265
			sprint(str, "%s+%ld(SB)", s->name, a->offset);
266
		break;
267
 
268
	case D_STATIC:
269
		if(s == S)
270
			sprint(str, "<>+%ld(SB)", a->offset);
271
		else
272
			sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
273
		break;
274
 
275
	case D_AUTO:
276
		if(s == S)
277
			sprint(str, "%ld(SP)", a->offset);
278
		else
279
			sprint(str, "%s-%ld(SP)", s->name, -a->offset);
280
		break;
281
 
282
	case D_PARAM:
283
		if(s == S)
284
			sprint(str, "%ld(FP)", a->offset);
285
		else
286
			sprint(str, "%s+%ld(FP)", s->name, a->offset);
287
		break;
288
	}
289
	return fmtstrcpy(fp, str);
290
}
291
 
292
int
293
Sconv(Fmt *fp)
294
{
295
	int i, c;
296
	char str[STRINGSZ], *p, *a;
297
 
298
	a = va_arg(fp->args, char*);
299
	p = str;
300
	for(i=0; i<sizeof(long); i++) {
301
		c = a[i] & 0xff;
302
		if(c >= 'a' && c <= 'z' ||
303
		   c >= 'A' && c <= 'Z' ||
304
		   c >= '0' && c <= '9' ||
305
		   c == ' ' || c == '%') {
306
			*p++ = c;
307
			continue;
308
		}
309
		*p++ = '\\';
310
		switch(c) {
311
		case 0:
312
			*p++ = 'z';
313
			continue;
314
		case '\\':
315
		case '"':
316
			*p++ = c;
317
			continue;
318
		case '\n':
319
			*p++ = 'n';
320
			continue;
321
		case '\t':
322
			*p++ = 't';
323
			continue;
324
		}
325
		*p++ = (c>>6) + '0';
326
		*p++ = ((c>>3) & 7) + '0';
327
		*p++ = (c & 7) + '0';
328
	}
329
	*p = 0;
330
	return fmtstrcpy(fp, str);
331
}
332
 
333
void
334
diag(char *fmt, ...)
335
{
336
	char buf[STRINGSZ], *tn;
337
	va_list arg;
338
 
339
	tn = "??none??";
340
	if(curtext != P && curtext->from.sym != S)
341
		tn = curtext->from.sym->name;
342
	va_start(arg, fmt);
343
	vseprint(buf, buf+sizeof(buf), fmt, arg);
344
	va_end(arg);
345
	print("%s: %s\n", tn, buf);
346
 
347
	nerrors++;
348
	if(nerrors > 10) {
349
		print("too many errors\n");
350
		errorexit();
351
	}
352
}