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 <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <mach.h>
5
#define Extern extern
6
#include "sparc.h"
7
 
8
void add(ulong);
9
void and(ulong);
10
void or(ulong);
11
void xor(ulong);
12
void sub(ulong);
13
void andn(ulong);
14
void xnor(ulong);
15
void subcc(ulong);
16
void sll(ulong);
17
void srl(ulong);
18
void sra(ulong);
19
void jmpl(ulong);
20
void andcc(ulong);
21
void xorcc(ulong);
22
void andncc(ulong);
23
void wry(ulong);
24
void rdy(ulong);
25
void mulscc(ulong);
26
void fcmp(ulong);
27
void farith(ulong);
28
void addcc(ulong);
29
void addx(ulong);
30
void addxcc(ulong);
31
void orcc(ulong);
32
void orncc(ulong);
33
void xnorcc(ulong);
34
void orn(ulong);
35
 
36
Inst op2[] = {
37
	{ add,		"add",	Iarith },
38
	{ and,		"and",	Iarith },
39
	{ or,		"or",	Iarith },
40
	{ xor,		"xor",	Iarith },
41
	{ sub,		"sub",	Iarith },
42
	{ andn,		"andn", Iarith },
43
	{ orn,		"orn",	Inop },
44
	{ xnor,		"xnor", Iarith },
45
	{ addx,		"addx", Iarith },
46
	{ undef,	"" },
47
	{ undef,	"" },
48
	{ undef,	"" },
49
	{ undef,	"" },
50
	{ undef,	"" },
51
	{ undef,	"" },
52
	{ undef,	"" },
53
	{ addcc, 	"addcc", Iarith },
54
	{ andcc, 	"andcc", Iarith },
55
	{ orcc,	 	"orcc",  Iarith },
56
	{ xorcc, 	"xorcc", Iarith },
57
	{ subcc, 	"subcc", Iarith },
58
	{ andncc,	"andncc",Iarith },
59
	{ orncc, 	"orncc", Iarith },
60
	{ xnorcc,	"xnorcc",Iarith },
61
	{ addxcc,	"addxcc",Iarith },
62
	{ undef,	"" },
63
	{ undef,	"" },
64
	{ undef,	"" },
65
	{ undef,	"" },
66
	{ undef,	"" },
67
	{ undef,	"" },
68
	{ undef,	"" },
69
	{ undef,	"" },
70
	{ undef,	"" },
71
	{ undef,	"" },
72
	{ undef,	"" },
73
	{ mulscc,	"mulscc", Iarith },
74
	{ sll,		"sll",	Iarith },
75
	{ srl,		"srl",	Iarith },
76
	{ sra,		"sra",	Iarith },
77
	{ rdy,		"rdy",	Ireg },
78
	{ undef,	"" },
79
	{ undef,	"" },
80
	{ undef,	"" },
81
	{ undef,	"" },
82
	{ undef,	"" },
83
	{ undef,	"" },
84
	{ undef,	"" },
85
	{ wry,		"wry",	Ireg },
86
	{ undef,	"" },
87
	{ undef,	"" },
88
	{ undef,	"" },
89
	{ farith,	"farith", Ifloat },
90
	{ fcmp,		"fcmp", Ifloat },
91
	{ undef,	"" },
92
	{ undef,	"" },
93
	{ jmpl,		"jmpl", Ibranch },
94
	{ undef,	"" },
95
	{ ta,		"ta",	Isyscall },
96
	{ undef,	"" },
97
	{ undef,	"" },
98
	{ undef,	"" },
99
	{ undef,	"" },
100
	{ undef,	"" },
101
	{ 0 }
102
};
103
 
104
void st(ulong);
105
void stb(ulong);
106
void sth(ulong);
107
void ld(ulong);
108
void ldub(ulong);
109
void ldsb(ulong);
110
void lduh(ulong);
111
void stf(ulong);
112
void ldf(ulong);
113
void ldsh(ulong);
114
void std(ulong);
115
void ldd(ulong);
116
void ldstub(ulong);
117
void swap(ulong);
118
void lddf(ulong);
119
void stdf(ulong);
120
 
121
Inst op3[] = {
122
	{ ld,		"ld",	Iload },
123
	{ ldub,		"ldub",	Iload },
124
	{ lduh,		"lduh",	Iload },
125
	{ ldd,		"ldd",	Iload },
126
	{ st,		"st",	Istore },
127
	{ stb,		"stb",	Istore },
128
	{ sth,		"sth",	Istore },
129
	{ std,		"std",	Istore },
130
	{ undef,	"" },
131
	{ ldsb,		"ldsb",	Iload },
132
	{ ldsh,		"ldsh", Iload },
133
	{ undef,	"" },
134
	{ undef,	"" },
135
	{ ldstub,	"ldstub", Iload },
136
	{ undef,	"" },
137
	{ swap,		"swap",	Iload },
138
	{ undef,	"" },
139
	{ undef,	"" },
140
	{ undef,	"" },
141
	{ undef,	"" },
142
	{ undef,	"" },
143
	{ undef,	"" },
144
	{ undef,	"" },
145
	{ undef,	"" },
146
	{ undef,	"" },
147
	{ undef,	"" },
148
	{ undef,	"" },
149
	{ undef,	"" },
150
	{ undef,	"" },
151
	{ undef,	"" },
152
	{ undef,	"" },
153
	{ undef,	"" },
154
	{ ldf,		"ldf",	Ifloat },
155
	{ undef,	"" },
156
	{ undef,	"" },
157
	{ lddf,		"lddf", Ifloat },
158
	{ stf,		"stf",	Ifloat },
159
	{ undef,	"" },
160
	{ undef,	"" },
161
	{ stdf,		"stdf",	Ifloat },
162
	{ undef,	"" },
163
	{ undef,	"" },
164
	{ undef,	"" },
165
	{ undef,	"" },
166
	{ undef,	"" },
167
	{ undef,	"" },
168
	{ undef,	"" },
169
	{ undef,	"" },
170
	{ undef,	"" },
171
	{ undef,	"" },
172
	{ undef,	"" },
173
	{ undef,	"" },
174
	{ undef,	"" },
175
	{ undef,	"" },
176
	{ undef,	"" },
177
	{ undef,	"" },
178
	{ undef,	"" },
179
	{ undef,	"" },
180
	{ undef,	"" },
181
	{ undef,	"" },
182
	{ undef,	"" },
183
	{ undef,	"" },
184
	{ undef,	"" },
185
	{ undef,	"" },
186
	{ 0 }
187
};
188
 
