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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [mn10200/] [interp.c] - Blame information for rev 1767

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

Line No. Rev Author Line
1 578 markom
#include <signal.h>
2
#include "sysdep.h"
3
#include "bfd.h"
4
 
5
#include "mn10200_sim.h"
6
 
7
#ifdef NEED_UI_LOOP_HOOK
8
/* How often to run the ui_loop update, when in use */
9
#define UI_LOOP_POLL_INTERVAL 0x60000
10
 
11
/* Counter for the ui_loop_hook update */
12
static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
13
 
14
/* Actual hook to call to run through gdb's gui event loop */
15
extern int (*ui_loop_hook) (int);
16
#endif /* NEED_UI_LOOP_HOOK */
17
 
18
host_callback *mn10200_callback;
19
int mn10200_debug;
20
static SIM_OPEN_KIND sim_kind;
21
static char *myname;
22
 
23
static void dispatch PARAMS ((uint32, uint32, int));
24
static long hash PARAMS ((long));
25
static void init_system PARAMS ((void));
26
#define MAX_HASH  127
27
 
28
struct hash_entry
29
{
30
  struct hash_entry *next;
31
  long opcode;
32
  long mask;
33
  struct simops *ops;
34
#ifdef HASH_STAT
35
  unsigned long count;
36
#endif
37
};
38
 
39
int max_mem = 0;
40
struct hash_entry hash_table[MAX_HASH+1];
41
 
42
 
43
/* This probably doesn't do a very good job at bucket filling, but
44
   it's simple... */
45
static INLINE long
46
hash(insn)
47
     long insn;
48
{
49
  /* These are one byte insns.  */
50
  if ((insn & 0xffffff00) == 0x00)
51
    {
52
      if ((insn & 0xf0) != 0x80)
53
        return ((insn & 0xf0) >> 4) & 0x7f;
54
 
55
      if ((insn & 0xf0) == 0x80
56
           && (insn & 0x0c) >> 2 != (insn & 0x03))
57
        return (insn & 0xf0) & 0x7f;
58
 
59
      return (insn & 0xff) & 0x7f;
60
    }
61
 
62
  if ((insn & 0xffff0000) == 0)
63
    {
64
      if ((insn & 0xf000) == 0xd000)
65
        return ((insn & 0xfc00) >> 10) & 0x7f;
66
 
67
      if ((insn & 0xf000) == 0xe000)
68
        return ((insn & 0xff00) >> 8) & 0x7f;
69
 
70
      if ((insn & 0xf200) == 0xf200)
71
        return ((insn & 0xfff0) >> 4) & 0x7f;
72
 
73
      if ((insn & 0xc000) == 0x4000
74
          || (insn & 0xf000) == 0x8000)
75
        return ((insn & 0xf000) >> 8) & 0x7f;
76
 
77
      if ((insn & 0xf200) == 0xf000)
78
        return ((insn & 0xffc0) >> 8) & 0x7f;
79
 
80
      return ((insn & 0xff00) >> 8) & 0x7f;
81
    }
82
 
83
  if ((insn & 0xff000000) == 0)
84
    {
85
 
86
      if ((insn & 0xf00000) != 0xf00000
87
           || (insn & 0xfc0000) == 0xf80000)
88
        return ((insn & 0xfc0000) >> 16) & 0x7f;
89
 
90
      if ((insn & 0xff0000) == 0xf50000)
91
        return ((insn & 0xfff000) >> 12) & 0x7f;
92
      return ((insn & 0xff0000) >> 16) & 0x7f;
93
    }
94
 
95
  return ((insn & 0xfff0000) >> 20) & 0x7f;
96
}
97
 
98
static INLINE void
99
dispatch (insn, extension, length)
100
     uint32 insn;
101
     uint32 extension;
102
     int length;
