Update sim copyright headers from GPLv2-or-later to GPLv3-or-later.
[deliverable/binutils-gdb.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 3 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, 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 }
This page took 0.092371 seconds and 5 git commands to generate.