1 /* SH5 simulator support code
2    Copyright (C) 2000, 2001, 2006, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4    Contributed by Red Hat, Inc.
5 
6 This file is part of the GNU simulators.
7 
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 #define WANT_CPU
22 #define WANT_CPU_SH64
23 
24 #include "sim-main.h"
25 #include "sim-fpu.h"
26 #include "cgen-mem.h"
27 #include "cgen-ops.h"
28 
29 #include "gdb/callback.h"
30 #include "defs-compact.h"
31 
32 #include "bfd.h"
33 /* From include/gdb/.  */
34 #include "gdb/sim-sh.h"
35 
36 #define SYS_exit        1
37 #define	SYS_read	3
38 #define SYS_write       4
39 #define	SYS_open	5
40 #define	SYS_close	6
41 #define	SYS_lseek	19
42 #define	SYS_time	23
43 #define	SYS_argc	172
44 #define	SYS_argnlen	173
45 #define	SYS_argn	174
46 
47 IDESC * sh64_idesc_media;
48 IDESC * sh64_idesc_compact;
49 
50 BI
sh64_endian(SIM_CPU * current_cpu)51 sh64_endian (SIM_CPU *current_cpu)
52 {
53   return (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN);
54 }
55 
56 SF
sh64_fldi0(SIM_CPU * current_cpu)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
sh64_fldi1(SIM_CPU * current_cpu)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
sh64_fabsd(SIM_CPU * current_cpu,DF drgh)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
sh64_fabss(SIM_CPU * current_cpu,SF frgh)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
sh64_faddd(SIM_CPU * current_cpu,DF drg,DF drh)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
sh64_fadds(SIM_CPU * current_cpu,SF frg,SF frh)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
sh64_fcmpeqd(SIM_CPU * current_cpu,DF drg,DF drh)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
sh64_fcmpeqs(SIM_CPU * current_cpu,SF frg,SF frh)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
sh64_fcmpged(SIM_CPU * current_cpu,DF drg,DF drh)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
sh64_fcmpges(SIM_CPU * current_cpu,SF frg,SF frh)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
sh64_fcmpgtd(SIM_CPU * current_cpu,DF drg,DF drh)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
sh64_fcmpgts(SIM_CPU * current_cpu,SF frg,SF frh)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
sh64_fcmpund(SIM_CPU * current_cpu,DF drg,DF drh)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
sh64_fcmpuns(SIM_CPU * current_cpu,SF frg,SF frh)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
sh64_fcnvds(SIM_CPU * current_cpu,DF drgh)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
sh64_fcnvsd(SIM_CPU * current_cpu,SF frgh)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
sh64_fdivd(SIM_CPU * current_cpu,DF drg,DF drh)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
sh64_fdivs(SIM_CPU * current_cpu,SF frg,SF frh)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
sh64_floatld(SIM_CPU * current_cpu,SF frgh)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
sh64_floatls(SIM_CPU * current_cpu,SF frgh)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
sh64_floatqd(SIM_CPU * current_cpu,DF drgh)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
sh64_floatqs(SIM_CPU * current_cpu,DF drgh)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
sh64_fmacs(SIM_CPU * current_cpu,SF fr0,SF frm,SF frn)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
sh64_fmuld(SIM_CPU * current_cpu,DF drg,DF drh)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
sh64_fmuls(SIM_CPU * current_cpu,SF frg,SF frh)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
sh64_fnegd(SIM_CPU * current_cpu,DF drgh)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
sh64_fnegs(SIM_CPU * current_cpu,SF frgh)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
sh64_fsqrtd(SIM_CPU * current_cpu,DF drgh)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
sh64_fsqrts(SIM_CPU * current_cpu,SF frgh)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
sh64_fsubd(SIM_CPU * current_cpu,DF drg,DF drh)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
sh64_fsubs(SIM_CPU * current_cpu,SF frg,SF frh)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
sh64_ftrcdl(SIM_CPU * current_cpu,DF drgh)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
sh64_ftrcsl(SIM_CPU * current_cpu,SF frgh)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
sh64_ftrcdq(SIM_CPU * current_cpu,DF drgh)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
sh64_ftrcsq(SIM_CPU * current_cpu,SF frgh)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
sh64_ftrvs(SIM_CPU * cpu,unsigned g,unsigned h,unsigned f)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
sh64_fipr(SIM_CPU * cpu,unsigned m,unsigned n)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
sh64_fiprs(SIM_CPU * cpu,unsigned g,unsigned h)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
sh64_fldp(SIM_CPU * cpu,PCADDR pc,DI rm,DI rn,unsigned f)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
sh64_fstp(SIM_CPU * cpu,PCADDR pc,DI rm,DI rn,unsigned f)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
sh64_ftrv(SIM_CPU * cpu,UINT ignored)522 sh64_ftrv (SIM_CPU *cpu, UINT ignored)
523 {
524   /* TODO: Unimplemented.  */
525 }
526 
527 VOID
sh64_pref(SIM_CPU * cpu,SI addr)528 sh64_pref (SIM_CPU *cpu, SI addr)
529 {
530   /* TODO: Unimplemented.  */
531 }
532 
533 /* Count the number of arguments.  */
534 static int
count_argc(cpu)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 *
fetch_str(current_cpu,pc,addr)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
trap_handler(SIM_CPU * current_cpu,int shmedia_abi_p,UQI trapnum,PCADDR pc)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
sh64_trapa(SIM_CPU * current_cpu,DI rm,PCADDR pc)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
sh64_compact_trapa(SIM_CPU * current_cpu,UQI trapnum,PCADDR pc)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
sh64_nsb(SIM_CPU * current_cpu,DI rm)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
sh64_break(SIM_CPU * current_cpu,PCADDR pc)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
sh64_movua(SIM_CPU * current_cpu,PCADDR pc,SI rn)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
set_isa(SIM_CPU * current_cpu,int mode)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
sim_engine_invalid_insn(SIM_CPU * current_cpu,IADDR cia,SEM_PC vpc)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
sh64_core_signal(SIM_DESC sd,SIM_CPU * current_cpu,sim_cia cia,unsigned int map,int nr_bytes,address_word addr,transfer_type transfer,sim_core_signals sig)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
sh64_compact_model_insn_before(SIM_CPU * cpu,int first_p)788 sh64_compact_model_insn_before (SIM_CPU *cpu, int first_p)
789 {
790   /* Do nothing.  */
791 }
792 
793 void
sh64_media_model_insn_before(SIM_CPU * cpu,int first_p)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
sh64_compact_model_insn_after(SIM_CPU * cpu,int last_p,int cycles)805 sh64_compact_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
806 {
807   /* Do nothing.  */
808 }
809 
810 void
sh64_media_model_insn_after(SIM_CPU * cpu,int last_p,int cycles)811 sh64_media_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
812 {
813   /* Do nothing.  */
814 }
815 
816 int
sh64_fetch_register(SIM_CPU * cpu,int nr,unsigned char * buf,int len)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
sh64_store_register(SIM_CPU * cpu,int nr,unsigned char * buf,int len)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
sh64_engine_run_full(SIM_CPU * cpu)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
sh64_engine_run_fast(SIM_CPU * cpu)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
sh64_prepare_run(SIM_CPU * cpu)986 sh64_prepare_run (SIM_CPU *cpu)
987 {
988   /* Nothing.  */
989 }
990 
991 static const CGEN_INSN *
sh64_get_idata(SIM_CPU * cpu,int inum)992 sh64_get_idata (SIM_CPU *cpu, int inum)
993 {
994   return CPU_IDESC (cpu) [inum].idata;
995 }
996 
997 static void
sh64_init_cpu(SIM_CPU * cpu)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
shmedia_init_cpu(SIM_CPU * cpu)1017 shmedia_init_cpu (SIM_CPU *cpu)
1018 {
1019   sh64_init_cpu (cpu);
1020 }
1021 
1022 static void
shcompact_init_cpu(SIM_CPU * cpu)1023 shcompact_init_cpu (SIM_CPU *cpu)
1024 {
1025   sh64_init_cpu (cpu);
1026 }
1027 
1028 static void
sh64_model_init()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 };
1156