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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 330 jeremybenn
/* SH5 simulator support code
2
   Copyright (C) 2000, 2001, 2006, 2008, 2009, 2010
3
   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
#define WANT_CPU
22
#define WANT_CPU_SH64
23
 
24
#include "sim-main.h"
25
#include "sim-fpu.h"
26
#include "cgen-mem.h"
27
#include "cgen-ops.h"
28
 
29
#include "gdb/callback.h"
30
#include "defs-compact.h"
31
 
32
#include "bfd.h"
33
/* From include/gdb/.  */
34
#include "gdb/sim-sh.h"
35
 
36
#define SYS_exit        1
37
#define SYS_read        3
38
#define SYS_write       4
39
#define SYS_open        5
40
#define SYS_close       6
41
#define SYS_lseek       19
42
#define SYS_time        23
43
#define SYS_argc        172
44
#define SYS_argnlen     173
45
#define SYS_argn        174
46
 
47
IDESC * sh64_idesc_media;
48
IDESC * sh64_idesc_compact;
49
 
50
BI
51
sh64_endian (SIM_CPU *current_cpu)
52
{
53
  return (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN);
54
}
55
 
56
SF
57
sh64_fldi0 (SIM_CPU *current_cpu)
58
{
59
  SF result;
60
  sim_fpu_to32 (&result, &sim_fpu_zero);
61
  return result;
62
}
63
 
64
SF
65
sh64_fldi1 (SIM_CPU *current_cpu)
66
{
67
  SF result;
68
  sim_fpu_to32 (&result, &sim_fpu_one);
69
  return result;
70
}
71
 
72
DF
73
sh64_fabsd(SIM_CPU *current_cpu, DF drgh)
74
{
75
  DF result;
76
  sim_fpu f, fres;
77
 
78
  sim_fpu_64to (&f, drgh);
79
  sim_fpu_abs (&fres, &f);
80
  sim_fpu_to64 (&result, &fres);
81
  return result;
82
}
83
 
84
SF
85
sh64_fabss(SIM_CPU *current_cpu, SF frgh)
86
{
87
  SF result;
88
  sim_fpu f, fres;
89
 
90
  sim_fpu_32to (&f, frgh);
91
  sim_fpu_abs (&fres, &f);
92
  sim_fpu_to32 (&result, &fres);
93
  return result;
94
}
95
 
96
DF
97
sh64_faddd(SIM_CPU *current_cpu, DF drg, DF drh)
98
{
99
  DF result;
100
  sim_fpu f1, f2, fres;
101
 
102
  sim_fpu_64to (&f1, drg);
103
  sim_fpu_64to (&f2, drh);
104
  sim_fpu_add (&fres, &f1, &f2);
105
  sim_fpu_to64 (&result, &fres);
106
  return result;
107
}
108
 
109
SF
110
sh64_fadds(SIM_CPU *current_cpu, SF frg, SF frh)
111
{
112
  SF result;
113
  sim_fpu f1, f2, fres;
114
 
115
  sim_fpu_32to (&f1, frg);
116
  sim_fpu_32to (&f2, frh);
117
  sim_fpu_add (&fres, &f1, &f2);
118
  sim_fpu_to32 (&result, &fres);
119
  return result;
120
}
121
 
122
BI
123
sh64_fcmpeqd(SIM_CPU *current_cpu, DF drg, DF drh)
124
{
125
  sim_fpu f1, f2;
126
 
127
  sim_fpu_64to (&f1, drg);
128
  sim_fpu_64to (&f2, drh);
129
  return sim_fpu_is_eq (&f1, &f2);
130
}
131
 
132
BI
133
sh64_fcmpeqs(SIM_CPU *current_cpu, SF frg, SF frh)
134
{
135
  sim_fpu f1, f2;
136
 
137
  sim_fpu_32to (&f1, frg);
138
  sim_fpu_32to (&f2, frh);
139
  return sim_fpu_is_eq (&f1, &f2);
140
}
141
 
142
BI
143
sh64_fcmpged(SIM_CPU *current_cpu, DF drg, DF drh)
144
{
145
  sim_fpu f1, f2;
146
 
147
  sim_fpu_64to (&f1, drg);
148
  sim_fpu_64to (&f2, drh);
149
  return sim_fpu_is_ge (&f1, &f2);
150
}
151
 
152
BI
153
sh64_fcmpges(SIM_CPU *current_cpu, SF frg, SF frh)
154
{
155
  sim_fpu f1, f2;
156
 
157
  sim_fpu_32to (&f1, frg);
158
  sim_fpu_32to (&f2, frh);
159
  return sim_fpu_is_ge (&f1, &f2);
160
}
161
 
162
BI
163
sh64_fcmpgtd(SIM_CPU *current_cpu, DF drg, DF drh)
164
{
165
  sim_fpu f1, f2;
166
 
167
  sim_fpu_64to (&f1, drg);
168
  sim_fpu_64to (&f2, drh);
169
  return sim_fpu_is_gt (&f1, &f2);
170
}
171
 
