* Makefile.in (HFILES_NO_SRCDIR): Remove old files.
[deliverable/binutils-gdb.git] / sim / sh64 / sh64.c
CommitLineData
cbb38b47
BE
1/* SH5 simulator support code
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Red Hat, Inc.
4
5This file is part of the GNU simulators.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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 "callback.h"
30#include "defs-compact.h"
31
32#include "bfd.h"
33/* From include/. */
34#include "sim-sh64.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
47IDESC * sh64_idesc_media;
48IDESC * sh64_idesc_compact;
49
50BI
51sh64_endian (SIM_CPU *current_cpu)
52{
53 return (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN);
54}
55
56SF
57sh64_fldi0 (SIM_CPU *current_cpu)
58{
59 SF result;
60 sim_fpu_to32 (&result, &sim_fpu_zero);
61 return result;
62}
63
64SF
65sh64_fldi1 (SIM_CPU *current_cpu)
66{
67 SF result;
68 sim_fpu_to32 (&result, &sim_fpu_one);
69 return result;
70}
71
72DF
73sh64_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
84SF
85sh64_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
96DF
97sh64_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
109SF
110sh64_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
122BI
123sh64_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
132BI
133sh64_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
142BI
143sh64_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
152BI
153sh64_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
162BI
163sh64_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
172BI
173sh64_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
182BI
183sh64_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
192BI
193sh64_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
202SF
203sh64_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
221DF
222sh64_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
232DF
233sh64_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
245SF
246sh64_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
258DF
259sh64_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
269SF
270sh64_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
280DF
281sh64_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
291SF
292sh64_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
302SF
303sh64_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
319DF
320sh64_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
332SF
333sh64_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
345DF
346sh64_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
357SF
358sh64_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
369DF
370sh64_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
381SF
382sh64_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
393DF
394sh64_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
406SF
407sh64_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
419SF
420sh64_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
430SF
431sh64_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
441DF
442sh64_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
452DF
453sh64_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
463void
464sh64_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/* Count the number of arguments. */
488static int
489count_argc (cpu)
490 SIM_CPU *cpu;
491{
492 int i = 0;
493
494 if (! STATE_PROG_ARGV (CPU_STATE (cpu)))
495 return -1;
496
497 while (STATE_PROG_ARGV (CPU_STATE (cpu)) [i] != NULL)
498 ++i;
499
500 return i;
501}
502
503/* Read a null terminated string from memory, return in a buffer */
504static char *
505fetch_str (current_cpu, pc, addr)
506 SIM_CPU *current_cpu;
507 PCADDR pc;
508 DI addr;
509{
510 char *buf;
511 int nr = 0;
512 while (sim_core_read_1 (current_cpu,
513 pc, read_map, addr + nr) != 0)
514 nr++;
515 buf = NZALLOC (char, nr + 1);
516 sim_read (CPU_STATE (current_cpu), addr, buf, nr);
517 return buf;
518}
519
520static void
521trap_handler (SIM_CPU *current_cpu, int shmedia_abi_p, UQI trapnum, PCADDR pc)
522{
523 char ch;
524 switch (trapnum)
525 {
526 case 1:
527 ch = GET_H_GRC (0);
528 sim_io_write_stdout (CPU_STATE (current_cpu), &ch, 1);
529 fflush (stdout);
530 break;
531 case 2:
532 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
533 break;
534 case 34:
535 {
536 int i;
537 int ret_reg = (shmedia_abi_p) ? 2 : 0;
538 char *buf;
539 DI PARM1 = GET_H_GR ((shmedia_abi_p) ? 3 : 5);
540 DI PARM2 = GET_H_GR ((shmedia_abi_p) ? 4 : 6);
541 DI PARM3 = GET_H_GR ((shmedia_abi_p) ? 5 : 7);
542
543 switch (GET_H_GR ((shmedia_abi_p) ? 2 : 4))
544 {
545 case SYS_write:
546 buf = zalloc (PARM3);
547 sim_read (CPU_STATE (current_cpu), PARM2, buf, PARM3);
548 SET_H_GR (ret_reg,
549 sim_io_write (CPU_STATE (current_cpu),
550 PARM1, buf, PARM3));
551 zfree (buf);
552 break;
553
554 case SYS_lseek:
555 SET_H_GR (ret_reg,
556 sim_io_lseek (CPU_STATE (current_cpu),
557 PARM1, PARM2, PARM3));
558 break;
559
560 case SYS_exit:
561 sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
562 NULL, pc, sim_exited, PARM1);
563 break;
564
565 case SYS_read:
566 buf = zalloc (PARM3);
567 SET_H_GR (ret_reg,
568 sim_io_read (CPU_STATE (current_cpu),
569 PARM1, buf, PARM3));
570 sim_write (CPU_STATE (current_cpu), PARM2, buf, PARM3);
571 zfree (buf);
572 break;
573
574 case SYS_open:
575 buf = fetch_str (current_cpu, pc, PARM1);
576 SET_H_GR (ret_reg,
577 sim_io_open (CPU_STATE (current_cpu),
578 buf, PARM2));
579 zfree (buf);
580 break;
581
582 case SYS_close:
583 SET_H_GR (ret_reg,
584 sim_io_close (CPU_STATE (current_cpu), PARM1));
585 break;
586
587 case SYS_time:
588 SET_H_GR (ret_reg, time (0));
589 break;
590
591 case SYS_argc:
592 SET_H_GR (ret_reg, count_argc (current_cpu));
593 break;
594
595 case SYS_argnlen:
596 if (PARM1 < count_argc (current_cpu))
597 SET_H_GR (ret_reg,
598 strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1]));
599 else
600 SET_H_GR (ret_reg, -1);
601 break;
602
603 case SYS_argn:
604 if (PARM1 < count_argc (current_cpu))
605 {
606 /* Include the NULL byte. */
607 i = strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1]) + 1;
608 sim_write (CPU_STATE (current_cpu),
609 PARM2,
610 STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1],
611 i);
612
613 /* Just for good measure. */
614 SET_H_GR (ret_reg, i);
615 break;
616 }
617 else
618 SET_H_GR (ret_reg, -1);
619 break;
620
621 default:
622 SET_H_GR (ret_reg, -1);
623 }
624 }
625 break;
626 case 253:
627 puts ("pass");
628 exit (0);
629 case 254:
630 puts ("fail");
631 exit (1);
632 case 0xc3:
633 /* fall through. */
634 case 255:
635 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
636 break;
637 }
638}
639
640void
641sh64_trapa (SIM_CPU *current_cpu, DI rm, PCADDR pc)
642{
643 trap_handler (current_cpu, 1, (UQI) rm & 0xff, pc);
644}
645
646void
647sh64_compact_trapa (SIM_CPU *current_cpu, UQI trapnum, PCADDR pc)
648{
649 int mach_sh5_p;
650
651 /* If this is an SH5 executable, this is SHcompact code running in
652 the SHmedia ABI. */
653
654 mach_sh5_p =
655 (bfd_get_mach (STATE_PROG_BFD (CPU_STATE (current_cpu))) == bfd_mach_sh5);
656
657 trap_handler (current_cpu, mach_sh5_p, trapnum, pc);
658}
659
660DI
661sh64_nsb (SIM_CPU *current_cpu, DI rm)
662{
663 int result = 0, count;
664 UDI source = (UDI) rm;
665
666 if ((source >> 63))
667 source = ~source;
668 source <<= 1;
669
670 for (count = 32; count; count >>= 1)
671 {
672 UDI newval = source << count;
673
674 if ((newval >> count) == source)
675 {
676 result |= count;
677 source = newval;
678 }
679 }
680
681 return result;
682}
683
684void
685sh64_break (SIM_CPU *current_cpu, PCADDR pc)
686{
687 SIM_DESC sd = CPU_STATE (current_cpu);
688 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
689}
690
691void
692set_isa (SIM_CPU *current_cpu, int mode)
693{
694 /* Do nothing. */
695}
696
697/* The semantic code invokes this for invalid (unrecognized) instructions. */
698
699SEM_PC
700sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
701{
702 SIM_DESC sd = CPU_STATE (current_cpu);
703 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
704
705 return vpc;
706}
707
708
709/* Process an address exception. */
710
711void
712sh64_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
713 unsigned int map, int nr_bytes, address_word addr,
714 transfer_type transfer, sim_core_signals sig)
715{
716 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
717 transfer, sig);
718}
719
720
721/* Initialize cycle counting for an insn.
722 FIRST_P is non-zero if this is the first insn in a set of parallel
723 insns. */
724
725void
726sh64_compact_model_insn_before (SIM_CPU *cpu, int first_p)
727{
728 /* Do nothing. */
729}
730
731void
732sh64_media_model_insn_before (SIM_CPU *cpu, int first_p)
733{
734 /* Do nothing. */
735}
736
737/* Record the cycles computed for an insn.
738 LAST_P is non-zero if this is the last insn in a set of parallel insns,
739 and we update the total cycle count.
740 CYCLES is the cycle count of the insn. */
741
742void
743sh64_compact_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
744{
745 /* Do nothing. */
746}
747
748void
749sh64_media_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
750{
751 /* Do nothing. */
752}
753
754int
755sh64_fetch_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
756{
757 /* Fetch general purpose registers. */
758 if (nr >= SIM_SH64_R0_REGNUM
759 && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS)
760 && len == 8)
761 {
762 *((unsigned64*) buf) =
763 H2T_8 (sh64_h_gr_get (cpu, nr - SIM_SH64_R0_REGNUM));
764 return len;
765 }
766
767 /* Fetch PC. */
768 if (nr == SIM_SH64_PC_REGNUM && len == 8)
769 {
770 *((unsigned64*) buf) = H2T_8 (sh64_h_pc_get (cpu) | sh64_h_ism_get (cpu));
771 return len;
772 }
773
774 /* Fetch status register (SR). */
775 if (nr == SIM_SH64_SR_REGNUM && len == 8)
776 {
777 *((unsigned64*) buf) = H2T_8 (sh64_h_sr_get (cpu));
778 return len;
779 }
780
781 /* Fetch saved status register (SSR) and PC (SPC). */
782 if ((nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM)
783 && len == 8)
784 {
785 *((unsigned64*) buf) = 0;
786 return len;
787 }
788
789 /* Fetch target registers. */
790 if (nr >= SIM_SH64_TR0_REGNUM
791 && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS)
792 && len == 8)
793 {
794 *((unsigned64*) buf) =
795 H2T_8 (sh64_h_tr_get (cpu, nr - SIM_SH64_TR0_REGNUM));
796 return len;
797 }
798
799 /* Fetch floating point registers. */
800 if (nr >= SIM_SH64_FR0_REGNUM
801 && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS)
802 && len == 4)
803 {
804 *((unsigned32*) buf) =
805 H2T_4 (sh64_h_fr_get (cpu, nr - SIM_SH64_FR0_REGNUM));
806 return len;
807 }
808
809 /* We should never get here. */
810 return 0;
811}
812
813int
814sh64_store_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
815{
816 /* Store general purpose registers. */
817 if (nr >= SIM_SH64_R0_REGNUM
818 && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS)
819 && len == 8)
820 {
821 sh64_h_gr_set (cpu, nr - SIM_SH64_R0_REGNUM, T2H_8 (*((unsigned64*)buf)));
822 return len;
823 }
824
825 /* Store PC. */
826 if (nr == SIM_SH64_PC_REGNUM && len == 8)
827 {
828 unsigned64 new_pc = T2H_8 (*((unsigned64*)buf));
829 sh64_h_pc_set (cpu, new_pc);
830 return len;
831 }
832
833 /* Store status register (SR). */
834 if (nr == SIM_SH64_SR_REGNUM && len == 8)
835 {
836 sh64_h_sr_set (cpu, T2H_8 (*((unsigned64*)buf)));
837 return len;
838 }
839
840 /* Store saved status register (SSR) and PC (SPC). */
841 if (nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM)
842 {
843 /* Do nothing. */
844 return len;
845 }
846
847 /* Store target registers. */
848 if (nr >= SIM_SH64_TR0_REGNUM
849 && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS)
850 && len == 8)
851 {
852 sh64_h_tr_set (cpu, nr - SIM_SH64_TR0_REGNUM, T2H_8 (*((unsigned64*)buf)));
853 return len;
854 }
855
856 /* Store floating point registers. */
857 if (nr >= SIM_SH64_FR0_REGNUM
858 && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS)
859 && len == 4)
860 {
861 sh64_h_fr_set (cpu, nr - SIM_SH64_FR0_REGNUM, T2H_4 (*((unsigned32*)buf)));
862 return len;
863 }
864
865 /* We should never get here. */
866 return 0;
867}
868
869void
870sh64_engine_run_full(SIM_CPU *cpu)
871{
872 if (sh64_h_ism_get (cpu) == ISM_MEDIA)
873 {
874 if (!sh64_idesc_media)
875 {
876 sh64_media_init_idesc_table (cpu);
877 sh64_idesc_media = CPU_IDESC (cpu);
878 }
879 else
880 CPU_IDESC (cpu) = sh64_idesc_media;
881 sh64_media_engine_run_full (cpu);
882 }
883 else
884 {
885 if (!sh64_idesc_compact)
886 {
887 sh64_compact_init_idesc_table (cpu);
888 sh64_idesc_compact = CPU_IDESC (cpu);
889 }
890 else
891 CPU_IDESC (cpu) = sh64_idesc_compact;
892 sh64_compact_engine_run_full (cpu);
893 }
894}
895
896void
897sh64_engine_run_fast (SIM_CPU *cpu)
898{
899 if (sh64_h_ism_get (cpu) == ISM_MEDIA)
900 {
901 if (!sh64_idesc_media)
902 {
903 sh64_media_init_idesc_table (cpu);
904 sh64_idesc_media = CPU_IDESC (cpu);
905 }
906 else
907 CPU_IDESC (cpu) = sh64_idesc_media;
908 sh64_media_engine_run_fast (cpu);
909 }
910 else
911 {
912 if (!sh64_idesc_compact)
913 {
914 sh64_compact_init_idesc_table (cpu);
915 sh64_idesc_compact = CPU_IDESC (cpu);
916 }
917 else
918 CPU_IDESC (cpu) = sh64_idesc_compact;
919 sh64_compact_engine_run_fast (cpu);
920 }
921}
922
923static void
924sh64_prepare_run (SIM_CPU *cpu)
925{
926 /* Nothing. */
927}
928
929static const CGEN_INSN *
930sh64_get_idata (SIM_CPU *cpu, int inum)
931{
932 return CPU_IDESC (cpu) [inum].idata;
933}
934
935static void
936sh64_init_cpu (SIM_CPU *cpu)
937{
938 CPU_REG_FETCH (cpu) = sh64_fetch_register;
939 CPU_REG_STORE (cpu) = sh64_store_register;
940 CPU_PC_FETCH (cpu) = sh64_h_pc_get;
941 CPU_PC_STORE (cpu) = sh64_h_pc_set;
942 CPU_GET_IDATA (cpu) = sh64_get_idata;
943 /* Only used by profiling. 0 disables it. */
944 CPU_MAX_INSNS (cpu) = 0;
945 CPU_INSN_NAME (cpu) = cgen_insn_name;
946 CPU_FULL_ENGINE_FN (cpu) = sh64_engine_run_full;
947#if WITH_FAST
948 CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_fast;
949#else
950 CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_full;
951#endif
952}
953
954static void
955shmedia_init_cpu (SIM_CPU *cpu)
956{
957 sh64_init_cpu (cpu);
958}
959
960static void
961shcompact_init_cpu (SIM_CPU *cpu)
962{
963 sh64_init_cpu (cpu);
964}
965
966static void
967sh64_model_init()
968{
969 /* Do nothing. */
970}
971
972static const MODEL sh_models [] =
973{
974 { "sh2", & sh2_mach, MODEL_SH5, NULL, sh64_model_init },
975 { "sh3", & sh3_mach, MODEL_SH5, NULL, sh64_model_init },
976 { "sh3e", & sh3_mach, MODEL_SH5, NULL, sh64_model_init },
977 { "sh4", & sh4_mach, MODEL_SH5, NULL, sh64_model_init },
978 { "sh5", & sh5_mach, MODEL_SH5, NULL, sh64_model_init },
979 { 0 }
980};
981
982static const MACH_IMP_PROPERTIES sh5_imp_properties =
983{
984 sizeof (SIM_CPU),
985#if WITH_SCACHE
986 sizeof (SCACHE)
987#else
988 0
989#endif
990};
991
992const MACH sh2_mach =
993{
994 "sh2", "sh2", MACH_SH5,
995 16, 16, &sh_models[0], &sh5_imp_properties,
996 shcompact_init_cpu,
997 sh64_prepare_run
998};
999
1000const MACH sh3_mach =
1001{
1002 "sh3", "sh3", MACH_SH5,
1003 16, 16, &sh_models[1], &sh5_imp_properties,
1004 shcompact_init_cpu,
1005 sh64_prepare_run
1006};
1007
1008const MACH sh3e_mach =
1009{
1010 "sh3e", "sh3e", MACH_SH5,
1011 16, 16, &sh_models[2], &sh5_imp_properties,
1012 shcompact_init_cpu,
1013 sh64_prepare_run
1014};
1015
1016const MACH sh4_mach =
1017{
1018 "sh4", "sh4", MACH_SH5,
1019 16, 16, &sh_models[3], &sh5_imp_properties,
1020 shcompact_init_cpu,
1021 sh64_prepare_run
1022};
1023
1024const MACH sh5_mach =
1025{
1026 "sh5", "sh5", MACH_SH5,
1027 32, 32, &sh_models[4], &sh5_imp_properties,
1028 shmedia_init_cpu,
1029 sh64_prepare_run
1030};
This page took 0.109784 seconds and 4 git commands to generate.