Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "cc.h"
2
 
3
/*
4
 * this is machine dependent, but it is totally
5
 * common on all of the 64-bit symulating machines.
6
 */
7
 
8
#define	FNX	100	/* botch -- redefinition */
9
 
10
Node*	nodaddv;
11
Node*	nodsubv;
12
Node*	nodmulv;
13
Node*	noddivv;
14
Node*	noddivvu;
15
Node*	nodmodv;
16
Node*	nodmodvu;
17
Node*	nodlshv;
18
Node*	nodrshav;
19
Node*	nodrshlv;
20
Node*	nodandv;
21
Node*	nodorv;
22
Node*	nodxorv;
23
Node*	nodnegv;
24
Node*	nodcomv;
25
 
26
Node*	nodtestv;
27
Node*	nodeqv;
28
Node*	nodnev;
29
Node*	nodlev;
30
Node*	nodltv;
31
Node*	nodgev;
32
Node*	nodgtv;
33
Node*	nodhiv;
34
Node*	nodhsv;
35
Node*	nodlov;
36
Node*	nodlsv;
37
 
38
Node*	nodf2v;
39
Node*	nodd2v;
40
Node*	nodp2v;
41
Node*	nodsi2v;
42
Node*	nodui2v;
43
Node*	nodsl2v;
44
Node*	nodul2v;
45
Node*	nodsh2v;
46
Node*	noduh2v;
47
Node*	nodsc2v;
48
Node*	noduc2v;
49
 
50
Node*	nodv2f;
51
Node*	nodv2d;
52
Node*	nodv2ui;
53
Node*	nodv2si;
54
Node*	nodv2ul;
55
Node*	nodv2sl;
56
Node*	nodv2uh;
57
Node*	nodv2sh;
58
Node*	nodv2uc;
59
Node*	nodv2sc;
60
 
61
Node*	nodvpp;
62
Node*	nodppv;
63
Node*	nodvmm;
64
Node*	nodmmv;
65
 
66
Node*	nodvasop;
67
 
68
char	etconv[NTYPE];	/* for _vasop */
69
Init	initetconv[] =
70
{
71
	TCHAR,		1,	0,
72
	TUCHAR,		2,	0,
73
	TSHORT,		3,	0,
74
	TUSHORT,	4,	0,
75
	TLONG,		5,	0,
76
	TULONG,		6,	0,
77
	TVLONG,		7,	0,
78
	TUVLONG,	8,	0,
79
	TINT,		9,	0,
80
	TUINT,		10,	0,
81
	-1,		0,	0,
82
};
83
 
84
Node*
85
fvn(char *name, int type)
86
{
87
	Node *n;
88
 
89
	n = new(ONAME, Z, Z);
90
	n->sym = slookup(name);
91
	n->sym->sig = SIGINTERN;
92
	if(fntypes[type] == 0)
93
		fntypes[type] = typ(TFUNC, types[type]);
94
	n->type = fntypes[type];
95
	n->etype = type;
96
	n->class = CGLOBL;
97
	n->addable = 10;
98
	n->complex = 0;
99
	return n;
100
}
101
 
