Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
#define	EXTERN
2
#include "a.h"
3
#include "y.tab.h"
4
#include <ctype.h>
5
 
6
void
7
main(int argc, char *argv[])
8
{
9
	char *p;
10
	int nout, nproc, status, i, c;
11
 
12
	thechar = '5';
13
	thestring = "arm";
14
	memset(debug, 0, sizeof(debug));
15
	cinit();
16
	outfile = 0;
17
	include[ninclude++] = ".";
18
	ARGBEGIN {
19
	default:
20
		c = ARGC();
21
		if(c >= 0 || c < sizeof(debug))
22
			debug[c] = 1;
23
		break;
24
 
25
	case 'o':
26
		outfile = ARGF();
27
		break;
28
 
29
	case 'D':
30
		p = ARGF();
31
		if(p)
32
			Dlist[nDlist++] = p;
33
		break;
34
 
35
	case 'I':
36
		p = ARGF();
37
		setinclude(p);
38
		break;
39
	case 't':
40
		thechar = 't';
41
		thestring = "thumb";
42
		break;
43
	} ARGEND
44
	if(*argv == 0) {
45
		print("usage: %ca [-options] file.s\n", thechar);
46
		errorexit();
47
	}
48
	if(argc > 1 && systemtype(Windows)){
49
		print("can't assemble multiple files on windows\n");
50
		errorexit();
51
	}
52
	if(argc > 1 && !systemtype(Windows)) {
53
		nproc = 1;
54
		if(p = getenv("NPROC"))
55
			nproc = atol(p);	/* */
56
		c = 0;
57
		nout = 0;
58
		for(;;) {
59
			while(nout < nproc && argc > 0) {
60
				i = myfork();
61
				if(i < 0) {
62
					i = mywait(&status);
63
					if(i < 0)
64
						errorexit();
65
					if(status)
66
						c++;
67
					nout--;
68
					continue;
69
				}
70
				if(i == 0) {
71
					print("%s:\n", *argv);
72
					if(assemble(*argv))
73
						errorexit();
74
					exits(0);
75
				}
76
				nout++;
77
				argc--;
78
				argv++;
79
			}
80
			i = mywait(&status);
81
			if(i < 0) {
82
				if(c)
83
					errorexit();
84
				exits(0);
85
			}
86
			if(status)
87
				c++;
88
			nout--;
89
		}
90
	}
91
	if(assemble(argv[0]))
92
		errorexit();
93
	exits(0);
94
}
95
 
96
int
97
assemble(char *file)
98
{
99
	char ofile[100], incfile[20], *p;
100
	int i, of;
101
 
102
	strcpy(ofile, file);
103
	p = utfrrune(ofile, pathchar());
104
	if(p) {
105
		include[0] = ofile;
106
		*p++ = 0;
107
	} else
108
		p = ofile;
109
	if(outfile == 0) {
110
		outfile = p;
111
		if(outfile){
112
			p = utfrrune(outfile, '.');
113
			if(p)
114
				if(p[1] == 's' && p[2] == 0)
115
					p[0] = 0;
116
			p = utfrune(outfile, 0);
117
			p[0] = '.';
118
			p[1] = thechar;
119
			p[2] = 0;
120
		} else
121
			outfile = "/dev/null";
122
	}
123
	p = getenv("INCLUDE");
124
	if(p) {
125
		setinclude(p);
126
	} else {
127
		if(systemtype(Plan9)) {
128
			sprint(incfile,"/%s/include", thestring);
129
			setinclude(strdup(incfile));
130
		}
131
	}
132
 
133
	of = mycreat(outfile, 0664);
134
	if(of < 0) {
135
		yyerror("%ca: cannot create %s", thechar, outfile);
136
		errorexit();
137
	}
138
	Binit(&obuf, of, OWRITE);
139
 
140
	pass = 1;
141
	pinit(file);
142
	for(i=0; i<nDlist; i++)
143
		dodefine(Dlist[i]);
144
	yyparse();
145
	if(nerrors) {
146
		cclean();
147
		return nerrors;
148
	}
149
 
150
	pass = 2;
151
	outhist();
152
	pinit(file);
153
	for(i=0; i<nDlist; i++)
154
		dodefine(Dlist[i]);
155
	yyparse();
156
	cclean();
157
	return nerrors;
158
}
159
 
