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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [rx/] [rx.c] - Blame information for rev 843

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

Line No. Rev Author Line
1 330 jeremybenn
/* rx.c --- opcode semantics for stand-alone RX simulator.
2
 
3
Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
4
Contributed by Red Hat, Inc.
5
 
6
This file is part of the GNU simulators.
7
 
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <signal.h>
25
 
26
#include "opcode/rx.h"
27
#include "cpu.h"
28
#include "mem.h"
29
#include "syscalls.h"
30
#include "fpu.h"
31
#include "err.h"
32
 
33
#define tprintf if (trace) printf
34
 
35
jmp_buf decode_jmp_buf;
36
unsigned int rx_cycles = 0;
37
 
38
static int size2bytes[] = {
39
  4, 1, 1, 1, 2, 2, 2, 3, 4
40
};
41
 
42
typedef struct {
43
  unsigned long dpc;
44
} RX_Data;
45
 
46
#define rx_abort() _rx_abort(__FILE__, __LINE__)
47
static void
48
_rx_abort (const char *file, int line)
49
{
50
  if (strrchr (file, '/'))
51
    file = strrchr (file, '/') + 1;
52
  fprintf(stderr, "abort at %s:%d\n", file, line);
53
  abort();
54
}
55
 
56
static int
57
rx_get_byte (void *vdata)
58
{
59
  int saved_trace = trace;
60
  unsigned char rv;
61
 
62
  if (trace == 1)
63
    trace = 0;
64
 
65
  RX_Data *rx_data = (RX_Data *)vdata;
66
  if (rx_big_endian)
67
    /* See load.c for an explanation of this.  */
68
    rv = mem_get_pc (rx_data->dpc ^ 3);
69
  else
70
    rv = mem_get_pc (rx_data->dpc);
71
  rx_data->dpc ++;
72
  trace = saved_trace;
73
  return rv;
74
}
75
 
76
static int
77
get_op (RX_Opcode_Decoded *rd, int i)
78
{
79
  RX_Opcode_Operand *o = rd->op + i;
80
  int addr, rv = 0;
81
 
82
  switch (o->type)
83
    {
84
    case RX_Operand_None:
85
      rx_abort ();
86
 
87
    case RX_Operand_Immediate:  /* #addend */
88
      return o->addend;
89
 
90
    case RX_Operand_Register:   /* Rn */
91
      rv = get_reg (o->reg);
92
      break;
93
 
94
    case RX_Operand_Predec:     /* [-Rn] */
95
      put_reg (o->reg, get_reg (o->reg) - size2bytes[o->size]);
96
      /* fall through */
97
    case RX_Operand_Postinc:    /* [Rn+] */
98
    case RX_Operand_Indirect:   /* [Rn + addend] */
99
 
100
      addr = get_reg (o->reg) + o->addend;
101
      switch (o->size)
102
        {
103
        case RX_AnySize:
104
          rx_abort ();
105
 
106
        case RX_Byte: /* undefined extension */
107
        case RX_UByte:
108
        case RX_SByte:
109
          rv = mem_get_qi (addr);
110
          break;
111
 
112
        case RX_Word: /* undefined extension */
113
        case RX_UWord:
114
        case RX_SWord:
115
          rv = mem_get_hi (addr);
116
          break;
117
 
118
        case RX_3Byte:
119
          rv = mem_get_psi (addr);
120
          break;
121
 
122
        case RX_Long:
123
          rv = mem_get_si (addr);
124
          break;
125
        }
126
 
127
      if (o->type == RX_Operand_Postinc)
128
        put_reg (o->reg, get_reg (o->reg) + size2bytes[o->size]);
129
 
130
      break;
131
 
132
    case RX_Operand_Condition:  /* eq, gtu, etc */
133
      return condition_true (o->reg);
134
 
135
    case RX_Operand_Flag:       /* [UIOSZC] */
136
      return (regs.r_psw & (1 << o->reg)) ? 1 : 0;
137
    }
138
 
139
  /* if we've gotten here, we need to clip/extend the value according
140
     to the size.  */
141
  switch (o->size)
142
    {
143
    case RX_AnySize:
144
      rx_abort ();
145
 
146
    case RX_Byte: /* undefined extension */
147
      rv |= 0xdeadbe00; /* keep them honest */
148
      break;
149
 
150
    case RX_UByte:
151
      rv &= 0xff;
152
      break;
153
 
154
    case RX_SByte:
155
      rv = sign_ext (rv, 8);
156
      break;
157
 
158
    case RX_Word: /* undefined extension */
159
      rv |= 0xdead0000; /* keep them honest */
160
      break;
161
 
162
    case RX_UWord:
163
      rv &=  0xffff;
164
      break;
165
 
166
    case RX_SWord:
167
      rv = sign_ext (rv, 16);
168
      break;
169
 
170
    case RX_3Byte:
171
      rv &= 0xffffff;
172
      break;
173
 
174
    case RX_Long:
175
      break;
176
    }
177
  return rv;
178
}
179
 