103
{
104
  struct hash_entry *h;
105
 
106
  h = &hash_table[hash(insn)];
107
 
108
  while ((insn & h->mask) != h->opcode
109
          || (length != h->ops->length))
110
    {
111
      if (!h->next)
112
        {
113
          (*mn10200_callback->printf_filtered) (mn10200_callback,
114
            "ERROR looking up hash for 0x%x, PC=0x%x\n", insn, PC);
115
          exit(1);
116
        }
117
      h = h->next;
118
    }
119
 
120
 
121
#ifdef HASH_STAT
122
  h->count++;
123
#endif
124
 
125
  /* Now call the right function.  */
126
  (h->ops->func)(insn, extension);
127
  PC += length;
128
}
129
 
130
/* FIXME These would more efficient to use than load_mem/store_mem,
131
   but need to be changed to use the memory map.  */
132
 
133
uint32
134
get_word (x)
135
      uint8 *x;
136
{
137
  uint8 *a = x;
138
  return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
139
}
140
 
141
void
142
put_word (addr, data)
143
     uint8 *addr;
144
     uint32 data;
145
{
146
  uint8 *a = addr;
147
  a[0] = data & 0xff;
148
  a[1] = (data >> 8) & 0xff;
149
  a[2] = (data >> 16) & 0xff;
150
  a[3] = (data >> 24) & 0xff;
151
}
152
 
153
void
154
sim_size (power)
155
     int power;
156
 
157
{
158
  if (State.mem)
159
    free (State.mem);
160
 
161
  max_mem = 1 << power;
162
  State.mem = (uint8 *) calloc (1,  1 << power);
163
  if (!State.mem)
164
    {
165
      (*mn10200_callback->printf_filtered) (mn10200_callback, "Allocation of main memory failed.\n");
166
      exit (1);
167
    }
168
}
169
 
170
static void
171
init_system ()
172
{
173
  if (!State.mem)
174
    sim_size(19);
175
}
176
 
177
int
178
sim_write (sd,addr, buffer, size)
179
     SIM_DESC sd;
180
     SIM_ADDR addr;
181
     unsigned char *buffer;
182
     int size;
183
{
184
  int i;
185
 
186
  init_system ();
187
 
188
  for (i = 0; i < size; i++)
189
    store_byte (addr + i, buffer[i]);
190
 
191
  return size;
192
}
193
 
194
/* Compare two opcode table entries for qsort.  */
195
static int
196
compare_simops (arg1, arg2)
197
     const PTR arg1;
198
     const PTR arg2;
199
{
200
  unsigned long code1 = ((struct simops *)arg1)->opcode;
201
  unsigned long code2 = ((struct simops *)arg2)->opcode;
202
 
203
  if (code1 < code2)
204
    return -1;
205
  if (code2 < code1)
206
    return 1;
207
  return 0;
208
}
209
 
210
SIM_DESC
211
sim_open (kind, cb, abfd, argv)
212
     SIM_OPEN_KIND kind;
213
     host_callback *cb;
214
     struct _bfd *abfd;
215
     char **argv;