102
void
103
com64init(void)
104
{
105
	Init *p;
106
 
107
	nodaddv = fvn("_addv", TVLONG);
108
	nodsubv = fvn("_subv", TVLONG);
109
	nodmulv = fvn("_mulv", TVLONG);
110
	noddivv = fvn("_divv", TVLONG);
111
	noddivvu = fvn("_divvu", TVLONG);
112
	nodmodv = fvn("_modv", TVLONG);
113
	nodmodvu = fvn("_modvu", TVLONG);
114
	nodlshv = fvn("_lshv", TVLONG);
115
	nodrshav = fvn("_rshav", TVLONG);
116
	nodrshlv = fvn("_rshlv", TVLONG);
117
	nodandv = fvn("_andv", TVLONG);
118
	nodorv = fvn("_orv", TVLONG);
119
	nodxorv = fvn("_xorv", TVLONG);
120
	nodnegv = fvn("_negv", TVLONG);
121
	nodcomv = fvn("_comv", TVLONG);
122
 
123
	nodtestv = fvn("_testv", TLONG);
124
	nodeqv = fvn("_eqv", TLONG);
125
	nodnev = fvn("_nev", TLONG);
126
	nodlev = fvn("_lev", TLONG);
127
	nodltv = fvn("_ltv", TLONG);
128
	nodgev = fvn("_gev", TLONG);
129
	nodgtv = fvn("_gtv", TLONG);
130
	nodhiv = fvn("_hiv", TLONG);
131
	nodhsv = fvn("_hsv", TLONG);
132
	nodlov = fvn("_lov", TLONG);
133
	nodlsv = fvn("_lsv", TLONG);
134
 
135
	nodf2v = fvn("_f2v", TVLONG);
136
	nodd2v = fvn("_d2v", TVLONG);
137
	nodp2v = fvn("_p2v", TVLONG);
138
	nodsi2v = fvn("_si2v", TVLONG);
139
	nodui2v = fvn("_ui2v", TVLONG);
140
	nodsl2v = fvn("_sl2v", TVLONG);
141
	nodul2v = fvn("_ul2v", TVLONG);
142
	nodsh2v = fvn("_sh2v", TVLONG);
143
	noduh2v = fvn("_uh2v", TVLONG);
144
	nodsc2v = fvn("_sc2v", TVLONG);
145
	noduc2v = fvn("_uc2v", TVLONG);
146
 
147
	nodv2f = fvn("_v2f", TFLOAT);
148
	nodv2d = fvn("_v2d", TDOUBLE);
149
	nodv2sl = fvn("_v2sl", TLONG);
150
	nodv2ul = fvn("_v2ul", TULONG);
151
	nodv2si = fvn("_v2si", TINT);
152
	nodv2ui = fvn("_v2ui", TUINT);
153
	nodv2sh = fvn("_v2sh", TSHORT);
154
	nodv2uh = fvn("_v2ul", TUSHORT);
155
	nodv2sc = fvn("_v2sc", TCHAR);
156
	nodv2uc = fvn("_v2uc", TUCHAR);
157
 
158
	nodvpp = fvn("_vpp", TVLONG);
159
	nodppv = fvn("_ppv", TVLONG);
160
	nodvmm = fvn("_vmm", TVLONG);
161
	nodmmv = fvn("_mmv", TVLONG);
162
 
163
	nodvasop = fvn("_vasop", TVLONG);
164
 
165
	for(p = initetconv; p->code >= 0; p++)
166
		etconv[p->code] = p->value;
167
}
168
 