172
BI
173
sh64_fcmpgts(SIM_CPU *current_cpu, SF frg, SF frh)
174
{
175
  sim_fpu f1, f2;
176
 
177
  sim_fpu_32to (&f1, frg);
178
  sim_fpu_32to (&f2, frh);
179
  return sim_fpu_is_gt (&f1, &f2);
180
}
181
 
182
BI
183
sh64_fcmpund(SIM_CPU *current_cpu, DF drg, DF drh)
184
{
185
  sim_fpu f1, f2;
186
 
187
  sim_fpu_64to (&f1, drg);
188
  sim_fpu_64to (&f2, drh);
189
  return (sim_fpu_is_nan (&f1) || sim_fpu_is_nan (&f2));
190
}
191
 
192
BI
193
sh64_fcmpuns(SIM_CPU *current_cpu, SF frg, SF frh)
194
{
195
  sim_fpu f1, f2;
196
 
197
  sim_fpu_32to (&f1, frg);
198
  sim_fpu_32to (&f2, frh);
199
  return (sim_fpu_is_nan (&f1) || sim_fpu_is_nan (&f2));
200
}
201
 
202
SF
203
sh64_fcnvds(SIM_CPU *current_cpu, DF drgh)
204
{
205
  union {
206
    unsigned long long ll;
207
    double d;
208
  } f1;
209
 
210
  union {
211
    unsigned long l;
212
    float f;
213
  } f2;
214
 
215
  f1.ll = drgh;
216
  f2.f = (float) f1.d;
217
 
218
  return (SF) f2.l;
219
}
220
 
221
DF
222
sh64_fcnvsd(SIM_CPU *current_cpu, SF frgh)
223
{
224
  DF result;
225
  sim_fpu f;
226
 
227
  sim_fpu_32to (&f, frgh);
228
  sim_fpu_to64 (&result, &f);
229
  return result;
230
}
231
 
232
DF
233
sh64_fdivd(SIM_CPU *current_cpu, DF drg, DF drh)
234
{
235
  DF result;
236
  sim_fpu f1, f2, fres;
237
 
238
  sim_fpu_64to (&f1, drg);
239
  sim_fpu_64to (&f2, drh);
240
  sim_fpu_div (&fres, &f1, &f2);
241
  sim_fpu_to64 (&result, &fres);
242
  return result;
243
}
244
 
245
SF
246
sh64_fdivs(SIM_CPU *current_cpu, SF frg, SF frh)
247
{
248
  SF result;
249
  sim_fpu f1, f2, fres;
250
 
251
  sim_fpu_32to (&f1, frg);
252
  sim_fpu_32to (&f2, frh);
253
  sim_fpu_div (&fres, &f1, &f2);
254
  sim_fpu_to32 (&result, &fres);
255
  return result;
256
}
257
 
258
DF
259
sh64_floatld(SIM_CPU *current_cpu, SF frgh)
260
{
261
  DF result;
262
  sim_fpu f;
263
 
264
  sim_fpu_i32to (&f, frgh, sim_fpu_round_default);
265
  sim_fpu_to64 (&result, &f);
266
  return result;
267
}
268
 
269
SF
270
sh64_floatls(SIM_CPU *current_cpu, SF frgh)
271
{
272
  SF result;
273
  sim_fpu f;
274
 
275
  sim_fpu_i32to (&f, frgh, sim_fpu_round_default);
276
  sim_fpu_to32 (&result, &f);
277
  return result;
278
}
279
 
280
DF
281
sh64_floatqd(SIM_CPU *current_cpu, DF drgh)
282
{
283
  DF result;
284
  sim_fpu f;
285
 
286
  sim_fpu_i64to (&f, drgh, sim_fpu_round_default);
287
  sim_fpu_to64 (&result, &f);
288
  return result;
289
}
290
 
291
SF
292
sh64_floatqs(SIM_CPU *current_cpu, DF drgh)
293
{
294
  SF result;
295
  sim_fpu f;
296
 
297
  sim_fpu_i64to (&f, drgh, sim_fpu_round_default);
298
  sim_fpu_to32 (&result, &f);
299
  return result;
300
}
301
 
302
SF
303
sh64_fmacs(SIM_CPU *current_cpu, SF fr0, SF frm, SF frn)
304
{
305
  SF result;
306
  sim_fpu m1, m2, a1, fres;
307
 
308
  sim_fpu_32to (&m1, fr0);
309
  sim_fpu_32to (&m2, frm);
310
  sim_fpu_32to (&a1, frn);
311
 
312
  sim_fpu_mul (&fres, &m1, &m2);
313
  sim_fpu_add (&fres, &fres, &a1);
314
 
315
  sim_fpu_to32 (&result, &fres);
316
  return result;
317
}
318
 
