OSDN Git Service

Updated copyright notices for most files.
[pf3gnuchains/pf3gnuchains3x.git] / sim / sh64 / sh64.c
1 /* 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   0
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 };