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