1*6881a400Schristos /* Copyright (C) 2017-2023 Free Software Foundation, Inc. 27d62b00eSchristos 37d62b00eSchristos This file is part of GDB. 47d62b00eSchristos 57d62b00eSchristos This program is free software; you can redistribute it and/or modify 67d62b00eSchristos it under the terms of the GNU General Public License as published by 77d62b00eSchristos the Free Software Foundation; either version 3 of the License, or 87d62b00eSchristos (at your option) any later version. 97d62b00eSchristos 107d62b00eSchristos This program is distributed in the hope that it will be useful, 117d62b00eSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 127d62b00eSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 137d62b00eSchristos GNU General Public License for more details. 147d62b00eSchristos 157d62b00eSchristos You should have received a copy of the GNU General Public License 167d62b00eSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 177d62b00eSchristos 187d62b00eSchristos 197d62b00eSchristos #include "gdbsupport/common-defs.h" 207d62b00eSchristos #include "arc.h" 217d62b00eSchristos #include <stdlib.h> 227d62b00eSchristos #include <unordered_map> 237d62b00eSchristos #include <string> 247d62b00eSchristos 257d62b00eSchristos /* Target description features. */ 267d62b00eSchristos #include "features/arc/v1-core.c" 277d62b00eSchristos #include "features/arc/v1-aux.c" 287d62b00eSchristos #include "features/arc/v2-core.c" 297d62b00eSchristos #include "features/arc/v2-aux.c" 307d62b00eSchristos 317d62b00eSchristos #ifndef GDBSERVER 327d62b00eSchristos #define STATIC_IN_GDB static 337d62b00eSchristos #else 347d62b00eSchristos #define STATIC_IN_GDB 357d62b00eSchristos #endif 367d62b00eSchristos 37*6881a400Schristos STATIC_IN_GDB target_desc_up 38*6881a400Schristos arc_create_target_description (const struct arc_arch_features &features) 397d62b00eSchristos { 407d62b00eSchristos /* Create a new target description. */ 41*6881a400Schristos target_desc_up tdesc = allocate_target_description (); 427d62b00eSchristos 437d62b00eSchristos #ifndef IN_PROCESS_AGENT 447d62b00eSchristos std::string arch_name; 457d62b00eSchristos 467d62b00eSchristos /* Architecture names here must match the ones in 477d62b00eSchristos ARCH_INFO_STRUCT in bfd/cpu-arc.c. */ 487d62b00eSchristos if (features.isa == ARC_ISA_ARCV1 && features.reg_size == 4) 497d62b00eSchristos arch_name = "arc:ARC700"; 507d62b00eSchristos else if (features.isa == ARC_ISA_ARCV2 && features.reg_size == 4) 517d62b00eSchristos arch_name = "arc:ARCv2"; 527d62b00eSchristos else 537d62b00eSchristos { 547d62b00eSchristos std::string msg = string_printf 557d62b00eSchristos ("Cannot determine architecture: ISA=%d; bitness=%d", 567d62b00eSchristos features.isa, 8 * features.reg_size); 57*6881a400Schristos gdb_assert_not_reached ("%s", msg.c_str ()); 587d62b00eSchristos } 597d62b00eSchristos 60*6881a400Schristos set_tdesc_architecture (tdesc.get (), arch_name.c_str ()); 617d62b00eSchristos #endif 627d62b00eSchristos 637d62b00eSchristos long regnum = 0; 647d62b00eSchristos 657d62b00eSchristos switch (features.isa) 667d62b00eSchristos { 677d62b00eSchristos case ARC_ISA_ARCV1: 68*6881a400Schristos regnum = create_feature_arc_v1_core (tdesc.get (), regnum); 69*6881a400Schristos regnum = create_feature_arc_v1_aux (tdesc.get (), regnum); 707d62b00eSchristos break; 717d62b00eSchristos case ARC_ISA_ARCV2: 72*6881a400Schristos regnum = create_feature_arc_v2_core (tdesc.get (), regnum); 73*6881a400Schristos regnum = create_feature_arc_v2_aux (tdesc.get (), regnum); 747d62b00eSchristos break; 757d62b00eSchristos default: 767d62b00eSchristos std::string msg = string_printf 777d62b00eSchristos ("Cannot choose target description XML: %d", features.isa); 78*6881a400Schristos gdb_assert_not_reached ("%s", msg.c_str ()); 797d62b00eSchristos } 807d62b00eSchristos 817d62b00eSchristos return tdesc; 827d62b00eSchristos } 837d62b00eSchristos 847d62b00eSchristos #ifndef GDBSERVER 857d62b00eSchristos 867d62b00eSchristos /* Wrapper used by std::unordered_map to generate hash for features set. */ 87*6881a400Schristos struct arc_arch_features_hasher 887d62b00eSchristos { 897d62b00eSchristos std::size_t 90*6881a400Schristos operator() (const arc_arch_features &features) const noexcept 917d62b00eSchristos { 927d62b00eSchristos return features.hash (); 937d62b00eSchristos } 947d62b00eSchristos }; 957d62b00eSchristos 967d62b00eSchristos /* Cache of previously created target descriptions, indexed by the hash 977d62b00eSchristos of the features set used to create them. */ 98*6881a400Schristos static std::unordered_map<arc_arch_features, 997d62b00eSchristos const target_desc_up, 100*6881a400Schristos arc_arch_features_hasher> arc_tdesc_cache; 1017d62b00eSchristos 1027d62b00eSchristos /* See arch/arc.h. */ 1037d62b00eSchristos 1047d62b00eSchristos const target_desc * 105*6881a400Schristos arc_lookup_target_description (const struct arc_arch_features &features) 1067d62b00eSchristos { 1077d62b00eSchristos /* Lookup in the cache first. If found, return the pointer from the 1087d62b00eSchristos "target_desc_up" type which is a "unique_ptr". This should be fine 1097d62b00eSchristos as the "arc_tdesc_cache" will persist until GDB terminates. */ 1107d62b00eSchristos const auto it = arc_tdesc_cache.find (features); 1117d62b00eSchristos if (it != arc_tdesc_cache.end ()) 1127d62b00eSchristos return it->second.get (); 1137d62b00eSchristos 114*6881a400Schristos target_desc_up tdesc = arc_create_target_description (features); 1157d62b00eSchristos 1167d62b00eSchristos 117*6881a400Schristos /* Add to the cache, and return a pointer borrowed from the 118*6881a400Schristos target_desc_up. This is safe as the cache (and the pointers 119*6881a400Schristos contained within it) are not deleted until GDB exits. */ 120*6881a400Schristos target_desc *ptr = tdesc.get (); 121*6881a400Schristos arc_tdesc_cache.emplace (features, std::move (tdesc)); 122*6881a400Schristos return ptr; 1237d62b00eSchristos } 1247d62b00eSchristos 1257d62b00eSchristos #endif /* !GDBSERVER */ 126