OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [erc32/] [exec.c] - Blame information for rev 321

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.