]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/sh64/sh64.c
b376ae4738770fb1e22f2159baa2ffa4f1628f26
[thirdparty/binutils-gdb.git] / sim / sh64 / sh64.c
1 /* SH5 simulator support code
2 Copyright (C) 2000-2001, 2006, 2008-2012 Free Software Foundation,
3 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 free (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 free (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 free (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 0
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 };