169
int
170
com64(Node *n)
171
{
172
	Node *l, *r, *a, *t;
173
	int lv, rv;
174
 
175
	if(n->type == 0)
176
		return 0;
177
 
178
	l = n->left;
179
	r = n->right;
180
 
181
	lv = 0;
182
	if(l && l->type && typev[l->type->etype])
183
		lv = 1;
184
	rv = 0;
185
	if(r && r->type && typev[r->type->etype])
186
		rv = 1;
187
 
188
	if(lv) {
189
		switch(n->op) {
190
		case OEQ:
191
			a = nodeqv;
192
			goto setbool;
193
		case ONE:
194
			a = nodnev;
195
			goto setbool;
196
		case OLE:
197
			a = nodlev;
198
			goto setbool;
199
		case OLT:
200
			a = nodltv;
201
			goto setbool;
202
		case OGE:
203
			a = nodgev;
204
			goto setbool;
205
		case OGT:
206
			a = nodgtv;
207
			goto setbool;
208
		case OHI:
209
			a = nodhiv;
210
			goto setbool;
211
		case OHS:
212
			a = nodhsv;
213
			goto setbool;
214
		case OLO:
215
			a = nodlov;
216
			goto setbool;
217
		case OLS:
218
			a = nodlsv;
219
			goto setbool;
220
 
221
		case OANDAND:
222
		case OOROR:
223
			if(machcap(n))
224
				return 1;
225
 
226
			if(rv) {
227
				r = new(OFUNC, nodtestv, r);
228
				n->right = r;
229
				r->complex = FNX;
230
				r->op = OFUNC;
231
				r->type = types[TLONG];
232
			}
233
 
234
		case OCOND:
235
		case ONOT:
236
			if(machcap(n))
237
				return 1;
238
 
239
			l = new(OFUNC, nodtestv, l);
240
			n->left = l;
241
			l->complex = FNX;
242
			l->op = OFUNC;
243
			l->type = types[TLONG];
244
			n->complex = FNX;
245
			return 1;
246
		}
247
	}
248
 
249
	if(rv) {
250
		if(machcap(n))
251
			return 1;
252
		switch(n->op) {
253
		case OANDAND:
254
		case OOROR:
255
			r = new(OFUNC, nodtestv, r);
256
			n->right = r;
257
			r->complex = FNX;
258
			r->op = OFUNC;
259
			r->type = types[TLONG];
260
			return 1;
261
		case OCOND:
262
			return 1;
263
		}
264
	}
265
 
266
	if(typev[n->type->etype]) {
267
		if(machcap(n))
268
			return 1;
269
		switch(n->op) {
270
		default:
271
			diag(n, "unknown vlong %O", n->op);
272
		case OFUNC:
273
			n->complex = FNX;
274
		case ORETURN:
275
		case OAS:
276
		case OIND:
277
		case OLIST:
278
		case OCOMMA:
279
			return 1;
280
		case OADD:
281
			a = nodaddv;
282
			goto setbop;
283
		case OSUB:
284
			a = nodsubv;
285
			goto setbop;
286
		case OMUL:
287
		case OLMUL:
288
			a = nodmulv;
289
			goto setbop;
290
		case ODIV:
291
			a = noddivv;
292
			goto setbop;
293
		case OLDIV:
294
			a = noddivvu;
295
			goto setbop;
296
		case OMOD:
297
			a = nodmodv;
298
			goto setbop;
299
		case OLMOD:
300
			a = nodmodvu;
301
			goto setbop;
302
		case OASHL:
303
			a = nodlshv;
304
			goto setbop;
305
		case OASHR:
306
			a = nodrshav;
307
			goto setbop;
308
		case OLSHR:
309
			a = nodrshlv;
310
			goto setbop;
311
		case OAND:
312
			a = nodandv;
313
			goto setbop;
314
		case OOR:
315
			a = nodorv;
316
			goto setbop;
317
		case OXOR:
318
			a = nodxorv;
319
			goto setbop;
320
		case OPOSTINC:
321
			a = nodvpp;
322
			goto setvinc;
323
		case OPOSTDEC:
324
			a = nodvmm;
325
			goto setvinc;
326
		case OPREINC:
327
			a = nodppv;
328
			goto setvinc;
329
		case OPREDEC:
330
			a = nodmmv;
331
			goto setvinc;
332
		case ONEG:
333
			a = nodnegv;
334
			goto setfnx;
335
		case OCOM:
336
			a = nodcomv;
337
			goto setfnx;
338
		case OCAST:
339
			switch(l->type->etype) {
340
			case TCHAR:
341
				a = nodsc2v;
342
				goto setfnxl;
343
			case TUCHAR:
344
				a = noduc2v;
345
				goto setfnxl;
346
			case TSHORT:
347
				a = nodsh2v;
348
				goto setfnxl;
349
			case TUSHORT:
350
				a = noduh2v;
351
				goto setfnxl;
352
			case TINT:
353
				a = nodsi2v;
354
				goto setfnx;
355
			case TUINT:
356
				a = nodui2v;
357
				goto setfnx;
358
			case TLONG:
359
				a = nodsl2v;
360
				goto setfnx;
361
			case TULONG:
362
				a = nodul2v;
363
				goto setfnx;
364
			case TFLOAT:
365
				a = nodf2v;
366
				goto setfnx;
367
			case TDOUBLE:
368
				a = nodd2v;
369
				goto setfnx;
370
			case TIND:
371
				a = nodp2v;
372
				goto setfnx;
373
			}
374
			diag(n, "unknown %T->vlong cast", l->type);
375
			return 1;
376
		case OASADD:
377
			a = nodaddv;
378
			goto setasop;
379
		case OASSUB:
380
			a = nodsubv;
381
			goto setasop;
382
		case OASMUL:
383
		case OASLMUL:
384
			a = nodmulv;
385
			goto setasop;
386
		case OASDIV:
387
			a = noddivv;
388
			goto setasop;
389
		case OASLDIV:
390
			a = noddivvu;
391
			goto setasop;
392
		case OASMOD:
393
			a = nodmodv;
394
			goto setasop;
395
		case OASLMOD:
396
			a = nodmodvu;
397
			goto setasop;
398
		case OASASHL:
399
			a = nodlshv;
400
			goto setasop;
401
		case OASASHR:
402
			a = nodrshav;
403
			goto setasop;
404
		case OASLSHR:
405
			a = nodrshlv;
406
			goto setasop;
407
		case OASAND:
408
			a = nodandv;
409
			goto setasop;
410
		case OASOR:
411
			a = nodorv;
412
			goto setasop;
413
		case OASXOR:
414
			a = nodxorv;
415
			goto setasop;
416
		}
417
	}
418
 
419
	if(typefd[n->type->etype] && l && l->op == OFUNC) {
420
		switch(n->op) {
421
		case OASADD:
422
		case OASSUB:
423
		case OASMUL:
424
		case OASLMUL:
425
		case OASDIV:
426
		case OASLDIV:
427
		case OASMOD:
428
		case OASLMOD:
429
		case OASASHL:
430
		case OASASHR:
431
		case OASLSHR:
432
		case OASAND:
433
		case OASOR:
434
		case OASXOR:
435
			if(l->right && typev[l->right->etype]) {
436
				diag(n, "sorry float <asop> vlong not implemented\n");
437
			}
438
		}
439
	}
440
 
441
	if(n->op == OCAST) {
442
		if(l->type && typev[l->type->etype]) {
443
			if(machcap(n))
444
				return 1;
445
			switch(n->type->etype) {
446
			case TDOUBLE:
447
				a = nodv2d;
448
				goto setfnx;
449
			case TFLOAT:
450
				a = nodv2f;
451
				goto setfnx;
452
			case TLONG:
453
				a = nodv2sl;
454
				goto setfnx;
455
			case TULONG:
456
				a = nodv2ul;
457
				goto setfnx;
458
			case TINT:
459
				a = nodv2si;
460
				goto setfnx;
461
			case TUINT:
462
				a = nodv2ui;
463
				goto setfnx;
464
			case TSHORT:
465
				a = nodv2sh;
466
				goto setfnx;
467
			case TUSHORT:
468
				a = nodv2uh;
469
				goto setfnx;
470
			case TCHAR:
471
				a = nodv2sc;
472
				goto setfnx;
473
			case TUCHAR:
474
				a = nodv2uc;
475
				goto setfnx;
476
			case TIND:	// small pun here
477
				a = nodv2ul;
478
				goto setfnx;
479
			}
480
			diag(n, "unknown vlong->%T cast", n->type);
481
			return 1;
482
		}
483
	}
484
 
485
	return 0;
486
 
487
setbop:
488
	n->left = a;
489
	n->right = new(OLIST, l, r);
490
	n->complex = FNX;
491
	n->op = OFUNC;
492
	return 1;
493
 
494
setfnxl:
495
	l = new(OCAST, l, 0);
496
	l->type = types[TLONG];
497
	l->complex = l->left->complex;
498
 
499
setfnx:
500
	n->left = a;
501
	n->right = l;
502
	n->complex = FNX;
503
	n->op = OFUNC;
504
	return 1;
505
 
506
setvinc:
507
	n->left = a;
508
	l = new(OADDR, l, Z);
509
	l->type = typ(TIND, l->left->type);
510
	l->complex = l->left->complex;
511
	n->right = new(OLIST, l, r);
512
	n->complex = FNX;
513
	n->op = OFUNC;
514
	return 1;
515
 
516
setbool:
517
	if(machcap(n))
518
		return 1;
519
	n->left = a;
520
	n->right = new(OLIST, l, r);
521
	n->complex = FNX;
522
	n->op = OFUNC;
523
	n->type = types[TLONG];
524
	return 1;
525
 
526
setasop:
527
	if(l->op == OFUNC) {
528
		l = l->right;
529
		goto setasop;
530
	}
531
 
532
	t = new(OCONST, 0, 0);
533
	t->vconst = etconv[l->type->etype];
534
	t->type = types[TLONG];
535
	t->addable = 20;
536
	r = new(OLIST, t, r);
537
 
538
	t = new(OADDR, a, 0);
539
	t->type = typ(TIND, a->type);
540
	r = new(OLIST, t, r);
541
 
542
	t = new(OADDR, l, 0);
543
	t->type = typ(TIND, l->type);
544
	t->complex = l->complex;
545
	r = new(OLIST, t, r);
546
 
547
	n->left = nodvasop;
548
	n->right = r;
549
	n->complex = FNX;
550
	n->op = OFUNC;
551
 
552
	return 1;
553
}
554
 