189
void sethi(ulong);
190
void bicc(ulong);
191
void fbcc(ulong);
192
void call(ulong);
193
 
194
Inst op0[] = {
195
	{ undef,	"" },
196
	{ undef,	"" },
197
	{ bicc,		"bicc",	Ibranch },
198
	{ undef,	"" },
199
	{ sethi,	"sethi",Iarith },
200
	{ undef,	"" },
201
	{ fbcc,		"fbcc",	Ibranch },
202
	{ undef,	"" },
203
	/* This is a fake and connot be reached by op0 decode */
204
	{ call,		"call", Ibranch },
205
	{ 0 }
206
};
207
 
208
void call(ulong);
209
 
210
void
211
run(void)
212
{
213
	do {
214
		reg.r[0] = 0;
215
		reg.ir = ifetch(reg.pc);
216
		switch(reg.ir>>30) {
217
		case 0:
218
			ci = &op0[(reg.ir>>22)&0x07];
219
			ci->count++;
220
			(*ci->func)(reg.ir);
221
			break;
222
		case 1:
223
			ci = &op0[8];
224
			ci->count++;
225
			call(reg.ir);
226
			break;
227
		case 2:
228
			ci = &op2[(reg.ir>>19)&0x3f];
229
			ci->count++;
230
			(*ci->func)(reg.ir);
231
			break;
232
		case 3:
233
			ci = &op3[(reg.ir>>19)&0x3f];
234
			ci->count++;
235
			(*ci->func)(reg.ir);
236
			break;
237
		}
238
		reg.pc += 4;
239
		if(bplist)
240
			brkchk(reg.pc, Instruction);
241
	}while(--count);
242
}
243
 
244
void
245
ilock(int rd)
246
{
247
	ulong ir;
248
 
249
	ir = getmem_4(reg.pc+4);
250
	switch(ir>>30) {
251
	case 0:
252
	case 1:
253
		break;
254
	case 2:
255
		if(((ir>>20)&0x1f) == 0x1a)		/* floating point */
256
			break;
257
	case 3:
258
		if(rd == ((ir>>14)&0x1f)) {
259
			loadlock++;
260
			break;
261
		}
262
		if(ir&IMMBIT)
263
			break;
264
		if(rd == (ir&0x1f))
265
			loadlock++;
266
		break;
267
	}
268
}
269
 
270
void
271
delay(ulong npc)
272
{
273
	ulong opc;
274
 
275
	reg.r[0] = 0;
276
	if(reg.ir != NOP)
277
		ci->useddelay++;
278
	switch(reg.ir>>30) {
279
	case 0:
280
		ci = &op0[(reg.ir>>22)&0x07];
281
		ci->count++;
282
		(*ci->func)(reg.ir);
283
		break;
284
	case 1:
285
		ci = &op0[8];
286
		ci->count++;
287
		call(reg.ir);
288
		break;
289
	case 2:
290
		ci = &op2[(reg.ir>>19)&0x3f];
291
		ci->count++;
292
		opc = reg.pc;
293
		reg.pc = npc-4;
294
		(*ci->func)(reg.ir);
295
		reg.pc = opc;
296
		break;
297
	case 3:
298
		ci = &op3[(reg.ir>>19)&0x3f];
299
		ci->count++;
300
		opc = reg.pc;
301
		reg.pc = npc-4;
302
		(*ci->func)(reg.ir);
303
		reg.pc = opc;
304
		break;
305
	}
306
}
307
 
308
void
309
undef(ulong ir)
310
{
311
/*	Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */
312
	Bprint(bioout, "illegal_instruction IR #%.8lux\n", ir);
313
	longjmp(errjmp, 0);
314
}
315
 
316
void
317
sub(ulong ir)
318
{
319
	long v;
320
	int rd, rs1, rs2;
321
 
322
	getrop23(ir);
323
	if(ir&IMMBIT) {
324
		ximm(v, ir);
325
		if(trace)
326
			itrace("sub\tr%d,#0x%x,r%d", rs1, v, rd);
327
	}
328
	else {
329
		v = reg.r[rs2];
330
		if(trace)
331
			itrace("sub\tr%d,r%d,r%d", rs1, rs2, rd);
332
	}
333
	reg.r[rd] = reg.r[rs1] - v;
334
}
335
 
336
void
337
sll(ulong ir)
338
{
339
	long v;
340
	int rd, rs1, rs2;
341
 
342
	getrop23(ir);
343
	if(ir&IMMBIT) {
344
		ximm(v, ir);
345
		if(trace)
346
			itrace("sll\tr%d,#0x%x,r%d", rs1, v, rd);
347
	}
348
	else {
349
		v = reg.r[rs2]&0x1F;
350
		if(trace)
351
			itrace("sll\tr%d,r%d,r%d", rs1, rs2, rd);
352
	}
353
	reg.r[rd] = reg.r[rs1] << v;
354
}
355
 