319
DF
320
sh64_fmuld(SIM_CPU *current_cpu, DF drg, DF drh)
321
{
322
  DF result;
323
  sim_fpu f1, f2, fres;
324
 
325
  sim_fpu_64to (&f1, drg);
326
  sim_fpu_64to (&f2, drh);
327
  sim_fpu_mul (&fres, &f1, &f2);
328
  sim_fpu_to64 (&result, &fres);
329
  return result;
330
}
331
 
332
SF
333
sh64_fmuls(SIM_CPU *current_cpu, SF frg, SF frh)
334
{
335
  SF result;
336
  sim_fpu f1, f2, fres;
337
 
338
  sim_fpu_32to (&f1, frg);
339
  sim_fpu_32to (&f2, frh);
340
  sim_fpu_mul (&fres, &f1, &f2);
341
  sim_fpu_to32 (&result, &fres);
342
  return result;
343
}
344
 
345
DF
346
sh64_fnegd(SIM_CPU *current_cpu, DF drgh)
347
{
348
  DF result;
349
  sim_fpu f1, f2;
350
 
351
  sim_fpu_64to (&f1, drgh);
352
  sim_fpu_neg (&f2, &f1);
353
  sim_fpu_to64 (&result, &f2);
354
  return result;
355
}
356
 
357
SF
358
sh64_fnegs(SIM_CPU *current_cpu, SF frgh)
359
{
360
  SF result;
361
  sim_fpu f, fres;
362
 
363
  sim_fpu_32to (&f, frgh);
364
  sim_fpu_neg (&fres, &f);
365
  sim_fpu_to32 (&result, &fres);
366
  return result;
367
}
368
 
369
DF
370
sh64_fsqrtd(SIM_CPU *current_cpu, DF drgh)
371
{
372
  DF result;
373
  sim_fpu f, fres;
374
 
375
  sim_fpu_64to (&f, drgh);
376
  sim_fpu_sqrt (&fres, &f);
377
  sim_fpu_to64 (&result, &fres);
378
  return result;
379
}
380
 
381
SF
382
sh64_fsqrts(SIM_CPU *current_cpu, SF frgh)
383
{
384
  SF result;
385
  sim_fpu f, fres;
386
 
387
  sim_fpu_32to (&f, frgh);
388
  sim_fpu_sqrt (&fres, &f);
389
  sim_fpu_to32 (&result, &fres);
390
  return result;
391
}
392
 
393
DF
394
sh64_fsubd(SIM_CPU *current_cpu, DF drg, DF drh)
395
{
396
  DF result;
397
  sim_fpu f1, f2, fres;
398
 
399
  sim_fpu_64to (&f1, drg);
400
  sim_fpu_64to (&f2, drh);
401
  sim_fpu_sub (&fres, &f1, &f2);
402
  sim_fpu_to64 (&result, &fres);
403
  return result;
404
}
405
 
406
SF
407
sh64_fsubs(SIM_CPU *current_cpu, SF frg, SF frh)
408
{
409
  SF result;
410
  sim_fpu f1, f2, fres;
411
 
412
  sim_fpu_32to (&f1, frg);
413
  sim_fpu_32to (&f2, frh);
414
  sim_fpu_sub (&fres, &f1, &f2);
415
  sim_fpu_to32 (&result, &fres);
416
  return result;
417
}
418
 
419
SF
420
sh64_ftrcdl(SIM_CPU *current_cpu, DF drgh)
421
{
422
  SI result;
423
  sim_fpu f;
424
 
425
  sim_fpu_64to (&f, drgh);
426
  sim_fpu_to32i (&result, &f, sim_fpu_round_zero);
427
  return (SF) result;
428
}
429
 
430
SF
431
sh64_ftrcsl(SIM_CPU *current_cpu, SF frgh)
432
{
433
  SI result;
434
  sim_fpu f;
435
 
436
  sim_fpu_32to (&f, frgh);
437
  sim_fpu_to32i (&result, &f, sim_fpu_round_zero);
438
  return (SF) result;
439
}
440
 
441
DF
442
sh64_ftrcdq(SIM_CPU *current_cpu, DF drgh)
443
{
444
  DI result;
445
  sim_fpu f;
446
 
447
  sim_fpu_64to (&f, drgh);
448
  sim_fpu_to64i (&result, &f, sim_fpu_round_zero);
449
  return (DF) result;
450
}
451
 
452
DF
453
sh64_ftrcsq(SIM_CPU *current_cpu, SF frgh)
454
{
455
  DI result;
456
  sim_fpu f;
457
 
458
  sim_fpu_32to (&f, frgh);
459
  sim_fpu_to64i (&result, &f, sim_fpu_round_zero);
460
  return (DF) result;
461
}
462
 
