xref: /netbsd-src/external/gpl3/gdb/dist/sim/erc32/exec.c (revision 1f4e7eb9e5e045e008f1894823a8e4e6c9f46890)
1 /* This file is part of SIS (SPARC instruction simulator)
2 
3    Copyright (C) 1995-2024 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 uresult, 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 		  uresult = 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 = uresult < remainder || uresult < (uint32_t) operand2;
737 
738 		  if (uresult & 0x80000000)
739 		    sregs->psr |= PSR_N;
740 		  else
741 		    sregs->psr &= ~PSR_N;
742 
743 		  y31 = (sregs->y & 0x80000000) == 0x80000000;
744 
745 		  if (uresult == 0 && sign == y31)
746 		    sregs->psr |= PSR_Z;
747 		  else
748 		    sregs->psr &= ~PSR_Z;
749 
750 		  sign = (sign && !y31) || (!c0 && (sign || !y31));
751 
752 		  if (sign ^ (uresult >> 31))
753 		    sregs->psr |= PSR_V;
754 		  else
755 		    sregs->psr &= ~PSR_V;
756 
757 		  if (!sign)
758 		    sregs->psr |= PSR_C;
759 		  else
760 		    sregs->psr &= ~PSR_C;
761 
762 		  sregs->y = uresult;
763 
764 		  if (rd != 0)
765 		    *rdd = (rs1 << 1) | !sign;
766 		}
767 		break;
768 	    case SMUL:
769 		{
770 		  mul64 (rs1, operand2, &sregs->y, rdd, 1);
771 		}
772 		break;
773 	    case SMULCC:
774 		{
775 		  uint32_t uresult;
776 
777 		  mul64 (rs1, operand2, &sregs->y, &uresult, 1);
778 
779 		  if (uresult & 0x80000000)
780 		    sregs->psr |= PSR_N;
781 		  else
782 		    sregs->psr &= ~PSR_N;
783 
784 		  if (uresult == 0)
785 		    sregs->psr |= PSR_Z;
786 		  else
787 		    sregs->psr &= ~PSR_Z;
788 
789 		  *rdd = uresult;
790 		}
791 		break;
792 	    case UMUL:
793 		{
794 		  mul64 (rs1, operand2, &sregs->y, rdd, 0);
795 		}
796 		break;
797 	    case UMULCC:
798 		{
799 		  uint32_t uresult;
800 
801 		  mul64 (rs1, operand2, &sregs->y, &uresult, 0);
802 
803 		  if (uresult & 0x80000000)
804 		    sregs->psr |= PSR_N;
805 		  else
806 		    sregs->psr &= ~PSR_N;
807 
808 		  if (uresult == 0)
809 		    sregs->psr |= PSR_Z;
810 		  else
811 		    sregs->psr &= ~PSR_Z;
812 
813 		  *rdd = uresult;
814 		}
815 		break;
816 	    case SDIV:
817 		{
818 		  if (sparclite) {
819 		     sregs->trap = TRAP_UNIMP;
820                      break;
821 		  }
822 
823 		  if (operand2 == 0) {
824 		    sregs->trap = TRAP_DIV0;
825 		    break;
826 		  }
827 
828 		  div64 (sregs->y, rs1, operand2, rdd, 1);
829 		}
830 		break;
831 	    case SDIVCC:
832 		{
833 		  uint32_t uresult;
834 
835 		  if (sparclite) {
836 		     sregs->trap = TRAP_UNIMP;
837                      break;
838 		  }
839 
840 		  if (operand2 == 0) {
841 		    sregs->trap = TRAP_DIV0;
842 		    break;
843 		  }
844 
845 		  div64 (sregs->y, rs1, operand2, &uresult, 1);
846 
847 		  if (uresult & 0x80000000)
848 		    sregs->psr |= PSR_N;
849 		  else
850 		    sregs->psr &= ~PSR_N;
851 
852 		  if (uresult == 0)
853 		    sregs->psr |= PSR_Z;
854 		  else
855 		    sregs->psr &= ~PSR_Z;
856 
857 		  /* FIXME: should set overflow flag correctly.  */
858 		  sregs->psr &= ~(PSR_C | PSR_V);
859 
860 		  *rdd = uresult;
861 		}
862 		break;
863 	    case UDIV:
864 		{
865 		  if (sparclite) {
866 		     sregs->trap = TRAP_UNIMP;
867                      break;
868 		  }
869 
870 		  if (operand2 == 0) {
871 		    sregs->trap = TRAP_DIV0;
872 		    break;
873 		  }
874 
875 		  div64 (sregs->y, rs1, operand2, rdd, 0);
876 		}
877 		break;
878 	    case UDIVCC:
879 		{
880 		  uint32_t uresult;
881 
882 		  if (sparclite) {
883 		     sregs->trap = TRAP_UNIMP;
884                      break;
885 		  }
886 
887 		  if (operand2 == 0) {
888 		    sregs->trap = TRAP_DIV0;
889 		    break;
890 		  }
891 
892 		  div64 (sregs->y, rs1, operand2, &uresult, 0);
893 
894 		  if (uresult & 0x80000000)
895 		    sregs->psr |= PSR_N;
896 		  else
897 		    sregs->psr &= ~PSR_N;
898 
899 		  if (uresult == 0)
900 		    sregs->psr |= PSR_Z;
901 		  else
902 		    sregs->psr &= ~PSR_Z;
903 
904 		  /* FIXME: should set overflow flag correctly.  */
905 		  sregs->psr &= ~(PSR_C | PSR_V);
906 
907 		  *rdd = uresult;
908 		}
909 		break;
910 	    case IXNOR:
911 		*rdd = rs1 ^ ~operand2;
912 		break;
913 	    case IXNORCC:
914 		*rdd = rs1 ^ ~operand2;
915 		log_cc(*rdd, sregs);
916 		break;
917 	    case IXOR:
918 		*rdd = rs1 ^ operand2;
919 		break;
920 	    case IXORCC:
921 		*rdd = rs1 ^ operand2;
922 		log_cc(*rdd, sregs);
923 		break;
924 	    case IOR:
925 		*rdd = rs1 | operand2;
926 		break;
927 	    case IORCC:
928 		*rdd = rs1 | operand2;
929 		log_cc(*rdd, sregs);
930 		break;
931 	    case IORN:
932 		*rdd = rs1 | ~operand2;
933 		break;
934 	    case IORNCC:
935 		*rdd = rs1 | ~operand2;
936 		log_cc(*rdd, sregs);
937 		break;
938 	    case IANDNCC:
939 		*rdd = rs1 & ~operand2;
940 		log_cc(*rdd, sregs);
941 		break;
942 	    case IANDN:
943 		*rdd = rs1 & ~operand2;
944 		break;
945 	    case IAND:
946 		*rdd = rs1 & operand2;
947 		break;
948 	    case IANDCC:
949 		*rdd = rs1 & operand2;
950 		log_cc(*rdd, sregs);
951 		break;
952 	    case SUB:
953 		*rdd = rs1 - operand2;
954 		break;
955 	    case SUBCC:
956 		*rdd = rs1 - operand2;
957 		sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd);
958 		break;
959 	    case SUBX:
960 		*rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1);
961 		break;
962 	    case SUBXCC:
963 		*rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1);
964 		sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd);
965 		break;
966 	    case ADD:
967 		*rdd = rs1 + operand2;
968 		break;
969 	    case ADDCC:
970 		*rdd = rs1 + operand2;
971 		sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
972 		break;
973 	    case ADDX:
974 		*rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1);
975 		break;
976 	    case ADDXCC:
977 		*rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1);
978 		sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
979 		break;
980 	    case TADDCC:
981 		*rdd = rs1 + operand2;
982 		sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd);
983 		if ((rs1 | operand2) & 0x3)
984 		    sregs->psr |= PSR_V;
985 		break;
986 	    case TSUBCC:
987 		*rdd = rs1 - operand2;
988 		sregs->psr = sub_cc (sregs->psr, rs1, operand2, *rdd);
989 		if ((rs1 | operand2) & 0x3)
990 		    sregs->psr |= PSR_V;
991 		break;
992 	    case TADDCCTV:
993 		*rdd = rs1 + operand2;
994 		result = add_cc(0, rs1, operand2, *rdd);
995 		if ((rs1 | operand2) & 0x3)
996 		    result |= PSR_V;
997 		if (result & PSR_V) {
998 		    sregs->trap = TRAP_TAG;
999 		} else {
1000 		    sregs->psr = (sregs->psr & ~PSR_CC) | result;
1001 		}
1002 		break;
1003 	    case TSUBCCTV:
1004 		*rdd = rs1 - operand2;
1005 		result = add_cc (0, rs1, operand2, *rdd);
1006 		if ((rs1 | operand2) & 0x3)
1007 		    result |= PSR_V;
1008 		if (result & PSR_V)
1009 		  {
1010 		      sregs->trap = TRAP_TAG;
1011 		  }
1012 		else
1013 		  {
1014 		      sregs->psr = (sregs->psr & ~PSR_CC) | result;
1015 		  }
1016 		break;
1017 	    case SLL:
1018 		*rdd = rs1 << (operand2 & 0x1f);
1019 		break;
1020 	    case SRL:
1021 		*rdd = rs1 >> (operand2 & 0x1f);
1022 		break;
1023 	    case SRA:
1024 		*rdd = ((int) rs1) >> (operand2 & 0x1f);
1025 		break;
1026 	    case FLUSH:
1027 		if (ift) sregs->trap = TRAP_UNIMP;
1028 		break;
1029 	    case SAVE:
1030 		new_cwp = ((sregs->psr & PSR_CWP) - 1) & PSR_CWP;
1031 		if (sregs->wim & (1 << new_cwp)) {
1032 		    sregs->trap = TRAP_WOFL;
1033 		    break;
1034 		}
1035 		if (rd > 7)
1036 		    rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]);
1037 		*rdd = rs1 + operand2;
1038 		sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp;
1039 		break;
1040 	    case RESTORE:
1041 
1042 		new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP;
1043 		if (sregs->wim & (1 << new_cwp)) {
1044 		    sregs->trap = TRAP_WUFL;
1045 		    break;
1046 		}
1047 		if (rd > 7)
1048 		    rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]);
1049 		*rdd = rs1 + operand2;
1050 		sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp;
1051 		break;
1052 	    case RDPSR:
1053 		if (!(sregs->psr & PSR_S)) {
1054 		    sregs->trap = TRAP_PRIVI;
1055 		    break;
1056 		}
1057 		*rdd = sregs->psr;
1058 		break;
1059 	    case RDY:
1060                 if (!sparclite)
1061                     *rdd = sregs->y;
1062                 else {
1063                     int rs1_is_asr = (sregs->inst >> 14) & 0x1f;
1064                     if ( 0 == rs1_is_asr )
1065                         *rdd = sregs->y;
1066                     else if ( 17 == rs1_is_asr )
1067                         *rdd = sregs->asr17;
1068                     else {
1069                         sregs->trap = TRAP_UNIMP;
1070                         break;
1071                     }
1072                 }
1073 		break;
1074 	    case RDWIM:
1075 		if (!(sregs->psr & PSR_S)) {
1076 		    sregs->trap = TRAP_PRIVI;
1077 		    break;
1078 		}
1079 		*rdd = sregs->wim;
1080 		break;
1081 	    case RDTBR:
1082 		if (!(sregs->psr & PSR_S)) {
1083 		    sregs->trap = TRAP_PRIVI;
1084 		    break;
1085 		}
1086 		*rdd = sregs->tbr;
1087 		break;
1088 	    case WRPSR:
1089 		if ((sregs->psr & 0x1f) > 7) {
1090 		    sregs->trap = TRAP_UNIMP;
1091 		    break;
1092 		}
1093 		if (!(sregs->psr & PSR_S)) {
1094 		    sregs->trap = TRAP_PRIVI;
1095 		    break;
1096 		}
1097 		sregs->psr = (sregs->psr & 0xff000000) |
1098 			((rs1 ^ operand2) & 0x00f03fff);
1099 		break;
1100 	    case WRWIM:
1101 		if (!(sregs->psr & PSR_S)) {
1102 		    sregs->trap = TRAP_PRIVI;
1103 		    break;
1104 		}
1105 		sregs->wim = (rs1 ^ operand2) & 0x0ff;
1106 		break;
1107 	    case WRTBR:
1108 		if (!(sregs->psr & PSR_S)) {
1109 		    sregs->trap = TRAP_PRIVI;
1110 		    break;
1111 		}
1112 		sregs->tbr = (sregs->tbr & 0x00000ff0) |
1113 		    ((rs1 ^ operand2) & 0xfffff000);
1114 		break;
1115 	    case WRY:
1116                 if (!sparclite)
1117                     sregs->y = (rs1 ^ operand2);
1118                 else {
1119                     if ( 0 == rd )
1120                         sregs->y = (rs1 ^ operand2);
1121                     else if ( 17 == rd )
1122                         sregs->asr17 = (rs1 ^ operand2);
1123                     else {
1124                         sregs->trap = TRAP_UNIMP;
1125                         break;
1126                     }
1127                 }
1128 		break;
1129 	    case JMPL:
1130 
1131 #ifdef STAT
1132 		sregs->nbranch++;
1133 #endif
1134 		sregs->icnt = T_JMPL;	/* JMPL takes two cycles */
1135 		if (rs1 & 0x3) {
1136 		    sregs->trap = TRAP_UNALI;
1137 		    break;
1138 		}
1139 		*rdd = sregs->pc;
1140 		npc = rs1 + operand2;
1141 		break;
1142 	    case RETT:
1143 		address = rs1 + operand2;
1144 		new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP;
1145 		sregs->icnt = T_RETT;	/* RETT takes two cycles */
1146 		if (sregs->psr & PSR_ET) {
1147 		    sregs->trap = TRAP_UNIMP;
1148 		    break;
1149 		}
1150 		if (!(sregs->psr & PSR_S)) {
1151 		    sregs->trap = TRAP_PRIVI;
1152 		    break;
1153 		}
1154 		if (sregs->wim & (1 << new_cwp)) {
1155 		    sregs->trap = TRAP_WUFL;
1156 		    break;
1157 		}
1158 		if (address & 0x3) {
1159 		    sregs->trap = TRAP_UNALI;
1160 		    break;
1161 		}
1162 		sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp | PSR_ET;
1163 		sregs->psr =
1164 		    (sregs->psr & ~PSR_S) | ((sregs->psr & PSR_PS) << 1);
1165 		npc = address;
1166 		break;
1167 
1168 	    case SCAN:
1169 		{
1170 		  uint32_t uresult, mask;
1171 		  int i;
1172 
1173 		  if (!sparclite) {
1174 		     sregs->trap = TRAP_UNIMP;
1175                      break;
1176 		  }
1177 		  mask = (operand2 & 0x80000000) | (operand2 >> 1);
1178 		  uresult = rs1 ^ mask;
1179 
1180 		  for (i = 0; i < 32; i++) {
1181 		    if (uresult & 0x80000000)
1182 		      break;
1183 		    uresult <<= 1;
1184 		  }
1185 
1186 		  *rdd = i == 32 ? 63 : i;
1187 		}
1188 		break;
1189 
1190 	    default:
1191 		sregs->trap = TRAP_UNIMP;
1192 		break;
1193 	    }
1194 	}
1195 	break;
1196     case 3:			/* Load/store instructions */
1197 
1198 	address = rs1 + operand2;
1199 
1200 	if (sregs->psr & PSR_S)
1201 	    asi = 11;
1202 	 else
1203 	    asi = 10;
1204 
1205 	if (op3 & 4) {
1206 	    sregs->icnt = T_ST;	/* Set store instruction count */
1207 #ifdef STAT
1208 	    sregs->nstore++;
1209 #endif
1210 	} else {
1211 	    sregs->icnt = T_LD;	/* Set load instruction count */
1212 #ifdef STAT
1213 	    sregs->nload++;
1214 #endif
1215 	}
1216 
1217 	/* Decode load/store instructions */
1218 
1219 	switch (op3) {
1220 	case LDDA:
1221 	    if (!chk_asi(sregs, &asi, op3)) break;
1222 	    ATTRIBUTE_FALLTHROUGH;
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 	    ATTRIBUTE_FALLTHROUGH;
1254 	case LD:
1255 	    if (address & 0x3) {
1256 		sregs->trap = TRAP_UNALI;
1257 		break;
1258 	    }
1259 	    mexc = memory_read(asi, address, &data, 2, &ws);
1260 	    sregs->hold += ws;
1261 	    if (mexc) {
1262 		sregs->trap = TRAP_DEXC;
1263 	    } else {
1264 		*rdd = data;
1265 	    }
1266 	    break;
1267 	case LDSTUBA:
1268 	    if (!chk_asi(sregs, &asi, op3)) break;
1269 	    ATTRIBUTE_FALLTHROUGH;
1270 	case LDSTUB:
1271 	    mexc = memory_read(asi, address, &data, 0, &ws);
1272 	    sregs->hold += ws;
1273 	    sregs->icnt = T_LDST;
1274 	    if (mexc) {
1275 		sregs->trap = TRAP_DEXC;
1276 		break;
1277 	    }
1278 	    data = extract_byte (data, address);
1279 	    *rdd = data;
1280 	    data = 0x0ff;
1281 	    mexc = memory_write(asi, address, &data, 0, &ws);
1282 	    sregs->hold += ws;
1283 	    if (mexc) {
1284 		sregs->trap = TRAP_DEXC;
1285 	    }
1286 #ifdef STAT
1287 	    sregs->nload++;
1288 #endif
1289 	    break;
1290 	case LDSBA:
1291 	case LDUBA:
1292 	    if (!chk_asi(sregs, &asi, op3)) break;
1293 	    ATTRIBUTE_FALLTHROUGH;
1294 	case LDSB:
1295 	case LDUB:
1296 	    mexc = memory_read(asi, address, &data, 0, &ws);
1297 	    sregs->hold += ws;
1298 	    if (mexc) {
1299 		sregs->trap = TRAP_DEXC;
1300 		break;
1301 	    }
1302 	    if (op3 == LDSB)
1303 	        data = extract_byte_signed (data, address);
1304 	    else
1305 	        data = extract_byte (data, address);
1306 	    *rdd = data;
1307 	    break;
1308 	case LDSHA:
1309 	case LDUHA:
1310 	    if (!chk_asi(sregs, &asi, op3)) break;
1311 	    ATTRIBUTE_FALLTHROUGH;
1312 	case LDSH:
1313 	case LDUH:
1314 	    if (address & 0x1) {
1315 		sregs->trap = TRAP_UNALI;
1316 		break;
1317 	    }
1318 	    mexc = memory_read(asi, address, &data, 1, &ws);
1319 	    sregs->hold += ws;
1320 	    if (mexc) {
1321 		sregs->trap = TRAP_DEXC;
1322 		break;
1323 	    }
1324 	    if (op3 == LDSH)
1325 	        data = extract_short_signed (data, address);
1326 	    else
1327 	        data = extract_short (data, address);
1328 	    *rdd = data;
1329 	    break;
1330 	case LDF:
1331 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1332 		sregs->trap = TRAP_FPDIS;
1333 		break;
1334 	    }
1335 	    if (address & 0x3) {
1336 		sregs->trap = TRAP_UNALI;
1337 		break;
1338 	    }
1339 	    if (ebase.simtime < sregs->ftime) {
1340 		if ((sregs->frd == rd) || (sregs->frs1 == rd) ||
1341 		    (sregs->frs2 == rd))
1342 		    sregs->fhold += (sregs->ftime - ebase.simtime);
1343 	    }
1344 	    mexc = memory_read(asi, address, &data, 2, &ws);
1345 	    sregs->hold += ws;
1346 	    sregs->flrd = rd;
1347 	    sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
1348 		sregs->hold + sregs->fhold;
1349 	    if (mexc) {
1350 		sregs->trap = TRAP_DEXC;
1351 	    } else {
1352 		memcpy (&sregs->fs[rd], &data, sizeof (sregs->fs[rd]));
1353 	    }
1354 	    break;
1355 	case LDDF:
1356 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1357 		sregs->trap = TRAP_FPDIS;
1358 		break;
1359 	    }
1360 	    if (address & 0x7) {
1361 		sregs->trap = TRAP_UNALI;
1362 		break;
1363 	    }
1364 	    if (ebase.simtime < sregs->ftime) {
1365 		if (((sregs->frd >> 1) == (rd >> 1)) ||
1366 		    ((sregs->frs1 >> 1) == (rd >> 1)) ||
1367 		    ((sregs->frs2 >> 1) == (rd >> 1)))
1368 		    sregs->fhold += (sregs->ftime - ebase.simtime);
1369 	    }
1370 	    mexc = memory_read (asi, address, ddata, 2, &ws);
1371 	    sregs->hold += ws;
1372 	    mexc |= memory_read (asi, address+4, &ddata[1], 2, &ws);
1373 	    sregs->hold += ws;
1374 	    sregs->icnt = T_LDD;
1375 	    if (mexc) {
1376 		sregs->trap = TRAP_DEXC;
1377 	    } else {
1378 		rd &= 0x1E;
1379 		sregs->flrd = rd;
1380 		memcpy (&sregs->fs[rd], &ddata[0], sizeof (sregs->fs[rd]));
1381 #ifdef STAT
1382 		sregs->nload++;	/* Double load counts twice */
1383 #endif
1384 		memcpy (&sregs->fs[rd + 1], &ddata[1],
1385 			sizeof (sregs->fs[rd + 1]));
1386 		sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
1387 			       sregs->hold + sregs->fhold;
1388 	    }
1389 	    break;
1390 	case LDFSR:
1391 	    if (ebase.simtime < sregs->ftime) {
1392 		sregs->fhold += (sregs->ftime - ebase.simtime);
1393 	    }
1394 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1395 		sregs->trap = TRAP_FPDIS;
1396 		break;
1397 	    }
1398 	    if (address & 0x3) {
1399 		sregs->trap = TRAP_UNALI;
1400 		break;
1401 	    }
1402 	    mexc = memory_read(asi, address, &data, 2, &ws);
1403 	    sregs->hold += ws;
1404 	    if (mexc) {
1405 		sregs->trap = TRAP_DEXC;
1406 	    } else {
1407 		sregs->fsr =
1408 		    (sregs->fsr & 0x7FF000) | (data & ~0x7FF000);
1409 		set_fsr(sregs->fsr);
1410 	    }
1411 	    break;
1412 	case STFSR:
1413 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1414 		sregs->trap = TRAP_FPDIS;
1415 		break;
1416 	    }
1417 	    if (address & 0x3) {
1418 		sregs->trap = TRAP_UNALI;
1419 		break;
1420 	    }
1421 	    if (ebase.simtime < sregs->ftime) {
1422 		sregs->fhold += (sregs->ftime - ebase.simtime);
1423 	    }
1424 	    mexc = memory_write(asi, address, &sregs->fsr, 2, &ws);
1425 	    sregs->hold += ws;
1426 	    if (mexc) {
1427 		sregs->trap = TRAP_DEXC;
1428 	    }
1429 	    break;
1430 
1431 	case STA:
1432 	    if (!chk_asi(sregs, &asi, op3)) break;
1433 	    ATTRIBUTE_FALLTHROUGH;
1434 	case ST:
1435 	    if (address & 0x3) {
1436 		sregs->trap = TRAP_UNALI;
1437 		break;
1438 	    }
1439 	    mexc = memory_write(asi, address, rdd, 2, &ws);
1440 	    sregs->hold += ws;
1441 	    if (mexc) {
1442 		sregs->trap = TRAP_DEXC;
1443 	    }
1444 	    break;
1445 	case STBA:
1446 	    if (!chk_asi(sregs, &asi, op3)) break;
1447 	    ATTRIBUTE_FALLTHROUGH;
1448 	case STB:
1449 	    mexc = memory_write(asi, address, rdd, 0, &ws);
1450 	    sregs->hold += ws;
1451 	    if (mexc) {
1452 		sregs->trap = TRAP_DEXC;
1453 	    }
1454 	    break;
1455 	case STDA:
1456 	    if (!chk_asi(sregs, &asi, op3)) break;
1457 	    ATTRIBUTE_FALLTHROUGH;
1458 	case STD:
1459 	    if (address & 0x7) {
1460 		sregs->trap = TRAP_UNALI;
1461 		break;
1462 	    }
1463 	    if (rd & 1) {
1464 		rd &= 0x1e;
1465 		if (rd > 7)
1466 		    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
1467 		else
1468 		    rdd = &(sregs->g[rd]);
1469 	    }
1470 	    mexc = memory_write(asi, address, rdd, 3, &ws);
1471 	    sregs->hold += ws;
1472 	    sregs->icnt = T_STD;
1473 #ifdef STAT
1474 	    sregs->nstore++;	/* Double store counts twice */
1475 #endif
1476 	    if (mexc) {
1477 		sregs->trap = TRAP_DEXC;
1478 		break;
1479 	    }
1480 	    break;
1481 	case STDFQ:
1482 	    if ((sregs->psr & 0x1f) > 7) {
1483 		sregs->trap = TRAP_UNIMP;
1484 		break;
1485 	    }
1486 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1487 		sregs->trap = TRAP_FPDIS;
1488 		break;
1489 	    }
1490 	    if (address & 0x7) {
1491 		sregs->trap = TRAP_UNALI;
1492 		break;
1493 	    }
1494 	    if (!(sregs->fsr & FSR_QNE)) {
1495 		sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR;
1496 		break;
1497 	    }
1498 	    rdd = &(sregs->fpq[0]);
1499 	    mexc = memory_write(asi, address, rdd, 3, &ws);
1500 	    sregs->hold += ws;
1501 	    sregs->icnt = T_STD;
1502 #ifdef STAT
1503 	    sregs->nstore++;	/* Double store counts twice */
1504 #endif
1505 	    if (mexc) {
1506 		sregs->trap = TRAP_DEXC;
1507 		break;
1508 	    } else {
1509 		sregs->fsr &= ~FSR_QNE;
1510 		sregs->fpstate = FP_EXE_MODE;
1511 	    }
1512 	    break;
1513 	case STHA:
1514 	    if (!chk_asi(sregs, &asi, op3)) break;
1515 	    ATTRIBUTE_FALLTHROUGH;
1516 	case STH:
1517 	    if (address & 0x1) {
1518 		sregs->trap = TRAP_UNALI;
1519 		break;
1520 	    }
1521 	    mexc = memory_write(asi, address, rdd, 1, &ws);
1522 	    sregs->hold += ws;
1523 	    if (mexc) {
1524 		sregs->trap = TRAP_DEXC;
1525 	    }
1526 	    break;
1527 	case STF:
1528 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1529 		sregs->trap = TRAP_FPDIS;
1530 		break;
1531 	    }
1532 	    if (address & 0x3) {
1533 		sregs->trap = TRAP_UNALI;
1534 		break;
1535 	    }
1536 	    if (ebase.simtime < sregs->ftime) {
1537 		if (sregs->frd == rd)
1538 		    sregs->fhold += (sregs->ftime - ebase.simtime);
1539 	    }
1540 	    mexc = memory_write(asi, address, (uint32_t *)&sregs->fsi[rd], 2, &ws);
1541 	    sregs->hold += ws;
1542 	    if (mexc) {
1543 		sregs->trap = TRAP_DEXC;
1544 	    }
1545 	    break;
1546 	case STDF:
1547 	    if (!((sregs->psr & PSR_EF) && FP_PRES)) {
1548 		sregs->trap = TRAP_FPDIS;
1549 		break;
1550 	    }
1551 	    if (address & 0x7) {
1552 		sregs->trap = TRAP_UNALI;
1553 		break;
1554 	    }
1555 	    rd &= 0x1E;
1556 	    if (ebase.simtime < sregs->ftime) {
1557 		if ((sregs->frd == rd) || (sregs->frd + 1 == rd))
1558 		    sregs->fhold += (sregs->ftime - ebase.simtime);
1559 	    }
1560 	    mexc = memory_write(asi, address, (uint32_t *)&sregs->fsi[rd], 3, &ws);
1561 	    sregs->hold += ws;
1562 	    sregs->icnt = T_STD;
1563 #ifdef STAT
1564 	    sregs->nstore++;	/* Double store counts twice */
1565 #endif
1566 	    if (mexc) {
1567 		sregs->trap = TRAP_DEXC;
1568 	    }
1569 	    break;
1570 	case SWAPA:
1571 	    if (!chk_asi(sregs, &asi, op3)) break;
1572 	    ATTRIBUTE_FALLTHROUGH;
1573 	case SWAP:
1574 	    if (address & 0x3) {
1575 		sregs->trap = TRAP_UNALI;
1576 		break;
1577 	    }
1578 	    mexc = memory_read(asi, address, &data, 2, &ws);
1579 	    sregs->hold += ws;
1580 	    if (mexc) {
1581 		sregs->trap = TRAP_DEXC;
1582 		break;
1583 	    }
1584 	    mexc = memory_write(asi, address, rdd, 2, &ws);
1585 	    sregs->hold += ws;
1586 	    sregs->icnt = T_LDST;
1587 	    if (mexc) {
1588 		sregs->trap = TRAP_DEXC;
1589 		break;
1590 	    } else
1591 		*rdd = data;
1592 #ifdef STAT
1593 	    sregs->nload++;
1594 #endif
1595 	    break;
1596 
1597 
1598 	default:
1599 	    sregs->trap = TRAP_UNIMP;
1600 	    break;
1601 	}
1602 
1603 #ifdef LOAD_DEL
1604 
1605 	if (!(op3 & 4)) {
1606 	    sregs->ildtime = ebase.simtime + sregs->hold + sregs->icnt;
1607 	    sregs->ildreg = rd;
1608 	    if ((op3 | 0x10) == 0x13)
1609 		sregs->ildreg |= 1;	/* Double load, odd register loaded
1610 					 * last */
1611 	}
1612 #endif
1613 	break;
1614 
1615     default:
1616 	sregs->trap = TRAP_UNIMP;
1617 	break;
1618     }
1619     sregs->g[0] = 0;
1620     if (!sregs->trap) {
1621 	sregs->pc = pc;
1622 	sregs->npc = npc;
1623     }
1624     return 0;
1625 }
1626 
1627 #define T_FABSs		2
1628 #define T_FADDs		4
1629 #define T_FADDd		4
1630 #define T_FCMPs		4
1631 #define T_FCMPd		4
1632 #define T_FDIVs		20
1633 #define T_FDIVd		35
1634 #define T_FMOVs		2
1635 #define T_FMULs		5
1636 #define T_FMULd		9
1637 #define T_FNEGs		2
1638 #define T_FSQRTs	37
1639 #define T_FSQRTd	65
1640 #define T_FSUBs		4
1641 #define T_FSUBd		4
1642 #define T_FdTOi		7
1643 #define T_FdTOs		3
1644 #define T_FiTOs		6
1645 #define T_FiTOd		6
1646 #define T_FsTOi		6
1647 #define T_FsTOd		2
1648 
1649 #define FABSs	0x09
1650 #define FADDs	0x41
1651 #define FADDd	0x42
1652 #define FCMPs	0x51
1653 #define FCMPd	0x52
1654 #define FCMPEs	0x55
1655 #define FCMPEd	0x56
1656 #define FDIVs	0x4D
1657 #define FDIVd	0x4E
1658 #define FMOVs	0x01
1659 #define FMULs	0x49
1660 #define FMULd	0x4A
1661 #define FNEGs	0x05
1662 #define FSQRTs	0x29
1663 #define FSQRTd	0x2A
1664 #define FSUBs	0x45
1665 #define FSUBd	0x46
1666 #define FdTOi	0xD2
1667 #define FdTOs	0xC6
1668 #define FiTOs	0xC4
1669 #define FiTOd	0xC8
1670 #define FsTOi	0xD1
1671 #define FsTOd	0xC9
1672 
1673 
1674 static int
1675 fpexec(uint32_t op3, uint32_t rd, uint32_t rs1, uint32_t rs2, struct pstate *sregs)
1676 {
1677     uint32_t          opf, tem, accex;
1678     int32_t           fcc;
1679     uint32_t          ldadj;
1680 
1681     if (sregs->fpstate == FP_EXC_MODE) {
1682 	sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR;
1683 	sregs->fpstate = FP_EXC_PE;
1684 	return 0;
1685     }
1686     if (sregs->fpstate == FP_EXC_PE) {
1687 	sregs->fpstate = FP_EXC_MODE;
1688 	return TRAP_FPEXC;
1689     }
1690     opf = (sregs->inst >> 5) & 0x1ff;
1691 
1692     /*
1693      * Check if we already have an FPop in the pipe. If so, halt until it is
1694      * finished by incrementing fhold with the remaining execution time
1695      */
1696 
1697     if (ebase.simtime < sregs->ftime) {
1698 	sregs->fhold = (sregs->ftime - ebase.simtime);
1699     } else {
1700 	sregs->fhold = 0;
1701 
1702 	/* Check load dependencies. */
1703 
1704 	if (ebase.simtime < sregs->ltime) {
1705 
1706 	    /* Don't check rs1 if single operand instructions */
1707 
1708 	    if (((opf >> 6) == 0) || ((opf >> 6) == 3))
1709 		rs1 = 32;
1710 
1711 	    /* Adjust for double floats */
1712 
1713 	    ldadj = opf & 1;
1714 	    if (!(((sregs->flrd - rs1) >> ldadj) && ((sregs->flrd - rs2) >> ldadj)))
1715 		sregs->fhold++;
1716 	}
1717     }
1718 
1719     sregs->finst++;
1720 
1721     sregs->frs1 = rs1;		/* Store src and dst for dependecy check */
1722     sregs->frs2 = rs2;
1723     sregs->frd = rd;
1724 
1725     sregs->ftime = ebase.simtime + sregs->hold + sregs->fhold;
1726 
1727     /* SPARC is big-endian - swap double floats if host is little-endian */
1728     /* This is ugly - I know ... */
1729 
1730     /* FIXME: should use (HOST_BYTE_ORDER == CURRENT_TARGET_BYTE_ORDER)
1731        but what about machines where float values are different endianness
1732        from integer values? */
1733 
1734 #ifdef HOST_LITTLE_ENDIAN
1735     rs1 &= 0x1f;
1736     switch (opf) {
1737 	case FADDd:
1738 	case FDIVd:
1739 	case FMULd:
1740 	case FSQRTd:
1741 	case FSUBd:
1742         case FCMPd:
1743         case FCMPEd:
1744 	case FdTOi:
1745 	case FdTOs:
1746     	    sregs->fdp[rs1 | 1] = sregs->fs[rs1 & ~1];
1747     	    sregs->fdp[rs1 & ~1] = sregs->fs[rs1 | 1];
1748     	    sregs->fdp[rs2 | 1] = sregs->fs[rs2 & ~1];
1749     	    sregs->fdp[rs2 & ~1] = sregs->fs[rs2 | 1];
1750     default:
1751       break;
1752     }
1753 #endif
1754 
1755     clear_accex();
1756 
1757     switch (opf) {
1758     case FABSs:
1759 	sregs->fs[rd] = fabs(sregs->fs[rs2]);
1760 	sregs->ftime += T_FABSs;
1761 	sregs->frs1 = 32;	/* rs1 ignored */
1762 	break;
1763     case FADDs:
1764 	sregs->fs[rd] = sregs->fs[rs1] + sregs->fs[rs2];
1765 	sregs->ftime += T_FADDs;
1766 	break;
1767     case FADDd:
1768 	sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] + sregs->fd[rs2 >> 1];
1769 	sregs->ftime += T_FADDd;
1770 	break;
1771     case FCMPs:
1772     case FCMPEs:
1773 	if (sregs->fs[rs1] == sregs->fs[rs2])
1774 	    fcc = 3;
1775 	else if (sregs->fs[rs1] < sregs->fs[rs2])
1776 	    fcc = 2;
1777 	else if (sregs->fs[rs1] > sregs->fs[rs2])
1778 	    fcc = 1;
1779 	else
1780 	    fcc = 0;
1781 	sregs->fsr |= 0x0C00;
1782 	sregs->fsr &= ~(fcc << 10);
1783 	sregs->ftime += T_FCMPs;
1784 	sregs->frd = 32;	/* rd ignored */
1785 	if ((fcc == 0) && (opf == FCMPEs)) {
1786 	    sregs->fpstate = FP_EXC_PE;
1787 	    sregs->fsr = (sregs->fsr & ~0x1C000) | (1 << 14);
1788 	}
1789 	break;
1790     case FCMPd:
1791     case FCMPEd:
1792 	if (sregs->fd[rs1 >> 1] == sregs->fd[rs2 >> 1])
1793 	    fcc = 3;
1794 	else if (sregs->fd[rs1 >> 1] < sregs->fd[rs2 >> 1])
1795 	    fcc = 2;
1796 	else if (sregs->fd[rs1 >> 1] > sregs->fd[rs2 >> 1])
1797 	    fcc = 1;
1798 	else
1799 	    fcc = 0;
1800 	sregs->fsr |= 0x0C00;
1801 	sregs->fsr &= ~(fcc << 10);
1802 	sregs->ftime += T_FCMPd;
1803 	sregs->frd = 32;	/* rd ignored */
1804 	if ((fcc == 0) && (opf == FCMPEd)) {
1805 	    sregs->fpstate = FP_EXC_PE;
1806 	    sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
1807 	}
1808 	break;
1809     case FDIVs:
1810 	sregs->fs[rd] = sregs->fs[rs1] / sregs->fs[rs2];
1811 	sregs->ftime += T_FDIVs;
1812 	break;
1813     case FDIVd:
1814 	sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] / sregs->fd[rs2 >> 1];
1815 	sregs->ftime += T_FDIVd;
1816 	break;
1817     case FMOVs:
1818 	sregs->fs[rd] = sregs->fs[rs2];
1819 	sregs->ftime += T_FMOVs;
1820 	sregs->frs1 = 32;	/* rs1 ignored */
1821 	break;
1822     case FMULs:
1823 	sregs->fs[rd] = sregs->fs[rs1] * sregs->fs[rs2];
1824 	sregs->ftime += T_FMULs;
1825 	break;
1826     case FMULd:
1827 	sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] * sregs->fd[rs2 >> 1];
1828 	sregs->ftime += T_FMULd;
1829 	break;
1830     case FNEGs:
1831 	sregs->fs[rd] = -sregs->fs[rs2];
1832 	sregs->ftime += T_FNEGs;
1833 	sregs->frs1 = 32;	/* rs1 ignored */
1834 	break;
1835     case FSQRTs:
1836 	if (sregs->fs[rs2] < 0.0) {
1837 	    sregs->fpstate = FP_EXC_PE;
1838 	    sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
1839 	    sregs->fsr = (sregs->fsr & 0x1f) | 0x10;
1840 	    break;
1841 	}
1842 	sregs->fs[rd] = sqrt(sregs->fs[rs2]);
1843 	sregs->ftime += T_FSQRTs;
1844 	sregs->frs1 = 32;	/* rs1 ignored */
1845 	break;
1846     case FSQRTd:
1847 	if (sregs->fd[rs2 >> 1] < 0.0) {
1848 	    sregs->fpstate = FP_EXC_PE;
1849 	    sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
1850 	    sregs->fsr = (sregs->fsr & 0x1f) | 0x10;
1851 	    break;
1852 	}
1853 	sregs->fd[rd >> 1] = sqrt(sregs->fd[rs2 >> 1]);
1854 	sregs->ftime += T_FSQRTd;
1855 	sregs->frs1 = 32;	/* rs1 ignored */
1856 	break;
1857     case FSUBs:
1858 	sregs->fs[rd] = sregs->fs[rs1] - sregs->fs[rs2];
1859 	sregs->ftime += T_FSUBs;
1860 	break;
1861     case FSUBd:
1862 	sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] - sregs->fd[rs2 >> 1];
1863 	sregs->ftime += T_FSUBd;
1864 	break;
1865     case FdTOi:
1866 	sregs->fsi[rd] = (int) sregs->fd[rs2 >> 1];
1867 	sregs->ftime += T_FdTOi;
1868 	sregs->frs1 = 32;	/* rs1 ignored */
1869 	break;
1870     case FdTOs:
1871 	sregs->fs[rd] = (float32) sregs->fd[rs2 >> 1];
1872 	sregs->ftime += T_FdTOs;
1873 	sregs->frs1 = 32;	/* rs1 ignored */
1874 	break;
1875     case FiTOs:
1876 	sregs->fs[rd] = (float32) sregs->fsi[rs2];
1877 	sregs->ftime += T_FiTOs;
1878 	sregs->frs1 = 32;	/* rs1 ignored */
1879 	break;
1880     case FiTOd:
1881 	sregs->fd[rd >> 1] = (float64) sregs->fsi[rs2];
1882 	sregs->ftime += T_FiTOd;
1883 	sregs->frs1 = 32;	/* rs1 ignored */
1884 	break;
1885     case FsTOi:
1886 	sregs->fsi[rd] = (int) sregs->fs[rs2];
1887 	sregs->ftime += T_FsTOi;
1888 	sregs->frs1 = 32;	/* rs1 ignored */
1889 	break;
1890     case FsTOd:
1891 	sregs->fd[rd >> 1] = sregs->fs[rs2];
1892 	sregs->ftime += T_FsTOd;
1893 	sregs->frs1 = 32;	/* rs1 ignored */
1894 	break;
1895 
1896     default:
1897 	sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_UNIMP;
1898 	sregs->fpstate = FP_EXC_PE;
1899     }
1900 
1901 #ifdef ERRINJ
1902     if (errftt) {
1903 	sregs->fsr = (sregs->fsr & ~FSR_TT) | (errftt << 14);
1904 	sregs->fpstate = FP_EXC_PE;
1905 	if (sis_verbose) printf("Inserted fpu error %X\n",errftt);
1906 	errftt = 0;
1907     }
1908 #endif
1909 
1910     accex = get_accex();
1911 
1912 #ifdef HOST_LITTLE_ENDIAN
1913     switch (opf) {
1914     case FADDd:
1915     case FDIVd:
1916     case FMULd:
1917     case FSQRTd:
1918     case FSUBd:
1919     case FiTOd:
1920     case FsTOd:
1921 	sregs->fs[rd & ~1] = sregs->fdp[rd | 1];
1922 	sregs->fs[rd | 1] = sregs->fdp[rd & ~1];
1923     default:
1924       break;
1925     }
1926 #endif
1927     if (sregs->fpstate == FP_EXC_PE) {
1928 	sregs->fpq[0] = sregs->pc;
1929 	sregs->fpq[1] = sregs->inst;
1930 	sregs->fsr |= FSR_QNE;
1931     } else {
1932 	tem = (sregs->fsr >> 23) & 0x1f;
1933 	if (tem & accex) {
1934 	    sregs->fpstate = FP_EXC_PE;
1935 	    sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE;
1936 	    sregs->fsr = ((sregs->fsr & ~0x1f) | accex);
1937 	} else {
1938 	    sregs->fsr = ((((sregs->fsr >> 5) | accex) << 5) | accex);
1939 	}
1940 	if (sregs->fpstate == FP_EXC_PE) {
1941 	    sregs->fpq[0] = sregs->pc;
1942 	    sregs->fpq[1] = sregs->inst;
1943 	    sregs->fsr |= FSR_QNE;
1944 	}
1945     }
1946     clear_accex();
1947 
1948     return 0;
1949 
1950 
1951 }
1952 
1953 static int
1954 chk_asi(struct pstate *sregs, uint32_t *asi, uint32_t op3)
1955 {
1956     if (!(sregs->psr & PSR_S)) {
1957 	sregs->trap = TRAP_PRIVI;
1958 	return 0;
1959     } else if (sregs->inst & INST_I) {
1960 	sregs->trap = TRAP_UNIMP;
1961 	return 0;
1962     } else
1963 	*asi = (sregs->inst >> 5) & 0x0ff;
1964     return 1;
1965 }
1966 
1967 int
1968 execute_trap(struct pstate *sregs)
1969 {
1970     int32_t           cwp;
1971 
1972     if (sregs->trap == 256) {
1973 	sregs->pc = 0;
1974 	sregs->npc = 4;
1975 	sregs->trap = 0;
1976     } else if (sregs->trap == 257) {
1977 	    return ERROR;
1978     } else {
1979 
1980 	if ((sregs->psr & PSR_ET) == 0)
1981 	    return ERROR;
1982 
1983 	sregs->tbr = (sregs->tbr & 0xfffff000) | (sregs->trap << 4);
1984 	sregs->trap = 0;
1985 	sregs->psr &= ~PSR_ET;
1986 	sregs->psr |= ((sregs->psr & PSR_S) >> 1);
1987 	sregs->annul = 0;
1988 	sregs->psr = (((sregs->psr & PSR_CWP) - 1) & 0x7) | (sregs->psr & ~PSR_CWP);
1989 	cwp = ((sregs->psr & PSR_CWP) << 4);
1990 	sregs->r[(cwp + 17) & 0x7f] = sregs->pc;
1991 	sregs->r[(cwp + 18) & 0x7f] = sregs->npc;
1992 	sregs->psr |= PSR_S;
1993 	sregs->pc = sregs->tbr;
1994 	sregs->npc = sregs->tbr + 4;
1995 
1996         if ( 0 != (1 & sregs->asr17) ) {
1997             /* single vector trapping! */
1998             sregs->pc = sregs->tbr & 0xfffff000;
1999             sregs->npc = sregs->pc + 4;
2000         }
2001 
2002 	/* Increase simulator time */
2003 	sregs->icnt = TRAP_C;
2004 
2005     }
2006 
2007 
2008     return 0;
2009 
2010 }
2011 
2012 extern struct irqcell irqarr[16];
2013 
2014 int
2015 check_interrupts(struct pstate *sregs)
2016 {
2017 #ifdef ERRINJ
2018     if (errtt) {
2019 	sregs->trap = errtt;
2020 	if (sis_verbose) printf("Inserted error trap 0x%02X\n",errtt);
2021 	errtt = 0;
2022     }
2023 #endif
2024 
2025     if ((ext_irl) && (sregs->psr & PSR_ET) &&
2026 	((ext_irl == 15) || (ext_irl > (int) ((sregs->psr & PSR_PIL) >> 8)))) {
2027 	if (sregs->trap == 0) {
2028 	    sregs->trap = 16 + ext_irl;
2029 	    irqarr[ext_irl & 0x0f].callback(irqarr[ext_irl & 0x0f].arg);
2030 	    return 1;
2031 	}
2032     }
2033     return 0;
2034 }
2035 
2036 void
2037 init_regs(struct pstate *sregs)
2038 {
2039     sregs->pc = 0;
2040     sregs->npc = 4;
2041     sregs->trap = 0;
2042     sregs->psr &= 0x00f03fdf;
2043     sregs->psr |= 0x11000080;	/* Set supervisor bit */
2044     sregs->breakpoint = 0;
2045     sregs->annul = 0;
2046     sregs->fpstate = FP_EXE_MODE;
2047     sregs->fpqn = 0;
2048     sregs->ftime = 0;
2049     sregs->ltime = 0;
2050     sregs->err_mode = 0;
2051     ext_irl = 0;
2052     sregs->g[0] = 0;
2053 #ifdef HOST_LITTLE_ENDIAN
2054     sregs->fdp = (float32 *) sregs->fd;
2055     sregs->fsi = (int32_t *) sregs->fs;
2056 #else
2057     sregs->fs = (float32 *) sregs->fd;
2058     sregs->fsi = (int32_t *) sregs->fd;
2059 #endif
2060     sregs->fsr = 0;
2061     sregs->fpu_pres = !nfp;
2062     set_fsr(sregs->fsr);
2063     sregs->bphit = 0;
2064     sregs->ildreg = 0;
2065     sregs->ildtime = 0;
2066 
2067     sregs->y = 0;
2068     sregs->asr17 = 0;
2069 
2070     sregs->rett_err = 0;
2071     sregs->jmpltime = 0;
2072 }
2073