1 /* Copyright (C) 2018-2023 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 */ 137