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