216
{
217
  struct simops *s;
218
  struct hash_entry *h;
219
  char **p;
220
  int i;
221
 
222
  mn10200_callback = cb;
223
 
224
  /* Sort the opcode array from smallest opcode to largest.
225
     This will generally improve simulator performance as the smaller
226
     opcodes are generally preferred to the larger opcodes.  */
227
  for (i = 0, s = Simops; s->func; s++, i++)
228
    ;
229
  qsort (Simops, i, sizeof (Simops[0]), compare_simops);
230
 
231
  sim_kind = kind;
232
  myname = argv[0];
233
 
234
  for (p = argv + 1; *p; ++p)
235
    {
236
      if (strcmp (*p, "-E") == 0)
237
        ++p; /* ignore endian spec */
238
      else
239
#ifdef DEBUG
240
      if (strcmp (*p, "-t") == 0)
241
        mn10200_debug = DEBUG;
242
      else
243
#endif
244
        (*mn10200_callback->printf_filtered) (mn10200_callback, "ERROR: unsupported option(s): %s\n",*p);
245
    }
246
 
247
  /* put all the opcodes in the hash table */
248
  for (s = Simops; s->func; s++)
249
    {
250
      h = &hash_table[hash(s->opcode)];
251
 
252
      /* go to the last entry in the chain */
253
      while (h->next)
254
        {
255
          /* Don't insert the same opcode more than once.  */
256
          if (h->opcode == s->opcode
257
              && h->mask == s->mask
258
              && h->ops == s)
259
            break;
260
          else
261
            h = h->next;
262
        }
263
 
264
      /* Don't insert the same opcode more than once.  */
265
      if (h->opcode == s->opcode
266
          && h->mask == s->mask
267
          && h->ops == s)
268
        continue;
269
 
270
      if (h->ops)
271
        {
272
          h->next = calloc(1,sizeof(struct hash_entry));
273
          h = h->next;
274
        }
275
      h->ops = s;
276
      h->mask = s->mask;
277
      h->opcode = s->opcode;
278
#ifdef HASH_STAT
279
      h->count = 0;
280
#endif
281
    }
282
 
283
  /* fudge our descriptor for now */
284
  return (SIM_DESC) 1;
285
}
286
 
287
 
288
void
289
sim_set_profile (n)
290
     int n;
291
{
292
  (*mn10200_callback->printf_filtered) (mn10200_callback, "sim_set_profile %d\n", n);
293
}
294
 
295
void
296
sim_set_profile_size (n)
297
     int n;
298
{
299
  (*mn10200_callback->printf_filtered) (mn10200_callback, "sim_set_profile_size %d\n", n);
300
}
301
 
302
int
303
sim_stop (sd)
304
     SIM_DESC sd;
305
{
306
  State.exception = SIGINT;
307
  return 1;
308
}
309
 
310
void
311
sim_resume (sd, step, siggnal)
312
     SIM_DESC sd;
313
     int step, siggnal;
