xref: /netbsd-src/external/gpl3/gdb/dist/sim/erc32/exec.c (revision ccd9df534e375a4366c5b55f23782053c7a98d82)
1 /* This file is part of SIS (SPARC instruction simulator)
2 
3    Copyright (C) 1995-2023 Free Software Foundation, Inc.
4    Contributed by Jiri Gaisler, European Space Agency
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18 
19 /* This must come before any other includes.  */
20 #include "defs.h"
21 
22 #include "sis.h"
23 #include <math.h>
24 #include <stdio.h>
25 
26 extern int32_t    sis_verbose, sparclite;
27 int ext_irl = 0;
28 
29 /* Load/store interlock delay */
30 #define FLSTHOLD 1
31 
32 /* Load delay (delete if unwanted - speeds up simulation) */
33 #define LOAD_DEL 1
34 
35 #define T_LD	2
36 #define T_LDD	3
37 #define T_ST	3
38 #define T_STD	4
39 #define T_LDST	4
40 #define T_JMPL	2
41 #define T_RETT	2
42 
43 #define FSR_QNE 	0x2000
44 #define FP_EXE_MODE 0
45 #define	FP_EXC_PE   1
46 #define FP_EXC_MODE 2
47 
48 #define	FBA	8
49 #define	FBN	0
50 #define	FBNE	1
51 #define	FBLG	2
52 #define	FBUL	3
53 #define	FBL 	4
54 #define	FBUG	5
55 #define	FBG 	6
56 #define	FBU 	7
57 #define FBA	8
58 #define FBE	9
59 #define FBUE	10
60 #define FBGE	11
61 #define FBUGE	12
62 #define FBLE	13
63 #define FBULE	14
64 #define FBO	15
65 
66 #define	FCC_E 	0
67 #define	FCC_L 	1
68 #define	FCC_G 	2
69 #define	FCC_U 	3
70 
71 #define PSR_ET 0x20
72 #define PSR_EF 0x1000
73 #define PSR_PS 0x40
74 #define PSR_S  0x80
75 #define PSR_N  0x0800000
76 #define PSR_Z  0x0400000
77 #define PSR_V  0x0200000
78 #define PSR_C  0x0100000
79 #define PSR_CC 0x0F00000
80 #define PSR_CWP 0x7
81 #define PSR_PIL 0x0f00
82 
83 #define ICC_N	(icc >> 3)
84 #define ICC_Z	(icc >> 2)
85 #define ICC_V	(icc >> 1)
86 #define ICC_C	(icc)
87 
88 #define FP_PRES	(sregs->fpu_pres)
89 
90 #define TRAP_IEXC 1
91 #define TRAP_UNIMP 2
92 #define TRAP_PRIVI 3
93 #define TRAP_FPDIS 4
94 #define TRAP_WOFL 5
95 #define TRAP_WUFL 6
96 #define TRAP_UNALI 7
97 #define TRAP_FPEXC 8
98 #define TRAP_DEXC 9
99 #define TRAP_TAG 10
100 #define TRAP_DIV0 0x2a
101 
102 #define FSR_TT		0x1C000
103 #define FP_IEEE		0x04000
104 #define FP_UNIMP	0x0C000
105 #define FP_SEQ_ERR	0x10000
106 
107 #define	BICC_BN		0
108 #define	BICC_BE		1
109 #define	BICC_BLE	2
110 #define	BICC_BL		3
111 #define	BICC_BLEU	4
112 #define	BICC_BCS	5
113 #define	BICC_NEG	6
114 #define	BICC_BVS	7
115 #define	BICC_BA		8
116 #define	BICC_BNE	9
117 #define	BICC_BG		10
118 #define	BICC_BGE	11
119 #define	BICC_BGU	12
120 #define	BICC_BCC	13
121 #define	BICC_POS	14
122 #define	BICC_BVC	15
123 
124 #define INST_SIMM13 0x1fff
125 #define INST_RS2    0x1f
126 #define INST_I	    0x2000
127 #define ADD 	0x00
128 #define ADDCC 	0x10
129 #define ADDX 	0x08
130 #define ADDXCC 	0x18
131 #define TADDCC 	0x20
132 #define TSUBCC  0x21
133 #define TADDCCTV 0x22
134 #define TSUBCCTV 0x23
135 #define IAND 	0x01
136 #define IANDCC 	0x11
137 #define IANDN 	0x05
138 #define IANDNCC	0x15
139 #define MULScc 	0x24
140 #define DIVScc 	0x1D
141 #define SMUL	0x0B
142 #define SMULCC	0x1B
143 #define UMUL	0x0A
144 #define UMULCC	0x1A
145 #define SDIV	0x0F
146 #define SDIVCC	0x1F
147 #define UDIV	0x0E
148 #define UDIVCC	0x1E
149 #define IOR 	0x02
150 #define IORCC 	0x12
151 #define IORN 	0x06
152 #define IORNCC 	0x16
153 #define SLL 	0x25
154 #define SRA 	0x27
155 #define SRL 	0x26
156 #define SUB 	0x04
157 #define SUBCC 	0x14
158 #define SUBX 	0x0C
159 #define SUBXCC 	0x1C
160 #define IXNOR 	0x07
161 #define IXNORCC	0x17
162 #define IXOR 	0x03
163 #define IXORCC 	0x13
164 #define SETHI 	0x04
165 #define BICC 	0x02
166 #define FPBCC 	0x06
167 #define RDY 	0x28
168 #define RDPSR 	0x29
169 #define RDWIM 	0x2A
170 #define RDTBR 	0x2B
171 #define SCAN 	0x2C
172 #define WRY	0x30
173 #define WRPSR	0x31
174 #define WRWIM	0x32
175 #define WRTBR	0x33
176 #define JMPL 	0x38
177 #define RETT 	0x39
178 #define TICC 	0x3A
179 #define SAVE 	0x3C
180 #define RESTORE 0x3D
181 #define LDD	0x03
182 #define LDDA	0x13
183 #define LD	0x00
184 #define LDA	0x10
185 #define LDF	0x20
186 #define LDDF	0x23
187 #define LDSTUB	0x0D
188 #define LDSTUBA	0x1D
189 #define LDUB	0x01
190 #define LDUBA	0x11
191 #define LDSB	0x09
192 #define LDSBA	0x19
193 #define LDUH	0x02
194 #define LDUHA	0x12
195 #define LDSH	0x0A
196 #define LDSHA	0x1A
197 #define LDFSR	0x21
198 #define ST	0x04
199 #define STA	0x14
200 #define STB	0x05
201 #define STBA	0x15
202 #define STD	0x07
203 #define STDA	0x17
204 #define STF	0x24
205 #define STDFQ	0x26
206 #define STDF	0x27
207 #define STFSR	0x25
208 #define STH	0x06
209 #define STHA	0x16
210 #define SWAP	0x0F
211 #define SWAPA	0x1F
212 #define FLUSH	0x3B
213 
214 #define SIGN_BIT 0x80000000
215 
216 /* # of cycles overhead when a trap is taken */
217 #define TRAP_C  3
218 
219 /* Forward declarations */
220 
221 static uint32_t	sub_cc (uint32_t psr, int32_t operand1, int32_t operand2,
222 			int32_t result);
223 static uint32_t	add_cc (uint32_t psr, int32_t operand1, int32_t operand2,
224 			int32_t result);
225 static void	log_cc (int32_t result, struct pstate *sregs);
226 static int	fpexec (uint32_t op3, uint32_t rd, uint32_t rs1, uint32_t rs2,
227 			struct pstate *sregs);
228 static int	chk_asi (struct pstate *sregs, uint32_t *asi, uint32_t op3);
229 
230 
231 extern struct estate ebase;
232 extern int32_t    nfp,ift;
233 
234 #ifdef ERRINJ
235 extern uint32_t errtt, errftt;
236 #endif
237 
238 static uint32_t
239 sub_cc(uint32_t psr, int32_t operand1, int32_t operand2, int32_t result)
240 {
241     psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N));
242     if (result)
243 	psr &= ~PSR_Z;
244     else
245 	psr |= PSR_Z;
246     psr = (psr & ~PSR_V) | ((((operand1 & ~operand2 & ~result) |
247 			   (~operand1 & operand2 & result)) >> 10) & PSR_V);
248     psr = (psr & ~PSR_C) | ((((~operand1 & operand2) |
249 			 ((~operand1 | operand2) & result)) >> 11) & PSR_C);
250     return psr;
251 }
252 
253 uint32_t
254 add_cc(uint32_t psr, int32_t operand1, int32_t operand2, int32_t result)
255 {
256     psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N));
257     if (result)
258 	psr &= ~PSR_Z;
259     else
260 	psr |= PSR_Z;
261     psr = (psr & ~PSR_V) | ((((operand1 & operand2 & ~result) |
262 			  (~operand1 & ~operand2 & result)) >> 10) & PSR_V);
263     psr = (psr & ~PSR_C) | ((((operand1 & operand2) |
264 			 ((operand1 | operand2) & ~result)) >> 11) & PSR_C);
265     return psr;
266 }
267 
268 static void
269 log_cc(int32_t result, struct pstate *sregs)
270 {
271     sregs->psr &= ~(PSR_CC);	/* Zero CC bits */
272     sregs->psr = (sregs->psr | ((result >> 8) & PSR_N));
273     if (result == 0)
274 	sregs->psr |= PSR_Z;
275 }
276 
277 /* Add two unsigned 32-bit integers, and calculate the carry out. */
278 
279 static uint32_t
280 add32 (uint32_t n1, uint32_t n2, int *carry)
281 {
282   uint32_t result = n1 + n2;
283 
284   *carry = result < n1 || result < n2;
285   return result;
286 }
287 
288 /* Multiply two 32-bit integers.  */
289 
290 static void
291 mul64 (uint32_t n1, uint32_t n2, uint32_t *result_hi, uint32_t *result_lo, int msigned)
292 {
293   uint32_t lo, mid1, mid2, hi, reg_lo, reg_hi;
294   int carry;
295   int sign = 0;
296 
297   /* If this is a signed multiply, calculate the sign of the result
298      and make the operands positive.  */
299   if (msigned)
300     {
301       sign = (n1 ^ n2) & SIGN_BIT;
302       if (n1 & SIGN_BIT)
303 	n1 = -n1;
304       if (n2 & SIGN_BIT)
305 	n2 = -n2;
306 
307     }
308 
309   /* We can split the 32x32 into four 16x16 operations. This ensures
310      that we do not lose precision on 32bit only hosts: */
311   lo =   ((n1 & 0xFFFF) * (n2 & 0xFFFF));
312   mid1 = ((n1 & 0xFFFF) * ((n2 >> 16) & 0xFFFF));
313   mid2 = (((n1 >> 16) & 0xFFFF) * (n2 & 0xFFFF));
314   hi =   (((n1 >> 16) & 0xFFFF) * ((n2 >> 16) & 0xFFFF));
315 
316   /* We now need to add all of these results together, taking care
317      to propogate the carries from the additions: */
318   reg_lo = add32 (lo, (mid1 << 16), &carry);
319   reg_hi = carry;
320   reg_lo = add32 (reg_lo, (mid2 << 16), &carry);
321   reg_hi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
322 
323   /* Negate result if necessary. */
324   if (sign)
325     {
326       reg_hi = ~ reg_hi;
327       reg_lo = - reg_lo;
328       if (reg_lo == 0)
329 	reg_hi++;
330     }
331 
332   *result_lo = reg_lo;
333   *result_hi = reg_hi;
334 }
335 
336 
337 /* Divide a 64-bit integer by a 32-bit integer.  We cheat and assume
338    that the host compiler supports long long operations.  */
339 
340 static void
341 div64 (uint32_t n1_hi, uint32_t n1_low, uint32_t n2, uint32_t *result, int msigned)
342 {
343   uint64_t n1;
344 
345   n1 = ((uint64_t) n1_hi) << 32;
346   n1 |= ((uint64_t) n1_low) & 0xffffffff;
347 
348   if (msigned)
349     {
350       int64_t n1_s = (int64_t) n1;
351       int32_t n2_s = (int32_t) n2;
352       n1_s = n1_s / n2_s;
353       n1 = (uint64_t) n1_s;
354     }
355   else
356     n1 = n1 / n2;
357 
358   *result = (uint32_t) (n1 & 0xffffffff);
359 }
360 
361 
362 static int
363 extract_short (uint32_t data, uint32_t address)
364 {
365     return ((data >> ((2 - (address & 2)) * 8)) & 0xffff);
366 }
367 
368 static int
369 extract_short_signed (uint32_t data, uint32_t address)
370 {
371     uint32_t tmp = ((data >> ((2 - (address & 2)) * 8)) & 0xffff);
372     if (tmp & 0x8000)
373         tmp |= 0xffff0000;
374     return tmp;
375 }
376 
377 static int
378 extract_byte (uint32_t data, uint32_t address)
379 {
380     return ((data >> ((3 - (address & 3)) * 8)) & 0xff);
381 }
382 
383 static int
384 extract_byte_signed (uint32_t data, uint32_t address)
385 {
386     uint32_t tmp = ((data >> ((3 - (address & 3)) * 8)) & 0xff);
387     if (tmp & 0x80)
388         tmp |= 0xffffff00;
389     return tmp;
390 }
391 
392 int
393 dispatch_instruction(struct pstate *sregs)
394 {
395 
396     uint32_t          cwp, op, op2, op3, asi, rd, cond, rs1,
397                     rs2;
398     uint32_t          ldep, icc, data, *rdd;
399     int32_t           operand1, operand2, result, eicc,
400                     new_cwp;
401     int32_t           pc, npc, address, ws, mexc, fcc;
402     uint32_t	    ddata[2];
403 
404     sregs->ninst++;
405     cwp = ((sregs->psr & PSR_CWP) << 4);
406     op = sregs->inst >> 30;
407     pc = sregs->npc;
408     npc = sregs->npc + 4;
409     op3 = rd = rs1 = operand2 = eicc = 0;
410     rdd = 0;
411     if (op & 2) {
412 
413 	op3 = (sregs->inst >> 19) & 0x3f;
414 	rs1 = (sregs->inst >> 14) & 0x1f;
415 	rd = (sregs->inst >> 25) & 0x1f;
416 
417 #ifdef LOAD_DEL
418 
419 	/* Check if load dependecy is possible */
420 	if (ebase.simtime <= sregs->ildtime)
421 	    ldep = (((op3 & 0x38) != 0x28) && ((op3 & 0x3e) != 0x34) && (sregs->ildreg != 0));
422         else
423 	    ldep = 0;
424 	if (sregs->inst & INST_I) {
425 	    if (ldep && (sregs->ildreg == rs1))
426 		sregs->hold++;
427 	    operand2 = sregs->inst;
428 	    operand2 = ((operand2 << 19) >> 19);	/* sign extend */
429 	} else {
430 	    rs2 = sregs->inst & INST_RS2;
431 	    if (rs2 > 7)
432 		operand2 = sregs->r[(cwp + rs2) & 0x7f];
433 	    else
434 		operand2 = sregs->g[rs2];
435 	    if (ldep && ((sregs->ildreg == rs1) || (sregs->ildreg == rs2)))
436 		sregs->hold++;
437 	}
438 #else
439 	if (sregs->inst & INST_I) {
440 	    operand2 = sregs->inst;
441 	    operand2 = ((operand2 << 19) >> 19);	/* sign extend */
442 	} else {
443 	    rs2 = sregs->inst & INST_RS2;
444 	    if (rs2 > 7)
445 		operand2 = sregs->r[(cwp + rs2) & 0x7f];
446 	    else
447 		operand2 = sregs->g[rs2];
448 	}
449 #endif
450 
451 	if (rd > 7)
452 	    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
453 	else
454 	    rdd = &(sregs->g[rd]);
455 	if (rs1 > 7)
456 	    rs1 = sregs->r[(cwp + rs1) & 0x7f];
457 	else
458 	    rs1 = sregs->g[rs1];
459     }
460     switch (op) {
461     case 0:
462 	op2 = (sregs->inst >> 22) & 0x7;
463 	switch (op2) {
464 	case SETHI:
465 	    rd = (sregs->inst >> 25) & 0x1f;
466 	    if (rd > 7)
467 		rdd = &(sregs->r[(cwp + rd) & 0x7f]);
468 	    else
469 		rdd = &(sregs->g[rd]);
470 	    *rdd = sregs->inst << 10;
471 	    break;
472 	case BICC:
473 #ifdef STAT
474 	    sregs->nbranch++;
475 #endif
476 	    icc = sregs->psr >> 20;
477 	    cond = ((sregs->inst >> 25) & 0x0f);
478 	    switch (cond) {
479 	    case BICC_BN:
480 		eicc = 0;
481 		break;
482 	    case BICC_BE:
483 		eicc = ICC_Z;
484 		break;
485 	    case BICC_BLE:
486 		eicc = ICC_Z | (ICC_N ^ ICC_V);
487 		break;
488 	    case BICC_BL:
489 		eicc = (ICC_N ^ ICC_V);
490 		break;
491 	    case BICC_BLEU:
492 		eicc = ICC_C | ICC_Z;
493 		break;
494 	    case BICC_BCS:
495 		eicc = ICC_C;
496 		break;
497 	    case BICC_NEG:
498 		eicc = ICC_N;
499 		break;
500 	    case BICC_BVS:
501 		eicc = ICC_V;
502 		break;
503 	    case BICC_BA:
504 		eicc = 1;
505 		if (sregs->inst & 0x20000000)
506 		    sregs->annul = 1;
507 		break;
508 	    case BICC_BNE:
509 		eicc = ~(ICC_Z);
510 		break;
511 	    case BICC_BG:
512 		eicc = ~(ICC_Z | (ICC_N ^ ICC_V));
513 		break;
514 	    case BICC_BGE:
515 		eicc = ~(ICC_N ^ ICC_V);
516 		break;
517 	    case BICC_BGU:
518 		eicc = ~(ICC_C | ICC_Z);
519 		break;
520 	    case BICC_BCC:
521 		eicc = ~(ICC_C);
522 		break;
523 	    case BICC_POS:
524 		eicc = ~(ICC_N);
525 		break;
526 	    case BICC_BVC:
527 		eicc = ~(ICC_V);
528 		break;
529 	    }
530 	    if (eicc & 1) {
531 		operand1 = sregs->inst;
532 		operand1 = ((operand1 << 10) >> 8);	/* sign extend */
533 		npc = sregs->pc + operand1;
534 	    } else {
535 		if (sregs->inst & 0x20000000)
536 		    sregs->annul = 1;
537 	    }
538 	    break;
539 	case FPBCC:
540 #ifdef STAT
541 	    sregs->nbranch++;
542 #endif
543 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
544 		sregs->trap = TRAP_FPDIS;
545 		break;
546 	    }
547 	    if (ebase.simtime < sregs->ftime) {
548 		sregs->ftime = ebase.simtime + sregs->hold;
549 	    }
550 	    cond = ((sregs->inst >> 25) & 0x0f);
551 	    fcc = (sregs->fsr >> 10) & 0x3;
552 	    switch (cond) {
553 	    case FBN:
554 		eicc = 0;
555 		break;
556 	    case FBNE:
557 		eicc = (fcc != FCC_E);
558 		break;
559 	    case FBLG:
560 		eicc = (fcc == FCC_L) || (fcc == FCC_G);
561 		break;
562 	    case FBUL:
563 		eicc = (fcc == FCC_L) || (fcc == FCC_U);
564 		break;
565 	    case FBL:
566 		eicc = (fcc == FCC_L);
567 		break;
568 	    case FBUG:
569 		eicc = (fcc == FCC_G) || (fcc == FCC_U);
570 		break;
571 	    case FBG:
572 		eicc = (fcc == FCC_G);
573 		break;
574 	    case FBU:
575 		eicc = (fcc == FCC_U);
576 		break;
577 	    case FBA:
578 		eicc = 1;
579 		if (sregs->inst & 0x20000000)
580 		    sregs->annul = 1;
581 		break;
582 	    case FBE:
583 		eicc = !(fcc != FCC_E);
584 		break;
585 	    case FBUE:
586 		eicc = !((fcc == FCC_L) || (fcc == FCC_G));
587 		break;
588 	    case FBGE:
589 		eicc = !((fcc == FCC_L) || (fcc == FCC_U));
590 		break;
591 	    case FBUGE:
592 		eicc = !(fcc == FCC_L);
593 		break;
594 	    case FBLE:
595 		eicc = !((fcc == FCC_G) || (fcc == FCC_U));
596 		break;
597 	    case FBULE:
598 		eicc = !(fcc == FCC_G);
599 		break;
600 	    case FBO:
601 		eicc = !(fcc == FCC_U);
602 		break;
603 	    }
604 	    if (eicc) {
605 		operand1 = sregs->inst;
606 		operand1 = ((operand1 << 10) >> 8);	/* sign extend */
607 		npc = sregs->pc + operand1;
608 	    } else {
609 		if (sregs->inst & 0x20000000)
610 		    sregs->annul = 1;
611 	    }
612 	    break;
613 
614 	default:
615 	    sregs->trap = TRAP_UNIMP;
616 	    break;
617 	}
618 	break;
619     case 1:			/* CALL */
620 #ifdef STAT
621 	sregs->nbranch++;
622 #endif
623 	sregs->r[(cwp + 15) & 0x7f] = sregs->pc;
624 	npc = sregs->pc + (sregs->inst << 2);
625 	break;
626 
627     case 2:
628 	if ((op3 >> 1) == 0x1a) {
629 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
630 		sregs->trap = TRAP_FPDIS;
631 	    } else {
632 		rs1 = (sregs->inst >> 14) & 0x1f;
633 		rs2 = sregs->inst & 0x1f;
634 		sregs->trap = fpexec(op3, rd, rs1, rs2, sregs);
635 	    }
636 	} else {
637 
638 	    switch (op3) {
639 	    case TICC:
640 	        icc = sregs->psr >> 20;
641 	        cond = ((sregs->inst >> 25) & 0x0f);
642 	        switch (cond) {
643 		case BICC_BN:
644 		    eicc = 0;
645 		    break;
646 		case BICC_BE:
647 		    eicc = ICC_Z;
648 		    break;
649 		case BICC_BLE:
650 		    eicc = ICC_Z | (ICC_N ^ ICC_V);
651 		    break;
652 		case BICC_BL:
653 		    eicc = (ICC_N ^ ICC_V);
654 		    break;
655 		case BICC_BLEU:
656 		    eicc = ICC_C | ICC_Z;
657 		    break;
658 		case BICC_BCS:
659 		    eicc = ICC_C;
660 		    break;
661 		case BICC_NEG:
662 		    eicc = ICC_N;
663 		    break;
664 		case BICC_BVS:
665 		    eicc = ICC_V;
666 		    break;
667 	        case BICC_BA:
668 		    eicc = 1;
669 		    break;
670 	        case BICC_BNE:
671 		    eicc = ~(ICC_Z);
672 		    break;
673 	        case BICC_BG:
674 		    eicc = ~(ICC_Z | (ICC_N ^ ICC_V));
675 		    break;
676 	        case BICC_BGE:
677 		    eicc = ~(ICC_N ^ ICC_V);
678 		    break;
679 	        case BICC_BGU:
680 		    eicc = ~(ICC_C | ICC_Z);
681 		    break;
682 	        case BICC_BCC:
683 		    eicc = ~(ICC_C);
684 		    break;
685 	        case BICC_POS:
686 		    eicc = ~(ICC_N);
687 		    break;
688 	        case BICC_BVC:
689 		    eicc = ~(ICC_V);
690 		    break;
691 		}
692 		if (eicc & 1) {
693 		    sregs->trap = (0x80 | ((rs1 + operand2) & 0x7f));
694 		}
695 		break;
696 
697 	    case MULScc:
698 		operand1 =
699 		    (((sregs->psr & PSR_V) ^ ((sregs->psr & PSR_N) >> 2))
700 		     << 10) | (rs1 >> 1);
701 		if ((sregs->y & 1) == 0)
702 		    operand2 = 0;
703 		*rdd = operand1 + operand2;
704 		sregs->y = (rs1 << 31) | (sregs->y >> 1);
705 		sregs->psr = add_cc(sregs->psr, operand1, operand2, *rdd);
706 		break;
707 	    case DIVScc:
708 		{
709 		  int sign;
710 		  uint32_t result, remainder;
711 		  int c0, y31;
712 
713 		  if (!sparclite) {
714 		     sregs->trap = TRAP_UNIMP;
715                      break;
716 		  }
717 
718 		  sign = ((sregs->psr & PSR_V) != 0) ^ ((sregs->psr & PSR_N) != 0);
719 
720 		  remainder = (sregs->y << 1) | (rs1 >> 31);
721 
722 		  /* If true sign is positive, calculate remainder - divisor.
723 		     Otherwise, calculate remainder + divisor.  */
724 		  if (sign == 0)
725 		    operand2 = ~operand2 + 1;
726 		  result = remainder + operand2;
727 
728 		  /* The SPARClite User's Manual is not clear on how
729 		     the "carry out" of the above ALU operation is to
730 		     be calculated.  From trial and error tests
731 		     on the the chip itself, it appears that it is
732 		     a normal addition carry, and not a subtraction borrow,
733 		     even in cases where the divisor is subtracted
734 		     from the remainder.  FIXME: get the true story
735 		     from Fujitsu. */
736 		  c0 = result < (uint32_t) remainder
737 		       || result < (uint32_t) operand2;
738 
739 		  if (result & 0x80000000)
740 		    sregs->psr |= PSR_N;
741 		  else
742 		    sregs->psr &= ~PSR_N;
743 
744 		  y31 = (sregs->y & 0x80000000) == 0x80000000;
745 
746 		  if (result == 0 && sign == y31)
747 		    sregs->psr |= PSR_Z;
748 		  else
749 		    sregs->psr &= ~PSR_Z;
750 
751 		  sign = (sign && !y31) || (!c0 && (sign || !y31));
752 
753 		  if (sign ^ (result >> 31))
754 		    sregs->psr |= PSR_V;
755 		  else
756 		    sregs->psr &= ~PSR_V;
757 
758 		  if (!sign)
759 		    sregs->psr |= PSR_C;
760 		  else
761 		    sregs->psr &= ~PSR_C;
762 
763 		  sregs->y = result;
764 
765 		  if (rd != 0)
766 		    *rdd = (rs1 << 1) | !sign;
767 		}
768 		break;
769 	    case SMUL:
770 		{
771 		  mul64 (rs1, operand2, &sregs->y, rdd, 1);
772 		}
773 		break;
774 	    case SMULCC:
775 		{
776 		  uint32_t result;
777 
778 		  mul64 (rs1, operand2, &sregs->y, &result, 1);
779 
780 		  if (result & 0x80000000)
781 		    sregs->psr |= PSR_N;
782 		  else
783 		    sregs->psr &= ~PSR_N;
784 
785 		  if (result == 0)
786 		    sregs->psr |= PSR_Z;
787 		  else
788 		    sregs->psr &= ~PSR_Z;
789 
790 		  *rdd = result;
791 		}
792 		break;
793 	    case UMUL:
794 		{
795 		  mul64 (rs1, operand2, &sregs->y, rdd, 0);
796 		}
797 		break;
798 	    case UMULCC:
799 		{
800 		  uint32_t result;
801 
802 		  mul64 (rs1, operand2, &sregs->y, &result, 0);
803 
804 		  if (result & 0x80000000)
805 		    sregs->psr |= PSR_N;
806 		  else
807 		    sregs->psr &= ~PSR_N;
808 
809 		  if (result == 0)
810 		    sregs->psr |= PSR_Z;
811 		  else
812 		    sregs->psr &= ~PSR_Z;
813 
814 		  *rdd = result;
815 		}
816 		break;
817 	    case SDIV:
818 		{
819 		  if (sparclite) {
820 		     sregs->trap = TRAP_UNIMP;
821                      break;
822 		  }
823 
824 		  if (operand2 == 0) {
825 		    sregs->trap = TRAP_DIV0;
826 		    break;
827 		  }
828 
829 		  div64 (sregs->y, rs1, operand2, rdd, 1);
830 		}
831 		break;
832 	    case SDIVCC:
833 		{
834 		  uint32_t result;
835 
836 		  if (sparclite) {
837 		     sregs->trap = TRAP_UNIMP;
838                      break;
839 		  }
840 
841 		  if (operand2 == 0) {
842 		    sregs->trap = TRAP_DIV0;
843 		    break;
844 		  }
845 
846 		  div64 (sregs->y, rs1, operand2, &result, 1);
847 
848 		  if (result & 0x80000000)
849 		    sregs->psr |= PSR_N;
850 		  else
851 		    sregs->psr &= ~PSR_N;
852 
853 		  if (result == 0)
854 		    sregs->psr |= PSR_Z;
855 		  else
856 		    sregs->psr &= ~PSR_Z;
857 
858 		  /* FIXME: should set overflow flag correctly.  */
859 		  sregs->psr &= ~(PSR_C | PSR_V);
860 
861 		  *rdd = result;
862 		}
863 		break;
864 	    case UDIV:
865 		{
866 		  if (sparclite) {
867 		     sregs->trap = TRAP_UNIMP;
868                      break;
869 		  }
870 
871 		  if (operand2 == 0) {
872 		    sregs->trap = TRAP_DIV0;
873 		    break;
874 		  }
875 
876 		  div64 (sregs->y, rs1, operand2, rdd, 0);
877 		}
878 		break;
879 	    case UDIVCC:
880 		{
881 		  uint32_t result;
882 
883 		  if (sparclite) {
884 		     sregs->trap = TRAP_UNIMP;
885                      break;
886 		  }
887 
888 		  if (operand2 == 0) {
889 		    sregs->trap = TRAP_DIV0;
890 		    break;
891 		  }
892 
893 		  div64 (sregs->y, rs1, operand2, &result, 0);
894 
895 		  if (result & 0x80000000)
896 		    sregs->psr |= PSR_N;
897 		  else
898 		    sregs->psr &= ~PSR_N;
899 
900 		  if (result == 0)
901 		    sregs->psr |= PSR_Z;
902 		  else
903 		    sregs->psr &= ~PSR_Z;
904 
905 		  /* FIXME: should set overflow flag correctly.  */
906 		  sregs->psr &= ~(PSR_C | PSR_V);
907 
908 		  *rdd = result;
909 		}
910 		break;
911 	    case IXNOR:
912 		*rdd = rs1 ^ ~operand2;
913 		break;
914 	    case IXNORCC:
915 		*rdd = rs1 ^ ~operand2;
916 		log_cc(*rdd, sregs);
917 		break;
918 	    case IXOR:
919 		*rdd = rs1 ^ operand2;
920 		break;
921 	    case IXORCC:
922 		*rdd = rs1 ^ operand2;
923 		log_cc(*rdd, sregs);
924 		break;
925 	    case IOR:
926 		*rdd = rs1 | operand2;
927 		break;
928 	    case IORCC:
929 		*rdd = rs1 | operand2;
930 		log_cc(*rdd, sregs);
931 		break;
932 	    case IORN:
933 		*rdd = rs1 | ~operand2;
934 		break;
935 	    case IORNCC:
936 		*rdd = rs1 | ~operand2;
937 		log_cc(*rdd, sregs);
938 		break;
939 	    case IANDNCC:
940 		*rdd = rs1 & ~operand2;
941 		log_cc(*rdd, sregs);
942 		break;
943 	    case IANDN:
944 		*rdd = rs1 & ~operand2;
945 		break;
946 	    case IAND:
947 		*rdd = rs1 & operand2;
948 		break;
949 	    case IANDCC:
950 		*rdd = rs1 & operand2;
951 		log_cc(*rdd, sregs);
952 		break;
953 	    case SUB:
954 		*rdd = rs1 - operand2;
955 		break;
956 	    case SUBCC:
957 		*rdd = rs1 - operand2;
958 		sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd);
959 		break;
960 	    case SUBX:
961 		*rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1);
962 		break;
963 	    case SUBXCC:
964 		*rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1);
965 		sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd);
966 		break;
967 	    case ADD:
968 		*rdd = rs1 + operand2;
969 		break;
970 	    case ADDCC:
971 		*rdd = rs1 + operand2;
972 		sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
973 		break;
974 	    case ADDX:
975 		*rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1);
976 		break;
977 	    case ADDXCC:
978 		*rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1);
979 		sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
980 		break;
981 	    case TADDCC:
982 		*rdd = rs1 + operand2;
983 		sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
984 		if ((rs1 | operand2) & 0x3)
985 		    sregs->psr |= PSR_V;
986 		break;
987 	    case TSUBCC:
988 		*rdd = rs1 - operand2;
989 		sregs->psr = sub_cc (sregs->psr, rs1, operand2, *rdd);
990 		if ((rs1 | operand2) & 0x3)
991 		    sregs->psr |= PSR_V;
992 		break;
993 	    case TADDCCTV:
994 		*rdd = rs1 + operand2;
995 		result = add_cc(0, rs1, operand2, *rdd);
996 		if ((rs1 | operand2) & 0x3)
997 		    result |= PSR_V;
998 		if (result & PSR_V) {
999 		    sregs->trap = TRAP_TAG;
1000 		} else {
1001 		    sregs->psr = (sregs->psr & ~PSR_CC) | result;
1002 		}
1003 		break;
1004 	    case TSUBCCTV:
1005 		*rdd = rs1 - operand2;
1006 		result = add_cc (0, rs1, operand2, *rdd);
1007 		if ((rs1 | operand2) & 0x3)
1008 		    result |= PSR_V;
1009 		if (result & PSR_V)
1010 		  {
1011 		      sregs->trap = TRAP_TAG;
1012 		  }
1013 		else
1014 		  {
1015 		      sregs->psr = (sregs->psr & ~PSR_CC) | result;
1016 		  }
1017 		break;
1018 	    case SLL:
1019 		*rdd = rs1 << (operand2 & 0x1f);
1020 		break;
1021 	    case SRL:
1022 		*rdd = rs1 >> (operand2 & 0x1f);
1023 		break;
1024 	    case SRA:
1025 		*rdd = ((int) rs1) >> (operand2 & 0x1f);
1026 		break;
1027 	    case FLUSH:
1028 		if (ift) sregs->trap = TRAP_UNIMP;
1029 		break;
1030 	    case SAVE:
1031 		new_cwp = ((sregs->psr & PSR_CWP) - 1) & PSR_CWP;
1032 		if (sregs->wim & (1 << new_cwp)) {
1033 		    sregs->trap = TRAP_WOFL;
1034 		    break;
1035 		}
1036 		if (rd > 7)
1037 		    rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]);
1038 		*rdd = rs1 + operand2;
1039 		sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp;
1040 		break;
1041 	    case RESTORE:
1042 
1043 		new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP;
1044 		if (sregs->wim & (1 << new_cwp)) {
1045 		    sregs->trap = TRAP_WUFL;
1046 		    break;
1047 		}
1048 		if (rd > 7)
1049 		    rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]);
1050 		*rdd = rs1 + operand2;
1051 		sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp;
1052 		break;
1053 	    case RDPSR:
1054 		if (!(sregs->psr & PSR_S)) {
1055 		    sregs->trap = TRAP_PRIVI;
1056 		    break;
1057 		}
1058 		*rdd = sregs->psr;
1059 		break;
1060 	    case RDY:
1061                 if (!sparclite)
1062                     *rdd = sregs->y;
1063                 else {
1064                     int rs1_is_asr = (sregs->inst >> 14) & 0x1f;
1065                     if ( 0 == rs1_is_asr )
1066                         *rdd = sregs->y;
1067                     else if ( 17 == rs1_is_asr )
1068                         *rdd = sregs->asr17;
1069                     else {
1070                         sregs->trap = TRAP_UNIMP;
1071                         break;
1072                     }
1073                 }
1074 		break;
1075 	    case RDWIM:
1076 		if (!(sregs->psr & PSR_S)) {
1077 		    sregs->trap = TRAP_PRIVI;
1078 		    break;
1079 		}
1080 		*rdd = sregs->wim;
1081 		break;
1082 	    case RDTBR:
1083 		if (!(sregs->psr & PSR_S)) {
1084 		    sregs->trap = TRAP_PRIVI;
1085 		    break;
1086 		}
1087 		*rdd = sregs->tbr;
1088 		break;
1089 	    case WRPSR:
1090 		if ((sregs->psr & 0x1f) > 7) {
1091 		    sregs->trap = TRAP_UNIMP;
1092 		    break;
1093 		}
1094 		if (!(sregs->psr & PSR_S)) {
1095 		    sregs->trap = TRAP_PRIVI;
1096 		    break;
1097 		}
1098 		sregs->psr = (sregs->psr & 0xff000000) |
1099 			((rs1 ^ operand2) & 0x00f03fff);
1100 		break;
1101 	    case WRWIM:
1102 		if (!(sregs->psr & PSR_S)) {
1103 		    sregs->trap = TRAP_PRIVI;
1104 		    break;
1105 		}
1106 		sregs->wim = (rs1 ^ operand2) & 0x0ff;
1107 		break;
1108 	    case WRTBR:
1109 		if (!(sregs->psr & PSR_S)) {
1110 		    sregs->trap = TRAP_PRIVI;
1111 		    break;
1112 		}
1113 		sregs->tbr = (sregs->tbr & 0x00000ff0) |
1114 		    ((rs1 ^ operand2) & 0xfffff000);
1115 		break;
1116 	    case WRY:
1117                 if (!sparclite)
1118                     sregs->y = (rs1 ^ operand2);
1119                 else {
1120                     if ( 0 == rd )
1121                         sregs->y = (rs1 ^ operand2);
1122                     else if ( 17 == rd )
1123                         sregs->asr17 = (rs1 ^ operand2);
1124                     else {
1125                         sregs->trap = TRAP_UNIMP;
1126                         break;
1127                     }
1128                 }
1129 		break;
1130 	    case JMPL:
1131 
1132 #ifdef STAT
1133 		sregs->nbranch++;
1134 #endif
1135 		sregs->icnt = T_JMPL;	/* JMPL takes two cycles */
1136 		if (rs1 & 0x3) {
1137 		    sregs->trap = TRAP_UNALI;
1138 		    break;
1139 		}
1140 		*rdd = sregs->pc;
1141 		npc = rs1 + operand2;
1142 		break;
1143 	    case RETT:
1144 		address = rs1 + operand2;
1145 		new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP;
1146 		sregs->icnt = T_RETT;	/* RETT takes two cycles */
1147 		if (sregs->psr & PSR_ET) {
1148 		    sregs->trap = TRAP_UNIMP;
1149 		    break;
1150 		}
1151 		if (!(sregs->psr & PSR_S)) {
1152 		    sregs->trap = TRAP_PRIVI;
1153 		    break;
1154 		}
1155 		if (sregs->wim & (1 << new_cwp)) {
1156 		    sregs->trap = TRAP_WUFL;
1157 		    break;
1158 		}
1159 		if (address & 0x3) {
1160 		    sregs->trap = TRAP_UNALI;
1161 		    break;
1162 		}
1163 		sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp | PSR_ET;
1164 		sregs->psr =
1165 		    (sregs->psr & ~PSR_S) | ((sregs->psr & PSR_PS) << 1);
1166 		npc = address;
1167 		break;
1168 
1169 	    case SCAN:
1170 		{
1171 		  uint32_t result, mask;
1172 		  int i;
1173 
1174 		  if (!sparclite) {
1175 		     sregs->trap = TRAP_UNIMP;
1176                      break;
1177 		  }
1178 		  mask = (operand2 & 0x80000000) | (operand2 >> 1);
1179 		  result = rs1 ^ mask;
1180 
1181 		  for (i = 0; i < 32; i++) {
1182 		    if (result & 0x80000000)
1183 		      break;
1184 		    result <<= 1;
1185 		  }
1186 
1187 		  *rdd = i == 32 ? 63 : i;
1188 		}
1189 		break;
1190 
1191 	    default:
1192 		sregs->trap = TRAP_UNIMP;
1193 		break;
1194 	    }
1195 	}
1196 	break;
1197     case 3:			/* Load/store instructions */
1198 
1199 	address = rs1 + operand2;
1200 
1201 	if (sregs->psr & PSR_S)
1202 	    asi = 11;
1203 	 else
1204 	    asi = 10;
1205 
1206 	if (op3 & 4) {
1207 	    sregs->icnt = T_ST;	/* Set store instruction count */
1208 #ifdef STAT
1209 	    sregs->nstore++;
1210 #endif
1211 	} else {
1212 	    sregs->icnt = T_LD;	/* Set load instruction count */
1213 #ifdef STAT
1214 	    sregs->nload++;
1215 #endif
1216 	}
1217 
1218 	/* Decode load/store instructions */
1219 
1220 	switch (op3) {
1221 	case LDDA:
1222 	    if (!chk_asi(sregs, &asi, op3)) break;
1223 	case LDD:
1224 	    if (address & 0x7) {
1225 		sregs->trap = TRAP_UNALI;
1226 		break;
1227 	    }
1228 	    if (rd & 1) {
1229 		rd &= 0x1e;
1230 		if (rd > 7)
1231 		    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
1232 		else
1233 		    rdd = &(sregs->g[rd]);
1234 	    }
1235 	    mexc = memory_read (asi, address, ddata, 2, &ws);
1236 	    sregs->hold += ws;
1237 	    mexc |= memory_read (asi, address+4, &ddata[1], 2, &ws);
1238 	    sregs->hold += ws;
1239 	    sregs->icnt = T_LDD;
1240 	    if (mexc) {
1241 		sregs->trap = TRAP_DEXC;
1242 	    } else {
1243 		rdd[0] = ddata[0];
1244 		rdd[1] = ddata[1];
1245 #ifdef STAT
1246 		sregs->nload++;	/* Double load counts twice */
1247 #endif
1248 	    }
1249 	    break;
1250 
1251 	case LDA:
1252 	    if (!chk_asi(sregs, &asi, op3)) break;
1253 	case LD:
1254 	    if (address & 0x3) {
1255 		sregs->trap = TRAP_UNALI;
1256 		break;
1257 	    }
1258 	    mexc = memory_read(asi, address, &data, 2, &ws);
1259 	    sregs->hold += ws;
1260 	    if (mexc) {
1261 		sregs->trap = TRAP_DEXC;
1262 	    } else {
1263 		*rdd = data;
1264 	    }
1265 	    break;
1266 	case LDSTUBA:
1267 	    if (!chk_asi(sregs, &asi, op3)) break;
1268 	case LDSTUB:
1269 	    mexc = memory_read(asi, address, &data, 0, &ws);
1270 	    sregs->hold += ws;
1271 	    sregs->icnt = T_LDST;
1272 	    if (mexc) {
1273 		sregs->trap = TRAP_DEXC;
1274 		break;
1275 	    }
1276 	    data = extract_byte (data, address);
1277 	    *rdd = data;
1278 	    data = 0x0ff;
1279 	    mexc = memory_write(asi, address, &data, 0, &ws);
1280 	    sregs->hold += ws;
1281 	    if (mexc) {
1282 		sregs->trap = TRAP_DEXC;
1283 	    }
1284 #ifdef STAT
1285 	    sregs->nload++;
1286 #endif
1287 	    break;
1288 	case LDSBA:
1289 	case LDUBA:
1290 	    if (!chk_asi(sregs, &asi, op3)) break;
1291 	case LDSB:
1292 	case LDUB:
1293 	    mexc = memory_read(asi, address, &data, 0, &ws);
1294 	    sregs->hold += ws;
1295 	    if (mexc) {
1296 		sregs->trap = TRAP_DEXC;
1297 		break;
1298 	    }
1299 	    if (op3 == LDSB)
1300 	        data = extract_byte_signed (data, address);
1301 	    else
1302 	        data = extract_byte (data, address);
1303 	    *rdd = data;
1304 	    break;
1305 	case LDSHA:
1306 	case LDUHA:
1307 	    if (!chk_asi(sregs, &asi, op3)) break;
1308 	case LDSH:
1309 	case LDUH:
1310 	    if (address & 0x1) {
1311 		sregs->trap = TRAP_UNALI;
1312 		break;
1313 	    }
1314 	    mexc = memory_read(asi, address, &data, 1, &ws);
1315 	    sregs->hold += ws;
1316 	    if (mexc) {
1317 		sregs->trap = TRAP_DEXC;
1318 		break;
1319 	    }
1320 	    if (op3 == LDSH)
1321 	        data = extract_short_signed (data, address);
1322 	    else
1323 	        data = extract_short (data, address);
1324 	    *rdd = data;
1325 	    break;
1326 	case LDF:
1327 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1328 		sregs->trap = TRAP_FPDIS;
1329 		break;
1330 	    }
1331 	    if (address & 0x3) {
1332 		sregs->trap = TRAP_UNALI;
1333 		break;
1334 	    }
1335 	    if (ebase.simtime < sregs->ftime) {
1336 		if ((sregs->frd == rd) || (sregs->frs1 == rd) ||
1337 		    (sregs->frs2 == rd))
1338 		    sregs->fhold += (sregs->ftime - ebase.simtime);
1339 	    }
1340 	    mexc = memory_read(asi, address, &data, 2, &ws);
1341 	    sregs->hold += ws;
1342 	    sregs->flrd = rd;
1343 	    sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
1344 		sregs->hold + sregs->fhold;
1345 	    if (mexc) {
1346 		sregs->trap = TRAP_DEXC;
1347 	    } else {
1348 		memcpy (&sregs->fs[rd], &data, sizeof (sregs->fs[rd]));
1349 	    }
1350 	    break;
1351 	case LDDF:
1352 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1353 		sregs->trap = TRAP_FPDIS;
1354 		break;
1355 	    }
1356 	    if (address & 0x7) {
1357 		sregs->trap = TRAP_UNALI;
1358 		break;
1359 	    }
1360 	    if (ebase.simtime < sregs->ftime) {
1361 		if (((sregs->frd >> 1) == (rd >> 1)) ||
1362 		    ((sregs->frs1 >> 1) == (rd >> 1)) ||
1363 		    ((sregs->frs2 >> 1) == (rd >> 1)))
1364 		    sregs->fhold += (sregs->ftime - ebase.simtime);
1365 	    }
1366 	    mexc = memory_read (asi, address, ddata, 2, &ws);
1367 	    sregs->hold += ws;
1368 	    mexc |= memory_read (asi, address+4, &ddata[1], 2, &ws);
1369 	    sregs->hold += ws;
1370 	    sregs->icnt = T_LDD;
1371 	    if (mexc) {
1372 		sregs->trap = TRAP_DEXC;
1373 	    } else {
1374 		rd &= 0x1E;
1375 		sregs->flrd = rd;
1376 		memcpy (&sregs->fs[rd], &ddata[0], sizeof (sregs->fs[rd]));
1377 #ifdef STAT
1378 		sregs->nload++;	/* Double load counts twice */
1379 #endif
1380 		memcpy (&sregs->fs[rd + 1], &ddata[1],
1381 			sizeof (sregs->fs[rd + 1]));
1382 		sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
1383 			       sregs->hold + sregs->fhold;
1384 	    }
1385 	    break;
1386 	case LDFSR:
1387 	    if (ebase.simtime < sregs->ftime) {
1388 		sregs->fhold += (sregs->ftime - ebase.simtime);
1389 	    }
1390 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1391 		sregs->trap = TRAP_FPDIS;
1392 		break;
1393 	    }
1394 	    if (address & 0x3) {
1395 		sregs->trap = TRAP_UNALI;
1396 		break;
1397 	    }
1398 	    mexc = memory_read(asi, address, &data, 2, &ws);
1399 	    sregs->hold += ws;
1400 	    if (mexc) {
1401 		sregs->trap = TRAP_DEXC;
1402 	    } else {
1403 		sregs->fsr =
1404 		    (sregs->fsr & 0x7FF000) | (data & ~0x7FF000);
1405 		set_fsr(sregs->fsr);
1406 	    }
1407 	    break;
1408 	case STFSR:
1409 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1410 		sregs->trap = TRAP_FPDIS;
1411 		break;
1412 	    }
1413 	    if (address & 0x3) {
1414 		sregs->trap = TRAP_UNALI;
1415 		break;
1416 	    }
1417 	    if (ebase.simtime < sregs->ftime) {
1418 		sregs->fhold += (sregs->ftime - ebase.simtime);
1419 	    }
1420 	    mexc = memory_write(asi, address, &sregs->fsr, 2, &ws);
1421 	    sregs->hold += ws;
1422 	    if (mexc) {
1423 		sregs->trap = TRAP_DEXC;
1424 	    }
1425 	    break;
1426 
1427 	case STA:
1428 	    if (!chk_asi(sregs, &asi, op3)) break;
1429 	case ST:
1430 	    if (address & 0x3) {
1431 		sregs->trap = TRAP_UNALI;
1432 		break;
1433 	    }
1434 	    mexc = memory_write(asi, address, rdd, 2, &ws);
1435 	    sregs->hold += ws;
1436 	    if (mexc) {
1437 		sregs->trap = TRAP_DEXC;
1438 	    }
1439 	    break;
1440 	case STBA:
1441 	    if (!chk_asi(sregs, &asi, op3)) break;
1442 	case STB:
1443 	    mexc = memory_write(asi, address, rdd, 0, &ws);
1444 	    sregs->hold += ws;
1445 	    if (mexc) {
1446 		sregs->trap = TRAP_DEXC;
1447 	    }
1448 	    break;
1449 	case STDA:
1450 	    if (!chk_asi(sregs, &asi, op3)) break;
1451 	case STD:
1452 	    if (address & 0x7) {
1453 		sregs->trap = TRAP_UNALI;
1454 		break;
1455 	    }
1456 	    if (rd & 1) {
1457 		rd &= 0x1e;
1458 		if (rd > 7)
1459 		    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
1460 		else
1461 		    rdd = &(sregs->g[rd]);
1462 	    }
1463 	    mexc = memory_write(asi, address, rdd, 3, &ws);
1464 	    sregs->hold += ws;
1465 	    sregs->icnt = T_STD;
1466 #ifdef STAT
1467 	    sregs->nstore++;	/* Double store counts twice */
1468 #endif
1469 	    if (mexc) {
1470 		sregs->trap = TRAP_DEXC;
1471 		break;
1472 	    }
1473 	    break;
1474 	case STDFQ:
1475 	    if ((sregs->psr & 0x1f) > 7) {
1476 		sregs->trap = TRAP_UNIMP;
1477 		break;
1478 	    }
1479 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1480 		sregs->trap = TRAP_FPDIS;
1481 		break;
1482 	    }
1483 	    if (address & 0x7) {
1484 		sregs->trap = TRAP_UNALI;
1485 		break;
1486 	    }
1487 	    if (!(sregs->fsr & FSR_QNE)) {
1488 		sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR;
1489 		break;
1490 	    }
1491 	    rdd = &(sregs->fpq[0]);
1492 	    mexc = memory_write(asi, address, rdd, 3, &ws);
1493 	    sregs->hold += ws;
1494 	    sregs->icnt = T_STD;
1495 #ifdef STAT
1496 	    sregs->nstore++;	/* Double store counts twice */
1497 #endif
1498 	    if (mexc) {
1499 		sregs->trap = TRAP_DEXC;
1500 		break;
1501 	    } else {
1502 		sregs->fsr &= ~FSR_QNE;
1503 		sregs->fpstate = FP_EXE_MODE;
1504 	    }
1505 	    break;
1506 	case STHA:
1507 	    if (!chk_asi(sregs, &asi, op3)) break;
1508 	case STH:
1509 	    if (address & 0x1) {
1510 		sregs->trap = TRAP_UNALI;
1511 		break;
1512 	    }
1513 	    mexc = memory_write(asi, address, rdd, 1, &ws);
1514 	    sregs->hold += ws;
1515 	    if (mexc) {
1516 		sregs->trap = TRAP_DEXC;
1517 	    }
1518 	    break;
1519 	case STF:
1520 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1521 		sregs->trap = TRAP_FPDIS;
1522 		break;
1523 	    }
1524 	    if (address & 0x3) {
1525 		sregs->trap = TRAP_UNALI;
1526 		break;
1527 	    }
1528 	    if (ebase.simtime < sregs->ftime) {
1529 		if (sregs->frd == rd)
1530 		    sregs->fhold += (sregs->ftime - ebase.simtime);
1531 	    }
1532 	    mexc = memory_write(asi, address, (uint32_t *)&sregs->fsi[rd], 2, &ws);
1533 	    sregs->hold += ws;
1534 	    if (mexc) {
1535 		sregs->trap = TRAP_DEXC;
1536 	    }
1537 	    break;
1538 	case STDF:
1539 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1540 		sregs->trap = TRAP_FPDIS;
1541 		break;
1542 	    }
1543 	    if (address & 0x7) {
1544 		sregs->trap = TRAP_UNALI;
1545 		break;
1546 	    }
1547 	    rd &= 0x1E;
1548 	    if (ebase.simtime < sregs->ftime) {
1549 		if ((sregs->frd == rd) || (sregs->frd + 1 == rd))
1550 		    sregs->fhold += (sregs->ftime - ebase.simtime);
1551 	    }
1552 	    mexc = memory_write(asi, address, (uint32_t *)&sregs->fsi[rd], 3, &ws);
1553 	    sregs->hold += ws;
1554 	    sregs->icnt = T_STD;
1555 #ifdef STAT
1556 	    sregs->nstore++;	/* Double store counts twice */
1557 #endif
1558 	    if (mexc) {
1559 		sregs->trap = TRAP_DEXC;
1560 	    }
1561 	    break;
1562 	case SWAPA:
1563 	    if (!chk_asi(sregs, &asi, op3)) break;
1564 	case SWAP:
1565 	    if (address & 0x3) {
1566 		sregs->trap = TRAP_UNALI;
1567 		break;
1568 	    }
1569 	    mexc = memory_read(asi, address, &data, 2, &ws);
1570 	    sregs->hold += ws;
1571 	    if (mexc) {
1572 		sregs->trap = TRAP_DEXC;
1573 		break;
1574 	    }
1575 	    mexc = memory_write(asi, address, rdd, 2, &ws);
1576 	    sregs->hold += ws;
1577 	    sregs->icnt = T_LDST;
1578 	    if (mexc) {
1579 		sregs->trap = TRAP_DEXC;
1580 		break;
1581 	    } else
1582 		*rdd = data;
1583 #ifdef STAT
1584 	    sregs->nload++;
1585 #endif
1586 	    break;
1587 
1588 
1589 	default:
1590 	    sregs->trap = TRAP_UNIMP;
1591 	    break;
1592 	}
1593 
1594 #ifdef LOAD_DEL
1595 
1596 	if (!(op3 & 4)) {
1597 	    sregs->ildtime = ebase.simtime + sregs->hold + sregs->icnt;
1598 	    sregs->ildreg = rd;
1599 	    if ((op3 | 0x10) == 0x13)
1600 		sregs->ildreg |= 1;	/* Double load, odd register loaded
1601 					 * last */
1602 	}
1603 #endif
1604 	break;
1605 
1606     default:
1607 	sregs->trap = TRAP_UNIMP;
1608 	break;
1609     }
1610     sregs->g[0] = 0;
1611     if (!sregs->trap) {
1612 	sregs->pc = pc;
1613 	sregs->npc = npc;
1614     }
1615     return 0;
1616 }
1617 
1618 #define T_FABSs		2
1619 #define T_FADDs		4
1620 #define T_FADDd		4
1621 #define T_FCMPs		4
1622 #define T_FCMPd		4
1623 #define T_FDIVs		20
1624 #define T_FDIVd		35
1625 #define T_FMOVs		2
1626 #define T_FMULs		5
1627 #define T_FMULd		9
1628 #define T_FNEGs		2
1629 #define T_FSQRTs	37
1630 #define T_FSQRTd	65
1631 #define T_FSUBs		4
1632 #define T_FSUBd		4
1633 #define T_FdTOi		7
1634 #define T_FdTOs		3
1635 #define T_FiTOs		6
1636 #define T_FiTOd		6
1637 #define T_FsTOi		6
1638 #define T_FsTOd		2
1639 
1640 #define FABSs	0x09
1641 #define FADDs	0x41
1642 #define FADDd	0x42
1643 #define FCMPs	0x51
1644 #define FCMPd	0x52
1645 #define FCMPEs	0x55
1646 #define FCMPEd	0x56
1647 #define FDIVs	0x4D
1648 #define FDIVd	0x4E
1649 #define FMOVs	0x01
1650 #define FMULs	0x49
1651 #define FMULd	0x4A
1652 #define FNEGs	0x05
1653 #define FSQRTs	0x29
1654 #define FSQRTd	0x2A
1655 #define FSUBs	0x45
1656 #define FSUBd	0x46
1657 #define FdTOi	0xD2
1658 #define FdTOs	0xC6
1659 #define FiTOs	0xC4
1660 #define FiTOd	0xC8
1661 #define FsTOi	0xD1
1662 #define FsTOd	0xC9
1663 
1664 
1665 static int
1666 fpexec(uint32_t op3, uint32_t rd, uint32_t rs1, uint32_t rs2, struct pstate *sregs)
1667 {
1668     uint32_t          opf, tem, accex;
1669     int32_t           fcc;
1670     uint32_t          ldadj;
1671 
1672     if (sregs->fpstate == FP_EXC_MODE) {
1673 	sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR;
1674 	sregs->fpstate = FP_EXC_PE;
1675 	return 0;
1676     }
1677     if (sregs->fpstate == FP_EXC_PE) {
1678 	sregs->fpstate = FP_EXC_MODE;
1679 	return TRAP_FPEXC;
1680     }
1681     opf = (sregs->inst >> 5) & 0x1ff;
1682 
1683     /*
1684      * Check if we already have an FPop in the pipe. If so, halt until it is
1685      * finished by incrementing fhold with the remaining execution time
1686      */
1687 
1688     if (ebase.simtime < sregs->ftime) {
1689 	sregs->fhold = (sregs->ftime - ebase.simtime);
1690     } else {
1691 	sregs->fhold = 0;
1692 
1693 	/* Check load dependencies. */
1694 
1695 	if (ebase.simtime < sregs->ltime) {
1696 
1697 	    /* Don't check rs1 if single operand instructions */
1698 
1699 	    if (((opf >> 6) == 0) || ((opf >> 6) == 3))
1700 		rs1 = 32;
1701 
1702 	    /* Adjust for double floats */
1703 
1704 	    ldadj = opf & 1;
1705 	    if (!(((sregs->flrd - rs1) >> ldadj) && ((sregs->flrd - rs2) >> ldadj)))
1706 		sregs->fhold++;
1707 	}
1708     }
1709 
1710     sregs->finst++;
1711 
1712     sregs->frs1 = rs1;		/* Store src and dst for dependecy check */
1713     sregs->frs2 = rs2;
1714     sregs->frd = rd;
1715 
1716     sregs->ftime = ebase.simtime + sregs->hold + sregs->fhold;
1717 
1718     /* SPARC is big-endian - swap double floats if host is little-endian */
1719     /* This is ugly - I know ... */
1720 
1721     /* FIXME: should use (HOST_BYTE_ORDER == CURRENT_TARGET_BYTE_ORDER)
1722        but what about machines where float values are different endianness
1723        from integer values? */
1724 
1725 #ifdef HOST_LITTLE_ENDIAN
1726     rs1 &= 0x1f;
1727     switch (opf) {
1728 	case FADDd:
1729 	case FDIVd:
1730 	case FMULd:
1731 	case FSQRTd:
1732 	case FSUBd:
1733         case FCMPd:
1734         case FCMPEd:
1735 	case FdTOi:
1736 	case FdTOs:
1737     	    sregs->fdp[rs1 | 1] = sregs->fs[rs1 & ~1];
1738     	    sregs->fdp[rs1 & ~1] = sregs->fs[rs1 | 1];
1739     	    sregs->fdp[rs2 | 1] = sregs->fs[rs2 & ~1];
1740     	    sregs->fdp[rs2 & ~1] = sregs->fs[rs2 | 1];
1741     default:
1742       break;
1743     }
1744 #endif
1745 
1746     clear_accex();
1747 
1748     switch (opf) {
1749     case FABSs:
1750 	sregs->fs[rd] = fabs(sregs->fs[rs2]);
1751 	sregs->ftime += T_FABSs;
1752 	sregs->frs1 = 32;	/* rs1 ignored */
1753 	break;
1754     case FADDs:
1755 	sregs->fs[rd] = sregs->fs[rs1] + sregs->fs[rs2];
1756 	sregs->ftime += T_FADDs;
1757 	break;
1758     case FADDd:
1759 	sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] + sregs->fd[rs2 >> 1];
1760 	sregs->ftime += T_FADDd;
1761 	break;
1762     case FCMPs:
1763     case FCMPEs:
1764 	if (sregs->fs[rs1] == sregs->fs[rs2])
1765 	    fcc = 3;
1766 	else if (sregs->fs[rs1] < sregs->fs[rs2])
1767 	    fcc = 2;
1768 	else if (sregs->fs[rs1] > sregs->fs[rs2])
1769 	    fcc = 1;
1770 	else
1771 	    fcc = 0;
1772 	sregs->fsr |= 0x0C00;
1773 	sregs->fsr &= ~(fcc << 10);
1774 	sregs->ftime += T_FCMPs;
1775 	sregs->frd = 32;	/* rd ignored */
1776 	if ((fcc == 0) && (opf == FCMPEs)) {
1777 	    sregs->fpstate = FP_EXC_PE;
1778 	    sregs->fsr = (sregs->fsr & ~0x1C000) | (1 << 14);
1779 	}
1780 	break;
1781     case FCMPd:
1782     case FCMPEd:
1783 	if (sregs->fd[rs1 >> 1] == sregs->fd[rs2 >> 1])
1784 	    fcc = 3;
1785 	else if (sregs->fd[rs1 >> 1] < sregs->fd[rs2 >> 1])
1786 	    fcc = 2;
1787 	else if (sregs->fd[rs1 >> 1] > sregs->fd[rs2 >> 1])
1788 	    fcc = 1;
1789 	else
1790 	    fcc = 0;
1791 	sregs->fsr |= 0x0C00;
1792 	sregs->fsr &= ~(fcc << 10);
1793 	sregs->ftime += T_FCMPd;
1794 	sregs->frd = 32;	/* rd ignored */
1795 	if ((fcc == 0) && (opf == FCMPEd)) {
1796 	    sregs->fpstate = FP_EXC_PE;
1797 	    sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
1798 	}
1799 	break;
1800     case FDIVs:
1801 	sregs->fs[rd] = sregs->fs[rs1] / sregs->fs[rs2];
1802 	sregs->ftime += T_FDIVs;
1803 	break;
1804     case FDIVd:
1805 	sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] / sregs->fd[rs2 >> 1];
1806 	sregs->ftime += T_FDIVd;
1807 	break;
1808     case FMOVs:
1809 	sregs->fs[rd] = sregs->fs[rs2];
1810 	sregs->ftime += T_FMOVs;
1811 	sregs->frs1 = 32;	/* rs1 ignored */
1812 	break;
1813     case FMULs:
1814 	sregs->fs[rd] = sregs->fs[rs1] * sregs->fs[rs2];
1815 	sregs->ftime += T_FMULs;
1816 	break;
1817     case FMULd:
1818 	sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] * sregs->fd[rs2 >> 1];
1819 	sregs->ftime += T_FMULd;
1820 	break;
1821     case FNEGs:
1822 	sregs->fs[rd] = -sregs->fs[rs2];
1823 	sregs->ftime += T_FNEGs;
1824 	sregs->frs1 = 32;	/* rs1 ignored */
1825 	break;
1826     case FSQRTs:
1827 	if (sregs->fs[rs2] < 0.0) {
1828 	    sregs->fpstate = FP_EXC_PE;
1829 	    sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
1830 	    sregs->fsr = (sregs->fsr & 0x1f) | 0x10;
1831 	    break;
1832 	}
1833 	sregs->fs[rd] = sqrt(sregs->fs[rs2]);
1834 	sregs->ftime += T_FSQRTs;
1835 	sregs->frs1 = 32;	/* rs1 ignored */
1836 	break;
1837     case FSQRTd:
1838 	if (sregs->fd[rs2 >> 1] < 0.0) {
1839 	    sregs->fpstate = FP_EXC_PE;
1840 	    sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
1841 	    sregs->fsr = (sregs->fsr & 0x1f) | 0x10;
1842 	    break;
1843 	}
1844 	sregs->fd[rd >> 1] = sqrt(sregs->fd[rs2 >> 1]);
1845 	sregs->ftime += T_FSQRTd;
1846 	sregs->frs1 = 32;	/* rs1 ignored */
1847 	break;
1848     case FSUBs:
1849 	sregs->fs[rd] = sregs->fs[rs1] - sregs->fs[rs2];
1850 	sregs->ftime += T_FSUBs;
1851 	break;
1852     case FSUBd:
1853 	sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] - sregs->fd[rs2 >> 1];
1854 	sregs->ftime += T_FSUBd;
1855 	break;
1856     case FdTOi:
1857 	sregs->fsi[rd] = (int) sregs->fd[rs2 >> 1];
1858 	sregs->ftime += T_FdTOi;
1859 	sregs->frs1 = 32;	/* rs1 ignored */
1860 	break;
1861     case FdTOs:
1862 	sregs->fs[rd] = (float32) sregs->fd[rs2 >> 1];
1863 	sregs->ftime += T_FdTOs;
1864 	sregs->frs1 = 32;	/* rs1 ignored */
1865 	break;
1866     case FiTOs:
1867 	sregs->fs[rd] = (float32) sregs->fsi[rs2];
1868 	sregs->ftime += T_FiTOs;
1869 	sregs->frs1 = 32;	/* rs1 ignored */
1870 	break;
1871     case FiTOd:
1872 	sregs->fd[rd >> 1] = (float64) sregs->fsi[rs2];
1873 	sregs->ftime += T_FiTOd;
1874 	sregs->frs1 = 32;	/* rs1 ignored */
1875 	break;
1876     case FsTOi:
1877 	sregs->fsi[rd] = (int) sregs->fs[rs2];
1878 	sregs->ftime += T_FsTOi;
1879 	sregs->frs1 = 32;	/* rs1 ignored */
1880 	break;
1881     case FsTOd:
1882 	sregs->fd[rd >> 1] = sregs->fs[rs2];
1883 	sregs->ftime += T_FsTOd;
1884 	sregs->frs1 = 32;	/* rs1 ignored */
1885 	break;
1886 
1887     default:
1888 	sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_UNIMP;
1889 	sregs->fpstate = FP_EXC_PE;
1890     }
1891 
1892 #ifdef ERRINJ
1893     if (errftt) {
1894 	sregs->fsr = (sregs->fsr & ~FSR_TT) | (errftt << 14);
1895 	sregs->fpstate = FP_EXC_PE;
1896 	if (sis_verbose) printf("Inserted fpu error %X\n",errftt);
1897 	errftt = 0;
1898     }
1899 #endif
1900 
1901     accex = get_accex();
1902 
1903 #ifdef HOST_LITTLE_ENDIAN
1904     switch (opf) {
1905     case FADDd:
1906     case FDIVd:
1907     case FMULd:
1908     case FSQRTd:
1909     case FSUBd:
1910     case FiTOd:
1911     case FsTOd:
1912 	sregs->fs[rd & ~1] = sregs->fdp[rd | 1];
1913 	sregs->fs[rd | 1] = sregs->fdp[rd & ~1];
1914     default:
1915       break;
1916     }
1917 #endif
1918     if (sregs->fpstate == FP_EXC_PE) {
1919 	sregs->fpq[0] = sregs->pc;
1920 	sregs->fpq[1] = sregs->inst;
1921 	sregs->fsr |= FSR_QNE;
1922     } else {
1923 	tem = (sregs->fsr >> 23) & 0x1f;
1924 	if (tem & accex) {
1925 	    sregs->fpstate = FP_EXC_PE;
1926 	    sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
1927 	    sregs->fsr = ((sregs->fsr & ~0x1f) | accex);
1928 	} else {
1929 	    sregs->fsr = ((((sregs->fsr >> 5) | accex) << 5) | accex);
1930 	}
1931 	if (sregs->fpstate == FP_EXC_PE) {
1932 	    sregs->fpq[0] = sregs->pc;
1933 	    sregs->fpq[1] = sregs->inst;
1934 	    sregs->fsr |= FSR_QNE;
1935 	}
1936     }
1937     clear_accex();
1938 
1939     return 0;
1940 
1941 
1942 }
1943 
1944 static int
1945 chk_asi(struct pstate *sregs, uint32_t *asi, uint32_t op3)
1946 {
1947     if (!(sregs->psr & PSR_S)) {
1948 	sregs->trap = TRAP_PRIVI;
1949 	return 0;
1950     } else if (sregs->inst & INST_I) {
1951 	sregs->trap = TRAP_UNIMP;
1952 	return 0;
1953     } else
1954 	*asi = (sregs->inst >> 5) & 0x0ff;
1955     return 1;
1956 }
1957 
1958 int
1959 execute_trap(struct pstate *sregs)
1960 {
1961     int32_t           cwp;
1962 
1963     if (sregs->trap == 256) {
1964 	sregs->pc = 0;
1965 	sregs->npc = 4;
1966 	sregs->trap = 0;
1967     } else if (sregs->trap == 257) {
1968 	    return ERROR;
1969     } else {
1970 
1971 	if ((sregs->psr & PSR_ET) == 0)
1972 	    return ERROR;
1973 
1974 	sregs->tbr = (sregs->tbr & 0xfffff000) | (sregs->trap << 4);
1975 	sregs->trap = 0;
1976 	sregs->psr &= ~PSR_ET;
1977 	sregs->psr |= ((sregs->psr & PSR_S) >> 1);
1978 	sregs->annul = 0;
1979 	sregs->psr = (((sregs->psr & PSR_CWP) - 1) & 0x7) | (sregs->psr & ~PSR_CWP);
1980 	cwp = ((sregs->psr & PSR_CWP) << 4);
1981 	sregs->r[(cwp + 17) & 0x7f] = sregs->pc;
1982 	sregs->r[(cwp + 18) & 0x7f] = sregs->npc;
1983 	sregs->psr |= PSR_S;
1984 	sregs->pc = sregs->tbr;
1985 	sregs->npc = sregs->tbr + 4;
1986 
1987         if ( 0 != (1 & sregs->asr17) ) {
1988             /* single vector trapping! */
1989             sregs->pc = sregs->tbr & 0xfffff000;
1990             sregs->npc = sregs->pc + 4;
1991         }
1992 
1993 	/* Increase simulator time */
1994 	sregs->icnt = TRAP_C;
1995 
1996     }
1997 
1998 
1999     return 0;
2000 
2001 }
2002 
2003 extern struct irqcell irqarr[16];
2004 
2005 int
2006 check_interrupts(struct pstate *sregs)
2007 {
2008 #ifdef ERRINJ
2009     if (errtt) {
2010 	sregs->trap = errtt;
2011 	if (sis_verbose) printf("Inserted error trap 0x%02X\n",errtt);
2012 	errtt = 0;
2013     }
2014 #endif
2015 
2016     if ((ext_irl) && (sregs->psr & PSR_ET) &&
2017 	((ext_irl == 15) || (ext_irl > (int) ((sregs->psr & PSR_PIL) >> 8)))) {
2018 	if (sregs->trap == 0) {
2019 	    sregs->trap = 16 + ext_irl;
2020 	    irqarr[ext_irl & 0x0f].callback(irqarr[ext_irl & 0x0f].arg);
2021 	    return 1;
2022 	}
2023     }
2024     return 0;
2025 }
2026 
2027 void
2028 init_regs(struct pstate *sregs)
2029 {
2030     sregs->pc = 0;
2031     sregs->npc = 4;
2032     sregs->trap = 0;
2033     sregs->psr &= 0x00f03fdf;
2034     sregs->psr |= 0x11000080;	/* Set supervisor bit */
2035     sregs->breakpoint = 0;
2036     sregs->annul = 0;
2037     sregs->fpstate = FP_EXE_MODE;
2038     sregs->fpqn = 0;
2039     sregs->ftime = 0;
2040     sregs->ltime = 0;
2041     sregs->err_mode = 0;
2042     ext_irl = 0;
2043     sregs->g[0] = 0;
2044 #ifdef HOST_LITTLE_ENDIAN
2045     sregs->fdp = (float32 *) sregs->fd;
2046     sregs->fsi = (int32_t *) sregs->fs;
2047 #else
2048     sregs->fs = (float32 *) sregs->fd;
2049     sregs->fsi = (int32_t *) sregs->fd;
2050 #endif
2051     sregs->fsr = 0;
2052     sregs->fpu_pres = !nfp;
2053     set_fsr(sregs->fsr);
2054     sregs->bphit = 0;
2055     sregs->ildreg = 0;
2056     sregs->ildtime = 0;
2057 
2058     sregs->y = 0;
2059     sregs->asr17 = 0;
2060 
2061     sregs->rett_err = 0;
2062     sregs->jmpltime = 0;
2063 }
2064