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