314
{
315
  uint32 inst;
316
 
317
  if (step)
318
    State.exception = SIGTRAP;
319
  else
320
    State.exception = 0;
321
 
322
  State.exited = 0;
323
 
324
  do
325
    {
326
      unsigned long insn, extension;
327
 
328
#ifdef NEED_UI_LOOP_HOOK
329
    if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
330
      {
331
        ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
332
        ui_loop_hook (0);
333
      }
334
#endif /* NEED_UI_LOOP_HOOK */
335
 
336
      /* Fetch the current instruction, fetch a double word to
337
         avoid redundant fetching for the common cases below.  */
338
      inst = load_mem_big (PC, 2);
339
 
340
      /* Using a giant case statement may seem like a waste because of the
341
         code/rodata size the table itself will consume.  However, using
342
         a giant case statement speeds up the simulator by 10-15% by avoiding
343
         cascading if/else statements or cascading case statements.  */
344
      switch ((inst >> 8) & 0xff)
345
        {
346
        /* All the single byte insns except 0x80, which must
347
           be handled specially.  */
348
        case 0x00:
349
        case 0x01:
350
        case 0x02:
351
        case 0x03:
352
        case 0x04:
353
        case 0x05:
354
        case 0x06:
355
        case 0x07:
356
        case 0x08:
357
        case 0x09:
358
        case 0x0a:
359
        case 0x0b:
360
        case 0x0c:
361
        case 0x0d:
362
        case 0x0e:
363
        case 0x0f:
364
        case 0x10:
365
        case 0x11:
366
        case 0x12:
367
        case 0x13:
368
        case 0x14:
369
        case 0x15:
370
        case 0x16:
371
        case 0x17:
372
        case 0x18:
373
        case 0x19:
374
        case 0x1a:
375
        case 0x1b:
376
        case 0x1c:
377
        case 0x1d:
378
        case 0x1e:
379
        case 0x1f:
380
        case 0x20:
381
        case 0x21:
382
        case 0x22:
383
        case 0x23:
384
        case 0x24:
385
        case 0x25:
386
        case 0x26:
387
        case 0x27:
388
        case 0x28:
389
        case 0x29:
390
        case 0x2a:
391
        case 0x2b:
392
        case 0x2c:
393
        case 0x2d:
394
        case 0x2e:
395
        case 0x2f:
396
        case 0x30:
397
        case 0x31:
398
        case 0x32:
399
        case 0x33:
400
        case 0x34:
401
        case 0x35:
402
        case 0x36:
403
        case 0x37:
404
        case 0x38:
405
        case 0x39:
406
        case 0x3a:
407
        case 0x3b:
408
        case 0x3c:
409
        case 0x3d:
410
        case 0x3e:
411
        case 0x3f:
412
        case 0x90:
413
        case 0x91:
414
        case 0x92:
415
        case 0x93:
416
        case 0x94:
417
        case 0x95:
418
        case 0x96:
419
        case 0x97:
420
        case 0x98:
421
        case 0x99:
422
        case 0x9a:
423
        case 0x9b:
424
        case 0x9c:
425
        case 0x9d:
426
        case 0x9e:
427
        case 0x9f:
428
        case 0xa0:
429
        case 0xa1:
430
        case 0xa2:
431
        case 0xa3:
432
        case 0xa4:
433
        case 0xa5:
434
        case 0xa6:
435
        case 0xa7:
436
        case 0xa8:
437
        case 0xa9:
438
        case 0xaa:
439
        case 0xab:
440
        case 0xac:
441
        case 0xad:
442
        case 0xae:
443
        case 0xaf:
444
        case 0xb0:
445
        case 0xb1:
446
        case 0xb2:
447
        case 0xb3:
448
        case 0xb4:
449
        case 0xb5:
450
        case 0xb6:
451
        case 0xb7:
452
        case 0xb8:
453
        case 0xb9:
454
        case 0xba:
455
        case 0xbb:
456
        case 0xbc:
457
        case 0xbd:
458
        case 0xbe:
459
        case 0xbf:
460
        case 0xeb:
461
        case 0xf6:
462
        case 0xfe:
463
        case 0xff:
464
          insn = (inst >> 8) & 0xff;
465
          extension = 0;
466
          dispatch (insn, extension, 1);
467
          break;
468
 
469
        /* Special case as mov dX,dX really means mov imm8,dX.  */
470
        case 0x80:
471
        case 0x85:
472
        case 0x8a:
473
        case 0x8f:
474
          /* Fetch the full instruction.  */
475
          insn = inst;
476
          extension = 0;
477
          dispatch (insn, extension, 2);
478
          break;
479
 
480
        case 0x81:
481
        case 0x82:
482
        case 0x83:
483
        case 0x84:
484
        case 0x86:
485
        case 0x87:
486
        case 0x88:
487
        case 0x89:
488
        case 0x8b:
489
        case 0x8c:
490
        case 0x8d:
491
        case 0x8e:
492
          insn = (inst >> 8) & 0xff;
493
          extension = 0;
494
          dispatch (insn, extension, 1);
495
          break;
496
 
497
        /* And the two byte insns.  */
498
        case 0x40:
499
        case 0x41:
500
        case 0x42:
501
        case 0x43:
502
        case 0x44:
503
        case 0x45:
504
        case 0x46:
505
        case 0x47:
506
        case 0x48:
507
        case 0x49:
508
        case 0x4a:
509
        case 0x4b:
510
        case 0x4c:
511
        case 0x4d:
512
        case 0x4e:
513
        case 0x4f:
514
        case 0x50:
515
        case 0x51:
516
        case 0x52:
517
        case 0x53:
518
        case 0x54:
519
        case 0x55:
520
        case 0x56:
521
        case 0x57:
522
        case 0x58:
523
        case 0x59:
524
        case 0x5a:
525
        case 0x5b:
526
        case 0x5c:
527
        case 0x5d:
528
        case 0x5e:
529
        case 0x5f:
530
        case 0x60:
531
        case 0x61:
532
        case 0x62:
533
        case 0x63:
534
        case 0x64:
535
        case 0x65:
536
        case 0x66:
537
        case 0x67:
538
        case 0x68:
539
        case 0x69:
540
        case 0x6a:
541
        case 0x6b:
542
        case 0x6c:
543
        case 0x6d:
544
        case 0x6e:
545
        case 0x6f:
546
        case 0x70:
547
        case 0x71:
548
        case 0x72:
549
        case 0x73:
550
        case 0x74:
551
        case 0x75:
552
        case 0x76:
553
        case 0x77:
554
        case 0x78:
555
        case 0x79:
556
        case 0x7a:
557
        case 0x7b:
558
        case 0x7c:
559
        case 0x7d:
560
        case 0x7e:
561
        case 0x7f:
562
        case 0xd0:
563
        case 0xd1:
564
        case 0xd2:
565
        case 0xd3:
566
        case 0xd4:
567
        case 0xd5:
568
        case 0xd6:
569
        case 0xd7:
570
        case 0xd8:
571
        case 0xd9:
572
        case 0xda:
573
        case 0xdb:
574
        case 0xe0:
575
        case 0xe1:
576
        case 0xe2:
577
        case 0xe3:
578
        case 0xe4:
579
        case 0xe5:
580
        case 0xe6:
581
        case 0xe7:
582
        case 0xe8:
583
        case 0xe9:
584
        case 0xea:
585
        case 0xf0:
586
        case 0xf1:
587
        case 0xf2:
588
        case 0xf3:
589
          /* Fetch the full instruction.  */
590
          insn = inst;
591
          extension = 0;
592
          dispatch (insn, extension, 2);
593
          break;
594
 
595
        /* And the 3 byte insns with a 16bit operand in little
596
           endian format.  */
597
        case 0xc0:
598
        case 0xc1:
599
        case 0xc2:
600
        case 0xc3:
601
        case 0xc4:
602
        case 0xc5:
603
        case 0xc6:
604
        case 0xc7:
605
        case 0xc8:
606
        case 0xc9:
607
        case 0xca:
608
        case 0xcb:
609
        case 0xcc:
610
        case 0xcd:
611
        case 0xce:
612
        case 0xcf:
613
        case 0xdc:
614
        case 0xdd:
615
        case 0xde:
616
        case 0xdf:
617
        case 0xec:
618
        case 0xed:
619
        case 0xee:
620
        case 0xef:
621
        case 0xf8:
622
        case 0xf9:
623
        case 0xfa:
624
        case 0xfb:
625
        case 0xfc:
626
        case 0xfd:
627
          insn = load_byte (PC);
628
          insn <<= 16;
629
          insn |= load_half (PC + 1);
630
          extension = 0;
631
          dispatch (insn, extension, 3);
632
          break;
633
 
634
        /* 3 byte insns without 16bit operand.  */
635
        case 0xf5:
636
          insn = load_mem_big (PC, 3);
637
          extension = 0;
638
          dispatch (insn, extension, 3);
639
          break;
640
 
641
        /* 4 byte insns.  */
642
        case 0xf7:
643
          insn = inst;
644
          insn <<= 16;
645
          insn |= load_half (PC + 2);
646
          extension = 0;
647
          dispatch (insn, extension, 4);
648
          break;
649
 
650
        case 0xf4:
651
          insn = inst;
652
          insn <<= 16;
653
          insn |= load_mem_big (PC + 4, 1) << 8;
654
          insn |= load_mem_big (PC + 3, 1);
655
          extension = load_mem_big (PC + 2, 1);
656
          dispatch (insn, extension, 5);
657
          break;
658
 
659
        default:
660
          abort ();
661
        }
662
    }
663
  while (!State.exception);
664
 
665
#ifdef HASH_STAT
666
  {
667
    int i;
668
    for (i = 0; i < MAX_HASH; i++)
669
      {
670
        struct hash_entry *h;
671
        h = &hash_table[i];
672
 
673
        printf("hash 0x%x:\n", i);
674
 
675
        while (h)
676
          {
677
            printf("h->opcode = 0x%x, count = 0x%x\n", h->opcode, h->count);
678
            h = h->next;
679
          }
680
 
681
        printf("\n\n");
682
      }
683
    fflush (stdout);
684
  }
685
#endif
686
 
687
}
688
 