463
VOID
464
sh64_ftrvs(SIM_CPU *cpu, unsigned g, unsigned h, unsigned f)
465
{
466
  int i, j;
467
 
468
  for (i = 0; i < 4; i++)
469
    {
470
      SF result;
471
      sim_fpu sum;
472
      sim_fpu_32to (&sum, 0);
473
 
474
      for (j = 0; j < 4; j++)
475
        {
476
          sim_fpu f1, f2, temp;
477
          sim_fpu_32to (&f1, sh64_h_fr_get (cpu, (g + i) + (j * 4)));
478
          sim_fpu_32to (&f2, sh64_h_fr_get (cpu, h + j));
479
          sim_fpu_mul (&temp, &f1, &f2);
480
          sim_fpu_add (&sum, &sum, &temp);
481
        }
482
      sim_fpu_to32 (&result, &sum);
483
      sh64_h_fr_set (cpu, f + i, result);
484
    }
485
}
486
 
487
VOID
488
sh64_fipr (SIM_CPU *cpu, unsigned m, unsigned n)
489
{
490
  SF result = sh64_fmuls (cpu, sh64_h_fvc_get (cpu, m), sh64_h_fvc_get (cpu, n));
491
  result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 1), sh64_h_frc_get (cpu, n + 1)));
492
  result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 2), sh64_h_frc_get (cpu, n + 2)));
493
  result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 3), sh64_h_frc_get (cpu, n + 3)));
494
  sh64_h_frc_set (cpu, n + 3, result);
495
}
496
 
497
SF
498
sh64_fiprs (SIM_CPU *cpu, unsigned g, unsigned h)
499
{
500
  SF temp = sh64_fmuls (cpu, sh64_h_fr_get (cpu, g), sh64_h_fr_get (cpu, h));
501
  temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 1), sh64_h_fr_get (cpu, h + 1)));
502
  temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 2), sh64_h_fr_get (cpu, h + 2)));
503
  temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 3), sh64_h_fr_get (cpu, h + 3)));
504
  return temp;
505
}
506
 
507
VOID
508
sh64_fldp (SIM_CPU *cpu, PCADDR pc, DI rm, DI rn, unsigned f)
509
{
510
  sh64_h_fr_set (cpu, f,     GETMEMSF (cpu, pc, rm + rn));
511
  sh64_h_fr_set (cpu, f + 1, GETMEMSF (cpu, pc, rm + rn + 4));
512
}
513
 
514
VOID
515
sh64_fstp (SIM_CPU *cpu, PCADDR pc, DI rm, DI rn, unsigned f)
516
{
517
  SETMEMSF (cpu, pc, rm + rn,     sh64_h_fr_get (cpu, f));
518
  SETMEMSF (cpu, pc, rm + rn + 4, sh64_h_fr_get (cpu, f + 1));
519
}
520
 
521
VOID
522
sh64_ftrv (SIM_CPU *cpu, UINT ignored)
523
{
524
  /* TODO: Unimplemented.  */
525
}
526
 
527
VOID
528
sh64_pref (SIM_CPU *cpu, SI addr)
529
{
530
  /* TODO: Unimplemented.  */
531
}
532
 
533
/* Count the number of arguments.  */
534
static int
535
count_argc (cpu)
536
     SIM_CPU *cpu;
537
{
538
  int i = 0;
539
 
540
  if (! STATE_PROG_ARGV (CPU_STATE (cpu)))
541
    return -1;
542
 
543
  while (STATE_PROG_ARGV (CPU_STATE (cpu)) [i] != NULL)
544
    ++i;
545
 
546
  return i;
547
}
548
 
549
/* Read a null terminated string from memory, return in a buffer */
550
static char *
551
fetch_str (current_cpu, pc, addr)
552
     SIM_CPU *current_cpu;
553
     PCADDR pc;
554
     DI addr;
555
{
556
  char *buf;
557
  int nr = 0;
558
  while (sim_core_read_1 (current_cpu,
559
                          pc, read_map, addr + nr) != 0)
560
    nr++;
561
  buf = NZALLOC (char, nr + 1);
562
  sim_read (CPU_STATE (current_cpu), addr, buf, nr);
563
  return buf;
564
}
565
 