160
struct
161
{
162
	char	*name;
163
	ushort	type;
164
	ushort	value;
165
} itab[] =
166
{
167
	"SP",		LSP,	D_AUTO,
168
	"SB",		LSB,	D_EXTERN,
169
	"FP",		LFP,	D_PARAM,
170
	"PC",		LPC,	D_BRANCH,
171
 
172
	"R",		LR,	0,
173
	"R0",		LREG,	0,
174
	"R1",		LREG,	1,
175
	"R2",		LREG,	2,
176
	"R3",		LREG,	3,
177
	"R4",		LREG,	4,
178
	"R5",		LREG,	5,
179
	"R6",		LREG,	6,
180
	"R7",		LREG,	7,
181
	"R8",		LREG,	8,
182
	"R9",		LREG,	9,
183
	"R10",		LREG,	10,
184
	"R11",		LREG,	11,
185
	"R12",		LREG,	12,
186
	"R13",		LREG,	13,
187
	"R14",		LREG,	14,
188
	"R15",		LREG,	15,
189
 
190
	"F",		LF,	0,
191
 
192
	"F0",		LFREG,	0,
193
	"F1",		LFREG,	1,
194
	"F2",		LFREG,	2,
195
	"F3",		LFREG,	3,
196
	"F4",		LFREG,	4,
197
	"F5",		LFREG,	5,
198
	"F6",		LFREG,	6,
199
	"F7",		LFREG,	7,
200
	"F8",		LFREG,	8,
201
	"F9",		LFREG,	9,
202
	"F10",		LFREG,	10,
203
	"F11",		LFREG,	11,
204
	"F12",		LFREG,	12,
205
	"F13",		LFREG,	13,
206
	"F14",		LFREG,	14,
207
	"F15",		LFREG,	15,
208
 
209
	"C",		LC,	0,
210
 
211
	"C0",		LCREG,	0,
212
	"C1",		LCREG,	1,
213
	"C2",		LCREG,	2,
214
	"C3",		LCREG,	3,
215
	"C4",		LCREG,	4,
216
	"C5",		LCREG,	5,
217
	"C6",		LCREG,	6,
218
	"C7",		LCREG,	7,
219
	"C8",		LCREG,	8,
220
	"C9",		LCREG,	9,
221
	"C10",		LCREG,	10,
222
	"C11",		LCREG,	11,
223
	"C12",		LCREG,	12,
224
	"C13",		LCREG,	13,
225
	"C14",		LCREG,	14,
226
	"C15",		LCREG,	15,
227
 
228
	"CPSR",		LPSR,	0,
229
	"SPSR",		LPSR,	1,
230
 
231
	"FPSR",		LFCR,	0,
232
	"FPCR",		LFCR,	1,
233
 
234
	".EQ",		LCOND,	0,
235
	".NE",		LCOND,	1,
236
	".CS",		LCOND,	2,
237
	".HS",		LCOND,	2,
238
	".CC",		LCOND,	3,
239
	".LO",		LCOND,	3,
240
	".MI",		LCOND,	4,
241
	".PL",		LCOND,	5,
242
	".VS",		LCOND,	6,
243
	".VC",		LCOND,	7,
244
	".HI",		LCOND,	8,
245
	".LS",		LCOND,	9,
246
	".GE",		LCOND,	10,
247
	".LT",		LCOND,	11,
248
	".GT",		LCOND,	12,
249
	".LE",		LCOND,	13,
250
	".AL",		LCOND,	Always,
251
 
252
	".U",		LS,	C_UBIT,
253
	".S",		LS,	C_SBIT,
254
	".W",		LS,	C_WBIT,
255
	".P",		LS,	C_PBIT,
256
	".PW",		LS,	C_WBIT|C_PBIT,
257
	".WP",		LS,	C_WBIT|C_PBIT,
258
 
259
	".F",		LS,	C_FBIT,
260
 
261
	".IBW",		LS,	C_WBIT|C_PBIT|C_UBIT,
262
	".IAW",		LS,	C_WBIT|C_UBIT,
263
	".DBW",		LS,	C_WBIT|C_PBIT,
264
	".DAW",		LS,	C_WBIT,
265
	".IB",		LS,	C_PBIT|C_UBIT,
266
	".IA",		LS,	C_UBIT,
267
	".DB",		LS,	C_PBIT,
268
	".DA",		LS,	0,
269
 
270
	"@",		LAT,	0,
271
 
272
	"AND",		LTYPE1,	AAND,
273
	"EOR",		LTYPE1,	AEOR,
274
	"SUB",		LTYPE1,	ASUB,
275
	"RSB",		LTYPE1,	ARSB,
276
	"ADD",		LTYPE1,	AADD,
277
	"ADC",		LTYPE1,	AADC,
278
	"SBC",		LTYPE1,	ASBC,
279
	"RSC",		LTYPE1,	ARSC,
280
	"ORR",		LTYPE1,	AORR,
281
	"BIC",		LTYPE1,	ABIC,
282
 
283
	"SLL",		LTYPE1,	ASLL,
284
	"SRL",		LTYPE1,	ASRL,
285
	"SRA",		LTYPE1,	ASRA,
286
 
287
	"MUL",		LTYPE1, AMUL,
288
	"MULA",		LTYPEN, AMULA,
289
	"DIV",		LTYPE1,	ADIV,
290
	"MOD",		LTYPE1,	AMOD,
291
 
292
	"MULL",		LTYPEM, AMULL,
293
	"MULAL",	LTYPEM, AMULAL,
294
	"MULLU",	LTYPEM, AMULLU,
295
	"MULALU",	LTYPEM, AMULALU,
296
 
297
	"MVN",		LTYPE2, AMVN,	/* op2 ignored */
298
 
299
	"MOVB",		LTYPE3, AMOVB,
300
	"MOVBU",	LTYPE3, AMOVBU,
301
	"MOVH",		LTYPE3, AMOVH,
302
	"MOVHU",	LTYPE3, AMOVHU,
303
	"MOVW",		LTYPE3, AMOVW,
304
 
305
	"MOVD",		LTYPE3, AMOVD,
306
	"MOVDF",		LTYPE3, AMOVDF,
307
	"MOVDW",	LTYPE3, AMOVDW,
308
	"MOVF",		LTYPE3, AMOVF,
309
	"MOVFD",		LTYPE3, AMOVFD,
310
	"MOVFW",		LTYPE3, AMOVFW,
311
	"MOVWD",	LTYPE3, AMOVWD,
312
	"MOVWF",		LTYPE3, AMOVWF,
313
 
314
	"LDREX",		LTYPE3, ALDREX,
315
	"LDREXD",		LTYPE3, ALDREXD,
316
	"STREX",		LTYPE9, ASTREX,
317
	"STREXD",		LTYPE9, ASTREXD,
318
 
319
/*
320
	"ABSF",		LTYPEI, AABSF,
321
	"ABSD",		LTYPEI, AABSD,
322
	"NEGF",		LTYPEI, ANEGF,
323
	"NEGD",		LTYPEI, ANEGD,
324
	"SQTF",		LTYPEI,	ASQTF,
325
	"SQTD",		LTYPEI,	ASQTD,
326
	"RNDF",		LTYPEI,	ARNDF,
327
	"RNDD",		LTYPEI,	ARNDD,
328
	"URDF",		LTYPEI,	AURDF,
329
	"URDD",		LTYPEI,	AURDD,
330
	"NRMF",		LTYPEI,	ANRMF,
331
	"NRMD",		LTYPEI,	ANRMD,
332
*/
333
 
334
	"SQRTF",	LTYPEI, ASQRTF,
335
	"SQRTD",	LTYPEI, ASQRTD,
336
	"CMPF",		LTYPEL, ACMPF,
337
	"CMPD",		LTYPEL, ACMPD,
338
	"ADDF",		LTYPEK,	AADDF,
339
	"ADDD",		LTYPEK,	AADDD,
340
	"SUBF",		LTYPEK,	ASUBF,
341
	"SUBD",		LTYPEK,	ASUBD,
342
	"MULF",		LTYPEK,	AMULF,
343
	"MULD",		LTYPEK,	AMULD,
344
	"DIVF",		LTYPEK,	ADIVF,
345
	"DIVD",		LTYPEK,	ADIVD,
346
 
347
	"B",		LTYPE4, AB,
348
	"BL",		LTYPE4, ABL,
349
	"BX",		LTYPEBX,	ABX,
350
 
351
	"BEQ",		LTYPE5,	ABEQ,
352
	"BNE",		LTYPE5,	ABNE,
353
	"BCS",		LTYPE5,	ABCS,
354
	"BHS",		LTYPE5,	ABHS,
355
	"BCC",		LTYPE5,	ABCC,
356
	"BLO",		LTYPE5,	ABLO,
357
	"BMI",		LTYPE5,	ABMI,
358
	"BPL",		LTYPE5,	ABPL,
359
	"BVS",		LTYPE5,	ABVS,
360
	"BVC",		LTYPE5,	ABVC,
361
	"BHI",		LTYPE5,	ABHI,
362
	"BLS",		LTYPE5,	ABLS,
363
	"BGE",		LTYPE5,	ABGE,
364
	"BLT",		LTYPE5,	ABLT,
365
	"BGT",		LTYPE5,	ABGT,
366
	"BLE",		LTYPE5,	ABLE,
367
	"BCASE",	LTYPE5,	ABCASE,
368
 
369
	"SWI",		LTYPE6, ASWI,
370
 
371
	"CMP",		LTYPE7,	ACMP,
372
	"TST",		LTYPE7,	ATST,
373
	"TEQ",		LTYPE7,	ATEQ,
374
	"CMN",		LTYPE7,	ACMN,
375
 
376
	"MOVM",		LTYPE8, AMOVM,
377
 
378
	"SWPBU",	LTYPE9, ASWPBU,
379
	"SWPW",		LTYPE9, ASWPW,
380
 
381
	"RET",		LTYPEA, ARET,
382
	"RFE",		LTYPEA, ARFE,
383
 
384
	"TEXT",		LTYPEB, ATEXT,
385
	"GLOBL",	LTYPEB, AGLOBL,
386
	"DATA",		LTYPEC, ADATA,
387
	"CASE",		LTYPED, ACASE,
388
	"END",		LTYPEE, AEND,
389
	"WORD",		LTYPEH, AWORD,
390
	"NOP",		LTYPEI, ANOP,
391
 
392
	"MCR",		LTYPEJ, 0,
393
	"MRC",		LTYPEJ, 1,
394
 
395
};
396
 
