2018-11-30 Andrew Burgess <andrew.burgess@embecosm.com>
+ * arch/riscv.h (riscv_gdbarch_features::hash): New method.
+ * arch/riscv.c (struct riscv_gdbarch_features_hasher): New.
+ (riscv_tdesc_cache): New global.
+ (riscv_create_target_description): Look in the cache before
+ creating a new target description.
+
+2018-11-30 Andrew Burgess <andrew.burgess@embecosm.com>
+
* arch/riscv.h (riscv_gdb_features::operator==): New.
(riscv_gdb_features::operator!=): New.
* riscv-tdep.c (riscv_gdbarch_init): Make use of the inequality
#include "common-defs.h"
#include "riscv.h"
#include <stdlib.h>
+#include <unordered_map>
#include "../features/riscv/32bit-cpu.c"
#include "../features/riscv/64bit-cpu.c"
#include "../features/riscv/32bit-fpu.c"
#include "../features/riscv/64bit-fpu.c"
+/* Wrapper used by std::unordered_map to generate hash for feature set. */
+struct riscv_gdbarch_features_hasher
+{
+ std::size_t
+ operator() (const riscv_gdbarch_features &features) const noexcept
+ {
+ return features.hash ();
+ }
+};
+
+/* Cache of previously seen target descriptions, indexed by the feature set
+ that created them. */
+static std::unordered_map<riscv_gdbarch_features,
+ target_desc *,
+ riscv_gdbarch_features_hasher> riscv_tdesc_cache;
+
/* See arch/riscv.h. */
const target_desc *
riscv_create_target_description (struct riscv_gdbarch_features features)
{
+ /* Have we seen this feature set before? If we have return the same
+ target description. GDB expects that if two target descriptions are
+ the same (in content terms) then they will actually be the same
+ instance. This is important when trying to lookup gdbarch objects as
+ GDBARCH_LIST_LOOKUP_BY_INFO performs a pointer comparison on target
+ descriptions to find candidate gdbarch objects. */
+ const auto it = riscv_tdesc_cache.find (features);
+ if (it != riscv_tdesc_cache.end ())
+ return it->second;
+
+ /* Now we should create a new target description. */
target_desc *tdesc = allocate_target_description ();
#ifndef IN_PROCESS_AGENT
else if (features.flen == 8)
regnum = create_feature_riscv_64bit_fpu (tdesc, regnum);
+ /* Add to the cache. */
+ riscv_tdesc_cache.emplace (features, tdesc);
+
return tdesc;
}
{
return !((*this) == rhs);
}
+
+ /* Used by std::unordered_map to hash feature sets. */
+ std::size_t hash () const noexcept
+ {
+ std::size_t val = ((xlen & 0x1f) << 6
+ | (flen & 0x1f) << 1
+ | (hw_float_abi ? 1 : 0));
+ return val;
+ }
};
/* Create and return a target description that is compatible with