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