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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [sh64/] [sh64.c] - Blame information for rev 298

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

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

powered by: WebSVN 2.1.0

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