397
void
398
cinit(void)
399
{
400
	Sym *s;
401
	int i;
402
 
403
	nullgen.sym = S;
404
	nullgen.offset = 0;
405
	nullgen.type = D_NONE;
406
	nullgen.name = D_NONE;
407
	nullgen.reg = NREG;
408
	if(FPCHIP)
409
		nullgen.dval = 0;
410
	for(i=0; i<sizeof(nullgen.sval); i++)
411
		nullgen.sval[i] = 0;
412
 
413
	nerrors = 0;
414
	iostack = I;
415
	iofree = I;
416
	peekc = IGN;
417
	nhunk = 0;
418
	for(i=0; i<NHASH; i++)
419
		hash[i] = S;
420
	for(i=0; itab[i].name; i++) {
421
		s = slookup(itab[i].name);
422
		s->type = itab[i].type;
423
		s->value = itab[i].value;
424
	}
425
 
426
	pathname = allocn(pathname, 0, 100);
427
	if(getwd(pathname, 99) == 0) {
428
		pathname = allocn(pathname, 100, 900);
429
		if(getwd(pathname, 999) == 0)
430
			strcpy(pathname, "/???");
431
	}
432
}
433
 
434
void
435
syminit(Sym *s)
436
{
437
 
438
	s->type = LNAME;
439
	s->value = 0;
440
}
441
 