566
static void
567
trap_handler (SIM_CPU *current_cpu, int shmedia_abi_p, UQI trapnum, PCADDR pc)
568
{
569
  char ch;
570
  switch (trapnum)
571
    {
572
    case 1:
573
      ch = GET_H_GRC (0);
574
      sim_io_write_stdout (CPU_STATE (current_cpu), &ch, 1);
575
      fflush (stdout);
576
      break;
577
    case 2:
578
      sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
579
      break;
580
    case 34:
581
      {
582
        int i;
583
        int ret_reg = (shmedia_abi_p) ? 2 : 0;
584
        char *buf;
585
        DI PARM1 = GET_H_GR ((shmedia_abi_p) ? 3 : 5);
586
        DI PARM2 = GET_H_GR ((shmedia_abi_p) ? 4 : 6);
587
        DI PARM3 = GET_H_GR ((shmedia_abi_p) ? 5 : 7);
588
 
589
        switch (GET_H_GR ((shmedia_abi_p) ? 2 : 4))
590
          {
591
          case SYS_write:
592
            buf = zalloc (PARM3);
593
            sim_read (CPU_STATE (current_cpu), PARM2, buf, PARM3);
594
            SET_H_GR (ret_reg,
595
                      sim_io_write (CPU_STATE (current_cpu),
596
                                    PARM1, buf, PARM3));
597
            zfree (buf);
598
            break;
599
 
600
          case SYS_lseek:
601
            SET_H_GR (ret_reg,
602
                      sim_io_lseek (CPU_STATE (current_cpu),
603
                                    PARM1, PARM2, PARM3));
604
            break;
605
 
606
          case SYS_exit:
607
            sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
608
                             NULL, pc, sim_exited, PARM1);
609
            break;
610
 
611
          case SYS_read:
612
            buf = zalloc (PARM3);
613
            SET_H_GR (ret_reg,
614
                      sim_io_read (CPU_STATE (current_cpu),
615
                                   PARM1, buf, PARM3));
616
            sim_write (CPU_STATE (current_cpu), PARM2, buf, PARM3);
617
            zfree (buf);
618
            break;
619
 
620
          case SYS_open:
621
            buf = fetch_str (current_cpu, pc, PARM1);
622
            SET_H_GR (ret_reg,
623
                      sim_io_open (CPU_STATE (current_cpu),
624
                                   buf, PARM2));
625
            zfree (buf);
626
            break;
627
 
628
          case SYS_close:
629
            SET_H_GR (ret_reg,
630
                      sim_io_close (CPU_STATE (current_cpu), PARM1));
631
            break;
632
 
633
          case SYS_time:
634
            SET_H_GR (ret_reg, time (0));
635
            break;
636
 
637
          case SYS_argc:
638
            SET_H_GR (ret_reg, count_argc (current_cpu));
639
            break;
640
 
641
          case SYS_argnlen:
642
            if (PARM1 < count_argc (current_cpu))
643
              SET_H_GR (ret_reg,
644
                        strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1]));
645
            else
646
              SET_H_GR (ret_reg, -1);
647
            break;
648
 
649
          case SYS_argn:
650
            if (PARM1 < count_argc (current_cpu))
651
              {
652
                /* Include the NULL byte.  */
653
                i = strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1]) + 1;
654
                sim_write (CPU_STATE (current_cpu),
655
                           PARM2,
656
                           STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1],
657
                           i);
658
 
659
                /* Just for good measure.  */
660
                SET_H_GR (ret_reg, i);
661
                break;
662
              }
663
            else
664
              SET_H_GR (ret_reg, -1);
665
            break;
666
 
667
          default:
668
            SET_H_GR (ret_reg, -1);
669
          }
670
      }
671
      break;
672
    case 253:
673
      puts ("pass");
674
      exit (0);
675
    case 254:
676
      puts ("fail");
677
      exit (1);
678
    case 0xc3:
679
      /* fall through.  */
680
    case 255:
681
      sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
682
      break;
683
    }
684
}
685
 
686
void
687
sh64_trapa (SIM_CPU *current_cpu, DI rm, PCADDR pc)
688
{
689
  trap_handler (current_cpu, 1, (UQI) rm & 0xff, pc);
690
}
691
 
692
void
693
sh64_compact_trapa (SIM_CPU *current_cpu, UQI trapnum, PCADDR pc)
694
{
695
  int mach_sh5_p;
696
 
697
  /* If this is an SH5 executable, this is SHcompact code running in
698
     the SHmedia ABI.  */
699
 
700
  mach_sh5_p =
701
    (bfd_get_mach (STATE_PROG_BFD (CPU_STATE (current_cpu))) == bfd_mach_sh5);
702
 
703
  trap_handler (current_cpu, mach_sh5_p, trapnum, pc);
704
}
705
 
706
DI
707
sh64_nsb (SIM_CPU *current_cpu, DI rm)
708
{
709
  int result = 0, count;
710
  UDI source = (UDI) rm;
711
 
712
  if ((source >> 63))
713
    source = ~source;
714
  source <<= 1;
715
 
716
  for (count = 32; count; count >>= 1)
717
    {
718
      UDI newval = source << count;
719
 
720
      if ((newval >> count) == source)
721
        {
722
          result |= count;
723
          source = newval;
724
        }
725
    }
726
 
727
  return result;
728
}
729
 
730
void
731
sh64_break (SIM_CPU *current_cpu, PCADDR pc)
732
{
733
  SIM_DESC sd = CPU_STATE (current_cpu);
734
  sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
735
}
736
 
737
SI
738
sh64_movua (SIM_CPU *current_cpu, PCADDR pc, SI rn)
739
{
740
  SI v;
741
  int i;
742
 
743
  /* Move the data one byte at a time to avoid alignment problems.
744
     Be aware of endianness.  */
745
  v = 0;
746
  for (i = 0; i < 4; ++i)
747
    v = (v << 8) | (GETMEMQI (current_cpu, pc, rn + i) & 0xff);
748
 
749
  v = T2H_4 (v);
750
  return v;
751
}
752
 
