1*56bb7041Schristos /* Copyright (C) 2017-2020 Free Software Foundation, Inc.
2*56bb7041Schristos
3*56bb7041Schristos This file is part of GDB.
4*56bb7041Schristos
5*56bb7041Schristos This program is free software; you can redistribute it and/or modify
6*56bb7041Schristos it under the terms of the GNU General Public License as published by
7*56bb7041Schristos the Free Software Foundation; either version 3 of the License, or
8*56bb7041Schristos (at your option) any later version.
9*56bb7041Schristos
10*56bb7041Schristos This program is distributed in the hope that it will be useful,
11*56bb7041Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
12*56bb7041Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*56bb7041Schristos GNU General Public License for more details.
14*56bb7041Schristos
15*56bb7041Schristos You should have received a copy of the GNU General Public License
16*56bb7041Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */
17*56bb7041Schristos
18*56bb7041Schristos
19*56bb7041Schristos #include "gdbsupport/common-defs.h"
20*56bb7041Schristos #include "arc.h"
21*56bb7041Schristos #include <stdlib.h>
22*56bb7041Schristos #include <unordered_map>
23*56bb7041Schristos #include <string>
24*56bb7041Schristos
25*56bb7041Schristos /* Target description features. */
26*56bb7041Schristos #include "features/arc/v1-core.c"
27*56bb7041Schristos #include "features/arc/v1-aux.c"
28*56bb7041Schristos #include "features/arc/v2-core.c"
29*56bb7041Schristos #include "features/arc/v2-aux.c"
30*56bb7041Schristos
31*56bb7041Schristos #ifndef GDBSERVER
32*56bb7041Schristos #define STATIC_IN_GDB static
33*56bb7041Schristos #else
34*56bb7041Schristos #define STATIC_IN_GDB
35*56bb7041Schristos #endif
36*56bb7041Schristos
37*56bb7041Schristos STATIC_IN_GDB target_desc *
arc_create_target_description(const struct arc_gdbarch_features & features)38*56bb7041Schristos arc_create_target_description (const struct arc_gdbarch_features &features)
39*56bb7041Schristos {
40*56bb7041Schristos /* Create a new target description. */
41*56bb7041Schristos target_desc *tdesc = allocate_target_description ();
42*56bb7041Schristos
43*56bb7041Schristos #ifndef IN_PROCESS_AGENT
44*56bb7041Schristos std::string arch_name;
45*56bb7041Schristos
46*56bb7041Schristos /* Architecture names here must match the ones in
47*56bb7041Schristos ARCH_INFO_STRUCT in bfd/cpu-arc.c. */
48*56bb7041Schristos if (features.isa == ARC_ISA_ARCV1 && features.reg_size == 4)
49*56bb7041Schristos arch_name = "arc:ARC700";
50*56bb7041Schristos else if (features.isa == ARC_ISA_ARCV2 && features.reg_size == 4)
51*56bb7041Schristos arch_name = "arc:ARCv2";
52*56bb7041Schristos else
53*56bb7041Schristos {
54*56bb7041Schristos std::string msg = string_printf
55*56bb7041Schristos ("Cannot determine architecture: ISA=%d; bitness=%d",
56*56bb7041Schristos features.isa, 8 * features.reg_size);
57*56bb7041Schristos gdb_assert_not_reached (msg.c_str ());
58*56bb7041Schristos }
59*56bb7041Schristos
60*56bb7041Schristos set_tdesc_architecture (tdesc, arch_name.c_str ());
61*56bb7041Schristos #endif
62*56bb7041Schristos
63*56bb7041Schristos long regnum = 0;
64*56bb7041Schristos
65*56bb7041Schristos switch (features.isa)
66*56bb7041Schristos {
67*56bb7041Schristos case ARC_ISA_ARCV1:
68*56bb7041Schristos regnum = create_feature_arc_v1_core (tdesc, regnum);
69*56bb7041Schristos regnum = create_feature_arc_v1_aux (tdesc, regnum);
70*56bb7041Schristos break;
71*56bb7041Schristos case ARC_ISA_ARCV2:
72*56bb7041Schristos regnum = create_feature_arc_v2_core (tdesc, regnum);
73*56bb7041Schristos regnum = create_feature_arc_v2_aux (tdesc, regnum);
74*56bb7041Schristos break;
75*56bb7041Schristos default:
76*56bb7041Schristos std::string msg = string_printf
77*56bb7041Schristos ("Cannot choose target description XML: %d", features.isa);
78*56bb7041Schristos gdb_assert_not_reached (msg.c_str ());
79*56bb7041Schristos }
80*56bb7041Schristos
81*56bb7041Schristos return tdesc;
82*56bb7041Schristos }
83*56bb7041Schristos
84*56bb7041Schristos #ifndef GDBSERVER
85*56bb7041Schristos
86*56bb7041Schristos /* Wrapper used by std::unordered_map to generate hash for features set. */
87*56bb7041Schristos struct arc_gdbarch_features_hasher
88*56bb7041Schristos {
89*56bb7041Schristos std::size_t
operatorarc_gdbarch_features_hasher90*56bb7041Schristos operator() (const arc_gdbarch_features &features) const noexcept
91*56bb7041Schristos {
92*56bb7041Schristos return features.hash ();
93*56bb7041Schristos }
94*56bb7041Schristos };
95*56bb7041Schristos
96*56bb7041Schristos /* Cache of previously created target descriptions, indexed by the hash
97*56bb7041Schristos of the features set used to create them. */
98*56bb7041Schristos static std::unordered_map<arc_gdbarch_features,
99*56bb7041Schristos const target_desc_up,
100*56bb7041Schristos arc_gdbarch_features_hasher> arc_tdesc_cache;
101*56bb7041Schristos
102*56bb7041Schristos /* See arch/arc.h. */
103*56bb7041Schristos
104*56bb7041Schristos const target_desc *
arc_lookup_target_description(const struct arc_gdbarch_features & features)105*56bb7041Schristos arc_lookup_target_description (const struct arc_gdbarch_features &features)
106*56bb7041Schristos {
107*56bb7041Schristos /* Lookup in the cache first. If found, return the pointer from the
108*56bb7041Schristos "target_desc_up" type which is a "unique_ptr". This should be fine
109*56bb7041Schristos as the "arc_tdesc_cache" will persist until GDB terminates. */
110*56bb7041Schristos const auto it = arc_tdesc_cache.find (features);
111*56bb7041Schristos if (it != arc_tdesc_cache.end ())
112*56bb7041Schristos return it->second.get ();
113*56bb7041Schristos
114*56bb7041Schristos target_desc *tdesc = arc_create_target_description (features);
115*56bb7041Schristos
116*56bb7041Schristos /* Add the newly created target description to the repertoire. */
117*56bb7041Schristos arc_tdesc_cache.emplace (features, tdesc);
118*56bb7041Schristos
119*56bb7041Schristos return tdesc;
120*56bb7041Schristos }
121*56bb7041Schristos
122*56bb7041Schristos #endif /* !GDBSERVER */
123