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