356
void
357
srl(ulong ir)
358
{
359
	long v;
360
	int rd, rs1, rs2;
361
 
362
	getrop23(ir);
363
	if(ir&IMMBIT) {
364
		ximm(v, ir);
365
		if(trace)
366
			itrace("srl\tr%d,#0x%x,r%d", rs1, v, rd);
367
	}
368
	else {
369
		v = reg.r[rs2];
370
		if(trace)
371
			itrace("srl\tr%d,r%d,r%d", rs1, rs2, rd);
372
	}
373
	reg.r[rd] = (ulong)reg.r[rs1] >> v;
374
}
375
 
376
void
377
sra(ulong ir)
378
{
379
	long v;
380
	int rd, rs1, rs2;
381
 
382
	getrop23(ir);
383
	if(ir&IMMBIT) {
384
		ximm(v, ir);
385
		if(trace)
386
			itrace("sra\tr%d,#0x%x,r%d", rs1, v, rd);
387
	}
388
	else {
389
		v = reg.r[rs2];
390
		if(trace)
391
			itrace("sra\tr%d,r%d,r%d", rs1, rs2, rd);
392
	}
393
	if(reg.r[rs1]&SIGNBIT)
394
		reg.r[rd] = reg.r[rs1]>>v | ~((1<<(32-v))-1);
395
	else
396
		reg.r[rd] = reg.r[rs1]>>v;
397
}
398
 
399
void
400
subcc(ulong ir)
401
{
402
	long v;
403
	int b31rs1, b31op2, b31res, r, rd, rs1, rs2;
404
 
405
	getrop23(ir);
406
	if(ir&IMMBIT) {
407
		ximm(v, ir);
408
		if(trace)
409
			itrace("subcc\tr%d,#0x%x,r%d", rs1, v, rd);
410
	}
411
	else {
412
		v = reg.r[rs2];
413
		if(trace)
414
			itrace("subcc\tr%d,r%d,r%d", rs1, rs2, rd);
415
	}
416
	r = reg.r[rs1] - v;
417
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
418
	if(r == 0)
419
		reg.psr |= PSR_z;
420
	if(r < 0)
421
		reg.psr |= PSR_n;
422
 
423
	b31rs1 = reg.r[rs1]>>31;
424
	b31op2 = v>>31;
425
	b31res = r>>31;
426
 
427
	if((b31rs1 & ~b31op2 & ~b31res)|(~b31rs1 & b31op2 & b31res))
428
		reg.psr |= PSR_v;
429
 
430
	if((~b31rs1 & b31op2)|(b31res & (~b31rs1|b31op2)))
431
		reg.psr |= PSR_c;
432
 
433
	reg.r[rd] = r;
434
 
435
}
436
 
437
void
438
add(ulong ir)
439
{
440
	long v;
441
	int rd, rs1, rs2;
442
 
443
	getrop23(ir);
444
	if(ir&IMMBIT) {
445
		ximm(v, ir);
446
		if(trace)
447
			itrace("add\tr%d,#0x%x,r%d", rs1, v, rd);
448
	}
449
	else {
450
		v = reg.r[rs2];
451
		if(trace)
452
			itrace("add\tr%d,r%d,r%d", rs1, rs2, rd);
453
	}
454
	reg.r[rd] = reg.r[rs1] + v;
455
}
456
 
457
void
458
addcc(ulong ir)
459
{
460
	long v, r;
461
	int rd, rs1, rs2, b31rs1, b31op2, b31r;
462
 
463
	getrop23(ir);
464
	if(ir&IMMBIT) {
465
		ximm(v, ir);
466
		if(trace)
467
			itrace("addcc\tr%d,#0x%x,r%d", rs1, v, rd);
468
	}
469
	else {
470
		v = reg.r[rs2];
471
		if(trace)
472
			itrace("addcc\tr%d,r%d,r%d", rs1, rs2, rd);
473
	}
474
	r = reg.r[rs1] + v;
475
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
476
	if(r == 0)
477
		reg.psr |= PSR_z;
478
	if(r < 0)
479
		reg.psr |= PSR_n;
480
 
481
	b31rs1 = reg.r[rs1]>>31;
482
	b31op2 = v>>31;
483
	b31r = r>>31;
484
	if((b31rs1 & b31op2 & ~b31r)|(~b31rs1 & ~b31op2 & b31r))
485
		reg.psr |= PSR_v;
486
	if((b31rs1 & b31op2) | (~b31r & (b31rs1 | b31op2)))
487
		reg.psr |= PSR_c;
488
 
489
	reg.r[rd] = r;
490
}
491
 
492
void
493
addx(ulong ir)
494
{
495
	long v;
496
	int rd, rs1, rs2;
497
 
498
	getrop23(ir);
499
	if(ir&IMMBIT) {
500
		ximm(v, ir);
501
		if(trace)
502
			itrace("addx\tr%d,#0x%x,r%d", rs1, v, rd);
503
	}
504
	else {
505
		v = reg.r[rs2];
506
		if(trace)
507
			itrace("addx\tr%d,r%d,r%d", rs1, rs2, rd);
508
	}
509
	if(reg.psr&PSR_c)
510
		v++;
511
	reg.r[rd] = reg.r[rs1] + v;
512
}
513
 