442
int
443
isreg(Gen *g)
444
{
445
 
446
	USED(g);
447
	return 1;
448
}
449
 
450
void
451
cclean(void)
452
{
453
 
454
	outcode(AEND, Always, &nullgen, NREG, &nullgen);
455
	Bflush(&obuf);
456
}
457
 
458
void
459
zname(char *n, int t, int s)
460
{
461
 
462
	Bputc(&obuf, ANAME);
463
	Bputc(&obuf, t);	/* type */
464
	Bputc(&obuf, s);	/* sym */
465
	while(*n) {
466
		Bputc(&obuf, *n);
467
		n++;
468
	}
469
	Bputc(&obuf, 0);
470
}
471
 
472
void
473
zaddr(Gen *a, int s)
474
{
475
	long l;
476
	int i;
477
	char *n;
478
	Ieee e;
479
 
480
	Bputc(&obuf, a->type);
481
	Bputc(&obuf, a->reg);
482
	Bputc(&obuf, s);
483
	Bputc(&obuf, a->name);
484
	switch(a->type) {
485
	default:
486
		print("unknown type %d\n", a->type);
487
		exits("arg");
488
 
489
	case D_NONE:
490
	case D_REG:
491
	case D_FREG:
492
	case D_PSR:
493
	case D_FPCR:
494
		break;
495
 
496
	case D_REGREG:
497
		Bputc(&obuf, a->offset);
498
		break;
499
 
500
	case D_OREG:
501
	case D_CONST:
502
	case D_BRANCH:
503
	case D_SHIFT:
504
		l = a->offset;
505
		Bputc(&obuf, l);
506
		Bputc(&obuf, l>>8);
507
		Bputc(&obuf, l>>16);
508
		Bputc(&obuf, l>>24);
509
		break;
510
 
511
	case D_SCONST:
512
		n = a->sval;
513
		for(i=0; i<NSNAME; i++) {
514
			Bputc(&obuf, *n);
515
			n++;
516
		}
517
		break;
518
 
519
	case D_FCONST:
520
		ieeedtod(&e, a->dval);
521
		Bputc(&obuf, e.l);
522
		Bputc(&obuf, e.l>>8);
523
		Bputc(&obuf, e.l>>16);
524
		Bputc(&obuf, e.l>>24);
525
		Bputc(&obuf, e.h);
526
		Bputc(&obuf, e.h>>8);
527
		Bputc(&obuf, e.h>>16);
528
		Bputc(&obuf, e.h>>24);
529
		break;
530
	}
531
}
532
 