180
static void
181
put_op (RX_Opcode_Decoded *rd, int i, int v)
182
{
183
  RX_Opcode_Operand *o = rd->op + i;
184
  int addr;
185
 
186
  switch (o->size)
187
    {
188
    case RX_AnySize:
189
      if (o->type != RX_Operand_Register)
190
        rx_abort ();
191
      break;
192
 
193
    case RX_Byte: /* undefined extension */
194
      v |= 0xdeadbe00; /* keep them honest */
195
      break;
196
 
197
    case RX_UByte:
198
      v &= 0xff;
199
      break;
200
 
201
    case RX_SByte:
202
      v = sign_ext (v, 8);
203
      break;
204
 
205
    case RX_Word: /* undefined extension */
206
      v |= 0xdead0000; /* keep them honest */
207
      break;
208
 
209
    case RX_UWord:
210
      v &=  0xffff;
211
      break;
212
 
213
    case RX_SWord:
214
      v = sign_ext (v, 16);
215
      break;
216
 
217
    case RX_3Byte:
218
      v &= 0xffffff;
219
      break;
220
 
221
    case RX_Long:
222
      break;
223
    }
224
 
225
  switch (o->type)
226
    {
227
    case RX_Operand_None:
228
      /* Opcodes like TST and CMP use this.  */
229
      break;
230
 
231
    case RX_Operand_Immediate:  /* #addend */
232
    case RX_Operand_Condition:  /* eq, gtu, etc */
233
      rx_abort ();
234
 
235
    case RX_Operand_Register:   /* Rn */
236
      put_reg (o->reg, v);
237
      break;
238
 
239
    case RX_Operand_Predec:     /* [-Rn] */
240
      put_reg (o->reg, get_reg (o->reg) - size2bytes[o->size]);
241
      /* fall through */
242
    case RX_Operand_Postinc:    /* [Rn+] */
243
    case RX_Operand_Indirect:   /* [Rn + addend] */
244
 
245
      addr = get_reg (o->reg) + o->addend;
246
      switch (o->size)
247
        {
248
        case RX_AnySize:
249
          rx_abort ();
250
 
251
        case RX_Byte: /* undefined extension */
252
        case RX_UByte:
253
        case RX_SByte:
254
          mem_put_qi (addr, v);
255
          break;
256
 
257
        case RX_Word: /* undefined extension */
258
        case RX_UWord:
259
        case RX_SWord:
260
          mem_put_hi (addr, v);
261
          break;
262
 
263
        case RX_3Byte:
264
          mem_put_psi (addr, v);
265
          break;
266
 
267
        case RX_Long:
268
          mem_put_si (addr, v);
269
          break;
270
        }
271
 
272
      if (o->type == RX_Operand_Postinc)
273
        put_reg (o->reg, get_reg (o->reg) + size2bytes[o->size]);
274
 
275
      break;
276
 
277
    case RX_Operand_Flag:       /* [UIOSZC] */
278
      if (v)
279
        regs.r_psw |= (1 << o->reg);
280
      else
281
        regs.r_psw &= ~(1 << o->reg);
282
      break;
283
    }
284
}
285
 
286
#define PD(x) put_op (&opcode, 0, x)
287
#define PS(x) put_op (&opcode, 1, x)
288
#define PS2(x) put_op (&opcode, 2, x)
289
#define GD() get_op (&opcode, 0)
290
#define GS() get_op (&opcode, 1)
291
#define GS2() get_op (&opcode, 2)
292
#define DSZ() size2bytes[opcode.op[0].size]
293
#define SSZ() size2bytes[opcode.op[0].size]
294
#define S2SZ() size2bytes[opcode.op[0].size]
295
 
296
/* "Universal" sources.  */
297
#define US1() ((opcode.op[2].type == RX_Operand_None) ? GD() : GS())
298
#define US2() ((opcode.op[2].type == RX_Operand_None) ? GS() : GS2())
299
 
300
static void
301
push(int val)
302
{
303
  int rsp = get_reg (sp);
304
  rsp -= 4;
305
  put_reg (sp, rsp);
306
  mem_put_si (rsp, val);
307
}
308
 
309
/* Just like the above, but tag the memory as "pushed pc" so if anyone
310
   tries to write to it, it will cause an error.  */
311
static void
312
pushpc(int val)
313
{
314
  int rsp = get_reg (sp);
315
  rsp -= 4;
316
  put_reg (sp, rsp);
317
  mem_put_si (rsp, val);
318
  mem_set_content_range (rsp, rsp+3, MC_PUSHED_PC);
319
}
320
 
321
static int
322
pop()
323
{
324
  int rv;
325
  int rsp = get_reg (sp);
326
  rv = mem_get_si (rsp);
327
  rsp += 4;
328
  put_reg (sp, rsp);
329
  return rv;
330
}
331
 
332
static int
333
poppc()
334
{
335
  int rv;
336
  int rsp = get_reg (sp);
337
  if (mem_get_content_type (rsp) != MC_PUSHED_PC)
338
    execution_error (SIM_ERR_CORRUPT_STACK, rsp);
339
  rv = mem_get_si (rsp);
340
  mem_set_content_range (rsp, rsp+3, MC_UNINIT);
341
  rsp += 4;
342
  put_reg (sp, rsp);
343
  return rv;
344
}
345
 