514
void
515
addxcc(ulong ir)
516
{
517
	long r, v;
518
	int rd, rs1, rs2, b31rs1, b31op2, b31r;
519
 
520
	getrop23(ir);
521
	if(ir&IMMBIT) {
522
		ximm(v, ir);
523
		if(trace)
524
			itrace("addxcc\tr%d,#0x%x,r%d", rs1, v, rd);
525
	}
526
	else {
527
		v = reg.r[rs2];
528
		if(trace)
529
			itrace("addxcc\tr%d,r%d,r%d", rs1, rs2, rd);
530
	}
531
	if(reg.psr&PSR_c)
532
		v++;
533
 
534
	r = reg.r[rs1] + v;
535
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
536
	if(r == 0)
537
		reg.psr |= PSR_z;
538
	if(r < 0)
539
		reg.psr |= PSR_n;
540
 
541
	b31rs1 = reg.r[rs1]>>31;
542
	b31op2 = v>>31;
543
	b31r = r>>31;
544
	if((b31rs1 & b31op2 & ~b31r)|(~b31rs1 & ~b31op2 & b31r))
545
		reg.psr |= PSR_v;
546
	if((b31rs1 & b31op2) | (~b31r & (b31rs1 | b31op2)))
547
		reg.psr |= PSR_c;
548
 
549
	reg.r[rd] = r;
550
}
551
 
552
void
553
wry(ulong ir)
554
{
555
	long v;
556
	int rd, rs1, rs2;
557
 
558
	getrop23(ir);
559
	if(rd != 0)
560
		undef(ir);
561
	if(ir&IMMBIT) {
562
		ximm(v, ir);
563
		if(trace)
564
			itrace("wry\tr%d,#0x%x,Y", rs1, v);
565
	}
566
	else {
567
		v = reg.r[rs2];
568
		if(trace)
569
			itrace("wry\tr%d,r%d,Y", rs1, rs2);
570
	}
571
	reg.Y = reg.r[rs1] + v;
572
}
573
 
574
void
575
rdy(ulong ir)
576
{
577
	int rd, rs1, rs2;
578
 
579
	getrop23(ir);
580
	USED(rs2);
581
	if(rs1 != 0)
582
		undef(ir);
583
 
584
	if(trace)
585
		itrace("rdy\tY,r%d", rd);
586
 
587
	reg.r[rd] = reg.Y;
588
}
589
 
590
void
591
and(ulong ir)
592
{
593
	long v;
594
	int rd, rs1, rs2;
595
 
596
	getrop23(ir);
597
	if(ir&IMMBIT) {
598
		ximm(v, ir);
599
		if(trace)
600
			itrace("and\tr%d,#0x%x,r%d", rs1, v, rd);
601
	}
602
	else {
603
		v = reg.r[rs2];
604
		if(trace)
605
			itrace("and\tr%d,r%d,r%d", rs1, rs2, rd);
606
	}
607
	reg.r[rd] = reg.r[rs1] & v;
608
}
609
 
610
void
611
andcc(ulong ir)
612
{
613
	long v, r;
614
	int rd, rs1, rs2;
615
 
616
	getrop23(ir);
617
	if(ir&IMMBIT) {
618
		ximm(v, ir);
619
		if(trace)
620
			itrace("andcc\tr%d,#0x%x,r%d", rs1, v, rd);
621
	}
622
	else {
623
		v = reg.r[rs2];
624
		if(trace)
625
			itrace("andcc\tr%d,r%d,r%d", rs1, rs2, rd);
626
	}
627
	r = reg.r[rs1] & v;
628
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
629
	if(r == 0)
630
		reg.psr |= PSR_z;
631
	if(r < 0)
632
		reg.psr |= PSR_n;
633
 
634
	reg.r[rd] = r;
635
}
636
 
637
void
638
orcc(ulong ir)
639
{
640
	long v, r;
641
	int rd, rs1, rs2;
642
 
643
	getrop23(ir);
644
	if(ir&IMMBIT) {
645
		ximm(v, ir);
646
		if(trace)
647
			itrace("orcc\tr%d,#0x%x,r%d", rs1, v, rd);
648
	}
649
	else {
650
		v = reg.r[rs2];
651
		if(trace)
652
			itrace("orcc\tr%d,r%d,r%d", rs1, rs2, rd);
653
	}
654
	r = reg.r[rs1] | v;
655
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
656
	if(r == 0)
657
		reg.psr |= PSR_z;
658
	if(r < 0)
659
		reg.psr |= PSR_n;
660
 
661
	reg.r[rd] = r;
662
}
663
 
664
void
665
mulscc(ulong ir)
666
{
667
	int b, n, v, rd, rs1, rs2;
668
	long o1, o2, r, b31o1, b31o2, b31r;
669
 
670
	getrop23(ir);
671
	if(ir&IMMBIT) {
672
		ximm(o2, ir);
673
		if(trace)
674
			itrace("mulscc\tr%d,#0x%x,r%d", rs1, o2, rd);
675
	}
676
	else {
677
		o2 = reg.r[rs2];
678
		if(trace)
679
			itrace("mulscc\tr%d,r%d,r%d", rs1, rs2, rd);
680
	}
681
	o1 = reg.r[rs1]>>1;
682
	n = reg.psr&PSR_n ? 1 : 0;
683
	v = reg.psr&PSR_v ? 1 : 0;
684
 
685
	o1 |= (n ^ v)<<31;
686
	if((reg.Y&1) == 0)
687
		o2 = 0;
688
 
689
	r = o1 + o2;
690
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
691
	if(r == 0)
692
		reg.psr |= PSR_z;
693
	if(r < 0)
694
		reg.psr |= PSR_n;
695
 
696
	b31o1 = o1>>31;
697
	b31o2 = o2>>31;
698
	b31r = r>>31;
699
	if((b31o1 & b31o2 & ~b31r) | (~b31o1 & ~b31o2 & b31r))
700
		reg.psr |= PSR_v;
701
	if((b31o1 & b31o2) | (~b31r & (b31o1 | b31o2)))		
702
		reg.psr |= PSR_c;
703
 
704
	b = reg.r[rs1]&1;
705
	reg.Y = (reg.Y>>1)|(b<<31);
706
	reg.r[rd] = r;
707
}
708
 