689
 
690
void
691
sim_close (sd, quitting)
692
     SIM_DESC sd;
693
     int quitting;
694
{
695
  /* nothing to do */
696
}
697
 
698
int
699
sim_trace (sd)
700
     SIM_DESC sd;
701
{
702
#ifdef DEBUG
703
  mn10200_debug = DEBUG;
704
#endif
705
  sim_resume (sd, 0, 0);
706
  return 1;
707
}
708
 
709
void
710
sim_info (sd, verbose)
711
     SIM_DESC sd;
712
     int verbose;
713
{
714
  (*mn10200_callback->printf_filtered) (mn10200_callback, "sim_info\n");
715
}
716
 
717
SIM_RC
718
sim_create_inferior (sd, abfd, argv, env)
719
     SIM_DESC sd;
720
     struct _bfd *abfd;
721
     char **argv;
722
     char **env;
723
{
724
  if (abfd != NULL)
725
    PC = bfd_get_start_address (abfd);
726
  else
727
    PC = 0;
728
  return SIM_RC_OK;
729
}
730
 
731
void
732
sim_set_callbacks (p)
733
     host_callback *p;
734
{
735
  mn10200_callback = p;
736
}
737
 
738
/* All the code for exiting, signals, etc needs to be revamped.
739
 
740
   This is enough to get c-torture limping though.  */
