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