709
void
710
or(ulong ir)
711
{
712
	long v;
713
	int rd, rs1, rs2;
714
 
715
	getrop23(ir);
716
	if(ir&IMMBIT) {
717
		ximm(v, ir);
718
		if(trace)
719
			itrace("or\tr%d,#0x%x,r%d", rs1, v, rd);
720
	}
721
	else {
722
		v = reg.r[rs2];
723
		if(trace)
724
			itrace("or\tr%d,r%d,r%d", rs1, rs2, rd);
725
	}
726
	reg.r[rd] = reg.r[rs1] | v;
727
}
728
 
729
void
730
xor(ulong ir)
731
{
732
	long v;
733
	int rd, rs1, rs2;
734
 
735
	getrop23(ir);
736
	if(ir&IMMBIT) {
737
		ximm(v, ir);
738
		if(trace)
739
			itrace("xor\tr%d,#0x%x,r%d", rs1, v, rd);
740
	}
741
	else {
742
		v = reg.r[rs2];
743
		if(trace)
744
			itrace("xor\tr%d,r%d,r%d", rs1, rs2, rd);
745
	}
746
	reg.r[rd] = reg.r[rs1] ^ v;
747
}
748
 
749
void
750
xorcc(ulong ir)
751
{
752
	long v, r;
753
	int rd, rs1, rs2;
754
 
755
	getrop23(ir);
756
	if(ir&IMMBIT) {
757
		ximm(v, ir);
758
		if(trace)
759
			itrace("xorcc\tr%d,#0x%x,r%d", rs1, v, rd);
760
	}
761
	else {
762
		v = reg.r[rs2];
763
		if(trace)
764
			itrace("xorcc\tr%d,r%d,r%d", rs1, rs2, rd);
765
	}
766
	r = reg.r[rs1] ^ v;
767
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
768
	if(r == 0)
769
		reg.psr |= PSR_z;
770
	if(r < 0)
771
		reg.psr |= PSR_n;
772
 
773
	reg.r[rd] = r;
774
}
775
 
776
void
777
andn(ulong ir)
778
{
779
	long v;
780
	int rd, rs1, rs2;
781
 
782
	getrop23(ir);
783
	if(ir&IMMBIT) {
784
		ximm(v, ir);
785
		if(trace)
786
			itrace("andn\tr%d,#0x%x,r%d", rs1, v, rd);
787
	}
788
	else {
789
		v = reg.r[rs2];
790
		if(trace)
791
			itrace("andn\tr%d,r%d,r%d", rs1, rs2, rd);
792
	}
793
	reg.r[rd] = reg.r[rs1] & ~v;
794
}
795
 
796
void
797
andncc(ulong ir)
798
{
799
	long v, r;
800
	int rd, rs1, rs2;
801
 
802
	getrop23(ir);
803
	if(ir&IMMBIT) {
804
		ximm(v, ir);
805
		if(trace)
806
			itrace("andncc\tr%d,#0x%x,r%d", rs1, v, rd);
807
	}
808
	else {
809
		v = reg.r[rs2];
810
		if(trace)
811
			itrace("andncc\tr%d,r%d,r%d", rs1, rs2, rd);
812
	}
813
	r = reg.r[rs1] & ~v;
814
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
815
	if(r == 0)
816
		reg.psr |= PSR_z;
817
	if(r < 0)
818
		reg.psr |= PSR_n;
819
 
820
	reg.r[rd] = r;
821
}
822
 
823
void
824
orn(ulong ir)
825
{
826
	long v;
827
	int rd, rs1, rs2;
828
 
829
	getrop23(ir);
830
	if(rd == 0 && rs1 == 0)	/* ken used orn r0,r0,r0 as nop */
831
		nopcount++;
832
 
833
	if(ir&IMMBIT) {
834
		ximm(v, ir);
835
		if(trace)
836
			itrace("orn\tr%d,#0x%x,r%d", rs1, v, rd);
837
	}
838
	else {
839
		v = reg.r[rs2];
840
		if(trace)
841
			itrace("orn\tr%d,r%d,r%d", rs1, rs2, rd);
842
	}
843
	reg.r[rd] = reg.r[rs1] | ~v;
844
}
845
 
846
void
847
orncc(ulong ir)
848
{
849
	long r, v;
850
	int rd, rs1, rs2;
851
 
852
	getrop23(ir);
853
	if(ir&IMMBIT) {
854
		ximm(v, ir);
855
		if(trace)
856
			itrace("orncc\tr%d,#0x%x,r%d", rs1, v, rd);
857
	}
858
	else {
859
		v = reg.r[rs2];
860
		if(trace)
861
			itrace("orncc\tr%d,r%d,r%d", rs1, rs2, rd);
862
	}
863
	r = reg.r[rs1] | ~v;
864
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
865
	if(r == 0)
866
		reg.psr |= PSR_z;
867
	if(r < 0)
868
		reg.psr |= PSR_n;
869
 
870
	reg.r[rd] = r;
871
}
872
 
873
void
874
xnor(ulong ir)
875
{
876
	long v;
877
	int rd, rs1, rs2;
878
 
879
	getrop23(ir);
880
	if(ir&IMMBIT) {
881
		ximm(v, ir);
882
		if(trace)
883
			itrace("xnor\tr%d,#0x%x,r%d", rs1, v, rd);
884
	}
885
	else {
886
		v = reg.r[rs2];
887
		if(trace)
888
			itrace("xnor\tr%d,r%d,r%d", rs1, rs2, rd);
889
	}
890
	reg.r[rd] = reg.r[rs1] ^ ~v;
891
}
892
 
