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
9
ldf(ulong ir)
10
{
11
	ulong ea;
12
	int rd, rs1, rs2;
13
 
14
	getrop23(ir);
15
	if(ir&IMMBIT) {
16
		ximm(ea, ir);
17
		if(trace)
18
			itrace("ldf\tf%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
19
		ea += reg.r[rs1];
20
	}
21
	else {
22
		ea = reg.r[rs1] + reg.r[rs2];
23
		if(trace)
24
			itrace("ldf\tf%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
25
	}
26
 
27
	reg.di[rd] = getmem_w(ea);
28
}
29
 
30
void
31
lddf(ulong ir)
32
{
33
	ulong ea;
34
	int rd, rs1, rs2;
35
 
36
	getrop23(ir);
37
	if(ir&IMMBIT) {
38
		ximm(ea, ir);
39
		if(trace)
40
			itrace("lddf\tf%d,0x%lux(r%d) ea=%lux",
41
							rd, ea, rs1, ea+reg.r[rs1]);
42
		ea += reg.r[rs1];
43
	}
44
	else {
45
		ea = reg.r[rs1] + reg.r[rs2];
46
		if(trace)
47
			itrace("lddf\tf%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
48
	}
49
 
50
	if(ea&7) {
51
		Bprint(bioout, "mem_address_not_aligned [load addr %.8lux]\n", ea);
52
		longjmp(errjmp, 0);
53
	}
54
	if(rd&1)
55
		undef(ir);
56
 
57
	reg.di[rd] = getmem_w(ea);
58
	reg.di[rd+1] = getmem_w(ea+4);
59
}
60
 
61
void
62
stf(ulong ir)
63
{
64
	ulong ea;
65
	int rd, rs1, rs2;
66
 
67
	getrop23(ir);
68
	if(ir&IMMBIT) {
69
		ximm(ea, ir);
70
		if(trace)
71
			itrace("stf\tf%d,0x%lux(r%d) %lux=%g",
72
					rd, ea, rs1, ea+reg.r[rs1], reg.fl[rd]);
73
		ea += reg.r[rs1];
74
	}
75
	else {
76
		ea = reg.r[rs1] + reg.r[rs2];
77
		if(trace)
78
			itrace("stf\tf%d,[r%d+r%d] %lux=%lux",
79
					rd, rs1, rs2, ea, reg.r[rd]);
80
	}
81
 
82
	putmem_w(ea, reg.di[rd]);
83
}
84
 
85
void
86
stdf(ulong ir)
87
{
88
	ulong ea;
89
	int rd, rs1, rs2;
90
 
91
	getrop23(ir);
92
	if(ir&IMMBIT) {
93
		ximm(ea, ir);
94
		if(trace)
95
			itrace("stdf\tf%d,0x%lux(r%d) %lux=%g",
96
					rd, ea, rs1, ea+reg.r[rs1], reg.fl[rd]);
97
		ea += reg.r[rs1];
98
	}
99
	else {
100
		ea = reg.r[rs1] + reg.r[rs2];
101
		if(trace)
102
			itrace("stdf\tf%d,[r%d+r%d] %lux=%lux",
103
					rd, rs1, rs2, ea, reg.r[rd]);
104
	}
105
 
106
	if(ea&7) {
107
		Bprint(bioout, "mem_address_not_aligned [store addr %.8lux]\n", ea);
108
		longjmp(errjmp, 0);
109
	}
110
	if(rd&1)
111
		undef(ir);
112
 
113
	putmem_w(ea, reg.di[rd]);
114
	putmem_w(ea+4, reg.di[rd+1]);
115
}
116
 
117
void
118
fcmp(ulong ir)
119
{
120
	int fc, rd, rs1, rs2;
121
 
122
	getrop23(ir);
123
	USED(rd);
124
	SET(fc);
125
	switch((ir>>5)&0x1FF) {
126
	default:
127
		undef(ir);
128
	case 0x51:		/* fcmps */
129
		if(trace)
130
			itrace("fcmps\tf%d,f%d", rs1, rs2);
131
		if(isNaN(reg.fl[rs1]) || isNaN(reg.fl[rs2])) {
132
			fc = 3;
133
			break;
134
		}
135
		if(reg.fl[rs1] == reg.fl[rs2]) {
136
			fc = 0;
137
			break;
138
		}
139
		if(reg.fl[rs1] < reg.fl[rs2]) {
140
			fc = 1;
141
			break;
142
		}
143
		if(reg.fl[rs1] > reg.fl[rs2]) {
144
			fc = 2;
145
			break;
146
		}
147
		print("ki: fcmp error\n");
148
		break;
149
	case 0x52:
150
		if(trace)
151
			itrace("fcmpd\tf%d,f%d", rs1, rs2);
152
		rs1 >>= 1;
153
		rs2 >>= 1;
154
		if(isNaN(reg.fd[rs1]) || isNaN(reg.fd[rs2])) {
155
			fc = 3;
156
			break;
157
		}
158
		if(reg.fd[rs1] == reg.fd[rs2]) {
159
			fc = 0;
160
			break;
161
		}
162
		if(reg.fd[rs1] < reg.fd[rs2]) {
163
			fc = 1;
164
			break;
165
		}
166
		if(reg.fd[rs1] > reg.fd[rs2]) {
167
			fc = 2;
168
			break;
169
		}
170
		print("ki: fcmp error\n");
171
		break;
172
	case 0x55:		/* fcmpes */
173
		if(trace)
174
			itrace("fcmpes\tf%d,f%d", rs1, rs2);
175
		rs1 >>= 1;
176
		rs2 >>= 2;
177
		if(isNaN(reg.fl[rs1]) || isNaN(reg.fl[rs2])) {
178
			Bprint(bioout, "invalid_fp_register\n");
179
			longjmp(errjmp, 0);
180
		}
181
		if(reg.fl[rs1] == reg.fl[rs2]) {
182
			fc = 0;
183
			break;
184
		}
185
		if(reg.fl[rs1] < reg.fl[rs2]) {
186
			fc = 1;
187
			break;
188
		}
189
		if(reg.fl[rs1] > reg.fl[rs2]) {
190
			fc = 2;
191
			break;
192
		}
193
		print("ki: fcmp error\n");
194
		break;
195
	case 0x56:
196
		if(trace)
197
			itrace("fcmped\tf%d,f%d", rs1, rs2);
198
		if(isNaN(reg.fd[rs1]) || isNaN(reg.fd[rs2])) {
199
			Bprint(bioout, "invalid_fp_register\n");
200
			longjmp(errjmp, 0);
201
		}
202
		if(reg.fd[rs1] == reg.fd[rs2]) {
203
			fc = 0;
204
			break;
205
		}
206
		if(reg.fd[rs1] < reg.fd[rs2]) {
207
			fc = 1;
208
			break;
209
		}
210
		if(reg.fd[rs1] > reg.fd[rs2]) {
211
			fc = 2;
212
			break;
213
		}
214
		print("ki: fcmp error\n");
215
		break;
216
 
217
	}
218
	reg.fpsr = (reg.fpsr&~(0x3<<10)) | (fc<<10);
219
}
220
 
221
void
222
fbcc(ulong ir)
223
{
224
	char *op;
225
	ulong npc;
226
	int takeit, fc, ba, anul;
227
 
228
	fc = (reg.fpsr>>10)&3;
229
	ba = 0;
230
	SET(op, takeit);
231
	switch((ir>>25)&0x0F) {
232
	case 0:
233
		op = "fbn";
234
		takeit = 0;
235
		break;
236
	case 1:
237
		op = "fbne";
238
		takeit = fc == FP_L || fc == FP_G || fc == FP_U;
239
		break;
240
	case 2:
241
		op = "fblg";
242
		takeit = fc == FP_L || fc == FP_G;
243
		break;
244
	case 3:
245
		op = "fbul";
246
		takeit = fc == FP_L || fc == FP_U;
247
		break;
248
	case 4:
249
		op = "fbl";
250
		takeit = fc == FP_L;
251
		break;
252
	case 5:
253
		op = "fbug";
254
		takeit = fc == FP_U || fc == FP_G;
255
		break;
256
	case 6:
257
		op = "fbg";
258
		takeit = fc == FP_G;
259
		break;
260
	case 7:
261
		op = "fbu";
262
		takeit = fc == FP_U;
263
		break;
264
	case 8:
265
		op = "fba";
266
		ba = 1;
267
		takeit = 1;
268
		break;
269
	case 9:
270
		op = "fbe";
271
		takeit = fc == FP_E;
272
		break;
273
	case 10:
274
		op = "fbue";
275
		takeit = fc == FP_E || fc == FP_U;
276
		break;
277
	case 11:
278
		op = "fbge";
279
		takeit = fc == FP_E || fc == FP_G;
280
		break;
281
	case 12:
282
		op = "fbuge";
283
		takeit = fc == FP_E || fc == FP_G || fc == FP_U;
284
		break;
285
	case 13:
286
		op = "fble";
287
		takeit = fc == FP_E || fc == FP_L;
288
		break;
289
	case 14:
290
		op = "fbule";
291
		takeit = fc == FP_E || fc == FP_L || fc == FP_U;
292
		break;
293
	case 15:
294
		op = "fbo";
295
		takeit = fc == FP_E || fc == FP_L || fc == FP_G;
296
		break;
297
	}
298
 
299
	npc = ir & 0x3FFFFF;
300
	if(npc & (1<<21))
301
		npc |= ~((1<<22)-1);
302
	npc = (npc<<2) + reg.pc;
303
 
304
	anul = ir&ANUL;
305
	if(trace) {
306
		if(anul)
307
			itrace("%s,a\t%lux", op, npc);
308
		else
309
			itrace("%s\t%lux", op, npc);
310
	}
311
 
312
	if(takeit == 0) {
313
		reg.pc += 4;
314
		if(anul == 0) {
315
			reg.ir = ifetch(reg.pc);
316
			delay(reg.pc+4);
317
		}
318
		else
319
			anulled++;
320
		return;
321
	}
322
 
323
	ci->taken++;
324
	if(ba && anul) {
325
		reg.pc = npc-4;
326
		anulled++;
327
		return;	
328
	}
329
	reg.ir = ifetch(reg.pc+4);
330
	delay(npc);
331
	reg.pc = npc-4;
332
}
333
 
334
void
335
farith(ulong ir)
336
{
337
	char *op;
338
	long v;
339
	int rd, rs1, rs2, fmt;
340
 
341
	fmt = 0;
342
	getrop23(ir);
343
	switch((ir>>5)&0x1FF) {
344
	default:
345
		undef(ir);
346
	case 0x41:
347
		reg.fl[rd] = reg.fl[rs1] + reg.fl[rs2];
348
		op = "fadds";
349
		break;
350
	case 0x42:
351
		reg.fd[rd>>1] = reg.fd[rs1>>1] + reg.fd[rs2>>1];
352
		op = "faddd";
353
		break;
354
	case 0x45:
355
		reg.fl[rd] = reg.fl[rs1] - reg.fl[rs2];
356
		op = "fsubs";
357
		break;
358
	case 0x46:
359
		reg.fd[rd>>1] = reg.fd[rs1>>1] - reg.fd[rs2>>1];
360
		op = "fsubd";
361
		break;
362
	case 0x4d:
363
		if(reg.fl[rs2] == 0.0) {
364
			Bprint(bioout, "fp_exception DZ\n");
365
			longjmp(errjmp, 0);
366
		}
367
		reg.fl[rd] = reg.fl[rs1] / reg.fl[rs2];
368
		op = "fdivs";
369
		break;
370
	case 0x4e:
371
		if(reg.fd[rs2>>1] == 0.0) {
372
			Bprint(bioout, "fp_exception DZ\n");
373
			longjmp(errjmp, 0);
374
		}
375
		reg.fd[rd>>1] = reg.fd[rs1>>1] / reg.fd[rs2>>1];
376
		op = "fdivd";
377
		break;
378
	case 0x49:
379
		reg.fl[rd] = reg.fl[rs1] * reg.fl[rs2];
380
		op = "fmuls";
381
		break;
382
	case 0x4a:
383
		reg.fd[rd>>1] = reg.fd[rs1>>1] * reg.fd[rs2>>1];
384
		op = "fmuld";
385
		break;
386
	case 0xc4:
387
		reg.fl[rd] = (long)reg.di[rs2];
388
		fmt = 1;
389
		op = "fitos";
390
		break;
391
	case 0xc8:
392
		reg.fd[rd>>1] = (long)reg.di[rs2];
393
		fmt = 1;
394
		op = "fitod";
395
		break;
396
	case 0xd1:
397
		v = reg.fl[rs2];
398
		reg.di[rd] = v;
399
		fmt = 1;
400
		op = "fstoi";
401
		break;
402
	case 0xd2:
403
		v = reg.fd[rs2>>1];
404
		reg.di[rd] = v;
405
		fmt = 1;
406
		op = "fdtoi";
407
		break;
408
	case 0x01:
409
		reg.di[rd] = reg.di[rs2];
410
		fmt = 1;
411
		op = "fmovs";
412
		break;
413
	case 0x05:
414
		reg.fl[rd] = -reg.fl[rs2];
415
		fmt = 1;
416
		op = "fnegs";
417
		break;
418
	case 0x09:
419
		reg.fl[rd] = fabs(reg.fl[rs2]);
420
		fmt = 1;
421
		op = "fabss";
422
		break;
423
	case 0xc9:
424
		reg.fd[rd>>1] = reg.fl[rs2];
425
		fmt = 1;
426
		op = "fstod";
427
		break;
428
	case 0xc6:
429
		reg.fl[rd] = reg.fd[rs2>>1];
430
		fmt = 1;
431
		op = "fdtos";
432
		break;
433
	}
434
 
435
	if(trace) {
436
		switch(fmt) {
437
		case 0:
438
			itrace("%s\tf%d,f%d,f%d", op, rs1, rs2, rd);
439
			break;
440
		case 1:
441
			itrace("%s\tf%d,f%d", op, rs2, rd);
442
			break;
443
		}
444
	}
445
}