753
void
754
set_isa (SIM_CPU *current_cpu, int mode)
755
{
756
  /* Do nothing.  */
757
}
758
 
759
/* The semantic code invokes this for invalid (unrecognized) instructions.  */
760
 
761
SEM_PC
762
sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
763
{
764
  SIM_DESC sd = CPU_STATE (current_cpu);
765
  sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
766
 
767
  return vpc;
768
}
769
 
770
 
771
/* Process an address exception.  */
772
 
773
void
774
sh64_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
775
                  unsigned int map, int nr_bytes, address_word addr,
776
                  transfer_type transfer, sim_core_signals sig)
777
{
778
  sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
779
                   transfer, sig);
780
}
781
 
782
 
783
/* Initialize cycle counting for an insn.
784
   FIRST_P is non-zero if this is the first insn in a set of parallel
785
   insns.  */
786
 
787
void
788
sh64_compact_model_insn_before (SIM_CPU *cpu, int first_p)
789
{
790
  /* Do nothing.  */
791
}
792
 
793
void
794
sh64_media_model_insn_before (SIM_CPU *cpu, int first_p)
795
{
796
  /* Do nothing.  */
797
}
798
 
799
/* Record the cycles computed for an insn.
800
   LAST_P is non-zero if this is the last insn in a set of parallel insns,
801
   and we update the total cycle count.
802
   CYCLES is the cycle count of the insn.  */
803
 
804
void
805
sh64_compact_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
806
{
807
  /* Do nothing.  */
808
}
809
 
810
void
811
sh64_media_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
812
{
813
  /* Do nothing.  */
814
}
815
 
816
int
817
sh64_fetch_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
818
{
819
  /* Fetch general purpose registers. */
820
  if (nr >= SIM_SH64_R0_REGNUM
821
      && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS)
822
      && len == 8)
823
    {
824
      *((unsigned64*) buf) =
825
        H2T_8 (sh64_h_gr_get (cpu, nr - SIM_SH64_R0_REGNUM));
826
      return len;
827
    }
828
 
829
  /* Fetch PC.  */
830
  if (nr == SIM_SH64_PC_REGNUM && len == 8)
831
    {
832
      *((unsigned64*) buf) = H2T_8 (sh64_h_pc_get (cpu) | sh64_h_ism_get (cpu));
833
      return len;
834
    }
835
 
836
  /* Fetch status register (SR).  */
837
  if (nr == SIM_SH64_SR_REGNUM && len == 8)
838
    {
839
      *((unsigned64*) buf) = H2T_8 (sh64_h_sr_get (cpu));
840
      return len;
841
    }
842
 
843
  /* Fetch saved status register (SSR) and PC (SPC).  */
844
  if ((nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM)
845
      && len == 8)
846
    {
847
      *((unsigned64*) buf) = 0;
848
      return len;
849
    }
850
 
851
  /* Fetch target registers.  */
852
  if (nr >= SIM_SH64_TR0_REGNUM
853
      && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS)
854
      && len == 8)
855
    {
856
      *((unsigned64*) buf) =
857
        H2T_8 (sh64_h_tr_get (cpu, nr - SIM_SH64_TR0_REGNUM));
858
      return len;
859
    }
860
 
861
  /* Fetch floating point registers.  */
862
  if (nr >= SIM_SH64_FR0_REGNUM
863
      && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS)
864
      && len == 4)
865
    {
866
      *((unsigned32*) buf) =
867
        H2T_4 (sh64_h_fr_get (cpu, nr - SIM_SH64_FR0_REGNUM));
868
      return len;
869
    }
870
 
871
  /* We should never get here.  */
872
  return 0;
873
}
874
 
875
int
876
sh64_store_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
877
{
878
  /* Store general purpose registers. */
879
  if (nr >= SIM_SH64_R0_REGNUM
880
      && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS)
881
      && len == 8)
882
    {
883
      sh64_h_gr_set (cpu, nr - SIM_SH64_R0_REGNUM, T2H_8 (*((unsigned64*)buf)));
884
      return len;
885
    }
886
 
887
  /* Store PC.  */
888
  if (nr == SIM_SH64_PC_REGNUM && len == 8)
889
    {
890
      unsigned64 new_pc = T2H_8 (*((unsigned64*)buf));
891
      sh64_h_pc_set (cpu, new_pc);
892
      return len;
893
    }
894
 
895
  /* Store status register (SR).  */
896
  if (nr == SIM_SH64_SR_REGNUM && len == 8)
897
    {
898
      sh64_h_sr_set (cpu, T2H_8 (*((unsigned64*)buf)));
899
      return len;
900
    }
901
 
902
  /* Store saved status register (SSR) and PC (SPC).  */