893
void
894
xnorcc(ulong ir)
895
{
896
	long v, r;
897
	int rd, rs1, rs2;
898
 
899
	getrop23(ir);
900
	if(ir&IMMBIT) {
901
		ximm(v, ir);
902
		if(trace)
903
			itrace("xnorcc\tr%d,#0x%x,r%d", rs1, v, rd);
904
	}
905
	else {
906
		v = reg.r[rs2];
907
		if(trace)
908
			itrace("xnorcc\tr%d,r%d,r%d", rs1, rs2, rd);
909
	}
910
	r = reg.r[rs1] ^ ~v;
911
	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
912
	if(r == 0)
913
		reg.psr |= PSR_z;
914
	if(r < 0)
915
		reg.psr |= PSR_n;
916
 
917
	reg.r[rd] = r;
918
}
919
 
920
void
921
st(ulong ir)
922
{
923
	ulong ea;
924
	int rd, rs1, rs2;
925
 
926
	getrop23(ir);
927
	if(ir&IMMBIT) {
928
		ximm(ea, ir);
929
		if(trace)
930
			itrace("st\tr%d,0x%lux(r%d) %lux=%lux",
931
					rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]);
932
		ea += reg.r[rs1];
933
	}
934
	else {
935
		ea = reg.r[rs1] + reg.r[rs2];
936
		if(trace)
937
			itrace("st\tr%d,[r%d+r%d] %lux=%lux",
938
					rd, rs1, rs2, ea, reg.r[rd]);
939
	}
940
 
941
	putmem_w(ea, reg.r[rd]);
942
}
943
 
944
void
945
std(ulong ir)
946
{
947
	ulong ea;
948
	int rd, rs1, rs2;
949
 
950
	getrop23(ir);
951
	if(ir&IMMBIT) {
952
		ximm(ea, ir);
953
		if(trace)
954
			itrace("std\tr%d,0x%lux(r%d) %lux=%lux",
955
					rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]);
956
		ea += reg.r[rs1];
957
	}
958
	else {
959
		ea = reg.r[rs1] + reg.r[rs2];
960
		if(trace)
961
			itrace("std\tr%d,[r%d+r%d] %lux=%lux",
962
					rd, rs1, rs2, ea, reg.r[rd]);
963
	}
964
 
965
	putmem_w(ea, reg.r[rd]);
966
	putmem_w(ea+4, reg.r[rd+1]);
967
}
968
 
969
void
970
stb(ulong ir)
971
{
972
	ulong ea;
973
	int rd, rs1, rs2;
974
 
975
	getrop23(ir);
976
	if(ir&IMMBIT) {
977
		ximm(ea, ir);
978
		if(trace)
979
			itrace("stb\tr%d,0x%lux(r%d) %lux=%lux",
980
					rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]&0xff);
981
		ea += reg.r[rs1];
982
	}
983
	else {
984
		ea = reg.r[rs1] + reg.r[rs2];
985
		if(trace)
986
			itrace("stb\tr%d,[r%d+r%d] %lux=%lux",
987
					rd, rs1, rs2, ea, reg.r[rd]&0xff);
988
	}
989
 
990
	putmem_b(ea, reg.r[rd]);
991
}
992
 
993
void
994
sth(ulong ir)
995
{
996
	ulong ea;
997
	int rd, rs1, rs2;
998
 
999
	getrop23(ir);
1000
	if(ir&IMMBIT) {
1001
		ximm(ea, ir);
1002
		if(trace)
1003
			itrace("sth\tr%d,0x%lux(r%d) %lux=%lux",
1004
					rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]&0xffff);
1005
		ea += reg.r[rs1];
1006
	}
1007
	else {
1008
		ea = reg.r[rs1] + reg.r[rs2];
1009
		if(trace)
1010
			itrace("sth\tr%d,[r%d+r%d] %lux=%lux",
1011
					rd, rs1, rs2, ea, reg.r[rd]&0xffff);
1012
	}
1013
 
1014
	putmem_h(ea, reg.r[rd]);
1015
}
1016
 
