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