533
static int bcode[] =
534
{
535
	ABEQ,
536
	ABNE,
537
	ABCS,
538
	ABCC,
539
	ABMI,
540
	ABPL,
541
	ABVS,
542
	ABVC,
543
	ABHI,
544
	ABLS,
545
	ABGE,
546
	ABLT,
547
	ABGT,
548
	ABLE,
549
	AB,
550
	ANOP,
551
};
552
 
553
void
554
outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
555
{
556
	int sf, st, t;
557
	Sym *s;
558
 
559
	/* hack to make B.NE etc. work: turn it into the corresponding conditional */
560
	if(a == AB){
561
		a = bcode[scond&0xf];
562
		scond = (scond & ~0xf) | Always;
563
	}
564
 
565
	if(pass == 1)
566
		goto out;
567
jackpot:
568
	sf = 0;
569
	s = g1->sym;
570
	while(s != S) {
571
		sf = s->sym;
572
		if(sf < 0 || sf >= NSYM)
573
			sf = 0;
574
		t = g1->name;
575
		if(h[sf].type == t)
576
		if(h[sf].sym == s)
577
			break;
578
		zname(s->name, t, sym);
579
		s->sym = sym;
580
		h[sym].sym = s;
581
		h[sym].type = t;
582
		sf = sym;
583
		sym++;
584
		if(sym >= NSYM)
585
			sym = 1;
586
		break;
587
	}
588
	st = 0;
589
	s = g2->sym;
590
	while(s != S) {
591
		st = s->sym;
592
		if(st < 0 || st >= NSYM)
593
			st = 0;
594
		t = g2->name;
595
		if(h[st].type == t)
596
		if(h[st].sym == s)
597
			break;
598
		zname(s->name, t, sym);
599
		s->sym = sym;
600
		h[sym].sym = s;
601
		h[sym].type = t;
602
		st = sym;
603
		sym++;
604
		if(sym >= NSYM)
605
			sym = 1;
606
		if(st == sf)
607
			goto jackpot;
608
		break;
609
	}
610
	Bputc(&obuf, a);
611
	Bputc(&obuf, scond);
612
	Bputc(&obuf, reg);
613
	Bputc(&obuf, lineno);
614
	Bputc(&obuf, lineno>>8);
615
	Bputc(&obuf, lineno>>16);
616
	Bputc(&obuf, lineno>>24);
617
	zaddr(g1, sf);
618
	zaddr(g2, st);
619
 
620
out:
621
	if(a != AGLOBL && a != ADATA)
622
		pc++;
623
}
624
 