555
void
556
bool64(Node *n)
557
{
558
	Node *n1;
559
 
560
	if(machcap(Z))
561
		return;
562
	if(typev[n->type->etype]) {
563
		n1 = new(OXXX, 0, 0);
564
		*n1 = *n;
565
 
566
		n->right = n1;
567
		n->left = nodtestv;
568
		n->complex = FNX;
569
		n->addable = 0;
570
		n->op = OFUNC;
571
		n->type = types[TLONG];
572
	}
573
}
574
 
575
/*
576
 * more machine depend stuff.
577
 * this is common for 8,16,32,64 bit machines.
578
 * this is common for ieee machines.
579
 */
580
double
581
convvtof(vlong v)
582
{
583
	double d;
584
 
585
	d = v;		/* BOTCH */
586
	return d;
587
}
588
 
589
vlong
590
convftov(double d)
591
{
592
	vlong v;
593
 
594
 
595
	v = d;		/* BOTCH */
596
	return v;
597
}
598
 
599
double
600
convftox(double d, int et)
601
{
602
 
603
	if(!typefd[et])
604
		diag(Z, "bad type in castftox %s", tnames[et]);
605
	return d;
606
}
607
 
608
vlong
609
convvtox(vlong c, int et)
610
{
611
	int n;
612
 
613
	n = 8 * ewidth[et];
614
	c &= MASK(n);
615
	if(!typeu[et])
616
		if(c & SIGN(n))
617
			c |= ~MASK(n);
618
	return c;
619
}