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