625
void
626
outhist(void)
627
{
628
	Gen g;
629
	Hist *h;
630
	char *p, *q, *op, c;
631
	int n;
632
 
633
	g = nullgen;
634
	c = pathchar();
635
	for(h = hist; h != H; h = h->link) {
636
		p = h->name;
637
		op = 0;
638
		/* on windows skip drive specifier in pathname */
639
		if(systemtype(Windows) && p && p[1] == ':'){
640
			p += 2;
641
			c = *p;
642
		}
643
		if(p && p[0] != c && h->offset == 0 && pathname){
644
			/* on windows skip drive specifier in pathname */
645
			if(systemtype(Windows) && pathname[1] == ':') {
646
				op = p;
647
				p = pathname+2;
648
				c = *p;
649
			} else if(pathname[0] == c){
650
				op = p;
651
				p = pathname;
652
			}
653
		}
654
		while(p) {
655
			q = strchr(p, c);
656
			if(q) {
657
				n = q-p;
658
				if(n == 0){
659
					n = 1;	/* leading "/" */
660
					*p = '/';	/* don't emit "\" on windows */
661
				}
662
				q++;
663
			} else {
664
				n = strlen(p);
665
				q = 0;
666
			}
667
			if(n) {
668
				Bputc(&obuf, ANAME);
669
				Bputc(&obuf, D_FILE);	/* type */
670
				Bputc(&obuf, 1);	/* sym */
671
				Bputc(&obuf, '<');
672
				Bwrite(&obuf, p, n);
673
				Bputc(&obuf, 0);
674
			}
675
			p = q;
676
			if(p == 0 && op) {
677
				p = op;
678
				op = 0;
679
			}
680
		}
681
		g.offset = h->offset;
682
 
683
		Bputc(&obuf, AHISTORY);
684
		Bputc(&obuf, Always);
685
		Bputc(&obuf, 0);
686
		Bputc(&obuf, h->line);
687
		Bputc(&obuf, h->line>>8);
688
		Bputc(&obuf, h->line>>16);
689
		Bputc(&obuf, h->line>>24);
690
		zaddr(&nullgen, 0);
691
		zaddr(&g, 0);
692
	}
693
}
694
 
695
#include "../cc/lexbody"
696
#include "../cc/macbody"
697
#include "../cc/compat"