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