]> Git Repo - binutils.git/blob - gdb/arch/riscv.c
Automatic date update in version.in
[binutils.git] / gdb / arch / riscv.c
1 /* Copyright (C) 2018-2022 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 #include "gdbsupport/common-defs.h"
19 #include "riscv.h"
20 #include <stdlib.h>
21 #include <unordered_map>
22
23 #include "../features/riscv/32bit-cpu.c"
24 #include "../features/riscv/64bit-cpu.c"
25 #include "../features/riscv/32bit-fpu.c"
26 #include "../features/riscv/64bit-fpu.c"
27 #include "../features/riscv/rv32e-xregs.c"
28
29 #ifndef GDBSERVER
30 #define STATIC_IN_GDB static
31 #else
32 #define STATIC_IN_GDB
33 #endif
34
35 /* See arch/riscv.h.  */
36
37 STATIC_IN_GDB target_desc_up
38 riscv_create_target_description (const struct riscv_gdbarch_features features)
39 {
40   /* Now we should create a new target description.  */
41   target_desc_up tdesc = allocate_target_description ();
42
43 #ifndef IN_PROCESS_AGENT
44   std::string arch_name = "riscv";
45
46   if (features.xlen == 4)
47     {
48       if (features.embedded)
49         arch_name.append (":rv32e");
50       else
51         arch_name.append (":rv32i");
52     }
53   else if (features.xlen == 8)
54     arch_name.append (":rv64i");
55   else if (features.xlen == 16)
56     arch_name.append (":rv128i");
57
58   if (features.flen == 4)
59     arch_name.append ("f");
60   else if (features.flen == 8)
61     arch_name.append ("d");
62   else if (features.flen == 16)
63     arch_name.append ("q");
64
65   set_tdesc_architecture (tdesc.get (), arch_name.c_str ());
66 #endif
67
68   long regnum = 0;
69
70   /* For now we only support creating 32-bit or 64-bit x-registers.  */
71   if (features.xlen == 4)
72     {
73       if (features.embedded)
74         regnum = create_feature_riscv_rv32e_xregs (tdesc.get (), regnum);
75       else
76         regnum = create_feature_riscv_32bit_cpu (tdesc.get (), regnum);
77     }
78   else if (features.xlen == 8)
79     regnum = create_feature_riscv_64bit_cpu (tdesc.get (), regnum);
80
81   /* For now we only support creating 32-bit or 64-bit f-registers.  */
82   if (features.flen == 4)
83     regnum = create_feature_riscv_32bit_fpu (tdesc.get (), regnum);
84   else if (features.flen == 8)
85     regnum = create_feature_riscv_64bit_fpu (tdesc.get (), regnum);
86
87   /* Currently GDB only supports vector features coming from remote
88      targets.  We don't support creating vector features on native targets
89      (yet).  */
90   if (features.vlen != 0)
91     error (_("unable to create vector feature"));
92
93   return tdesc;
94 }
95
96 #ifndef GDBSERVER
97
98 /* Wrapper used by std::unordered_map to generate hash for feature set.  */
99 struct riscv_gdbarch_features_hasher
100 {
101   std::size_t
102   operator() (const riscv_gdbarch_features &features) const noexcept
103   {
104     return features.hash ();
105   }
106 };
107
108 /* Cache of previously seen target descriptions, indexed by the feature set
109    that created them.  */
110 static std::unordered_map<riscv_gdbarch_features,
111                           const target_desc_up,
112                           riscv_gdbarch_features_hasher> riscv_tdesc_cache;
113
114 /* See arch/riscv.h.  */
115
116 const target_desc *
117 riscv_lookup_target_description (const struct riscv_gdbarch_features features)
118 {
119   /* Lookup in the cache.  If we find it then return the pointer out of
120      the target_desc_up (which is a unique_ptr).  This is safe as the
121      riscv_tdesc_cache will exist until GDB exits.  */
122   const auto it = riscv_tdesc_cache.find (features);
123   if (it != riscv_tdesc_cache.end ())
124     return it->second.get ();
125
126   target_desc_up tdesc (riscv_create_target_description (features));
127
128   /* Add to the cache, and return a pointer borrowed from the
129      target_desc_up.  This is safe as the cache (and the pointers
130      contained within it) are not deleted until GDB exits.  */
131   target_desc *ptr = tdesc.get ();
132   riscv_tdesc_cache.emplace (features, std::move (tdesc));
133   return ptr;
134 }
135
136 #endif /* !GDBSERVER */
This page took 0.032302 seconds and 4 git commands to generate.