903
  if (nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM)
904
    {
905
      /* Do nothing.  */
906
      return len;
907
    }
908
 
909
  /* Store target registers.  */
910
  if (nr >= SIM_SH64_TR0_REGNUM
911
      && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS)
912
      && len == 8)
913
    {
914
      sh64_h_tr_set (cpu, nr - SIM_SH64_TR0_REGNUM, T2H_8 (*((unsigned64*)buf)));
915
      return len;
916
    }
917
 
918
  /* Store floating point registers.  */
919
  if (nr >= SIM_SH64_FR0_REGNUM
920
      && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS)
921
      && len == 4)
922
    {
923
      sh64_h_fr_set (cpu, nr - SIM_SH64_FR0_REGNUM, T2H_4 (*((unsigned32*)buf)));
924
      return len;
925
    }
926
 
927
  /* We should never get here.  */
928
  return 0;
929
}
930
 
931
void
932
sh64_engine_run_full(SIM_CPU *cpu)
933
{
934
  if (sh64_h_ism_get (cpu) == ISM_MEDIA)
935
    {
936
      if (!sh64_idesc_media)
937
        {
938
          sh64_media_init_idesc_table (cpu);
939
          sh64_idesc_media = CPU_IDESC (cpu);
940
        }
941
      else
942
        CPU_IDESC (cpu) = sh64_idesc_media;
943
      sh64_media_engine_run_full (cpu);
944
    }
945
  else
946
    {
947
      if (!sh64_idesc_compact)
948
        {
949
          sh64_compact_init_idesc_table (cpu);
950
          sh64_idesc_compact = CPU_IDESC (cpu);
951
        }
952
      else
953
        CPU_IDESC (cpu) = sh64_idesc_compact;
954
      sh64_compact_engine_run_full (cpu);
955
    }
956
}
957
 
958
void
959
sh64_engine_run_fast (SIM_CPU *cpu)
960
{
961
  if (sh64_h_ism_get (cpu) == ISM_MEDIA)
962
    {
963
      if (!sh64_idesc_media)
964
        {
965
          sh64_media_init_idesc_table (cpu);
966
          sh64_idesc_media = CPU_IDESC (cpu);
967
        }
968
      else
969
        CPU_IDESC (cpu) = sh64_idesc_media;
970
      sh64_media_engine_run_fast (cpu);
971
    }
972
  else
973
    {
974
      if (!sh64_idesc_compact)
975
        {
976
          sh64_compact_init_idesc_table (cpu);
977
          sh64_idesc_compact = CPU_IDESC (cpu);
978
        }
979
      else
980
        CPU_IDESC (cpu) = sh64_idesc_compact;
981
      sh64_compact_engine_run_fast (cpu);
982
    }
983
}
984
 
985
static void
986
sh64_prepare_run (SIM_CPU *cpu)
987
{
988
  /* Nothing.  */
989
}
990
 
991
static const CGEN_INSN *
992
sh64_get_idata (SIM_CPU *cpu, int inum)
993
{
994
  return CPU_IDESC (cpu) [inum].idata;
995
}
996
 
997
static void
998
sh64_init_cpu (SIM_CPU *cpu)
999
{
1000
  CPU_REG_FETCH (cpu) = sh64_fetch_register;
1001
  CPU_REG_STORE (cpu) = sh64_store_register;
1002
  CPU_PC_FETCH (cpu) = sh64_h_pc_get;
1003
  CPU_PC_STORE (cpu) = sh64_h_pc_set;
1004
  CPU_GET_IDATA (cpu) = sh64_get_idata;
1005
  /* Only used by profiling.  0 disables it. */
1006
  CPU_MAX_INSNS (cpu) = 0;
1007
  CPU_INSN_NAME (cpu) = cgen_insn_name;
1008
  CPU_FULL_ENGINE_FN (cpu) = sh64_engine_run_full;
1009
#if WITH_FAST
1010
  CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_fast;
1011
#else
1012
  CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_full;
1013
#endif
1014
}
1015
 
1016
static void
1017
shmedia_init_cpu (SIM_CPU *cpu)
1018
{
1019
  sh64_init_cpu (cpu);
1020
}
1021
 
1022
static void
1023
shcompact_init_cpu (SIM_CPU *cpu)
1024
{
1025
  sh64_init_cpu (cpu);
1026
}
1027
 
1028
static void
1029
sh64_model_init()
1030
{
1031
  /* Do nothing.  */
1032
}
1033
 