1017
void
1018
ld(ulong ir)
1019
{
1020
	ulong ea;
1021
	int rd, rs1, rs2;
1022
 
1023
	getrop23(ir);
1024
	if(ir&IMMBIT) {
1025
		ximm(ea, ir);
1026
		if(trace)
1027
			itrace("ld\tr%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
1028
		ea += reg.r[rs1];
1029
	}
1030
	else {
1031
		ea = reg.r[rs1] + reg.r[rs2];
1032
		if(trace)
1033
			itrace("ld\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1034
	}
1035
 
1036
	reg.r[rd] = getmem_w(ea);
1037
	ilock(rd);
1038
}
1039
 
1040
void
1041
swap(ulong ir)
1042
{
1043
	ulong t, ea;
1044
	int rd, rs1, rs2;
1045
 
1046
	getrop23(ir);
1047
	if(ir&IMMBIT) {
1048
		ximm(ea, ir);
1049
		if(trace)
1050
			itrace("swap\tr%d,0x%lux(r%d) ea=%lux",
1051
						rd, ea, rs1, ea+reg.r[rs1]);
1052
		ea += reg.r[rs1];
1053
	}
1054
	else {
1055
		ea = reg.r[rs1] + reg.r[rs2];
1056
		if(trace)
1057
			itrace("swap\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1058
	}
1059
 
1060
	t = reg.r[rd];
1061
	reg.r[rd] = getmem_w(ea);
1062
	putmem_w(ea, t);
1063
}
1064
 
1065
void
1066
ldd(ulong ir)
1067
{
1068
	ulong ea;
1069
	int rd, rs1, rs2;
1070
 
1071
	getrop23(ir);
1072
	if(ir&IMMBIT) {
1073
		ximm(ea, ir);
1074
		if(trace)
1075
			itrace("ldd\tr%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
1076
		ea += reg.r[rs1];
1077
	}
1078
	else {
1079
		ea = reg.r[rs1] + reg.r[rs2];
1080
		if(trace)
1081
			itrace("ldd\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1082
	}
1083
 
1084
	reg.r[rd] = getmem_w(ea);
1085
	reg.r[rd+1] = getmem_w(ea+4);
1086
}
1087
 
1088
void
1089
ldub(ulong ir)
1090
{
1091
	ulong ea;
1092
	int rd, rs1, rs2;
1093
 
1094
	getrop23(ir);
1095
	if(ir&IMMBIT) {
1096
		ximm(ea, ir);
1097
		if(trace)
1098
			itrace("ldub\tr%d,0x%lux(r%d) ea=%lux",
1099
						rd, ea, rs1, ea+reg.r[rs1]);
1100
		ea += reg.r[rs1];
1101
	}
1102
	else {
1103
		ea = reg.r[rs1] + reg.r[rs2];
1104
		if(trace)
1105
			itrace("ldub\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1106
	}
1107
 
1108
	reg.r[rd] = getmem_b(ea) & 0xff;
1109
	ilock(rd);
1110
}
1111
 
1112
void
1113
ldstub(ulong ir)
1114
{
1115
	ulong ea;
1116
	int rd, rs1, rs2;
1117
 
1118
	getrop23(ir);
1119
	if(ir&IMMBIT) {
1120
		ximm(ea, ir);
1121
		if(trace)
1122
			itrace("ldstub\tr%d,0x%lux(r%d) ea=%lux",
1123
						rd, ea, rs1, ea+reg.r[rs1]);
1124
		ea += reg.r[rs1];
1125
	}
1126
	else {
1127
		ea = reg.r[rs1] + reg.r[rs2];
1128
		if(trace)
1129
			itrace("ldstub\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1130
	}
1131
 
1132
	reg.r[rd] = getmem_b(ea) & 0xff;
1133
	putmem_b(ea, 0xff);
1134
}
1135
 
1136
void
1137
ldsb(ulong ir)
1138
{
1139
	ulong ea;
1140
	int rd, rs1, rs2;
1141
 
1142
	getrop23(ir);
1143
	if(ir&IMMBIT) {
1144
		ximm(ea, ir);
1145
		if(trace)
1146
			itrace("ldsb\tr%d,0x%lux(r%d) ea=%lux",
1147
						rd, ea, rs1, ea+reg.r[rs1]);
1148
		ea += reg.r[rs1];
1149
	}
1150
	else {
1151
		ea = reg.r[rs1] + reg.r[rs2];
1152
		if(trace)
1153
			itrace("ldsb\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1154
	}
1155
 
1156
	reg.r[rd] = (schar)getmem_b(ea);
1157
	ilock(rd);
1158
}
1159
 
1160
void
1161
lduh(ulong ir)
1162
{
1163
	ulong ea;
1164
	int rd, rs1, rs2;
1165
 
1166
	getrop23(ir);
1167
	if(ir&IMMBIT) {
1168
		ximm(ea, ir);
1169
		if(trace)
1170
			itrace("lduh\tr%d,0x%lux(r%d) ea=%lux",
1171
						rd, ea, rs1, ea+reg.r[rs1]);
1172
		ea += reg.r[rs1];
1173
	}
1174
	else {
1175
		ea = reg.r[rs1] + reg.r[rs2];
1176
		if(trace)
1177
			itrace("lduh\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1178
	}
1179
 
1180
	reg.r[rd] = getmem_h(ea) & 0xffff;
1181
	ilock(rd);
1182
}
1183
 
1184
void
1185
ldsh(ulong ir)
1186
{
1187
	ulong ea;
1188
	int rd, rs1, rs2;
1189
 
1190
	getrop23(ir);
1191
	if(ir&IMMBIT) {
1192
		ximm(ea, ir);
1193
		if(trace)
1194
			itrace("ldsh\tr%d,0x%lux(r%d) ea=%lux",
1195
						rd, ea, rs1, ea+reg.r[rs1]);
1196
		ea += reg.r[rs1];
1197
	}
1198
	else {
1199
		ea = reg.r[rs1] + reg.r[rs2];
1200
		if(trace)
1201
			itrace("ldsh\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1202
	}
1203
 
1204
	reg.r[rd] = (short)getmem_h(ea);
1205
	ilock(rd);
1206
}
1207
 
1208
void
1209
sethi(ulong ir)
1210
{
1211
	int rd;
1212
	ulong v;
1213
 
1214
	rd = (ir>>25)&0x1f;
1215
	v = (ir&0x3FFFFF)<<10;
1216
 
1217
	if(rd == 0)
1218
		nopcount++;
1219
 
1220
	if(trace)
1221
		itrace("sethi\t0x%lux,r%d", v, rd);
1222
 
1223
	reg.r[rd] = v;
1224
}
1225
 
1226
void
1227
call(ulong ir)
1228
{
1229
	Symbol s;
1230
	ulong npc;
1231
 
1232
	npc = (ir<<2) + reg.pc;
1233
	if(trace)
1234
		itrace("call\t%lux", npc);
1235
 
1236
	ci->taken++;
1237
	reg.r[15] = reg.pc;
1238
	reg.ir = ifetch(reg.pc+4);
1239
	delay(npc);
1240
 
1241
	if(calltree) {
1242
		findsym(npc, CTEXT, &s);
1243
		Bprint(bioout, "%8lux %s(", reg.pc, s.name);
1244
		printparams(&s, reg.r[1]);
1245
		Bprint(bioout, "from ");
1246
		printsource(reg.pc);
1247
		Bputc(bioout, '\n');
1248
	}
1249
	npc -= 4;
1250
	reg.pc = npc;
1251
}
1252
 
1253
void
1254
jmpl(ulong ir)
1255
{
1256
	ulong ea, o;
1257
	Symbol s;
1258
	int rd, rs1, rs2;
1259
 
1260
	getrop23(ir);
1261
	if(ir&IMMBIT) {
1262
		ximm(ea, ir);
1263
		o = ea;
1264
		if(trace)
1265
			itrace("jmpl\t0x%lux(r%d),r%d", ea, rs1, rd);
1266
 
1267
		ea += reg.r[rs1];
1268
		if(calltree && rd == 0 && o == 8) {
1269
			findsym(ea-4, CTEXT, &s);
1270
			Bprint(bioout, "%8lux return to %lux %s r7=%lux\n",
1271
						reg.pc, ea-4, s.name, reg.r[7]);
1272
		}
1273
	}
1274
	else {
1275
		ea = reg.r[rs1] + reg.r[rs2];
1276
		if(trace)
1277
			itrace("jmpl\t[r%d+r%d],r%d", rs1, rs2, rd);
1278
	}
1279
 
1280
	ci->taken++;
1281
	reg.r[rd] = reg.pc;
1282
	reg.ir = ifetch(reg.pc+4);
1283
	delay(ea);
1284
	reg.pc = ea-4;
1285
}
1286
 
1287
void
1288
bicc(ulong ir)
1289
{
1290
	char *op;
1291
	ulong npc, anul, ba;
1292
	int takeit, z, v, n, c;
1293
 
1294
	SET(op, takeit);
1295
	ba = 0;
1296
	switch((ir>>25)&0x0F) {
1297
	case 0:
1298
		op = "bn";
1299
		takeit = 0;
1300
		break;
1301
	case 1:
1302
		op = "be";
1303
		takeit = reg.psr&PSR_z;
1304
		break;
1305
	case 2:
1306
		op = "ble";
1307
		z = reg.psr&PSR_z ? 1 : 0;
1308
		v = reg.psr&PSR_v ? 1 : 0;
1309
		n = reg.psr&PSR_n ? 1 : 0;
1310
		takeit = z | (n ^ v);
1311
		break;
1312
	case 3:
1313
		op = "bl";
1314
		v = reg.psr&PSR_v ? 1 : 0;
1315
		n = reg.psr&PSR_n ? 1 : 0;
1316
		takeit = n ^ v;
1317
		break;
1318
	case 4:
1319
		op = "bleu";
1320
		z = reg.psr&PSR_z ? 1 : 0;
1321
		c = reg.psr&PSR_c ? 1 : 0;
1322
		takeit = c | z;
1323
		break;
1324
	case 5:
1325
		op = "bcs";
1326
		takeit = reg.psr&PSR_c;
1327
		break;
1328
	case 6:
1329
		op = "bneg";
1330
		takeit = reg.psr&PSR_n;
1331
		break;
1332
	case 7:
1333
		op = "bvs";
1334
		takeit = reg.psr&PSR_v;
1335
		break;
1336
	case 8:
1337
		op = "ba";
1338
		ba = 1;
1339
		takeit = 1;
1340
		break;
1341
	case 9:
1342
		op = "bne";
1343
		takeit = !(reg.psr&PSR_z);
1344
		break;
1345
	case 10:
1346
		op = "bg";
1347
		z = reg.psr&PSR_z ? 1 : 0;
1348
		v = reg.psr&PSR_v ? 1 : 0;
1349
		n = reg.psr&PSR_n ? 1 : 0;
1350
		takeit = !(z | (n ^ v));
1351
		break;
1352
	case 11:
1353
		op = "bge";
1354
		v = reg.psr&PSR_v ? 1 : 0;
1355
		n = reg.psr&PSR_n ? 1 : 0;
1356
		takeit = !(n ^ v);
1357
		break;
1358
	case 12:
1359
		op = "bgu";
1360
		z = reg.psr&PSR_z ? 1 : 0;
1361
		c = reg.psr&PSR_c ? 1 : 0;
1362
		takeit = !(c | z);
1363
		break;
1364
	case 13:
1365
		op = "bcc";
1366
		takeit = !(reg.psr&PSR_c);
1367
		break;
1368
	case 14:
1369
		op = "bpos";
1370
		takeit = !(reg.psr&PSR_n);
1371
		break;
1372
	case 15:
1373
		op = "bvc";
1374
		takeit = !(reg.psr&PSR_v);
1375
		break;
1376
	}
1377
 
1378
	npc = ir & 0x3FFFFF;
1379
	if(npc & (1<<21))
1380
		npc |= ~((1<<22)-1);
1381
	npc = (npc<<2) + reg.pc;
1382
 
1383
	anul = ir&ANUL;
1384
	if(trace) {
1385
		if(anul)
1386
			itrace("%s,a\t%lux", op, npc);
1387
		else
1388
			itrace("%s\t%lux", op, npc);
1389
	}
1390
 
1391
	if(takeit == 0) {
1392
		reg.pc += 4;
1393
		if(anul == 0) {
1394
			reg.ir = ifetch(reg.pc);
1395
			delay(reg.pc+4);
1396
		}
1397
		else
1398
			anulled++;
1399
		return;
1400
	}
1401
 
1402
	ci->taken++;
1403
	if(ba && anul) {
1404
		anulled++;
1405
		reg.pc = npc-4;
1406
		return;	
1407
	}
1408
	reg.ir = ifetch(reg.pc+4);
1409
	delay(npc);
1410
	reg.pc = npc-4;
1411
}