xref: /netbsd/external/gpl3/gdb/dist/sim/sh64/sh64.c (revision 1424dfb3)
166e63ce3Schristos /* SH5 simulator support code
2*1424dfb3Schristos    Copyright (C) 2000-2020 Free Software Foundation, Inc.
366e63ce3Schristos    Contributed by Red Hat, Inc.
466e63ce3Schristos 
566e63ce3Schristos This file is part of the GNU simulators.
666e63ce3Schristos 
766e63ce3Schristos This program is free software; you can redistribute it and/or modify
866e63ce3Schristos it under the terms of the GNU General Public License as published by
966e63ce3Schristos the Free Software Foundation; either version 3 of the License, or
1066e63ce3Schristos (at your option) any later version.
1166e63ce3Schristos 
1266e63ce3Schristos This program is distributed in the hope that it will be useful,
1366e63ce3Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1466e63ce3Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1566e63ce3Schristos GNU General Public License for more details.
1666e63ce3Schristos 
1766e63ce3Schristos You should have received a copy of the GNU General Public License
1866e63ce3Schristos along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
1966e63ce3Schristos 
2066e63ce3Schristos #define WANT_CPU
2166e63ce3Schristos #define WANT_CPU_SH64
2266e63ce3Schristos 
2366e63ce3Schristos #include "sim-main.h"
2466e63ce3Schristos #include "sim-fpu.h"
2566e63ce3Schristos #include "cgen-mem.h"
2666e63ce3Schristos #include "cgen-ops.h"
2766e63ce3Schristos 
2866e63ce3Schristos #include "gdb/callback.h"
2966e63ce3Schristos #include "defs-compact.h"
3066e63ce3Schristos 
3166e63ce3Schristos #include "bfd.h"
3266e63ce3Schristos /* From include/gdb/.  */
3366e63ce3Schristos #include "gdb/sim-sh.h"
3466e63ce3Schristos 
3566e63ce3Schristos #define SYS_exit        1
3666e63ce3Schristos #define	SYS_read	3
3766e63ce3Schristos #define SYS_write       4
3866e63ce3Schristos #define	SYS_open	5
3966e63ce3Schristos #define	SYS_close	6
4066e63ce3Schristos #define	SYS_lseek	19
4166e63ce3Schristos #define	SYS_time	23
4266e63ce3Schristos #define	SYS_argc	172
4366e63ce3Schristos #define	SYS_argnlen	173
4466e63ce3Schristos #define	SYS_argn	174
4566e63ce3Schristos 
4666e63ce3Schristos IDESC * sh64_idesc_media;
4766e63ce3Schristos IDESC * sh64_idesc_compact;
4866e63ce3Schristos 
4966e63ce3Schristos BI
sh64_endian(SIM_CPU * current_cpu)5066e63ce3Schristos sh64_endian (SIM_CPU *current_cpu)
5166e63ce3Schristos {
5266e63ce3Schristos   return (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN);
5366e63ce3Schristos }
5466e63ce3Schristos 
5566e63ce3Schristos SF
sh64_fldi0(SIM_CPU * current_cpu)5666e63ce3Schristos sh64_fldi0 (SIM_CPU *current_cpu)
5766e63ce3Schristos {
5866e63ce3Schristos   SF result;
5966e63ce3Schristos   sim_fpu_to32 (&result, &sim_fpu_zero);
6066e63ce3Schristos   return result;
6166e63ce3Schristos }
6266e63ce3Schristos 
6366e63ce3Schristos SF
sh64_fldi1(SIM_CPU * current_cpu)6466e63ce3Schristos sh64_fldi1 (SIM_CPU *current_cpu)
6566e63ce3Schristos {
6666e63ce3Schristos   SF result;
6766e63ce3Schristos   sim_fpu_to32 (&result, &sim_fpu_one);
6866e63ce3Schristos   return result;
6966e63ce3Schristos }
7066e63ce3Schristos 
7166e63ce3Schristos DF
sh64_fabsd(SIM_CPU * current_cpu,DF drgh)7266e63ce3Schristos sh64_fabsd(SIM_CPU *current_cpu, DF drgh)
7366e63ce3Schristos {
7466e63ce3Schristos   DF result;
7566e63ce3Schristos   sim_fpu f, fres;
7666e63ce3Schristos 
7766e63ce3Schristos   sim_fpu_64to (&f, drgh);
7866e63ce3Schristos   sim_fpu_abs (&fres, &f);
7966e63ce3Schristos   sim_fpu_to64 (&result, &fres);
8066e63ce3Schristos   return result;
8166e63ce3Schristos }
8266e63ce3Schristos 
8366e63ce3Schristos SF
sh64_fabss(SIM_CPU * current_cpu,SF frgh)8466e63ce3Schristos sh64_fabss(SIM_CPU *current_cpu, SF frgh)
8566e63ce3Schristos {
8666e63ce3Schristos   SF result;
8766e63ce3Schristos   sim_fpu f, fres;
8866e63ce3Schristos 
8966e63ce3Schristos   sim_fpu_32to (&f, frgh);
9066e63ce3Schristos   sim_fpu_abs (&fres, &f);
9166e63ce3Schristos   sim_fpu_to32 (&result, &fres);
9266e63ce3Schristos   return result;
9366e63ce3Schristos }
9466e63ce3Schristos 
9566e63ce3Schristos DF
sh64_faddd(SIM_CPU * current_cpu,DF drg,DF drh)9666e63ce3Schristos sh64_faddd(SIM_CPU *current_cpu, DF drg, DF drh)
9766e63ce3Schristos {
9866e63ce3Schristos   DF result;
9966e63ce3Schristos   sim_fpu f1, f2, fres;
10066e63ce3Schristos 
10166e63ce3Schristos   sim_fpu_64to (&f1, drg);
10266e63ce3Schristos   sim_fpu_64to (&f2, drh);
10366e63ce3Schristos   sim_fpu_add (&fres, &f1, &f2);
10466e63ce3Schristos   sim_fpu_to64 (&result, &fres);
10566e63ce3Schristos   return result;
10666e63ce3Schristos }
10766e63ce3Schristos 
10866e63ce3Schristos SF
sh64_fadds(SIM_CPU * current_cpu,SF frg,SF frh)10966e63ce3Schristos sh64_fadds(SIM_CPU *current_cpu, SF frg, SF frh)
11066e63ce3Schristos {
11166e63ce3Schristos   SF result;
11266e63ce3Schristos   sim_fpu f1, f2, fres;
11366e63ce3Schristos 
11466e63ce3Schristos   sim_fpu_32to (&f1, frg);
11566e63ce3Schristos   sim_fpu_32to (&f2, frh);
11666e63ce3Schristos   sim_fpu_add (&fres, &f1, &f2);
11766e63ce3Schristos   sim_fpu_to32 (&result, &fres);
11866e63ce3Schristos   return result;
11966e63ce3Schristos }
12066e63ce3Schristos 
12166e63ce3Schristos BI
sh64_fcmpeqd(SIM_CPU * current_cpu,DF drg,DF drh)12266e63ce3Schristos sh64_fcmpeqd(SIM_CPU *current_cpu, DF drg, DF drh)
12366e63ce3Schristos {
12466e63ce3Schristos   sim_fpu f1, f2;
12566e63ce3Schristos 
12666e63ce3Schristos   sim_fpu_64to (&f1, drg);
12766e63ce3Schristos   sim_fpu_64to (&f2, drh);
12866e63ce3Schristos   return sim_fpu_is_eq (&f1, &f2);
12966e63ce3Schristos }
13066e63ce3Schristos 
13166e63ce3Schristos BI
sh64_fcmpeqs(SIM_CPU * current_cpu,SF frg,SF frh)13266e63ce3Schristos sh64_fcmpeqs(SIM_CPU *current_cpu, SF frg, SF frh)
13366e63ce3Schristos {
13466e63ce3Schristos   sim_fpu f1, f2;
13566e63ce3Schristos 
13666e63ce3Schristos   sim_fpu_32to (&f1, frg);
13766e63ce3Schristos   sim_fpu_32to (&f2, frh);
13866e63ce3Schristos   return sim_fpu_is_eq (&f1, &f2);
13966e63ce3Schristos }
14066e63ce3Schristos 
14166e63ce3Schristos BI
sh64_fcmpged(SIM_CPU * current_cpu,DF drg,DF drh)14266e63ce3Schristos sh64_fcmpged(SIM_CPU *current_cpu, DF drg, DF drh)
14366e63ce3Schristos {
14466e63ce3Schristos   sim_fpu f1, f2;
14566e63ce3Schristos 
14666e63ce3Schristos   sim_fpu_64to (&f1, drg);
14766e63ce3Schristos   sim_fpu_64to (&f2, drh);
14866e63ce3Schristos   return sim_fpu_is_ge (&f1, &f2);
14966e63ce3Schristos }
15066e63ce3Schristos 
15166e63ce3Schristos BI
sh64_fcmpges(SIM_CPU * current_cpu,SF frg,SF frh)15266e63ce3Schristos sh64_fcmpges(SIM_CPU *current_cpu, SF frg, SF frh)
15366e63ce3Schristos {
15466e63ce3Schristos   sim_fpu f1, f2;
15566e63ce3Schristos 
15666e63ce3Schristos   sim_fpu_32to (&f1, frg);
15766e63ce3Schristos   sim_fpu_32to (&f2, frh);
15866e63ce3Schristos   return sim_fpu_is_ge (&f1, &f2);
15966e63ce3Schristos }
16066e63ce3Schristos 
16166e63ce3Schristos BI
sh64_fcmpgtd(SIM_CPU * current_cpu,DF drg,DF drh)16266e63ce3Schristos sh64_fcmpgtd(SIM_CPU *current_cpu, DF drg, DF drh)
16366e63ce3Schristos {
16466e63ce3Schristos   sim_fpu f1, f2;
16566e63ce3Schristos 
16666e63ce3Schristos   sim_fpu_64to (&f1, drg);
16766e63ce3Schristos   sim_fpu_64to (&f2, drh);
16866e63ce3Schristos   return sim_fpu_is_gt (&f1, &f2);
16966e63ce3Schristos }
17066e63ce3Schristos 
17166e63ce3Schristos BI
sh64_fcmpgts(SIM_CPU * current_cpu,SF frg,SF frh)17266e63ce3Schristos sh64_fcmpgts(SIM_CPU *current_cpu, SF frg, SF frh)
17366e63ce3Schristos {
17466e63ce3Schristos   sim_fpu f1, f2;
17566e63ce3Schristos 
17666e63ce3Schristos   sim_fpu_32to (&f1, frg);
17766e63ce3Schristos   sim_fpu_32to (&f2, frh);
17866e63ce3Schristos   return sim_fpu_is_gt (&f1, &f2);
17966e63ce3Schristos }
18066e63ce3Schristos 
18166e63ce3Schristos BI
sh64_fcmpund(SIM_CPU * current_cpu,DF drg,DF drh)18266e63ce3Schristos sh64_fcmpund(SIM_CPU *current_cpu, DF drg, DF drh)
18366e63ce3Schristos {
18466e63ce3Schristos   sim_fpu f1, f2;
18566e63ce3Schristos 
18666e63ce3Schristos   sim_fpu_64to (&f1, drg);
18766e63ce3Schristos   sim_fpu_64to (&f2, drh);
18866e63ce3Schristos   return (sim_fpu_is_nan (&f1) || sim_fpu_is_nan (&f2));
18966e63ce3Schristos }
19066e63ce3Schristos 
19166e63ce3Schristos BI
sh64_fcmpuns(SIM_CPU * current_cpu,SF frg,SF frh)19266e63ce3Schristos sh64_fcmpuns(SIM_CPU *current_cpu, SF frg, SF frh)
19366e63ce3Schristos {
19466e63ce3Schristos   sim_fpu f1, f2;
19566e63ce3Schristos 
19666e63ce3Schristos   sim_fpu_32to (&f1, frg);
19766e63ce3Schristos   sim_fpu_32to (&f2, frh);
19866e63ce3Schristos   return (sim_fpu_is_nan (&f1) || sim_fpu_is_nan (&f2));
19966e63ce3Schristos }
20066e63ce3Schristos 
20166e63ce3Schristos SF
sh64_fcnvds(SIM_CPU * current_cpu,DF drgh)20266e63ce3Schristos sh64_fcnvds(SIM_CPU *current_cpu, DF drgh)
20366e63ce3Schristos {
20466e63ce3Schristos   union {
20566e63ce3Schristos     unsigned long long ll;
20666e63ce3Schristos     double d;
20766e63ce3Schristos   } f1;
20866e63ce3Schristos 
20966e63ce3Schristos   union {
21066e63ce3Schristos     unsigned long l;
21166e63ce3Schristos     float f;
21266e63ce3Schristos   } f2;
21366e63ce3Schristos 
21466e63ce3Schristos   f1.ll = drgh;
21566e63ce3Schristos   f2.f = (float) f1.d;
21666e63ce3Schristos 
21766e63ce3Schristos   return (SF) f2.l;
21866e63ce3Schristos }
21966e63ce3Schristos 
22066e63ce3Schristos DF
sh64_fcnvsd(SIM_CPU * current_cpu,SF frgh)22166e63ce3Schristos sh64_fcnvsd(SIM_CPU *current_cpu, SF frgh)
22266e63ce3Schristos {
22366e63ce3Schristos   DF result;
22466e63ce3Schristos   sim_fpu f;
22566e63ce3Schristos 
22666e63ce3Schristos   sim_fpu_32to (&f, frgh);
22766e63ce3Schristos   sim_fpu_to64 (&result, &f);
22866e63ce3Schristos   return result;
22966e63ce3Schristos }
23066e63ce3Schristos 
23166e63ce3Schristos DF
sh64_fdivd(SIM_CPU * current_cpu,DF drg,DF drh)23266e63ce3Schristos sh64_fdivd(SIM_CPU *current_cpu, DF drg, DF drh)
23366e63ce3Schristos {
23466e63ce3Schristos   DF result;
23566e63ce3Schristos   sim_fpu f1, f2, fres;
23666e63ce3Schristos 
23766e63ce3Schristos   sim_fpu_64to (&f1, drg);
23866e63ce3Schristos   sim_fpu_64to (&f2, drh);
23966e63ce3Schristos   sim_fpu_div (&fres, &f1, &f2);
24066e63ce3Schristos   sim_fpu_to64 (&result, &fres);
24166e63ce3Schristos   return result;
24266e63ce3Schristos }
24366e63ce3Schristos 
24466e63ce3Schristos SF
sh64_fdivs(SIM_CPU * current_cpu,SF frg,SF frh)24566e63ce3Schristos sh64_fdivs(SIM_CPU *current_cpu, SF frg, SF frh)
24666e63ce3Schristos {
24766e63ce3Schristos   SF result;
24866e63ce3Schristos   sim_fpu f1, f2, fres;
24966e63ce3Schristos 
25066e63ce3Schristos   sim_fpu_32to (&f1, frg);
25166e63ce3Schristos   sim_fpu_32to (&f2, frh);
25266e63ce3Schristos   sim_fpu_div (&fres, &f1, &f2);
25366e63ce3Schristos   sim_fpu_to32 (&result, &fres);
25466e63ce3Schristos   return result;
25566e63ce3Schristos }
25666e63ce3Schristos 
25766e63ce3Schristos DF
sh64_floatld(SIM_CPU * current_cpu,SF frgh)25866e63ce3Schristos sh64_floatld(SIM_CPU *current_cpu, SF frgh)
25966e63ce3Schristos {
26066e63ce3Schristos   DF result;
26166e63ce3Schristos   sim_fpu f;
26266e63ce3Schristos 
26366e63ce3Schristos   sim_fpu_i32to (&f, frgh, sim_fpu_round_default);
26466e63ce3Schristos   sim_fpu_to64 (&result, &f);
26566e63ce3Schristos   return result;
26666e63ce3Schristos }
26766e63ce3Schristos 
26866e63ce3Schristos SF
sh64_floatls(SIM_CPU * current_cpu,SF frgh)26966e63ce3Schristos sh64_floatls(SIM_CPU *current_cpu, SF frgh)
27066e63ce3Schristos {
27166e63ce3Schristos   SF result;
27266e63ce3Schristos   sim_fpu f;
27366e63ce3Schristos 
27466e63ce3Schristos   sim_fpu_i32to (&f, frgh, sim_fpu_round_default);
27566e63ce3Schristos   sim_fpu_to32 (&result, &f);
27666e63ce3Schristos   return result;
27766e63ce3Schristos }
27866e63ce3Schristos 
27966e63ce3Schristos DF
sh64_floatqd(SIM_CPU * current_cpu,DF drgh)28066e63ce3Schristos sh64_floatqd(SIM_CPU *current_cpu, DF drgh)
28166e63ce3Schristos {
28266e63ce3Schristos   DF result;
28366e63ce3Schristos   sim_fpu f;
28466e63ce3Schristos 
28566e63ce3Schristos   sim_fpu_i64to (&f, drgh, sim_fpu_round_default);
28666e63ce3Schristos   sim_fpu_to64 (&result, &f);
28766e63ce3Schristos   return result;
28866e63ce3Schristos }
28966e63ce3Schristos 
29066e63ce3Schristos SF
sh64_floatqs(SIM_CPU * current_cpu,DF drgh)29166e63ce3Schristos sh64_floatqs(SIM_CPU *current_cpu, DF drgh)
29266e63ce3Schristos {
29366e63ce3Schristos   SF result;
29466e63ce3Schristos   sim_fpu f;
29566e63ce3Schristos 
29666e63ce3Schristos   sim_fpu_i64to (&f, drgh, sim_fpu_round_default);
29766e63ce3Schristos   sim_fpu_to32 (&result, &f);
29866e63ce3Schristos   return result;
29966e63ce3Schristos }
30066e63ce3Schristos 
30166e63ce3Schristos SF
sh64_fmacs(SIM_CPU * current_cpu,SF fr0,SF frm,SF frn)30266e63ce3Schristos sh64_fmacs(SIM_CPU *current_cpu, SF fr0, SF frm, SF frn)
30366e63ce3Schristos {
30466e63ce3Schristos   SF result;
30566e63ce3Schristos   sim_fpu m1, m2, a1, fres;
30666e63ce3Schristos 
30766e63ce3Schristos   sim_fpu_32to (&m1, fr0);
30866e63ce3Schristos   sim_fpu_32to (&m2, frm);
30966e63ce3Schristos   sim_fpu_32to (&a1, frn);
31066e63ce3Schristos 
31166e63ce3Schristos   sim_fpu_mul (&fres, &m1, &m2);
31266e63ce3Schristos   sim_fpu_add (&fres, &fres, &a1);
31366e63ce3Schristos 
31466e63ce3Schristos   sim_fpu_to32 (&result, &fres);
31566e63ce3Schristos   return result;
31666e63ce3Schristos }
31766e63ce3Schristos 
31866e63ce3Schristos DF
sh64_fmuld(SIM_CPU * current_cpu,DF drg,DF drh)31966e63ce3Schristos sh64_fmuld(SIM_CPU *current_cpu, DF drg, DF drh)
32066e63ce3Schristos {
32166e63ce3Schristos   DF result;
32266e63ce3Schristos   sim_fpu f1, f2, fres;
32366e63ce3Schristos 
32466e63ce3Schristos   sim_fpu_64to (&f1, drg);
32566e63ce3Schristos   sim_fpu_64to (&f2, drh);
32666e63ce3Schristos   sim_fpu_mul (&fres, &f1, &f2);
32766e63ce3Schristos   sim_fpu_to64 (&result, &fres);
32866e63ce3Schristos   return result;
32966e63ce3Schristos }
33066e63ce3Schristos 
33166e63ce3Schristos SF
sh64_fmuls(SIM_CPU * current_cpu,SF frg,SF frh)33266e63ce3Schristos sh64_fmuls(SIM_CPU *current_cpu, SF frg, SF frh)
33366e63ce3Schristos {
33466e63ce3Schristos   SF result;
33566e63ce3Schristos   sim_fpu f1, f2, fres;
33666e63ce3Schristos 
33766e63ce3Schristos   sim_fpu_32to (&f1, frg);
33866e63ce3Schristos   sim_fpu_32to (&f2, frh);
33966e63ce3Schristos   sim_fpu_mul (&fres, &f1, &f2);
34066e63ce3Schristos   sim_fpu_to32 (&result, &fres);
34166e63ce3Schristos   return result;
34266e63ce3Schristos }
34366e63ce3Schristos 
34466e63ce3Schristos DF
sh64_fnegd(SIM_CPU * current_cpu,DF drgh)34566e63ce3Schristos sh64_fnegd(SIM_CPU *current_cpu, DF drgh)
34666e63ce3Schristos {
34766e63ce3Schristos   DF result;
34866e63ce3Schristos   sim_fpu f1, f2;
34966e63ce3Schristos 
35066e63ce3Schristos   sim_fpu_64to (&f1, drgh);
35166e63ce3Schristos   sim_fpu_neg (&f2, &f1);
35266e63ce3Schristos   sim_fpu_to64 (&result, &f2);
35366e63ce3Schristos   return result;
35466e63ce3Schristos }
35566e63ce3Schristos 
35666e63ce3Schristos SF
sh64_fnegs(SIM_CPU * current_cpu,SF frgh)35766e63ce3Schristos sh64_fnegs(SIM_CPU *current_cpu, SF frgh)
35866e63ce3Schristos {
35966e63ce3Schristos   SF result;
36066e63ce3Schristos   sim_fpu f, fres;
36166e63ce3Schristos 
36266e63ce3Schristos   sim_fpu_32to (&f, frgh);
36366e63ce3Schristos   sim_fpu_neg (&fres, &f);
36466e63ce3Schristos   sim_fpu_to32 (&result, &fres);
36566e63ce3Schristos   return result;
36666e63ce3Schristos }
36766e63ce3Schristos 
36866e63ce3Schristos DF
sh64_fsqrtd(SIM_CPU * current_cpu,DF drgh)36966e63ce3Schristos sh64_fsqrtd(SIM_CPU *current_cpu, DF drgh)
37066e63ce3Schristos {
37166e63ce3Schristos   DF result;
37266e63ce3Schristos   sim_fpu f, fres;
37366e63ce3Schristos 
37466e63ce3Schristos   sim_fpu_64to (&f, drgh);
37566e63ce3Schristos   sim_fpu_sqrt (&fres, &f);
37666e63ce3Schristos   sim_fpu_to64 (&result, &fres);
37766e63ce3Schristos   return result;
37866e63ce3Schristos }
37966e63ce3Schristos 
38066e63ce3Schristos SF
sh64_fsqrts(SIM_CPU * current_cpu,SF frgh)38166e63ce3Schristos sh64_fsqrts(SIM_CPU *current_cpu, SF frgh)
38266e63ce3Schristos {
38366e63ce3Schristos   SF result;
38466e63ce3Schristos   sim_fpu f, fres;
38566e63ce3Schristos 
38666e63ce3Schristos   sim_fpu_32to (&f, frgh);
38766e63ce3Schristos   sim_fpu_sqrt (&fres, &f);
38866e63ce3Schristos   sim_fpu_to32 (&result, &fres);
38966e63ce3Schristos   return result;
39066e63ce3Schristos }
39166e63ce3Schristos 
39266e63ce3Schristos DF
sh64_fsubd(SIM_CPU * current_cpu,DF drg,DF drh)39366e63ce3Schristos sh64_fsubd(SIM_CPU *current_cpu, DF drg, DF drh)
39466e63ce3Schristos {
39566e63ce3Schristos   DF result;
39666e63ce3Schristos   sim_fpu f1, f2, fres;
39766e63ce3Schristos 
39866e63ce3Schristos   sim_fpu_64to (&f1, drg);
39966e63ce3Schristos   sim_fpu_64to (&f2, drh);
40066e63ce3Schristos   sim_fpu_sub (&fres, &f1, &f2);
40166e63ce3Schristos   sim_fpu_to64 (&result, &fres);
40266e63ce3Schristos   return result;
40366e63ce3Schristos }
40466e63ce3Schristos 
40566e63ce3Schristos SF
sh64_fsubs(SIM_CPU * current_cpu,SF frg,SF frh)40666e63ce3Schristos sh64_fsubs(SIM_CPU *current_cpu, SF frg, SF frh)
40766e63ce3Schristos {
40866e63ce3Schristos   SF result;
40966e63ce3Schristos   sim_fpu f1, f2, fres;
41066e63ce3Schristos 
41166e63ce3Schristos   sim_fpu_32to (&f1, frg);
41266e63ce3Schristos   sim_fpu_32to (&f2, frh);
41366e63ce3Schristos   sim_fpu_sub (&fres, &f1, &f2);
41466e63ce3Schristos   sim_fpu_to32 (&result, &fres);
41566e63ce3Schristos   return result;
41666e63ce3Schristos }
41766e63ce3Schristos 
41866e63ce3Schristos SF
sh64_ftrcdl(SIM_CPU * current_cpu,DF drgh)41966e63ce3Schristos sh64_ftrcdl(SIM_CPU *current_cpu, DF drgh)
42066e63ce3Schristos {
42166e63ce3Schristos   SI result;
42266e63ce3Schristos   sim_fpu f;
42366e63ce3Schristos 
42466e63ce3Schristos   sim_fpu_64to (&f, drgh);
42566e63ce3Schristos   sim_fpu_to32i (&result, &f, sim_fpu_round_zero);
42666e63ce3Schristos   return (SF) result;
42766e63ce3Schristos }
42866e63ce3Schristos 
42966e63ce3Schristos SF
sh64_ftrcsl(SIM_CPU * current_cpu,SF frgh)43066e63ce3Schristos sh64_ftrcsl(SIM_CPU *current_cpu, SF frgh)
43166e63ce3Schristos {
43266e63ce3Schristos   SI result;
43366e63ce3Schristos   sim_fpu f;
43466e63ce3Schristos 
43566e63ce3Schristos   sim_fpu_32to (&f, frgh);
43666e63ce3Schristos   sim_fpu_to32i (&result, &f, sim_fpu_round_zero);
43766e63ce3Schristos   return (SF) result;
43866e63ce3Schristos }
43966e63ce3Schristos 
44066e63ce3Schristos DF
sh64_ftrcdq(SIM_CPU * current_cpu,DF drgh)44166e63ce3Schristos sh64_ftrcdq(SIM_CPU *current_cpu, DF drgh)
44266e63ce3Schristos {
44366e63ce3Schristos   DI result;
44466e63ce3Schristos   sim_fpu f;
44566e63ce3Schristos 
44666e63ce3Schristos   sim_fpu_64to (&f, drgh);
44766e63ce3Schristos   sim_fpu_to64i (&result, &f, sim_fpu_round_zero);
44866e63ce3Schristos   return (DF) result;
44966e63ce3Schristos }
45066e63ce3Schristos 
45166e63ce3Schristos DF
sh64_ftrcsq(SIM_CPU * current_cpu,SF frgh)45266e63ce3Schristos sh64_ftrcsq(SIM_CPU *current_cpu, SF frgh)
45366e63ce3Schristos {
45466e63ce3Schristos   DI result;
45566e63ce3Schristos   sim_fpu f;
45666e63ce3Schristos 
45766e63ce3Schristos   sim_fpu_32to (&f, frgh);
45866e63ce3Schristos   sim_fpu_to64i (&result, &f, sim_fpu_round_zero);
45966e63ce3Schristos   return (DF) result;
46066e63ce3Schristos }
46166e63ce3Schristos 
46266e63ce3Schristos VOID
sh64_ftrvs(SIM_CPU * cpu,unsigned g,unsigned h,unsigned f)46366e63ce3Schristos sh64_ftrvs(SIM_CPU *cpu, unsigned g, unsigned h, unsigned f)
46466e63ce3Schristos {
46566e63ce3Schristos   int i, j;
46666e63ce3Schristos 
46766e63ce3Schristos   for (i = 0; i < 4; i++)
46866e63ce3Schristos     {
46966e63ce3Schristos       SF result;
47066e63ce3Schristos       sim_fpu sum;
47166e63ce3Schristos       sim_fpu_32to (&sum, 0);
47266e63ce3Schristos 
47366e63ce3Schristos       for (j = 0; j < 4; j++)
47466e63ce3Schristos 	{
47566e63ce3Schristos 	  sim_fpu f1, f2, temp;
47666e63ce3Schristos 	  sim_fpu_32to (&f1, sh64_h_fr_get (cpu, (g + i) + (j * 4)));
47766e63ce3Schristos 	  sim_fpu_32to (&f2, sh64_h_fr_get (cpu, h + j));
47866e63ce3Schristos 	  sim_fpu_mul (&temp, &f1, &f2);
47966e63ce3Schristos 	  sim_fpu_add (&sum, &sum, &temp);
48066e63ce3Schristos 	}
48166e63ce3Schristos       sim_fpu_to32 (&result, &sum);
48266e63ce3Schristos       sh64_h_fr_set (cpu, f + i, result);
48366e63ce3Schristos     }
48466e63ce3Schristos }
48566e63ce3Schristos 
48666e63ce3Schristos VOID
sh64_fipr(SIM_CPU * cpu,unsigned m,unsigned n)48766e63ce3Schristos sh64_fipr (SIM_CPU *cpu, unsigned m, unsigned n)
48866e63ce3Schristos {
48966e63ce3Schristos   SF result = sh64_fmuls (cpu, sh64_h_fvc_get (cpu, m), sh64_h_fvc_get (cpu, n));
49066e63ce3Schristos   result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 1), sh64_h_frc_get (cpu, n + 1)));
49166e63ce3Schristos   result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 2), sh64_h_frc_get (cpu, n + 2)));
49266e63ce3Schristos   result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 3), sh64_h_frc_get (cpu, n + 3)));
49366e63ce3Schristos   sh64_h_frc_set (cpu, n + 3, result);
49466e63ce3Schristos }
49566e63ce3Schristos 
49666e63ce3Schristos SF
sh64_fiprs(SIM_CPU * cpu,unsigned g,unsigned h)49766e63ce3Schristos sh64_fiprs (SIM_CPU *cpu, unsigned g, unsigned h)
49866e63ce3Schristos {
49966e63ce3Schristos   SF temp = sh64_fmuls (cpu, sh64_h_fr_get (cpu, g), sh64_h_fr_get (cpu, h));
50066e63ce3Schristos   temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 1), sh64_h_fr_get (cpu, h + 1)));
50166e63ce3Schristos   temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 2), sh64_h_fr_get (cpu, h + 2)));
50266e63ce3Schristos   temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 3), sh64_h_fr_get (cpu, h + 3)));
50366e63ce3Schristos   return temp;
50466e63ce3Schristos }
50566e63ce3Schristos 
50666e63ce3Schristos VOID
sh64_fldp(SIM_CPU * cpu,PCADDR pc,DI rm,DI rn,unsigned f)50766e63ce3Schristos sh64_fldp (SIM_CPU *cpu, PCADDR pc, DI rm, DI rn, unsigned f)
50866e63ce3Schristos {
50966e63ce3Schristos   sh64_h_fr_set (cpu, f,     GETMEMSF (cpu, pc, rm + rn));
51066e63ce3Schristos   sh64_h_fr_set (cpu, f + 1, GETMEMSF (cpu, pc, rm + rn + 4));
51166e63ce3Schristos }
51266e63ce3Schristos 
51366e63ce3Schristos VOID
sh64_fstp(SIM_CPU * cpu,PCADDR pc,DI rm,DI rn,unsigned f)51466e63ce3Schristos sh64_fstp (SIM_CPU *cpu, PCADDR pc, DI rm, DI rn, unsigned f)
51566e63ce3Schristos {
51666e63ce3Schristos   SETMEMSF (cpu, pc, rm + rn,     sh64_h_fr_get (cpu, f));
51766e63ce3Schristos   SETMEMSF (cpu, pc, rm + rn + 4, sh64_h_fr_get (cpu, f + 1));
51866e63ce3Schristos }
51966e63ce3Schristos 
52066e63ce3Schristos VOID
sh64_ftrv(SIM_CPU * cpu,UINT ignored)52166e63ce3Schristos sh64_ftrv (SIM_CPU *cpu, UINT ignored)
52266e63ce3Schristos {
52366e63ce3Schristos   /* TODO: Unimplemented.  */
52466e63ce3Schristos }
52566e63ce3Schristos 
52666e63ce3Schristos VOID
sh64_pref(SIM_CPU * cpu,SI addr)52766e63ce3Schristos sh64_pref (SIM_CPU *cpu, SI addr)
52866e63ce3Schristos {
52966e63ce3Schristos   /* TODO: Unimplemented.  */
53066e63ce3Schristos }
53166e63ce3Schristos 
53266e63ce3Schristos /* Read a null terminated string from memory, return in a buffer */
53366e63ce3Schristos static char *
fetch_str(current_cpu,pc,addr)53466e63ce3Schristos fetch_str (current_cpu, pc, addr)
53566e63ce3Schristos      SIM_CPU *current_cpu;
53666e63ce3Schristos      PCADDR pc;
53766e63ce3Schristos      DI addr;
53866e63ce3Schristos {
53966e63ce3Schristos   char *buf;
54066e63ce3Schristos   int nr = 0;
54166e63ce3Schristos   while (sim_core_read_1 (current_cpu,
54266e63ce3Schristos 			  pc, read_map, addr + nr) != 0)
54366e63ce3Schristos     nr++;
54466e63ce3Schristos   buf = NZALLOC (char, nr + 1);
54566e63ce3Schristos   sim_read (CPU_STATE (current_cpu), addr, buf, nr);
54666e63ce3Schristos   return buf;
54766e63ce3Schristos }
54866e63ce3Schristos 
54966e63ce3Schristos static void
trap_handler(SIM_CPU * current_cpu,int shmedia_abi_p,UQI trapnum,PCADDR pc)55066e63ce3Schristos trap_handler (SIM_CPU *current_cpu, int shmedia_abi_p, UQI trapnum, PCADDR pc)
55166e63ce3Schristos {
55266e63ce3Schristos   char ch;
55366e63ce3Schristos   switch (trapnum)
55466e63ce3Schristos     {
55566e63ce3Schristos     case 1:
55666e63ce3Schristos       ch = GET_H_GRC (0);
55766e63ce3Schristos       sim_io_write_stdout (CPU_STATE (current_cpu), &ch, 1);
55866e63ce3Schristos       fflush (stdout);
55966e63ce3Schristos       break;
56066e63ce3Schristos     case 2:
56166e63ce3Schristos       sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
56266e63ce3Schristos       break;
56366e63ce3Schristos     case 34:
56466e63ce3Schristos       {
56566e63ce3Schristos 	int i;
56666e63ce3Schristos 	int ret_reg = (shmedia_abi_p) ? 2 : 0;
56766e63ce3Schristos 	char *buf;
56866e63ce3Schristos 	DI PARM1 = GET_H_GR ((shmedia_abi_p) ? 3 : 5);
56966e63ce3Schristos 	DI PARM2 = GET_H_GR ((shmedia_abi_p) ? 4 : 6);
57066e63ce3Schristos 	DI PARM3 = GET_H_GR ((shmedia_abi_p) ? 5 : 7);
57166e63ce3Schristos 
57266e63ce3Schristos 	switch (GET_H_GR ((shmedia_abi_p) ? 2 : 4))
57366e63ce3Schristos 	  {
57466e63ce3Schristos 	  case SYS_write:
57566e63ce3Schristos 	    buf = zalloc (PARM3);
57666e63ce3Schristos 	    sim_read (CPU_STATE (current_cpu), PARM2, buf, PARM3);
57766e63ce3Schristos 	    SET_H_GR (ret_reg,
57866e63ce3Schristos 		      sim_io_write (CPU_STATE (current_cpu),
57966e63ce3Schristos 				    PARM1, buf, PARM3));
58066e63ce3Schristos 	    free (buf);
58166e63ce3Schristos 	    break;
58266e63ce3Schristos 
58366e63ce3Schristos 	  case SYS_lseek:
58466e63ce3Schristos 	    SET_H_GR (ret_reg,
58566e63ce3Schristos 		      sim_io_lseek (CPU_STATE (current_cpu),
58666e63ce3Schristos 				    PARM1, PARM2, PARM3));
58766e63ce3Schristos 	    break;
58866e63ce3Schristos 
58966e63ce3Schristos 	  case SYS_exit:
59066e63ce3Schristos 	    sim_engine_halt (CPU_STATE (current_cpu), current_cpu,
59166e63ce3Schristos 			     NULL, pc, sim_exited, PARM1);
59266e63ce3Schristos 	    break;
59366e63ce3Schristos 
59466e63ce3Schristos 	  case SYS_read:
59566e63ce3Schristos 	    buf = zalloc (PARM3);
59666e63ce3Schristos 	    SET_H_GR (ret_reg,
59766e63ce3Schristos 		      sim_io_read (CPU_STATE (current_cpu),
59866e63ce3Schristos 				   PARM1, buf, PARM3));
59966e63ce3Schristos 	    sim_write (CPU_STATE (current_cpu), PARM2, buf, PARM3);
60066e63ce3Schristos 	    free (buf);
60166e63ce3Schristos 	    break;
60266e63ce3Schristos 
60366e63ce3Schristos 	  case SYS_open:
60466e63ce3Schristos 	    buf = fetch_str (current_cpu, pc, PARM1);
60566e63ce3Schristos 	    SET_H_GR (ret_reg,
60666e63ce3Schristos 		      sim_io_open (CPU_STATE (current_cpu),
60766e63ce3Schristos 				   buf, PARM2));
60866e63ce3Schristos 	    free (buf);
60966e63ce3Schristos 	    break;
61066e63ce3Schristos 
61166e63ce3Schristos 	  case SYS_close:
61266e63ce3Schristos 	    SET_H_GR (ret_reg,
61366e63ce3Schristos 		      sim_io_close (CPU_STATE (current_cpu), PARM1));
61466e63ce3Schristos 	    break;
61566e63ce3Schristos 
61666e63ce3Schristos 	  case SYS_time:
61766e63ce3Schristos 	    SET_H_GR (ret_reg, time (0));
61866e63ce3Schristos 	    break;
61966e63ce3Schristos 
62066e63ce3Schristos 	  case SYS_argc:
621c03b94e9Schristos 	    SET_H_GR (ret_reg, countargv (STATE_PROG_ARGV (CPU_STATE (current_cpu))));
62266e63ce3Schristos 	    break;
62366e63ce3Schristos 
62466e63ce3Schristos 	  case SYS_argnlen:
625c03b94e9Schristos 	    if (PARM1 < countargv (STATE_PROG_ARGV (CPU_STATE (current_cpu))))
62666e63ce3Schristos 	      SET_H_GR (ret_reg,
62766e63ce3Schristos 			strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1]));
62866e63ce3Schristos 	    else
62966e63ce3Schristos 	      SET_H_GR (ret_reg, -1);
63066e63ce3Schristos 	    break;
63166e63ce3Schristos 
63266e63ce3Schristos 	  case SYS_argn:
633c03b94e9Schristos 	    if (PARM1 < countargv (STATE_PROG_ARGV (CPU_STATE (current_cpu))))
63466e63ce3Schristos 	      {
63566e63ce3Schristos 		/* Include the NULL byte.  */
63666e63ce3Schristos 		i = strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1]) + 1;
63766e63ce3Schristos 		sim_write (CPU_STATE (current_cpu),
63866e63ce3Schristos 			   PARM2,
63966e63ce3Schristos 			   STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1],
64066e63ce3Schristos 			   i);
64166e63ce3Schristos 
64266e63ce3Schristos 		/* Just for good measure.  */
64366e63ce3Schristos 		SET_H_GR (ret_reg, i);
64466e63ce3Schristos 		break;
64566e63ce3Schristos 	      }
64666e63ce3Schristos 	    else
64766e63ce3Schristos 	      SET_H_GR (ret_reg, -1);
64866e63ce3Schristos 	    break;
64966e63ce3Schristos 
65066e63ce3Schristos 	  default:
65166e63ce3Schristos 	    SET_H_GR (ret_reg, -1);
65266e63ce3Schristos 	  }
65366e63ce3Schristos       }
65466e63ce3Schristos       break;
65566e63ce3Schristos     case 253:
65666e63ce3Schristos       puts ("pass");
65766e63ce3Schristos       exit (0);
65866e63ce3Schristos     case 254:
65966e63ce3Schristos       puts ("fail");
66066e63ce3Schristos       exit (1);
66166e63ce3Schristos     case 0xc3:
66266e63ce3Schristos       /* fall through.  */
66366e63ce3Schristos     case 255:
66466e63ce3Schristos       sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
66566e63ce3Schristos       break;
66666e63ce3Schristos     }
66766e63ce3Schristos }
66866e63ce3Schristos 
66966e63ce3Schristos void
sh64_trapa(SIM_CPU * current_cpu,DI rm,PCADDR pc)67066e63ce3Schristos sh64_trapa (SIM_CPU *current_cpu, DI rm, PCADDR pc)
67166e63ce3Schristos {
67266e63ce3Schristos   trap_handler (current_cpu, 1, (UQI) rm & 0xff, pc);
67366e63ce3Schristos }
67466e63ce3Schristos 
67566e63ce3Schristos void
sh64_compact_trapa(SIM_CPU * current_cpu,UQI trapnum,PCADDR pc)67666e63ce3Schristos sh64_compact_trapa (SIM_CPU *current_cpu, UQI trapnum, PCADDR pc)
67766e63ce3Schristos {
67866e63ce3Schristos   int mach_sh5_p;
67966e63ce3Schristos 
68066e63ce3Schristos   /* If this is an SH5 executable, this is SHcompact code running in
68166e63ce3Schristos      the SHmedia ABI.  */
68266e63ce3Schristos 
68366e63ce3Schristos   mach_sh5_p =
68466e63ce3Schristos     (bfd_get_mach (STATE_PROG_BFD (CPU_STATE (current_cpu))) == bfd_mach_sh5);
68566e63ce3Schristos 
68666e63ce3Schristos   trap_handler (current_cpu, mach_sh5_p, trapnum, pc);
68766e63ce3Schristos }
68866e63ce3Schristos 
68966e63ce3Schristos DI
sh64_nsb(SIM_CPU * current_cpu,DI rm)69066e63ce3Schristos sh64_nsb (SIM_CPU *current_cpu, DI rm)
69166e63ce3Schristos {
69266e63ce3Schristos   int result = 0, count;
69366e63ce3Schristos   UDI source = (UDI) rm;
69466e63ce3Schristos 
69566e63ce3Schristos   if ((source >> 63))
69666e63ce3Schristos     source = ~source;
69766e63ce3Schristos   source <<= 1;
69866e63ce3Schristos 
69966e63ce3Schristos   for (count = 32; count; count >>= 1)
70066e63ce3Schristos     {
70166e63ce3Schristos       UDI newval = source << count;
70266e63ce3Schristos 
70366e63ce3Schristos       if ((newval >> count) == source)
70466e63ce3Schristos 	{
70566e63ce3Schristos 	  result |= count;
70666e63ce3Schristos 	  source = newval;
70766e63ce3Schristos 	}
70866e63ce3Schristos     }
70966e63ce3Schristos 
71066e63ce3Schristos   return result;
71166e63ce3Schristos }
71266e63ce3Schristos 
71366e63ce3Schristos void
sh64_break(SIM_CPU * current_cpu,PCADDR pc)71466e63ce3Schristos sh64_break (SIM_CPU *current_cpu, PCADDR pc)
71566e63ce3Schristos {
71666e63ce3Schristos   SIM_DESC sd = CPU_STATE (current_cpu);
71766e63ce3Schristos   sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
71866e63ce3Schristos }
71966e63ce3Schristos 
72066e63ce3Schristos SI
sh64_movua(SIM_CPU * current_cpu,PCADDR pc,SI rn)72166e63ce3Schristos sh64_movua (SIM_CPU *current_cpu, PCADDR pc, SI rn)
72266e63ce3Schristos {
72366e63ce3Schristos   SI v;
72466e63ce3Schristos   int i;
72566e63ce3Schristos 
72666e63ce3Schristos   /* Move the data one byte at a time to avoid alignment problems.
72766e63ce3Schristos      Be aware of endianness.  */
72866e63ce3Schristos   v = 0;
72966e63ce3Schristos   for (i = 0; i < 4; ++i)
73066e63ce3Schristos     v = (v << 8) | (GETMEMQI (current_cpu, pc, rn + i) & 0xff);
73166e63ce3Schristos 
73266e63ce3Schristos   v = T2H_4 (v);
73366e63ce3Schristos   return v;
73466e63ce3Schristos }
73566e63ce3Schristos 
73666e63ce3Schristos void
set_isa(SIM_CPU * current_cpu,int mode)73766e63ce3Schristos set_isa (SIM_CPU *current_cpu, int mode)
73866e63ce3Schristos {
73966e63ce3Schristos   /* Do nothing.  */
74066e63ce3Schristos }
74166e63ce3Schristos 
74266e63ce3Schristos /* The semantic code invokes this for invalid (unrecognized) instructions.  */
74366e63ce3Schristos 
74466e63ce3Schristos SEM_PC
sim_engine_invalid_insn(SIM_CPU * current_cpu,IADDR cia,SEM_PC vpc)74566e63ce3Schristos sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
74666e63ce3Schristos {
74766e63ce3Schristos   SIM_DESC sd = CPU_STATE (current_cpu);
74866e63ce3Schristos   sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
74966e63ce3Schristos 
75066e63ce3Schristos   return vpc;
75166e63ce3Schristos }
75266e63ce3Schristos 
75366e63ce3Schristos 
75466e63ce3Schristos /* Process an address exception.  */
75566e63ce3Schristos 
75666e63ce3Schristos 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)75766e63ce3Schristos sh64_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
75866e63ce3Schristos                   unsigned int map, int nr_bytes, address_word addr,
75966e63ce3Schristos                   transfer_type transfer, sim_core_signals sig)
76066e63ce3Schristos {
76166e63ce3Schristos   sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
76266e63ce3Schristos 		   transfer, sig);
76366e63ce3Schristos }
76466e63ce3Schristos 
76566e63ce3Schristos 
76666e63ce3Schristos /* Initialize cycle counting for an insn.
76766e63ce3Schristos    FIRST_P is non-zero if this is the first insn in a set of parallel
76866e63ce3Schristos    insns.  */
76966e63ce3Schristos 
77066e63ce3Schristos void
sh64_compact_model_insn_before(SIM_CPU * cpu,int first_p)77166e63ce3Schristos sh64_compact_model_insn_before (SIM_CPU *cpu, int first_p)
77266e63ce3Schristos {
77366e63ce3Schristos   /* Do nothing.  */
77466e63ce3Schristos }
77566e63ce3Schristos 
77666e63ce3Schristos void
sh64_media_model_insn_before(SIM_CPU * cpu,int first_p)77766e63ce3Schristos sh64_media_model_insn_before (SIM_CPU *cpu, int first_p)
77866e63ce3Schristos {
77966e63ce3Schristos   /* Do nothing.  */
78066e63ce3Schristos }
78166e63ce3Schristos 
78266e63ce3Schristos /* Record the cycles computed for an insn.
78366e63ce3Schristos    LAST_P is non-zero if this is the last insn in a set of parallel insns,
78466e63ce3Schristos    and we update the total cycle count.
78566e63ce3Schristos    CYCLES is the cycle count of the insn.  */
78666e63ce3Schristos 
78766e63ce3Schristos void
sh64_compact_model_insn_after(SIM_CPU * cpu,int last_p,int cycles)78866e63ce3Schristos sh64_compact_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
78966e63ce3Schristos {
79066e63ce3Schristos   /* Do nothing.  */
79166e63ce3Schristos }
79266e63ce3Schristos 
79366e63ce3Schristos void
sh64_media_model_insn_after(SIM_CPU * cpu,int last_p,int cycles)79466e63ce3Schristos sh64_media_model_insn_after(SIM_CPU *cpu, int last_p, int cycles)
79566e63ce3Schristos {
79666e63ce3Schristos   /* Do nothing.  */
79766e63ce3Schristos }
79866e63ce3Schristos 
79966e63ce3Schristos int
sh64_fetch_register(SIM_CPU * cpu,int nr,unsigned char * buf,int len)80066e63ce3Schristos sh64_fetch_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
80166e63ce3Schristos {
80266e63ce3Schristos   /* Fetch general purpose registers. */
80366e63ce3Schristos   if (nr >= SIM_SH64_R0_REGNUM
80466e63ce3Schristos       && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS)
80566e63ce3Schristos       && len == 8)
80666e63ce3Schristos     {
80766e63ce3Schristos       *((unsigned64*) buf) =
80866e63ce3Schristos 	H2T_8 (sh64_h_gr_get (cpu, nr - SIM_SH64_R0_REGNUM));
80966e63ce3Schristos       return len;
81066e63ce3Schristos     }
81166e63ce3Schristos 
81266e63ce3Schristos   /* Fetch PC.  */
81366e63ce3Schristos   if (nr == SIM_SH64_PC_REGNUM && len == 8)
81466e63ce3Schristos     {
81566e63ce3Schristos       *((unsigned64*) buf) = H2T_8 (sh64_h_pc_get (cpu) | sh64_h_ism_get (cpu));
81666e63ce3Schristos       return len;
81766e63ce3Schristos     }
81866e63ce3Schristos 
81966e63ce3Schristos   /* Fetch status register (SR).  */
82066e63ce3Schristos   if (nr == SIM_SH64_SR_REGNUM && len == 8)
82166e63ce3Schristos     {
82266e63ce3Schristos       *((unsigned64*) buf) = H2T_8 (sh64_h_sr_get (cpu));
82366e63ce3Schristos       return len;
82466e63ce3Schristos     }
82566e63ce3Schristos 
82666e63ce3Schristos   /* Fetch saved status register (SSR) and PC (SPC).  */
82766e63ce3Schristos   if ((nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM)
82866e63ce3Schristos       && len == 8)
82966e63ce3Schristos     {
83066e63ce3Schristos       *((unsigned64*) buf) = 0;
83166e63ce3Schristos       return len;
83266e63ce3Schristos     }
83366e63ce3Schristos 
83466e63ce3Schristos   /* Fetch target registers.  */
83566e63ce3Schristos   if (nr >= SIM_SH64_TR0_REGNUM
83666e63ce3Schristos       && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS)
83766e63ce3Schristos       && len == 8)
83866e63ce3Schristos     {
83966e63ce3Schristos       *((unsigned64*) buf) =
84066e63ce3Schristos 	H2T_8 (sh64_h_tr_get (cpu, nr - SIM_SH64_TR0_REGNUM));
84166e63ce3Schristos       return len;
84266e63ce3Schristos     }
84366e63ce3Schristos 
84466e63ce3Schristos   /* Fetch floating point registers.  */
84566e63ce3Schristos   if (nr >= SIM_SH64_FR0_REGNUM
84666e63ce3Schristos       && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS)
84766e63ce3Schristos       && len == 4)
84866e63ce3Schristos     {
84966e63ce3Schristos       *((unsigned32*) buf) =
85066e63ce3Schristos 	H2T_4 (sh64_h_fr_get (cpu, nr - SIM_SH64_FR0_REGNUM));
85166e63ce3Schristos       return len;
85266e63ce3Schristos     }
85366e63ce3Schristos 
85466e63ce3Schristos   /* We should never get here.  */
85566e63ce3Schristos   return 0;
85666e63ce3Schristos }
85766e63ce3Schristos 
85866e63ce3Schristos int
sh64_store_register(SIM_CPU * cpu,int nr,unsigned char * buf,int len)85966e63ce3Schristos sh64_store_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len)
86066e63ce3Schristos {
86166e63ce3Schristos   /* Store general purpose registers. */
86266e63ce3Schristos   if (nr >= SIM_SH64_R0_REGNUM
86366e63ce3Schristos       && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS)
86466e63ce3Schristos       && len == 8)
86566e63ce3Schristos     {
86666e63ce3Schristos       sh64_h_gr_set (cpu, nr - SIM_SH64_R0_REGNUM, T2H_8 (*((unsigned64*)buf)));
86766e63ce3Schristos       return len;
86866e63ce3Schristos     }
86966e63ce3Schristos 
87066e63ce3Schristos   /* Store PC.  */
87166e63ce3Schristos   if (nr == SIM_SH64_PC_REGNUM && len == 8)
87266e63ce3Schristos     {
87366e63ce3Schristos       unsigned64 new_pc = T2H_8 (*((unsigned64*)buf));
87466e63ce3Schristos       sh64_h_pc_set (cpu, new_pc);
87566e63ce3Schristos       return len;
87666e63ce3Schristos     }
87766e63ce3Schristos 
87866e63ce3Schristos   /* Store status register (SR).  */
87966e63ce3Schristos   if (nr == SIM_SH64_SR_REGNUM && len == 8)
88066e63ce3Schristos     {
88166e63ce3Schristos       sh64_h_sr_set (cpu, T2H_8 (*((unsigned64*)buf)));
88266e63ce3Schristos       return len;
88366e63ce3Schristos     }
88466e63ce3Schristos 
88566e63ce3Schristos   /* Store saved status register (SSR) and PC (SPC).  */
88666e63ce3Schristos   if (nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM)
88766e63ce3Schristos     {
88866e63ce3Schristos       /* Do nothing.  */
88966e63ce3Schristos       return len;
89066e63ce3Schristos     }
89166e63ce3Schristos 
89266e63ce3Schristos   /* Store target registers.  */
89366e63ce3Schristos   if (nr >= SIM_SH64_TR0_REGNUM
89466e63ce3Schristos       && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS)
89566e63ce3Schristos       && len == 8)
89666e63ce3Schristos     {
89766e63ce3Schristos       sh64_h_tr_set (cpu, nr - SIM_SH64_TR0_REGNUM, T2H_8 (*((unsigned64*)buf)));
89866e63ce3Schristos       return len;
89966e63ce3Schristos     }
90066e63ce3Schristos 
90166e63ce3Schristos   /* Store floating point registers.  */
90266e63ce3Schristos   if (nr >= SIM_SH64_FR0_REGNUM
90366e63ce3Schristos       && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS)
90466e63ce3Schristos       && len == 4)
90566e63ce3Schristos     {
90666e63ce3Schristos       sh64_h_fr_set (cpu, nr - SIM_SH64_FR0_REGNUM, T2H_4 (*((unsigned32*)buf)));
90766e63ce3Schristos       return len;
90866e63ce3Schristos     }
90966e63ce3Schristos 
91066e63ce3Schristos   /* We should never get here.  */
91166e63ce3Schristos   return 0;
91266e63ce3Schristos }
91366e63ce3Schristos 
91466e63ce3Schristos void
sh64_engine_run_full(SIM_CPU * cpu)91566e63ce3Schristos sh64_engine_run_full(SIM_CPU *cpu)
91666e63ce3Schristos {
91766e63ce3Schristos   if (sh64_h_ism_get (cpu) == ISM_MEDIA)
91866e63ce3Schristos     {
91966e63ce3Schristos       if (!sh64_idesc_media)
92066e63ce3Schristos 	{
92166e63ce3Schristos 	  sh64_media_init_idesc_table (cpu);
92266e63ce3Schristos 	  sh64_idesc_media = CPU_IDESC (cpu);
92366e63ce3Schristos 	}
92466e63ce3Schristos       else
92566e63ce3Schristos 	CPU_IDESC (cpu) = sh64_idesc_media;
92666e63ce3Schristos       sh64_media_engine_run_full (cpu);
92766e63ce3Schristos     }
92866e63ce3Schristos   else
92966e63ce3Schristos     {
93066e63ce3Schristos       if (!sh64_idesc_compact)
93166e63ce3Schristos 	{
93266e63ce3Schristos 	  sh64_compact_init_idesc_table (cpu);
93366e63ce3Schristos 	  sh64_idesc_compact = CPU_IDESC (cpu);
93466e63ce3Schristos 	}
93566e63ce3Schristos       else
93666e63ce3Schristos 	CPU_IDESC (cpu) = sh64_idesc_compact;
93766e63ce3Schristos       sh64_compact_engine_run_full (cpu);
93866e63ce3Schristos     }
93966e63ce3Schristos }
94066e63ce3Schristos 
94166e63ce3Schristos void
sh64_engine_run_fast(SIM_CPU * cpu)94266e63ce3Schristos sh64_engine_run_fast (SIM_CPU *cpu)
94366e63ce3Schristos {
94466e63ce3Schristos   if (sh64_h_ism_get (cpu) == ISM_MEDIA)
94566e63ce3Schristos     {
94666e63ce3Schristos       if (!sh64_idesc_media)
94766e63ce3Schristos 	{
94866e63ce3Schristos 	  sh64_media_init_idesc_table (cpu);
94966e63ce3Schristos 	  sh64_idesc_media = CPU_IDESC (cpu);
95066e63ce3Schristos 	}
95166e63ce3Schristos       else
95266e63ce3Schristos 	CPU_IDESC (cpu) = sh64_idesc_media;
95366e63ce3Schristos       sh64_media_engine_run_fast (cpu);
95466e63ce3Schristos     }
95566e63ce3Schristos   else
95666e63ce3Schristos     {
95766e63ce3Schristos       if (!sh64_idesc_compact)
95866e63ce3Schristos 	{
95966e63ce3Schristos 	  sh64_compact_init_idesc_table (cpu);
96066e63ce3Schristos 	  sh64_idesc_compact = CPU_IDESC (cpu);
96166e63ce3Schristos 	}
96266e63ce3Schristos       else
96366e63ce3Schristos 	CPU_IDESC (cpu) = sh64_idesc_compact;
96466e63ce3Schristos       sh64_compact_engine_run_fast (cpu);
96566e63ce3Schristos     }
96666e63ce3Schristos }
96766e63ce3Schristos 
96866e63ce3Schristos static void
sh64_prepare_run(SIM_CPU * cpu)96966e63ce3Schristos sh64_prepare_run (SIM_CPU *cpu)
97066e63ce3Schristos {
97166e63ce3Schristos   /* Nothing.  */
97266e63ce3Schristos }
97366e63ce3Schristos 
97466e63ce3Schristos static const CGEN_INSN *
sh64_get_idata(SIM_CPU * cpu,int inum)97566e63ce3Schristos sh64_get_idata (SIM_CPU *cpu, int inum)
97666e63ce3Schristos {
97766e63ce3Schristos   return CPU_IDESC (cpu) [inum].idata;
97866e63ce3Schristos }
97966e63ce3Schristos 
98066e63ce3Schristos static void
sh64_init_cpu(SIM_CPU * cpu)98166e63ce3Schristos sh64_init_cpu (SIM_CPU *cpu)
98266e63ce3Schristos {
98366e63ce3Schristos   CPU_REG_FETCH (cpu) = sh64_fetch_register;
98466e63ce3Schristos   CPU_REG_STORE (cpu) = sh64_store_register;
98566e63ce3Schristos   CPU_PC_FETCH (cpu) = sh64_h_pc_get;
98666e63ce3Schristos   CPU_PC_STORE (cpu) = sh64_h_pc_set;
98766e63ce3Schristos   CPU_GET_IDATA (cpu) = sh64_get_idata;
98866e63ce3Schristos   /* Only used by profiling.  0 disables it. */
98966e63ce3Schristos   CPU_MAX_INSNS (cpu) = 0;
99066e63ce3Schristos   CPU_INSN_NAME (cpu) = cgen_insn_name;
99166e63ce3Schristos   CPU_FULL_ENGINE_FN (cpu) = sh64_engine_run_full;
99266e63ce3Schristos #if WITH_FAST
99366e63ce3Schristos   CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_fast;
99466e63ce3Schristos #else
99566e63ce3Schristos   CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_full;
99666e63ce3Schristos #endif
99766e63ce3Schristos }
99866e63ce3Schristos 
99966e63ce3Schristos static void
shmedia_init_cpu(SIM_CPU * cpu)100066e63ce3Schristos shmedia_init_cpu (SIM_CPU *cpu)
100166e63ce3Schristos {
100266e63ce3Schristos   sh64_init_cpu (cpu);
100366e63ce3Schristos }
100466e63ce3Schristos 
100566e63ce3Schristos static void
shcompact_init_cpu(SIM_CPU * cpu)100666e63ce3Schristos shcompact_init_cpu (SIM_CPU *cpu)
100766e63ce3Schristos {
100866e63ce3Schristos   sh64_init_cpu (cpu);
100966e63ce3Schristos }
101066e63ce3Schristos 
101166e63ce3Schristos static void
sh64_model_init()101266e63ce3Schristos sh64_model_init()
101366e63ce3Schristos {
101466e63ce3Schristos   /* Do nothing.  */
101566e63ce3Schristos }
101666e63ce3Schristos 
1017c03b94e9Schristos static const SIM_MODEL sh_models [] =
101866e63ce3Schristos {
101966e63ce3Schristos   { "sh2",        & sh2_mach,         MODEL_SH5, NULL, sh64_model_init },
102066e63ce3Schristos   { "sh2e",       & sh2e_mach,        MODEL_SH5, NULL, sh64_model_init },
102166e63ce3Schristos   { "sh2a",       & sh2a_fpu_mach,    MODEL_SH5, NULL, sh64_model_init },
102266e63ce3Schristos   { "sh2a_nofpu", & sh2a_nofpu_mach,  MODEL_SH5, NULL, sh64_model_init },
102366e63ce3Schristos   { "sh3",        & sh3_mach,         MODEL_SH5, NULL, sh64_model_init },
102466e63ce3Schristos   { "sh3e",       & sh3_mach,         MODEL_SH5, NULL, sh64_model_init },
102566e63ce3Schristos   { "sh4",        & sh4_mach,         MODEL_SH5, NULL, sh64_model_init },
102666e63ce3Schristos   { "sh4_nofpu",  & sh4_nofpu_mach,   MODEL_SH5, NULL, sh64_model_init },
102766e63ce3Schristos   { "sh4a",       & sh4a_mach,        MODEL_SH5, NULL, sh64_model_init },
102866e63ce3Schristos   { "sh4a_nofpu", & sh4a_nofpu_mach,  MODEL_SH5, NULL, sh64_model_init },
102966e63ce3Schristos   { "sh4al",      & sh4al_mach,       MODEL_SH5, NULL, sh64_model_init },
103066e63ce3Schristos   { "sh5",        & sh5_mach,         MODEL_SH5, NULL, sh64_model_init },
103166e63ce3Schristos   { 0 }
103266e63ce3Schristos };
103366e63ce3Schristos 
1034c03b94e9Schristos static const SIM_MACH_IMP_PROPERTIES sh5_imp_properties =
103566e63ce3Schristos {
103666e63ce3Schristos   sizeof (SIM_CPU),
103766e63ce3Schristos #if WITH_SCACHE
103866e63ce3Schristos   sizeof (SCACHE)
103966e63ce3Schristos #else
104066e63ce3Schristos   0
104166e63ce3Schristos #endif
104266e63ce3Schristos };
104366e63ce3Schristos 
1044c03b94e9Schristos const SIM_MACH sh2_mach =
104566e63ce3Schristos {
104666e63ce3Schristos   "sh2", "sh2", MACH_SH5,
104766e63ce3Schristos   16, 16, &sh_models[0], &sh5_imp_properties,
104866e63ce3Schristos   shcompact_init_cpu,
104966e63ce3Schristos   sh64_prepare_run
105066e63ce3Schristos };
105166e63ce3Schristos 
1052c03b94e9Schristos const SIM_MACH sh2e_mach =
105366e63ce3Schristos {
105466e63ce3Schristos   "sh2e", "sh2e", MACH_SH5,
105566e63ce3Schristos   16, 16, &sh_models[1], &sh5_imp_properties,
105666e63ce3Schristos   shcompact_init_cpu,
105766e63ce3Schristos   sh64_prepare_run
105866e63ce3Schristos };
105966e63ce3Schristos 
1060c03b94e9Schristos const SIM_MACH sh2a_fpu_mach =
106166e63ce3Schristos {
106266e63ce3Schristos   "sh2a", "sh2a", MACH_SH5,
106366e63ce3Schristos   16, 16, &sh_models[2], &sh5_imp_properties,
106466e63ce3Schristos   shcompact_init_cpu,
106566e63ce3Schristos   sh64_prepare_run
106666e63ce3Schristos };
106766e63ce3Schristos 
1068c03b94e9Schristos const SIM_MACH sh2a_nofpu_mach =
106966e63ce3Schristos {
107066e63ce3Schristos   "sh2a_nofpu", "sh2a_nofpu", MACH_SH5,
107166e63ce3Schristos   16, 16, &sh_models[3], &sh5_imp_properties,
107266e63ce3Schristos   shcompact_init_cpu,
107366e63ce3Schristos   sh64_prepare_run
107466e63ce3Schristos };
107566e63ce3Schristos 
1076c03b94e9Schristos const SIM_MACH sh3_mach =
107766e63ce3Schristos {
107866e63ce3Schristos   "sh3", "sh3", MACH_SH5,
107966e63ce3Schristos   16, 16, &sh_models[4], &sh5_imp_properties,
108066e63ce3Schristos   shcompact_init_cpu,
108166e63ce3Schristos   sh64_prepare_run
108266e63ce3Schristos };
108366e63ce3Schristos 
1084c03b94e9Schristos const SIM_MACH sh3e_mach =
108566e63ce3Schristos {
108666e63ce3Schristos   "sh3e", "sh3e", MACH_SH5,
108766e63ce3Schristos   16, 16, &sh_models[5], &sh5_imp_properties,
108866e63ce3Schristos   shcompact_init_cpu,
108966e63ce3Schristos   sh64_prepare_run
109066e63ce3Schristos };
109166e63ce3Schristos 
1092c03b94e9Schristos const SIM_MACH sh4_mach =
109366e63ce3Schristos {
109466e63ce3Schristos   "sh4", "sh4", MACH_SH5,
109566e63ce3Schristos   16, 16, &sh_models[6], &sh5_imp_properties,
109666e63ce3Schristos   shcompact_init_cpu,
109766e63ce3Schristos   sh64_prepare_run
109866e63ce3Schristos };
109966e63ce3Schristos 
1100c03b94e9Schristos const SIM_MACH sh4_nofpu_mach =
110166e63ce3Schristos {
110266e63ce3Schristos   "sh4_nofpu", "sh4_nofpu", MACH_SH5,
110366e63ce3Schristos   16, 16, &sh_models[7], &sh5_imp_properties,
110466e63ce3Schristos   shcompact_init_cpu,
110566e63ce3Schristos   sh64_prepare_run
110666e63ce3Schristos };
110766e63ce3Schristos 
1108c03b94e9Schristos const SIM_MACH sh4a_mach =
110966e63ce3Schristos {
111066e63ce3Schristos   "sh4a", "sh4a", MACH_SH5,
111166e63ce3Schristos   16, 16, &sh_models[8], &sh5_imp_properties,
111266e63ce3Schristos   shcompact_init_cpu,
111366e63ce3Schristos   sh64_prepare_run
111466e63ce3Schristos };
111566e63ce3Schristos 
1116c03b94e9Schristos const SIM_MACH sh4a_nofpu_mach =
111766e63ce3Schristos {
111866e63ce3Schristos   "sh4a_nofpu", "sh4a_nofpu", MACH_SH5,
111966e63ce3Schristos   16, 16, &sh_models[9], &sh5_imp_properties,
112066e63ce3Schristos   shcompact_init_cpu,
112166e63ce3Schristos   sh64_prepare_run
112266e63ce3Schristos };
112366e63ce3Schristos 
1124c03b94e9Schristos const SIM_MACH sh4al_mach =
112566e63ce3Schristos {
112666e63ce3Schristos   "sh4al", "sh4al", MACH_SH5,
112766e63ce3Schristos   16, 16, &sh_models[10], &sh5_imp_properties,
112866e63ce3Schristos   shcompact_init_cpu,
112966e63ce3Schristos   sh64_prepare_run
113066e63ce3Schristos };
113166e63ce3Schristos 
1132c03b94e9Schristos const SIM_MACH sh5_mach =
113366e63ce3Schristos {
113466e63ce3Schristos   "sh5", "sh5", MACH_SH5,
113566e63ce3Schristos   32, 32, &sh_models[11], &sh5_imp_properties,
113666e63ce3Schristos   shmedia_init_cpu,
113766e63ce3Schristos   sh64_prepare_run
113866e63ce3Schristos };
1139