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