346
#define MATH_OP(vop,c)                          \
347
{ \
348
  uma = US1(); \
349
  umb = US2(); \
350
  ll = (unsigned long long) uma vop (unsigned long long) umb vop c; \
351
  tprintf ("0x%x " #vop " 0x%x " #vop " 0x%x = 0x%llx\n", uma, umb, c, ll); \
352
  ma = sign_ext (uma, DSZ() * 8);                                       \
353
  mb = sign_ext (umb, DSZ() * 8);                                       \
354
  sll = (long long) ma vop (long long) mb vop c; \
355
  tprintf ("%d " #vop " %d " #vop " %d = %lld\n", ma, mb, c, sll); \
356
  set_oszc (sll, DSZ(), (long long) ll > ((1 vop 1) ? (long long) b2mask[DSZ()] : (long long) -1)); \
357
  PD (sll); \
358
}
359
 
360
#define LOGIC_OP(vop) \
361
{ \
362
  ma = US1(); \
363
  mb = US2(); \
364
  v = ma vop mb; \
365
  tprintf("0x%x " #vop " 0x%x = 0x%x\n", ma, mb, v); \
366
  set_sz (v, DSZ()); \
367
  PD(v); \
368
}
369
 
370
#define SHIFT_OP(val, type, count, OP, carry_mask)      \
371
{ \
372
  int i, c=0; \
373
  val = (type)US1();                            \
374
  count = US2(); \
375
  tprintf("%lld " #OP " %d\n", val, count); \
376
  for (i = 0; i < count; i ++) \
377
    { \
378
      c = val & carry_mask; \
379
      val OP 1; \
380
    } \
381
  if (count) \
382
    set_oszc (val, 4, c); \
383
  PD (val); \
384
}
385
 
386
typedef union {
387
  int i;
388
  float f;
389
} FloatInt;
390
 
391
static inline int
392
float2int (float f)
393
{
394
  FloatInt fi;
395
  fi.f = f;
396
  return fi.i;
397
}
398
 
399
static inline float
400
int2float (int i)
401
{
402
  FloatInt fi;
403
  fi.i = i;
404
  return fi.f;
405
}
406
 
407
static int
408
fop_fadd (fp_t s1, fp_t s2, fp_t *d)
409
{
410
  *d = rxfp_add (s1, s2);
411
  return 1;
412
}
413
 
414
static int
415
fop_fmul (fp_t s1, fp_t s2, fp_t *d)
416
{
417
  *d = rxfp_mul (s1, s2);
418
  return 1;
419
}
420
 
421
static int
422
fop_fdiv (fp_t s1, fp_t s2, fp_t *d)
423
{
424
  *d = rxfp_div (s1, s2);
425
  return 1;
426
}
427
 
428
static int
429
fop_fsub (fp_t s1, fp_t s2, fp_t *d)
430
{
431
  *d = rxfp_sub (s1, s2);
432
  return 1;
433
}
434
 
435
#define FPPENDING() (regs.r_fpsw & (FPSWBITS_CE | (FPSWBITS_FMASK & (regs.r_fpsw << FPSW_EFSH))))
436
#define FPCLEAR() regs.r_fpsw &= FPSWBITS_CLEAR
437
#define FPCHECK() \
438
  if (FPPENDING()) \
439
    return do_fp_exception (opcode_pc)
440
 
441
#define FLOAT_OP(func) \
442
{ \
443
  int do_store;   \
444
  fp_t fa, fb, fc; \
445
  FPCLEAR(); \
446
  fa = GD (); \
447
  fb = GS (); \
448
  do_store = fop_##func (fa, fb, &fc); \
449
  tprintf("%g " #func " %g = %g %08x\n", int2float(fa), int2float(fb), int2float(fc), fc); \
450
  FPCHECK(); \
451
  if (do_store) \
452
    PD (fc);    \
453
  mb = 0; \
454
  if ((fc & 0x80000000UL) != 0) \
455
    mb |= FLAGBIT_S; \
456
  if ((fc & 0x7fffffffUL) == 0)                  \
457
    mb |= FLAGBIT_Z; \
458
  set_flags (FLAGBIT_S | FLAGBIT_Z, mb); \
459
}
460
 
461
#define carry (FLAG_C ? 1 : 0)
462
 
463
static struct {
464
  unsigned long vaddr;
465
  const char *str;
466
  int signal;
467
} exception_info[] = {
468
  { 0xFFFFFFD0UL, "priviledged opcode", SIGILL },
469
  { 0xFFFFFFD4UL, "access violation", SIGSEGV },
470
  { 0xFFFFFFDCUL, "undefined opcode", SIGILL },
471
  { 0xFFFFFFE4UL, "floating point", SIGFPE }
472
};
473
#define EX_PRIVILEDGED  0
474
#define EX_ACCESS       1
475
#define EX_UNDEFINED    2
476
#define EX_FLOATING     3
477
#define EXCEPTION(n)  \
478
  return generate_exception (n, opcode_pc)
479
 
480
#define PRIVILEDGED() \
481
  if (FLAG_PM) \
482
    EXCEPTION (EX_PRIVILEDGED)
483
 
484
static int
485
generate_exception (unsigned long type, SI opcode_pc)
486
{
487
  SI old_psw, old_pc, new_pc;
488
 
489
  new_pc = mem_get_si (exception_info[type].vaddr);
490
  /* 0x00020000 is the value used to initialise the known
491
     exception vectors (see rx.ld), but it is a reserved
492
     area of memory so do not try to access it, and if the
493
     value has not been changed by the program then the
494
     vector has not been installed.  */
495
  if (new_pc == 0 || new_pc == 0x00020000)
496
    {
497
      if (rx_in_gdb)
498
        return RX_MAKE_STOPPED (exception_info[type].signal);
499
 
500
      fprintf(stderr, "Unhandled %s exception at pc = %#lx\n",
501
              exception_info[type].str, (unsigned long) opcode_pc);
502
      if (type == EX_FLOATING)
503
        {
504
          int mask = FPPENDING ();
505
          fprintf (stderr, "Pending FP exceptions:");
506
          if (mask & FPSWBITS_FV)
507
            fprintf(stderr, " Invalid");
508
          if (mask & FPSWBITS_FO)
509
            fprintf(stderr, " Overflow");
510
          if (mask & FPSWBITS_FZ)
511
            fprintf(stderr, " Division-by-zero");
512
          if (mask & FPSWBITS_FU)
513
            fprintf(stderr, " Underflow");
514
          if (mask & FPSWBITS_FX)
515
            fprintf(stderr, " Inexact");
516
          if (mask & FPSWBITS_CE)
517
            fprintf(stderr, " Unimplemented");
518
          fprintf(stderr, "\n");
519
        }
520
      return RX_MAKE_EXITED (1);
521
    }
522
 
523
  tprintf ("Triggering %s exception\n", exception_info[type].str);
524
 
525
  old_psw = regs.r_psw;
526
  regs.r_psw &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM);
527
  old_pc = opcode_pc;
528
  regs.r_pc = new_pc;
529
  pushpc (old_psw);
530
  pushpc (old_pc);
531
  return RX_MAKE_STEPPED ();
532
}
533
 
534
void
535
generate_access_exception (void)
536
{
537
  int rv;
538
 
539
  rv = generate_exception (EX_ACCESS, regs.r_pc);
540
  if (RX_EXITED (rv))
541
    longjmp (decode_jmp_buf, rv);
542
}
543
 
544
static int
545
do_fp_exception (unsigned long opcode_pc)
546
{
547
  while (FPPENDING())
548
    EXCEPTION (EX_FLOATING);
549
  return RX_MAKE_STEPPED ();
550
}
551
 
552
int
553
decode_opcode ()
554
{
555
  unsigned int uma=0, umb=0;
556
  int ma=0, mb=0;
557
  int opcode_size, v;
558
  unsigned long long ll;
559
  long long sll;
560
  unsigned long opcode_pc;
561
  RX_Data rx_data;
562
  RX_Opcode_Decoded opcode;
563
  int rv;
564
 
565
  if ((rv = setjmp (decode_jmp_buf)))
566
    return rv;
567
 
568
  rx_cycles ++;
569
 
570
  rx_data.dpc = opcode_pc = regs.r_pc;
571
  opcode_size = rx_decode_opcode (opcode_pc, &opcode, rx_get_byte, &rx_data);
572
  regs.r_pc += opcode_size;
573
 
574
  rx_flagmask = opcode.flags_s;
575
  rx_flagand = ~(int)opcode.flags_0;
576
  rx_flagor = opcode.flags_1;
577
 
578
  switch (opcode.id)
579
    {
580
    case RXO_abs:
581
      sll = GS ();
582
      tprintf("|%lld| = ", sll);
583
      if (sll < 0)
584
        sll = -sll;
585
      tprintf("%lld\n", sll);
586
      PD (sll);
587
      set_osz (sll, 4);
588
      break;
589
 
590
    case RXO_adc:
591
      MATH_OP (+,carry);
592
      break;
593
 
594
    case RXO_add:
595
      MATH_OP (+,0);
596
      break;
597
 
598
    case RXO_and:
599
      LOGIC_OP (&);
600
      break;
601
 
602
    case RXO_bclr:
603
      ma = GD ();
604
      mb = GS ();
605
      if (opcode.op[0].type == RX_Operand_Register)
606
        mb &= 0x1f;
607
      else
608
        mb &= 0x07;
609
      ma &= ~(1 << mb);
610
      PD (ma);
611
      break;
612
 
613
    case RXO_bmcc:
614
      ma = GD ();
615
      mb = GS ();
616
      if (opcode.op[0].type == RX_Operand_Register)
617
        mb &= 0x1f;
618
      else
619
        mb &= 0x07;
620
      if (GS2 ())
621
        ma |= (1 << mb);
622
      else
623
        ma &= ~(1 << mb);
624
      PD (ma);
625
      break;
626
 
627
    case RXO_bnot:
628
      ma = GD ();
629
      mb = GS ();
630
      if (opcode.op[0].type == RX_Operand_Register)
631
        mb &= 0x1f;
632
      else
633
        mb &= 0x07;
634
      ma ^= (1 << mb);
635
      PD (ma);
636
      break;
637
 
638
    case RXO_branch:
639
      if (GS())
640
        regs.r_pc = GD();
641
      break;
642
 
643
    case RXO_branchrel:
644
      if (GS())
645
        regs.r_pc += GD();
646
      break;
647
 
648
    case RXO_brk:
649
      {
650
        int old_psw = regs.r_psw;
651
        if (rx_in_gdb)
652
          return RX_MAKE_HIT_BREAK ();
653
        if (regs.r_intb == 0)
654
          {
655
            tprintf("BREAK hit, no vector table.\n");
656
            return RX_MAKE_EXITED(1);
657
          }
658
        regs.r_psw &= ~(FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM);
659
        pushpc (old_psw);
660
        pushpc (regs.r_pc);
661
        regs.r_pc = mem_get_si (regs.r_intb);
662
      }
663
      break;
664
 
665
    case RXO_bset:
666
      ma = GD ();
667
      mb = GS ();
668
      if (opcode.op[0].type == RX_Operand_Register)
669
        mb &= 0x1f;
670
      else
671
        mb &= 0x07;
672
      ma |= (1 << mb);
673
      PD (ma);
674
      break;
675
 
676
    case RXO_btst:
677
      ma = GS ();
678
      mb = GS2 ();
679
      if (opcode.op[1].type == RX_Operand_Register)
680
        mb &= 0x1f;
681
      else
682
        mb &= 0x07;
683
      umb = ma & (1 << mb);
684
      set_zc (! umb, umb);
685
      break;
686
 
687
    case RXO_clrpsw:
688
      v = 1 << opcode.op[0].reg;
689
      if (FLAG_PM
690
          && (v == FLAGBIT_I
691
              || v == FLAGBIT_U))
692
        break;
693
      regs.r_psw &= ~v;
694
      break;
695
 
696
    case RXO_div: /* d = d / s */
697
      ma = GS();
698
      mb = GD();
699
      tprintf("%d / %d = ", mb, ma);
700
      if (ma == 0 || (ma == -1 && (unsigned int) mb == 0x80000000))
701
        {
702
          tprintf("#NAN\n");
703
          set_flags (FLAGBIT_O, FLAGBIT_O);
704
        }
705
      else
706
        {
707
          v = mb/ma;
708
          tprintf("%d\n", v);
709
          set_flags (FLAGBIT_O, 0);
710
          PD (v);
711
        }
712
      break;
713
 
714
    case RXO_divu: /* d = d / s */
715
      uma = GS();
716
      umb = GD();
717
      tprintf("%u / %u = ", umb, uma);
718
      if (uma == 0)
719
        {
720
          tprintf("#NAN\n");
721
          set_flags (FLAGBIT_O, FLAGBIT_O);
722
        }
723
      else
724
        {
725
          v = umb / uma;
726
          tprintf("%u\n", v);
727
          set_flags (FLAGBIT_O, 0);
728
          PD (v);
729
        }
730
      break;
731
 
732
    case RXO_ediv:
733
      ma = GS();
734
      mb = GD();
735
      tprintf("%d / %d = ", mb, ma);
736
      if (ma == 0 || (ma == -1 && (unsigned int) mb == 0x80000000))
737
        {
738
          tprintf("#NAN\n");
739
          set_flags (FLAGBIT_O, FLAGBIT_O);
740
        }
741
      else
742
        {
743
          v = mb/ma;
744
          mb = mb%ma;
745
          tprintf("%d, rem %d\n", v, mb);
746
          set_flags (FLAGBIT_O, 0);
747
          PD (v);
748
          opcode.op[0].reg ++;
749
          PD (mb);
750
        }
751
      break;
752
 
753
    case RXO_edivu:
754
      uma = GS();
755
      umb = GD();
756
      tprintf("%u / %u = ", umb, uma);
757
      if (uma == 0)
758
        {
759
          tprintf("#NAN\n");
760
          set_flags (FLAGBIT_O, FLAGBIT_O);
761
        }
762
      else
763
        {
764
          v = umb/uma;
765
          umb = umb%uma;
766
          tprintf("%u, rem %u\n", v, umb);
767
          set_flags (FLAGBIT_O, 0);
768
          PD (v);
769
          opcode.op[0].reg ++;
770
          PD (umb);
771
        }
772
      break;
773
 
774
    case RXO_emul:
775
      ma = GD ();
776
      mb = GS ();
777
      sll = (long long)ma * (long long)mb;
778
      tprintf("%d * %d = %lld\n", ma, mb, sll);
779
      PD (sll);
780
      opcode.op[0].reg ++;
781
      PD (sll >> 32);
782
      break;
783
 
784
    case RXO_emulu:
785
      uma = GD ();
786
      umb = GS ();
787
      ll = (long long)uma * (long long)umb;
788
      tprintf("%#x * %#x = %#llx\n", uma, umb, ll);
789
      PD (ll);
790
      opcode.op[0].reg ++;
791
      PD (ll >> 32);
792
      break;
793
 
794
    case RXO_fadd:
795
      FLOAT_OP (fadd);
796
      break;
797
 
798
    case RXO_fcmp:
799
      ma = GD();
800
      mb = GS();
801
      FPCLEAR ();
802
      rxfp_cmp (ma, mb);
803
      FPCHECK ();
804
      break;
805
 
806
    case RXO_fdiv:
807
      FLOAT_OP (fdiv);
808
      break;
809
 
810
    case RXO_fmul:
811
      FLOAT_OP (fmul);
812
      break;
813
 
814
    case RXO_rtfi:
815
      PRIVILEDGED ();
816
      regs.r_psw = regs.r_bpsw;
817
      regs.r_pc = regs.r_bpc;
818
      break;
819
 
820
    case RXO_fsub:
821
      FLOAT_OP (fsub);
822
      break;
823
 
824
    case RXO_ftoi:
825
      ma = GS ();
826
      FPCLEAR ();
827
      mb = rxfp_ftoi (ma, FPRM_ZERO);
828
      FPCHECK ();
829
      PD (mb);
830
      tprintf("(int) %g = %d\n", int2float(ma), mb);
831
      set_sz (mb, 4);
832
      break;
833
 
834
    case RXO_int:
835
      v = GS ();
836
      if (v == 255)
837
        {
838
          return rx_syscall (regs.r[5]);
839
        }
840
      else
841
        {
842
          int old_psw = regs.r_psw;
843
          regs.r_psw &= ~(FLAGBIT_I | FLAGBIT_U | FLAGBIT_PM);
844
          pushpc (old_psw);
845
          pushpc (regs.r_pc);
846
          regs.r_pc = mem_get_si (regs.r_intb + 4 * v);
847
        }
848
      break;
849
 
850
    case RXO_itof:
851
      ma = GS ();
852
      FPCLEAR ();
853
      mb = rxfp_itof (ma, regs.r_fpsw);
854
      FPCHECK ();
855
      tprintf("(float) %d = %x\n", ma, mb);
856
      PD (mb);
857
      set_sz (ma, 4);
858
      break;
859
 
860
    case RXO_jsr:
861
    case RXO_jsrrel:
862
      v = GD ();
863
      pushpc (get_reg (pc));
864
      if (opcode.id == RXO_jsrrel)
865
        v += regs.r_pc;
866
      put_reg (pc, v);
867
      break;
868
 
869
    case RXO_machi:
870
      ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16);
871
      ll <<= 16;
872
      put_reg64 (acc64, ll + regs.r_acc);
873
      break;
874
 
875
    case RXO_maclo:
876
      ll = (long long)(signed short)(GS()) * (long long)(signed short)(GS2 ());
877
      ll <<= 16;
878
      put_reg64 (acc64, ll + regs.r_acc);
879
      break;
880
 
881
    case RXO_max:
882
      ma = GD();
883
      mb = GS();
884
      if (ma > mb)
885
        PD (ma);
886
      else
887
        PD (mb);
888
      break;
889
 
890
    case RXO_min:
891
      ma = GD();
892
      mb = GS();
893
      if (ma < mb)
894
        PD (ma);
895
      else
896
        PD (mb);
897
      break;
898
 
899
    case RXO_mov:
900
      v = GS ();
901
      if (opcode.op[0].type == RX_Operand_Register
902
          && opcode.op[0].reg == 16 /* PSW */)
903
        {
904
          /* Special case, LDC and POPC can't ever modify PM.  */
905
          int pm = regs.r_psw & FLAGBIT_PM;
906
          v &= ~ FLAGBIT_PM;
907
          v |= pm;
908
          if (pm)
909
            {
910
              v &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL);
911
              v |= pm;
912
            }
913
        }
914
      if (FLAG_PM)
915
        {
916
          /* various things can't be changed in user mode.  */
917
          if (opcode.op[0].type == RX_Operand_Register)
918
            if (opcode.op[0].reg == 32)
919
              {
920
                v &= ~ (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL);
921
                v |= regs.r_psw & (FLAGBIT_I | FLAGBIT_U | FLAGBITS_IPL);
922
              }
923
          if (opcode.op[0].reg == 34 /* ISP */
924
              || opcode.op[0].reg == 37 /* BPSW */
925
              || opcode.op[0].reg == 39 /* INTB */
926
              || opcode.op[0].reg == 38 /* VCT */)
927
            /* These are ignored.  */
928
            break;
929
        }
930
      PD (v);
931
      set_sz (v, DSZ());
932
      break;
933
 
934
    case RXO_movbi:
935
      /* We cheat to save on code duplication. */
936
      regs.r_temp = (get_reg (opcode.op[1].reg) * size2bytes[opcode.size]
937
                     + get_reg (opcode.op[2].reg));
938
      opcode.op[1].reg = r_temp_idx;
939
      opcode.op[1].type = RX_Operand_Indirect;
940
      opcode.op[1].addend = 0;
941
      PD (GS ());
942
      break;
943
 
944
    case RXO_movbir:
945
      /* We cheat to save on code duplication. */
946
      regs.r_temp = (get_reg (opcode.op[1].reg) * size2bytes[opcode.size]
947
                     + get_reg (opcode.op[2].reg));
948
      opcode.op[1].reg = r_temp_idx;
949
      opcode.op[1].type = RX_Operand_Indirect;
950
      opcode.op[1].addend = 0;
951
      PS (GD ());
952
      break;
953
 
954
    case RXO_mul:
955
      ll = (unsigned long long) US1() * (unsigned long long) US2();
956
      PD(ll);
957
      break;
958
 
959
    case RXO_mulhi:
960
      ll = (long long)(signed short)(GS() >> 16) * (long long)(signed short)(GS2 () >> 16);
961
      ll <<= 16;
962
      put_reg64 (acc64, ll);
963
      break;
964
 
965
    case RXO_mullo:
966
      ll = (long long)(signed short)(GS()) * (long long)(signed short)(GS2 ());
967
      ll <<= 16;
968
      put_reg64 (acc64, ll);
969
      break;
970
 
971
    case RXO_mvfachi:
972
      PD (get_reg (acchi));
973
      break;
974
 
975
    case RXO_mvfaclo:
976
      PD (get_reg (acclo));
977
      break;
978
 
979
    case RXO_mvfacmi:
980
      PD (get_reg (accmi));
981
      break;
982
 
983
    case RXO_mvtachi:
984
      put_reg (acchi, GS ());
985
      break;
986
 
987
    case RXO_mvtaclo:
988
      put_reg (acclo, GS ());
989
      break;
990
 
991
    case RXO_mvtipl:
992
      regs.r_psw &= ~ FLAGBITS_IPL;
993
      regs.r_psw |= (GS () << FLAGSHIFT_IPL) & FLAGBITS_IPL;
994
      break;
995
 
996
    case RXO_nop:
997
      break;
998
 
999
    case RXO_or:
1000
      LOGIC_OP (|);
1001
      break;
1002
 
1003
    case RXO_popm:
1004
      /* POPM cannot pop R0 (sp).  */
1005
      if (opcode.op[1].reg == 0 || opcode.op[2].reg == 0)
1006
        EXCEPTION (EX_UNDEFINED);
1007
      if (opcode.op[1].reg >= opcode.op[2].reg)
1008
        {
1009
          regs.r_pc = opcode_pc;
1010
          return RX_MAKE_STOPPED (SIGILL);
1011
        }
1012
      for (v = opcode.op[1].reg; v <= opcode.op[2].reg; v++)
1013
        put_reg (v, pop ());
1014
      break;
1015
 
1016
    case RXO_pusha:
1017
      push (get_reg (opcode.op[1].reg) + opcode.op[1].addend);
1018
      break;
1019
 
1020
    case RXO_pushm:
1021
      /* PUSHM cannot push R0 (sp).  */
1022
      if (opcode.op[1].reg == 0 || opcode.op[2].reg == 0)
1023
        EXCEPTION (EX_UNDEFINED);
1024
      if (opcode.op[1].reg >= opcode.op[2].reg)
1025
        {
1026
          regs.r_pc = opcode_pc;
1027
          return RX_MAKE_STOPPED (SIGILL);
1028
        }
1029
      for (v = opcode.op[2].reg; v >= opcode.op[1].reg; v--)
1030
        push (get_reg (v));
1031
      break;
1032
 
1033
    case RXO_racw:
1034
      ll = get_reg64 (acc64) << GS ();
1035
      ll += 0x80000000ULL;
1036
      if ((signed long long)ll > (signed long long)0x00007fff00000000ULL)
1037
        ll = 0x00007fff00000000ULL;
1038
      else if ((signed long long)ll < (signed long long)0xffff800000000000ULL)
1039
        ll = 0xffff800000000000ULL;
1040
      else
1041
        ll &= 0xffffffff00000000ULL;
1042
      put_reg64 (acc64, ll);
1043
      break;
1044
 
1045
    case RXO_rte:
1046
      PRIVILEDGED ();
1047
      regs.r_pc = poppc ();
1048
      regs.r_psw = poppc ();
1049
      if (FLAG_PM)
1050
        regs.r_psw |= FLAGBIT_U;
1051
      break;
1052
 
1053
    case RXO_revl:
1054
      uma = GS ();
1055
      umb = (((uma >> 24) & 0xff)
1056
             | ((uma >> 8) & 0xff00)
1057
             | ((uma << 8) & 0xff0000)
1058
             | ((uma << 24) & 0xff000000UL));
1059
      PD (umb);
1060
      break;
1061
 
1062
    case RXO_revw:
1063
      uma = GS ();
1064
      umb = (((uma >> 8) & 0x00ff00ff)
1065
             | ((uma << 8) & 0xff00ff00UL));
1066
      PD (umb);
1067
      break;
1068
 
1069
    case RXO_rmpa:
1070
      while (regs.r[3] != 0)
1071
        {
1072
          long long tmp;
1073
 
1074
          switch (opcode.size)
1075
            {
1076
            case RX_Long:
1077
              ma = mem_get_si (regs.r[1]);
1078
              mb = mem_get_si (regs.r[2]);
1079
              regs.r[1] += 4;
1080
              regs.r[2] += 4;
1081
              break;
1082
            case RX_Word:
1083
              ma = sign_ext (mem_get_hi (regs.r[1]), 16);
1084
              mb = sign_ext (mem_get_hi (regs.r[2]), 16);
1085
              regs.r[1] += 2;
1086
              regs.r[2] += 2;
1087
              break;
1088
            case RX_Byte:
1089
              ma = sign_ext (mem_get_qi (regs.r[1]), 8);
1090
              mb = sign_ext (mem_get_qi (regs.r[2]), 8);
1091
              regs.r[1] += 1;
1092
              regs.r[2] += 1;
1093
              break;
1094
            default:
1095
              abort ();
1096
            }
1097
          /* We do the multiply as a signed value.  */
1098
          sll = (long long)ma * (long long)mb;
1099
          tprintf("        %016llx = %d * %d\n", sll, ma, mb);
1100
          /* but we do the sum as unsigned, while sign extending the operands.  */
1101
          tmp = regs.r[4] + (sll & 0xffffffffUL);
1102
          regs.r[4] = tmp & 0xffffffffUL;
1103
          tmp >>= 32;
1104
          sll >>= 32;
1105
          tmp += regs.r[5] + (sll & 0xffffffffUL);
1106
          regs.r[5] = tmp & 0xffffffffUL;
1107
          tmp >>= 32;
1108
          sll >>= 32;
1109
          tmp += regs.r[6] + (sll & 0xffffffffUL);
1110
          regs.r[6] = tmp & 0xffffffffUL;
1111
          tprintf("%08lx\033[36m%08lx\033[0m%08lx\n",
1112
                  (unsigned long) regs.r[6],
1113
                  (unsigned long) regs.r[5],
1114
                  (unsigned long) regs.r[4]);
1115
 
1116
          regs.r[3] --;
1117
        }
1118
      if (regs.r[6] & 0x00008000)
1119
        regs.r[6] |= 0xffff0000UL;
1120
      else
1121
        regs.r[6] &= 0x0000ffff;
1122
      ma = (regs.r[6] & 0x80000000UL) ? FLAGBIT_S : 0;
1123
      if (regs.r[6] != 0 && regs.r[6] != 0xffffffffUL)
1124
        set_flags (FLAGBIT_O|FLAGBIT_S, ma | FLAGBIT_O);
1125
      else
1126
        set_flags (FLAGBIT_O|FLAGBIT_S, ma);
1127
      break;
1128
 
1129
    case RXO_rolc:
1130
      v = GD ();
1131
      ma = v & 0x80000000UL;
1132
      v <<= 1;
1133
      v |= carry;
1134
      set_szc (v, 4, ma);
1135
      PD (v);
1136
      break;
1137
 
1138
    case RXO_rorc:
1139
      uma = GD ();
1140
      mb = uma & 1;
1141
      uma >>= 1;
1142
      uma |= (carry ? 0x80000000UL : 0);
1143
      set_szc (uma, 4, mb);
1144
      PD (uma);
1145
      break;
1146
 
1147
    case RXO_rotl:
1148
      mb = GS ();
1149
      uma = GD ();
1150
      if (mb)
1151
        {
1152
          uma = (uma << mb) | (uma >> (32-mb));
1153
          mb = uma & 1;
1154
        }
1155
      set_szc (uma, 4, mb);
1156
      PD (uma);
1157
      break;
1158
 
1159
    case RXO_rotr:
1160
      mb = GS ();
1161
      uma = GD ();
1162
      if (mb)
1163
        {
1164
          uma = (uma >> mb) | (uma << (32-mb));
1165
          mb = uma & 0x80000000;
1166
        }
1167
      set_szc (uma, 4, mb);
1168
      PD (uma);
1169
      break;
1170
 
1171
    case RXO_round:
1172
      ma = GS ();
1173
      FPCLEAR ();
1174
      mb = rxfp_ftoi (ma, regs.r_fpsw);
1175
      FPCHECK ();
1176
      PD (mb);
1177
      tprintf("(int) %g = %d\n", int2float(ma), mb);
1178
      set_sz (mb, 4);
1179
      break;
1180
 
1181
    case RXO_rts:
1182
      regs.r_pc = poppc ();
1183
      break;
1184
 
1185
    case RXO_rtsd:
1186
      if (opcode.op[2].type == RX_Operand_Register)
1187
        {
1188
          int i;
1189
          /* RTSD cannot pop R0 (sp).  */
1190
          put_reg (0, get_reg (0) + GS() - (opcode.op[0].reg-opcode.op[2].reg+1)*4);
1191
          if (opcode.op[2].reg == 0)
1192
            EXCEPTION (EX_UNDEFINED);
1193
          for (i = opcode.op[2].reg; i <= opcode.op[0].reg; i ++)
1194
            put_reg (i, pop ());
1195
        }
1196
      else
1197
        put_reg (0, get_reg (0) + GS());
1198
      put_reg (pc, poppc ());
1199
      break;
1200
 
1201
    case RXO_sat:
1202
      if (FLAG_O && FLAG_S)
1203
        PD (0x7fffffffUL);
1204
      else if (FLAG_O && ! FLAG_S)
1205
        PD (0x80000000UL);
1206
      break;
1207
 
1208
    case RXO_sbb:
1209
      MATH_OP (-, ! carry);
1210
      break;
1211
 
1212
    case RXO_sccnd:
1213
      if (GS())
1214
        PD (1);
1215
      else
1216
        PD (0);
1217
      break;
1218
 
1219
    case RXO_scmpu:
1220
      while (regs.r[3] != 0)
1221
        {
1222
          uma = mem_get_qi (regs.r[1] ++);
1223
          umb = mem_get_qi (regs.r[2] ++);
1224
          regs.r[3] --;
1225
          if (uma != umb || uma == 0)
1226
            break;
1227
        }
1228
      if (uma == umb)
1229
        set_zc (1, 1);
1230
      else
1231
        set_zc (0, ((int)uma - (int)umb) >= 0);
1232
      break;
1233
 
1234
    case RXO_setpsw:
1235
      v = 1 << opcode.op[0].reg;
1236
      if (FLAG_PM
1237
          && (v == FLAGBIT_I
1238
              || v == FLAGBIT_U))
1239
        break;
1240
      regs.r_psw |= v;
1241
      break;
1242
 
1243
    case RXO_smovb:
1244
      while (regs.r[3])
1245
        {
1246
          uma = mem_get_qi (regs.r[2] --);
1247
          mem_put_qi (regs.r[1]--, uma);
1248
          regs.r[3] --;
1249
        }
1250
      break;
1251
 
1252
    case RXO_smovf:
1253
      while (regs.r[3])
1254
        {
1255
          uma = mem_get_qi (regs.r[2] ++);
1256
          mem_put_qi (regs.r[1]++, uma);
1257
          regs.r[3] --;
1258
        }
1259
      break;
1260
 
1261
    case RXO_smovu:
1262
      while (regs.r[3] != 0)
1263
        {
1264
          uma = mem_get_qi (regs.r[2] ++);
1265
          mem_put_qi (regs.r[1]++, uma);
1266
          regs.r[3] --;
1267
          if (uma == 0)
1268
            break;
1269
        }
1270
      break;
1271
 
1272
    case RXO_shar: /* d = ma >> mb */
1273
      SHIFT_OP (sll, int, mb, >>=, 1);
1274
      break;
1275
 
1276
    case RXO_shll: /* d = ma << mb */
1277
      SHIFT_OP (ll, int, mb, <<=, 0x80000000UL);
1278
      break;
1279
 
1280
    case RXO_shlr: /* d = ma >> mb */
1281
      SHIFT_OP (ll, unsigned int, mb, >>=, 1);
1282
      break;
1283
 
1284
    case RXO_sstr:
1285
      switch (opcode.size)
1286
        {
1287
        case RX_Long:
1288
          while (regs.r[3] != 0)
1289
            {
1290
              mem_put_si (regs.r[1], regs.r[2]);
1291
              regs.r[1] += 4;
1292
              regs.r[3] --;
1293
            }
1294
          break;
1295
        case RX_Word:
1296
          while (regs.r[3] != 0)
1297
            {
1298
              mem_put_hi (regs.r[1], regs.r[2]);
1299
              regs.r[1] += 2;
1300
              regs.r[3] --;
1301
            }
1302
          break;
1303
        case RX_Byte:
1304
          while (regs.r[3] != 0)
1305
            {
1306
              mem_put_qi (regs.r[1], regs.r[2]);
1307
              regs.r[1] ++;
1308
              regs.r[3] --;
1309
            }
1310
          break;
1311
        default:
1312
          abort ();
1313
        }
1314
      break;
1315
 
1316
    case RXO_stcc:
1317
      if (GS2())
1318
        PD (GS ());
1319
      break;
1320
 
1321
    case RXO_stop:
1322
      PRIVILEDGED ();
1323
      regs.r_psw |= FLAGBIT_I;
1324
      return RX_MAKE_STOPPED(0);
1325
 
1326
    case RXO_sub:
1327
      MATH_OP (-, 0);
1328
      break;
1329
 
1330
    case RXO_suntil:
1331
      if (regs.r[3] == 0)
1332
        break;
1333
      switch (opcode.size)
1334
        {
1335
        case RX_Long:
1336
          uma = get_reg (2);
1337
          while (regs.r[3] != 0)
1338
            {
1339
              regs.r[3] --;
1340
              umb = mem_get_si (get_reg (1));
1341
              regs.r[1] += 4;
1342
              if (umb == uma)
1343
                break;
1344
            }
1345
          break;
1346
        case RX_Word:
1347
          uma = get_reg (2) & 0xffff;
1348
          while (regs.r[3] != 0)
1349
            {
1350
              regs.r[3] --;
1351
              umb = mem_get_hi (get_reg (1));
1352
              regs.r[1] += 2;
1353
              if (umb == uma)
1354
                break;
1355
            }
1356
          break;
1357
        case RX_Byte:
1358
          uma = get_reg (2) & 0xff;
1359
          while (regs.r[3] != 0)
1360
            {
1361
              regs.r[3] --;
1362
              umb = mem_get_qi (regs.r[1]);
1363
              regs.r[1] += 1;
1364
              if (umb == uma)
1365
                break;
1366
            }
1367
          break;
1368
        default:
1369
          abort();
1370
        }
1371
      if (uma == umb)
1372
        set_zc (1, 1);
1373
      else
1374
        set_zc (0, ((int)uma - (int)umb) >= 0);
1375
      break;
1376
 
1377
    case RXO_swhile:
1378
      if (regs.r[3] == 0)
1379
        break;
1380
      switch (opcode.size)
1381
        {
1382
        case RX_Long:
1383
          uma = get_reg (2);
1384
          while (regs.r[3] != 0)
1385
            {
1386
              regs.r[3] --;
1387
              umb = mem_get_si (get_reg (1));
1388
              regs.r[1] += 4;
1389
              if (umb != uma)
1390
                break;
1391
            }
1392
          break;
1393
        case RX_Word:
1394
          uma = get_reg (2) & 0xffff;
1395
          while (regs.r[3] != 0)
1396
            {
1397
              regs.r[3] --;
1398
              umb = mem_get_hi (get_reg (1));
1399
              regs.r[1] += 2;
1400
              if (umb != uma)
1401
                break;
1402
            }
1403
          break;
1404
        case RX_Byte:
1405
          uma = get_reg (2) & 0xff;
1406
          while (regs.r[3] != 0)
1407
            {
1408
              regs.r[3] --;
1409
              umb = mem_get_qi (regs.r[1]);
1410
              regs.r[1] += 1;
1411
              if (umb != uma)
1412
                break;
1413
            }
1414
          break;
1415
        default:
1416
          abort();
1417
        }
1418
      if (uma == umb)
1419
        set_zc (1, 1);
1420
      else
1421
        set_zc (0, ((int)uma - (int)umb) >= 0);
1422
      break;
1423
 
1424
    case RXO_wait:
1425
      PRIVILEDGED ();
1426
      regs.r_psw |= FLAGBIT_I;
1427
      return RX_MAKE_STOPPED(0);
1428
 
1429
    case RXO_xchg:
1430
      v = GS (); /* This is the memory operand, if any.  */
1431
      PS (GD ()); /* and this may change the address register.  */
1432
      PD (v);
1433
      break;
1434
 
1435
    case RXO_xor:
1436
      LOGIC_OP (^);
1437
      break;
1438
 
1439
    default:
1440
      EXCEPTION (EX_UNDEFINED);
1441
    }
1442
 
1443
  return RX_MAKE_STEPPED ();
1444
}

powered by: WebSVN 2.1.0

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