1034
static const MODEL sh_models [] =
1035
{
1036
  { "sh2",        & sh2_mach,         MODEL_SH5, NULL, sh64_model_init },
1037
  { "sh2e",       & sh2e_mach,        MODEL_SH5, NULL, sh64_model_init },
1038
  { "sh2a",       & sh2a_fpu_mach,    MODEL_SH5, NULL, sh64_model_init },
1039
  { "sh2a_nofpu", & sh2a_nofpu_mach,  MODEL_SH5, NULL, sh64_model_init },
1040
  { "sh3",        & sh3_mach,         MODEL_SH5, NULL, sh64_model_init },
1041
  { "sh3e",       & sh3_mach,         MODEL_SH5, NULL, sh64_model_init },
1042
  { "sh4",        & sh4_mach,         MODEL_SH5, NULL, sh64_model_init },
1043
  { "sh4_nofpu",  & sh4_nofpu_mach,   MODEL_SH5, NULL, sh64_model_init },
1044
  { "sh4a",       & sh4a_mach,        MODEL_SH5, NULL, sh64_model_init },
1045
  { "sh4a_nofpu", & sh4a_nofpu_mach,  MODEL_SH5, NULL, sh64_model_init },
1046
  { "sh4al",      & sh4al_mach,       MODEL_SH5, NULL, sh64_model_init },
1047
  { "sh5",        & sh5_mach,         MODEL_SH5, NULL, sh64_model_init },
1048
  { 0 }
1049
};
1050
 
1051
static const MACH_IMP_PROPERTIES sh5_imp_properties =
1052
{
1053
  sizeof (SIM_CPU),
1054
#if WITH_SCACHE
1055
  sizeof (SCACHE)
1056
#else
1057
 
1058
#endif
1059
};
1060
 
1061
const MACH sh2_mach =
1062
{
1063
  "sh2", "sh2", MACH_SH5,
1064
  16, 16, &sh_models[0], &sh5_imp_properties,
1065
  shcompact_init_cpu,
1066
  sh64_prepare_run
1067
};
1068
 
1069
const MACH sh2e_mach =
1070
{
1071
  "sh2e", "sh2e", MACH_SH5,
1072
  16, 16, &sh_models[1], &sh5_imp_properties,
1073
  shcompact_init_cpu,
1074
  sh64_prepare_run
1075
};
1076
 
1077
const MACH sh2a_fpu_mach =
1078
{
1079
  "sh2a", "sh2a", MACH_SH5,
1080
  16, 16, &sh_models[2], &sh5_imp_properties,
1081
  shcompact_init_cpu,
1082
  sh64_prepare_run
1083
};
1084
 
1085
const MACH sh2a_nofpu_mach =
1086
{
1087
  "sh2a_nofpu", "sh2a_nofpu", MACH_SH5,
1088
  16, 16, &sh_models[3], &sh5_imp_properties,
1089
  shcompact_init_cpu,
1090
  sh64_prepare_run
1091
};
1092
 
1093
const MACH sh3_mach =
1094
{
1095
  "sh3", "sh3", MACH_SH5,
1096
  16, 16, &sh_models[4], &sh5_imp_properties,
1097
  shcompact_init_cpu,
1098
  sh64_prepare_run
1099
};
1100
 
1101
const MACH sh3e_mach =
1102
{
1103
  "sh3e", "sh3e", MACH_SH5,
1104
  16, 16, &sh_models[5], &sh5_imp_properties,
1105
  shcompact_init_cpu,
1106
  sh64_prepare_run
1107
};
1108
 
1109
const MACH sh4_mach =
1110
{
1111
  "sh4", "sh4", MACH_SH5,
1112
  16, 16, &sh_models[6], &sh5_imp_properties,
1113
  shcompact_init_cpu,
1114
  sh64_prepare_run
1115
};
1116
 
1117
const MACH sh4_nofpu_mach =
1118
{
1119
  "sh4_nofpu", "sh4_nofpu", MACH_SH5,
1120
  16, 16, &sh_models[7], &sh5_imp_properties,
1121
  shcompact_init_cpu,
1122
  sh64_prepare_run
1123
};
1124
 
1125
const MACH sh4a_mach =
1126
{
1127
  "sh4a", "sh4a", MACH_SH5,
1128
  16, 16, &sh_models[8], &sh5_imp_properties,
1129
  shcompact_init_cpu,
1130
  sh64_prepare_run
1131
};
1132
 
1133
const MACH sh4a_nofpu_mach =
1134
{
1135
  "sh4a_nofpu", "sh4a_nofpu", MACH_SH5,
1136
  16, 16, &sh_models[9], &sh5_imp_properties,
1137
  shcompact_init_cpu,
1138
  sh64_prepare_run
1139
};
1140
 
1141
const MACH sh4al_mach =
1142
{
1143
  "sh4al", "sh4al", MACH_SH5,
1144
  16, 16, &sh_models[10], &sh5_imp_properties,
1145
  shcompact_init_cpu,
1146
  sh64_prepare_run
1147
};
1148
 
1149
const MACH sh5_mach =
1150
{
1151
  "sh5", "sh5", MACH_SH5,
1152
  32, 32, &sh_models[11], &sh5_imp_properties,
1153
  shmedia_init_cpu,
1154
  sh64_prepare_run
1155
};

powered by: WebSVN 2.1.0

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