741
 
742
void
743
sim_stop_reason (sd, reason, sigrc)
744
     SIM_DESC sd;
745
     enum sim_stop *reason;
746
     int *sigrc;
747
{
748
  if (State.exited)
749
    *reason = sim_exited;
750
  else
751
    *reason = sim_stopped;
752
  if (State.exception == SIGQUIT)
753
    *sigrc = 0;
754
  else
755
    *sigrc = State.exception;
756
}
757
 
758
int
759
sim_fetch_register (sd, rn, memory, length)
760
     SIM_DESC sd;
761
     int rn;
762
     unsigned char *memory;
763
     int length;
764
{
765
  put_word (memory, State.regs[rn]);
766
  return -1;
767
}
768
 
769
int
770
sim_store_register (sd, rn, memory, length)
771
     SIM_DESC sd;
772
     int rn;
773
     unsigned char *memory;
774
     int length;
775
{
776
  State.regs[rn] = get_word (memory);
777
  return -1;
778
}
779
 
780
int
781
sim_read (sd, addr, buffer, size)
782
     SIM_DESC sd;
783
     SIM_ADDR addr;
784
     unsigned char *buffer;
785
     int size;
786
{
787
  int i;
788
  for (i = 0; i < size; i++)
789
    buffer[i] = load_byte (addr + i);
790
 
791
  return size;
792
}
793
 
794
void
795
sim_do_command (sd, cmd)
796
     SIM_DESC sd;
797
     char *cmd;
798
{
799
  (*mn10200_callback->printf_filtered) (mn10200_callback, "\"%s\" is not a valid mn10200 simulator command.\n", cmd);
800
}
801
 
802
SIM_RC
803
sim_load (sd, prog, abfd, from_tty)
804
     SIM_DESC sd;
805
     char *prog;
806
     bfd *abfd;
807
     int from_tty;
808
{
809
  extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
810
  bfd *prog_bfd;
811
 
812
  prog_bfd = sim_load_file (sd, myname, mn10200_callback, prog, abfd,
813
                            sim_kind == SIM_OPEN_DEBUG,
814
                            0, sim_write);
815
  if (prog_bfd == NULL)
816
    return SIM_RC_FAIL;
817
  if (abfd == NULL)
818
    bfd_close (prog_bfd);
819
  return SIM_RC_OK;
820
}

powered by: WebSVN 2.1.0

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