]>
Commit | Line | Data |
---|---|---|
1d506c26 | 1 | /* Copyright (C) 2022-2024 Free Software Foundation, Inc. |
e74d0810 TY |
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 "loongarch.h" | |
20 | #include <stdlib.h> | |
21 | #include <unordered_map> | |
22 | ||
23 | /* Target description features. */ | |
24 | ||
25 | #include "../features/loongarch/base32.c" | |
26 | #include "../features/loongarch/base64.c" | |
657a5022 | 27 | #include "../features/loongarch/fpu.c" |
1e9569f3 HL |
28 | #include "../features/loongarch/lsx.c" |
29 | #include "../features/loongarch/lasx.c" | |
e4d74c01 | 30 | #include "../features/loongarch/lbt.c" |
e74d0810 | 31 | |
e5ab6af5 YT |
32 | #ifndef GDBSERVER |
33 | #define STATIC_IN_GDB static | |
34 | #else | |
35 | #define STATIC_IN_GDB | |
36 | #endif | |
37 | ||
38 | STATIC_IN_GDB target_desc_up | |
e74d0810 TY |
39 | loongarch_create_target_description (const struct loongarch_gdbarch_features features) |
40 | { | |
41 | /* Now we should create a new target description. */ | |
42 | target_desc_up tdesc = allocate_target_description (); | |
43 | ||
44 | std::string arch_name = "loongarch"; | |
45 | ||
46 | if (features.xlen == 4) | |
47 | arch_name.append ("32"); | |
48 | else if (features.xlen == 8) | |
49 | arch_name.append ("64"); | |
50 | ||
657a5022 TY |
51 | if (features.fputype == SINGLE_FLOAT) |
52 | arch_name.append ("f"); | |
53 | else if (features.fputype == DOUBLE_FLOAT) | |
54 | arch_name.append ("d"); | |
55 | ||
e74d0810 TY |
56 | set_tdesc_architecture (tdesc.get (), arch_name.c_str ()); |
57 | ||
58 | long regnum = 0; | |
59 | ||
60 | /* For now we only support creating 32-bit or 64-bit x-registers. */ | |
61 | if (features.xlen == 4) | |
62 | regnum = create_feature_loongarch_base32 (tdesc.get (), regnum); | |
63 | else if (features.xlen == 8) | |
64 | regnum = create_feature_loongarch_base64 (tdesc.get (), regnum); | |
65 | ||
657a5022 TY |
66 | /* For now we only support creating single float and double float. */ |
67 | regnum = create_feature_loongarch_fpu (tdesc.get (), regnum); | |
68 | ||
1e9569f3 HL |
69 | /* For now we only support creating lsx and lasx. */ |
70 | regnum = create_feature_loongarch_lsx (tdesc.get (), regnum); | |
71 | regnum = create_feature_loongarch_lasx (tdesc.get (), regnum); | |
72 | ||
e4d74c01 FC |
73 | /* For now we only support creating scr registers, eflags and ftop. */ |
74 | regnum = create_feature_loongarch_lbt (tdesc.get (), regnum); | |
75 | ||
e74d0810 TY |
76 | return tdesc; |
77 | } | |
78 | ||
e5ab6af5 YT |
79 | #ifndef GDBSERVER |
80 | ||
e74d0810 TY |
81 | /* Wrapper used by std::unordered_map to generate hash for feature set. */ |
82 | struct loongarch_gdbarch_features_hasher | |
83 | { | |
84 | std::size_t | |
85 | operator() (const loongarch_gdbarch_features &features) const noexcept | |
86 | { | |
87 | return features.hash (); | |
88 | } | |
89 | }; | |
90 | ||
91 | /* Cache of previously seen target descriptions, indexed by the feature set | |
92 | that created them. */ | |
93 | static std::unordered_map<loongarch_gdbarch_features, | |
94 | const target_desc_up, | |
95 | loongarch_gdbarch_features_hasher> loongarch_tdesc_cache; | |
96 | ||
97 | const target_desc * | |
98 | loongarch_lookup_target_description (const struct loongarch_gdbarch_features features) | |
99 | { | |
100 | /* Lookup in the cache. If we find it then return the pointer out of | |
101 | the target_desc_up (which is a unique_ptr). This is safe as the | |
102 | loongarch_tdesc_cache will exist until GDB exits. */ | |
103 | const auto it = loongarch_tdesc_cache.find (features); | |
104 | if (it != loongarch_tdesc_cache.end ()) | |
105 | return it->second.get (); | |
106 | ||
107 | target_desc_up tdesc (loongarch_create_target_description (features)); | |
108 | ||
109 | /* Add to the cache, and return a pointer borrowed from the | |
110 | target_desc_up. This is safe as the cache (and the pointers | |
111 | contained within it) are not deleted until GDB exits. */ | |
112 | target_desc *ptr = tdesc.get (); | |
113 | loongarch_tdesc_cache.emplace (features, std::move (tdesc)); | |
114 | return ptr; | |
115 | } | |
e5ab6af5 YT |
116 | |
117 | #endif /* !GDBSERVER */ |