From patchwork Sat Nov 2 02:56:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 840284 Delivered-To: patch@linaro.org Received: by 2002:adf:a38c:0:b0:37d:45d0:187 with SMTP id l12csp1159347wrb; Fri, 1 Nov 2024 20:01:54 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVeRsGoiqLMno5FR4L69R0FlycY8SCcNrX/e1yMwKxqH5bBEDzVClziMf+suXKZK79hL0gU4w==@linaro.org X-Google-Smtp-Source: AGHT+IG9x3CLlT+ENSlP3H9POt+1tylUQGcbbnD6+52CiGpO7k7jSzREfYxBfUyP1rx2KhZzhkIR X-Received: by 2002:a05:620a:372b:b0:7b1:5143:8da1 with SMTP id af79cd13be357-7b2fb9cc1a1mr829038185a.43.1730516514448; Fri, 01 Nov 2024 20:01:54 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1730516514; cv=pass; d=google.com; s=arc-20240605; b=SuNytOADVtx7aIHcISsWtzD8yLrFAWbN88K104CzwU1aducbPoYlJbuMZsD0DhmR5u TqOXVB+idQ9VOo5VNN2EOyTuxvZ2MIdlAec7OTxAidiw2yNoXZbesEuRNocIKAvkkAfh tYk4HKIRlQ3ePL7IZBS+RQzxdk8Yvd2PQpv9HvWg+d4ZBZcXQfzkL4EQvZMxWIbaTbvk qPD8gA6gwEmGmnOn8Fcrl4Gb58+kG45Vk8AhwQsDrFyZFz1PSNvbTr6TjaM7p+KruEAG ICtdwABjSzns01mGn+rAnxkfhCU47h9OypioiKOiqU/c1jZshPd/yp3UMYSYXPFGxKyo LYvQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=L0bo70u04TZg04dWHACJlBocsK5AtcL51r4yLJmc9gQ=; fh=72kqq0iQhigvR9Vv/oqX5ebs3Yyyw7XhzWxOOEPdupI=; b=knyuiaT2vEV6cV7FyeD81YsVzhUji8FMNlfMn/EPcrVaznqM1sPS/Ex/C0g463/5cV olJuYLThUTmZI6B4abOuIPfO/jd0xg2UwL5OgQglr0uH7U9VYcR4nL/VPH1Mzme69RaA w4PxifP7J2olMt988wtytfamvRTKrbA7LfZGKC9ky15IdDoSgdG6RmgkZSyq3pUbmdwF vzavXskG3G9MjCQ60aX/Jfvr6kCu1fYbYZpCqFOShuHZXN24QneC4hbuOWdJr6D9SFwA 9MQqxnonhtul/BxTuUWcnTY0NtGgAwjmonGBvG+0zciT9eKt97AgCBzZqW9q4kdv5zpc xitw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=n2jHdxzZ; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gdb-patches-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id af79cd13be357-7b2f3a833absi577805385a.368.2024.11.01.20.01.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2024 20:01:54 -0700 (PDT) Received-SPF: pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=n2jHdxzZ; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gdb-patches-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 190CE3858424 for ; Sat, 2 Nov 2024 03:01:54 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id 20EFF3857719 for ; Sat, 2 Nov 2024 02:57:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 20EFF3857719 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 20EFF3857719 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::62d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730516249; cv=none; b=xoVh3iDi6xrXDjrRKbgmHGwLCVqhtcYTrzus3RQUcwiFm8r5yJ55YbJlypwtQpGrKpHOXJ3JCr9O0qMH+lMu9qv/+VOA7m97PerVogMQamShKpFaUKsmkQtm6wyJ7PPtq96amTFM1A5EL3FuqpjwAsgSEaYQ1yfv5ajnP6OqAvM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730516249; c=relaxed/simple; bh=pQgMB/qRyZFNv+Osx1H/xC6w0aIgzWUhishLwuL6crk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=nEkRLyXu00NFEmkI/VdnM6wdlDKXeHKdRdBjvFznYDxcQApAMstjbrQV4yWhfVj5YIPtjmfWq5vKmZPd76rhtNKUoIDdO3sa2VvX5fwEiZ5n/B18Hg2RAi6ucI3NIC7zyAceudtmQ1BTdWXLGN+uSUgTrXBnQ0yH7DQcjVQi1jY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-20c70abba48so23623805ad.0 for ; Fri, 01 Nov 2024 19:57:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1730516240; x=1731121040; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=L0bo70u04TZg04dWHACJlBocsK5AtcL51r4yLJmc9gQ=; b=n2jHdxzZ1KUA7JEOfYcVjTV+31kk63nM71fddD6IY/sLjusMFLU39z8i2Kx8uMij8j eRaPOphDtrcN0Gs5TbeX67ZGSJ29Z6lbgmntWIXRHNyx2vnlnG1YyMLttEtFzxhk5h7o wD10YAEddjp/96l7HafjhnEW9zOqxisRhp3J14GBX4PynNcZxBIO6+qpDsaUJRlKT1+g Po6lJeLP3OtweCoj5MBmXXBbGO1fFh8+Semk+s1Dd0WLSJLMhadzbNeY7Yxkzc9x93sh gZIvBu7X1VGhZTVVY9Sz+kau0q+N+BTKsFC6cDBA0n/xUTwpKqtGnMsfm+lJhxCBZZx2 UGWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730516240; x=1731121040; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=L0bo70u04TZg04dWHACJlBocsK5AtcL51r4yLJmc9gQ=; b=KqRX3Ia18LMTYkccIfqQR7flEFl0GYf58T9aPxkimBPkjQMPctVq4hD9LkmTuckHWN CZWbGg44j9b4es5R9F5nJie1RHsx87a3WRl2jcPsFqkx1xQKSPTlYXpA8aSpb3vJGrEB yCoqt8NL6UKu7J/RcC56KQnKRJxpVhz+38ezn8a88dkbvaNAR0O5256ancfqYSnbFoCj HbohwJQeijvAXkr2jr3CUAVLCPSHOfhj1R+ifS4xjOk/dZrHdgmJ7887succrhckTkKH 6YkHQ7i0QpBjMItY2j1NtrMQ6ug9m/01XW8rSBvUKsRsbgZAl8jwUKSMK3b3xrx/B4/2 EupA== X-Gm-Message-State: AOJu0YwM27Gt+zuSOB6Vtj3a0qwDLWpSV/3rv8jb6HnuM3zVmxyznxrE ZN5DPXn/Wwdjcm2NbirHxVsEbSAbGet8vkPwP+ZCV6tkqtpB4DzmFsNE4Tt4B49DW8KMJYjExDh a X-Received: by 2002:a17:903:2449:b0:20b:6edd:e95a with SMTP id d9443c01a7336-2111af17c6bmr67240685ad.3.1730516239733; Fri, 01 Nov 2024 19:57:19 -0700 (PDT) Received: from localhost ([2804:14d:7e39:8470:f214:b4dc:314a:c1ee]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-211057c1117sm27103745ad.224.2024.11.01.19.57.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2024 19:57:19 -0700 (PDT) From: Thiago Jung Bauermann To: gdb-patches@sourceware.org Subject: [RFC PATCH v4 13/15] GDB, gdbserver: aarch64: Convert SVE feature to use variable-size registers Date: Fri, 1 Nov 2024 23:56:33 -0300 Message-ID: <20241102025635.586759-14-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241102025635.586759-1-thiago.bauermann@linaro.org> References: <20241102025635.586759-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patch=linaro.org@sourceware.org Everything needed to support describing variable-size vector registers in XML is now in place, so convert aarch64 SVE feature to XML. This commit introduces gdb/features/aarch64-sve.xml, and the corresponding aarch64-sve.c is created from it. aarch64_dwarf_reg_to_regnum () is moved to gdb/arch/aarch64.c so that it can be used by gdbserver, and an aarch64 implementation of the recently added regnum_to_dwarf2_reg () gdbarch hook is added. There's a FIXME about using max VQ in aarch64_linux_iterate_over_regset_sections () which I'm still considering how to solve. --- gdb/aarch64-linux-nat.c | 26 ++-- gdb/aarch64-linux-tdep.c | 55 +++++--- gdb/aarch64-tdep.c | 115 ++++++++-------- gdb/aarch64-tdep.h | 21 +-- gdb/arch/aarch64.c | 36 ++++- gdb/arch/aarch64.h | 25 ++-- gdb/features/Makefile | 1 + gdb/features/aarch64-sve.c | 199 +++++++++++++++------------- gdb/features/aarch64-sve.xml | 217 +++++++++++++++++++++++++++++++ gdbserver/configure.srv | 1 + gdbserver/linux-aarch64-low.cc | 6 +- gdbserver/linux-aarch64-tdesc.cc | 17 ++- 12 files changed, 494 insertions(+), 225 deletions(-) create mode 100644 gdb/features/aarch64-sve.xml diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index f1b014b5eb26..5e12a2e403f6 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -586,7 +586,7 @@ aarch64_fetch_registers (struct regcache *regcache, int regno) /* We attempt to fetch SVE registers if there is support for either SVE or SME (due to the SSVE state of SME). */ - if (tdep->has_sve () || tdep->has_sme ()) + if (tdep->has_sve || tdep->has_sme ()) fetch_sveregs_from_thread (regcache); else fetch_fpregs_from_thread (regcache); @@ -610,10 +610,9 @@ aarch64_fetch_registers (struct regcache *regcache, int regno) else if (regno < AARCH64_V0_REGNUM) fetch_gregs_from_thread (regcache); /* SVE register? */ - else if ((tdep->has_sve () || tdep->has_sme ()) - && regno < AARCH64_SVE_VG_REGNUM) + else if ((tdep->has_sve || tdep->has_sme ()) && regno < AARCH64_SVE_VG_REGNUM) fetch_sveregs_from_thread (regcache); - else if (tdep->has_sve () && regno == AARCH64_SVE_VG_REGNUM) + else if (tdep->has_sve && regno == AARCH64_SVE_VG_REGNUM) fetch_sve_vg_from_thread (regcache); /* FPSIMD register? */ else if (regno <= AARCH64_FPCR_REGNUM) @@ -694,7 +693,7 @@ aarch64_store_registers (struct regcache *regcache, int regno) /* We attempt to store SVE registers if there is support for either SVE or SME (due to the SSVE state of SME). */ - if (tdep->has_sve () || tdep->has_sme ()) + if (tdep->has_sve || tdep->has_sme ()) store_sveregs_to_thread (regcache); else store_fpregs_to_thread (regcache); @@ -715,10 +714,9 @@ aarch64_store_registers (struct regcache *regcache, int regno) else if (regno < AARCH64_V0_REGNUM) store_gregs_to_thread (regcache); /* SVE register? */ - else if ((tdep->has_sve () || tdep->has_sme ()) - && regno < AARCH64_SVE_VG_REGNUM) + else if ((tdep->has_sve || tdep->has_sme ()) && regno < AARCH64_SVE_VG_REGNUM) store_sveregs_to_thread (regcache); - else if (tdep->has_sve () && regno == AARCH64_SVE_VG_REGNUM) + else if (tdep->has_sve && regno == AARCH64_SVE_VG_REGNUM) store_sve_vg_to_thread (regcache); /* FPSIMD register? */ else if (regno <= AARCH64_FPCR_REGNUM) @@ -911,7 +909,7 @@ aarch64_linux_nat_target::read_description () /* SVE/SSVE check. Reading VQ may return either the regular vector length or the streaming vector length, depending on whether streaming mode is active or not. */ - features.vq = aarch64_sve_get_vq (tid); + features.sve = aarch64_sve_get_vq (tid) != 0; features.pauth = hwcap & AARCH64_HWCAP_PACA; features.mte = hwcap2 & HWCAP2_MTE; features.tls = aarch64_tls_register_count (tid); @@ -1025,19 +1023,19 @@ aarch64_linux_nat_target::thread_architecture (ptid_t ptid) the tdep. */ aarch64_gdbarch_tdep *tdep = gdbarch_tdep (inf->arch ()); - uint64_t vq = aarch64_sve_get_vq (ptid.lwp ()); + bool sve = aarch64_sve_get_vq (ptid.lwp ()) != 0; uint64_t svq = aarch64_za_get_svq (ptid.lwp ()); - if (vq == tdep->vq && svq == tdep->sme_svq) + if (sve == tdep->has_sve && svq == tdep->sme_svq) return inf->arch (); /* We reach here if any vector length for the thread is different from its value at process start. Lookup gdbarch via info (potentially creating a - new one) by using a target description that corresponds to the new vq/svq - value and the current architecture features. */ + new one) by using a target description that corresponds to the new + vector/matrix state and the current architecture features. */ const struct target_desc *tdesc = gdbarch_target_desc (inf->arch ()); aarch64_features features = aarch64_features_from_target_desc (tdesc); - features.vq = vq; + features.sve = sve; features.svq = svq; /* Check for the SME2 feature. */ diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index c608a84bc711..c04b693f70e7 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -275,7 +275,8 @@ read_aarch64_ctx (CORE_ADDR ctx_addr, enum bfd_endian byte_order, static void aarch64_linux_restore_vregs (struct gdbarch *gdbarch, struct trad_frame_cache *cache, - CORE_ADDR fpsimd_context) + CORE_ADDR fpsimd_context, + ULONGEST vl) { /* WARNING: SIMD state is laid out in memory in target-endian format. @@ -335,7 +336,7 @@ aarch64_linux_restore_vregs (struct gdbarch *gdbarch, num_regs + AARCH64_B0_REGNUM + i, {buf, B_REGISTER_SIZE}); - if (tdep->has_sve ()) + if (tdep->has_sve) trad_frame_set_reg_value_bytes (cache, num_regs + AARCH64_SVE_V0_REGNUM + i, {buf, V_REGISTER_SIZE}); @@ -356,22 +357,22 @@ aarch64_linux_restore_vregs (struct gdbarch *gdbarch, trad_frame_set_reg_addr (cache, num_regs + AARCH64_B0_REGNUM + i, offset); - if (tdep->has_sve ()) + if (tdep->has_sve) trad_frame_set_reg_addr (cache, num_regs + AARCH64_SVE_V0_REGNUM + i, offset); } - if (tdep->has_sve ()) + if (tdep->has_sve) { /* If SVE is supported for this target, zero out the Z registers then copy the first 16 bytes of each of the V registers to the associated Z register. Otherwise the Z registers will contain uninitialized data. */ - std::vector z_buffer (tdep->vq * 16); + std::vector z_buffer (vl); /* We have already handled the endianness swap above, so we don't need to worry about it here. */ - memcpy (z_buffer.data (), buf, V_REGISTER_SIZE); + memcpy (z_buffer.data (), buf, vl); trad_frame_set_reg_value_bytes (cache, AARCH64_SVE_Z0_REGNUM + i, z_buffer); @@ -403,8 +404,8 @@ aarch64_linux_read_signal_frame_info (const frame_info_ptr &this_frame, CORE_ADDR section_end = signal_frame.section_end; uint32_t size, magic; bool extra_found = false; - enum bfd_endian byte_order - = gdbarch_byte_order (get_frame_arch (this_frame)); + struct gdbarch *gdbarch = get_frame_arch (this_frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); while ((magic = read_aarch64_ctx (section, byte_order, &size)) != 0 && size != 0) @@ -423,6 +424,11 @@ aarch64_linux_read_signal_frame_info (const frame_info_ptr &this_frame, /* Check if the section is followed by a full SVE dump, and set sve_regs if it is. */ gdb_byte buf[4]; + aarch64_gdbarch_tdep *tdep + = gdbarch_tdep (gdbarch); + + if (!tdep->has_sve) + break; /* Extract the vector length. */ if (target_read_memory (section + AARCH64_SVE_CONTEXT_VL_OFFSET, @@ -436,6 +442,10 @@ aarch64_linux_read_signal_frame_info (const frame_info_ptr &this_frame, signal_frame.vl = extract_unsigned_integer (buf, 2, byte_order); + if (signal_frame.vl == 0) + error (_ ("Invalid vector length in signal frame %" PRIu64 "."), + signal_frame.vl); + /* Extract the flags to check if we are in streaming mode. */ if (target_read_memory (section + AARCH64_SVE_CONTEXT_FLAGS_OFFSET, @@ -598,7 +608,7 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self, aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* Restore the SVE / FPSIMD registers. */ - if (tdep->has_sve () && signal_frame.sve_section != 0) + if (tdep->has_sve && signal_frame.sve_section != 0) { ULONGEST vq = sve_vq_from_vl (signal_frame.vl); CORE_ADDR sve_regs = signal_frame.sve_section; @@ -648,8 +658,9 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self, fpsimd + AARCH64_FPSIMD_FPCR_OFFSET); /* If there was no SVE section then set up the V registers. */ - if (!tdep->has_sve () || signal_frame.sve_section == 0) - aarch64_linux_restore_vregs (gdbarch, this_cache, fpsimd); + if (!tdep->has_sve || signal_frame.sve_section == 0) + aarch64_linux_restore_vregs (gdbarch, this_cache, fpsimd, + tdep->has_sve ? signal_frame.vl : 0); } /* Restore the SME registers. */ @@ -726,7 +737,7 @@ aarch64_linux_sigframe_prev_arch (const frame_info_ptr &this_frame, const struct target_desc *tdesc = gdbarch_target_desc (get_frame_arch (this_frame)); aarch64_features features = aarch64_features_from_target_desc (tdesc); - features.vq = sve_vq_from_vl (signal_frame.vl); + features.sve = signal_frame.vl != 0; features.svq = (uint8_t) sve_vq_from_vl (signal_frame.svl); struct gdbarch_info info; @@ -1053,9 +1064,12 @@ collect_sve_regset (const struct regset *regset, gdb_byte *header = (gdb_byte *) buf; struct gdbarch *gdbarch = regcache->arch (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - uint64_t vq = tdep->vq; + ULONGEST vg; + // FIXME: Remove this cast. + enum register_status vg_status + = const_cast (regcache)->raw_read (AARCH64_SVE_VG_REGNUM, &vg); + gdb_assert (vg_status == REG_VALID); gdb_assert (buf != NULL); gdb_assert (size > SVE_HEADER_SIZE); @@ -1067,7 +1081,7 @@ collect_sve_regset (const struct regset *regset, store_unsigned_integer (header + SVE_HEADER_MAX_SIZE_OFFSET, SVE_HEADER_MAX_SIZE_LENGTH, byte_order, max_size); store_unsigned_integer (header + SVE_HEADER_VL_OFFSET, SVE_HEADER_VL_LENGTH, - byte_order, sve_vl_from_vq (vq)); + byte_order, sve_vl_from_vg (vg)); uint16_t max_vl = SVE_CORE_DUMMY_MAX_VL; store_unsigned_integer (header + SVE_HEADER_MAX_VL_OFFSET, SVE_HEADER_MAX_VL_LENGTH, byte_order, @@ -1437,14 +1451,15 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, cb (".reg", AARCH64_LINUX_SIZEOF_GREGSET, AARCH64_LINUX_SIZEOF_GREGSET, &aarch64_linux_gregset, NULL, cb_data); - if (tdep->has_sve ()) + if (tdep->has_sve) { /* Create this on the fly in order to handle vector register sizes. */ + // FIXME: Don't use maximum VQ. const struct regcache_map_entry sve_regmap[] = { - { 32, AARCH64_SVE_Z0_REGNUM, (int) (tdep->vq * 16) }, - { 16, AARCH64_SVE_P0_REGNUM, (int) (tdep->vq * 16 / 8) }, - { 1, AARCH64_SVE_FFR_REGNUM, (int) (tdep->vq * 16 / 8) }, + { 32, AARCH64_SVE_Z0_REGNUM, (int)(AARCH64_MAX_SVE_VQ * 16) }, + { 16, AARCH64_SVE_P0_REGNUM, (int)(AARCH64_MAX_SVE_VQ * 16 / 8) }, + { 1, AARCH64_SVE_FFR_REGNUM, (int)(AARCH64_MAX_SVE_VQ * 16 / 8) }, { 1, AARCH64_FPSR_REGNUM, 4 }, { 1, AARCH64_FPCR_REGNUM, 4 }, { 0 } @@ -1627,7 +1642,7 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch, Otherwise the SVE section is considered active. This guarantees we will have the correct target description with the correct SVE vector length. */ - features.vq = aarch64_linux_core_read_vq_from_sections (gdbarch, abfd); + features.sve = aarch64_linux_core_read_vq_from_sections (gdbarch, abfd) != 0; features.pauth = hwcap & AARCH64_HWCAP_PACA; features.mte = hwcap2 & HWCAP2_MTE; diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 04442f22ea3f..ff356b6a0ac7 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -2468,38 +2468,54 @@ aarch64_vnv_type (struct gdbarch *gdbarch) /* Implement the "dwarf2_reg_to_regnum" gdbarch method. */ static int -aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) +aarch64_tdep_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) { + int ret = aarch64_dwarf_reg_to_regnum (reg); + + if (ret != -1) + return ret; + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + if (tdep->has_pauth () && reg == AARCH64_DWARF_RA_SIGN_STATE) + return tdep->ra_sign_state_regnum; - if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30) - return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0; + return -1; +} + +/* Implement the "regnum_to_dwarf2_reg" gdbarch method. */ + +static int +aarch64_regnum_to_dwarf_reg (struct gdbarch *gdbarch, int regnum) +{ + if (regnum >= AARCH64_X0_REGNUM && regnum <= AARCH64_X0_REGNUM + 30) + return AARCH64_DWARF_X0 + regnum - AARCH64_X0_REGNUM; - if (reg == AARCH64_DWARF_SP) - return AARCH64_SP_REGNUM; + if (regnum == AARCH64_SP_REGNUM) + return AARCH64_DWARF_SP; - if (reg == AARCH64_DWARF_PC) - return AARCH64_PC_REGNUM; + if (regnum == AARCH64_PC_REGNUM) + return AARCH64_DWARF_PC; - if (reg >= AARCH64_DWARF_V0 && reg <= AARCH64_DWARF_V0 + 31) - return AARCH64_V0_REGNUM + reg - AARCH64_DWARF_V0; + if (regnum >= AARCH64_V0_REGNUM && regnum <= AARCH64_V0_REGNUM + 31) + return AARCH64_DWARF_V0 + regnum - AARCH64_V0_REGNUM; - if (reg == AARCH64_DWARF_SVE_VG) - return AARCH64_SVE_VG_REGNUM; + if (regnum == AARCH64_SVE_VG_REGNUM) + return AARCH64_DWARF_SVE_VG; - if (reg == AARCH64_DWARF_SVE_FFR) - return AARCH64_SVE_FFR_REGNUM; + if (regnum == AARCH64_SVE_FFR_REGNUM) + return AARCH64_DWARF_SVE_FFR; - if (reg >= AARCH64_DWARF_SVE_P0 && reg <= AARCH64_DWARF_SVE_P0 + 15) - return AARCH64_SVE_P0_REGNUM + reg - AARCH64_DWARF_SVE_P0; + if (regnum >= AARCH64_SVE_P0_REGNUM && regnum <= AARCH64_SVE_P0_REGNUM + 15) + return AARCH64_DWARF_SVE_P0 + regnum - AARCH64_SVE_P0_REGNUM; - if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15) - return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0; + if (regnum >= AARCH64_SVE_Z0_REGNUM && regnum <= AARCH64_SVE_Z0_REGNUM + 15) + return AARCH64_DWARF_SVE_Z0 + regnum - AARCH64_SVE_Z0_REGNUM; + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (tdep->has_pauth ()) { - if (reg == AARCH64_DWARF_RA_SIGN_STATE) - return tdep->ra_sign_state_regnum; + if (regnum == tdep->ra_sign_state_regnum) + return AARCH64_DWARF_RA_SIGN_STATE; } return -1; @@ -2994,7 +3010,7 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) if (is_w_pseudo_register (gdbarch, regnum)) return w_name[regnum - tdep->w_pseudo_base]; - if (tdep->has_sve ()) + if (tdep->has_sve) { static const char *const sve_v_name[] = { @@ -3050,7 +3066,7 @@ aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum) if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32) return aarch64_vnb_type (gdbarch); - if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM + if (tdep->has_sve && p_regnum >= AARCH64_SVE_V0_REGNUM && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) return aarch64_vnv_type (gdbarch); @@ -3090,7 +3106,7 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum, return group == all_reggroup || group == vector_reggroup; else if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32) return group == all_reggroup || group == vector_reggroup; - else if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM + else if (tdep->has_sve && p_regnum >= AARCH64_SVE_V0_REGNUM && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) return group == all_reggroup || group == vector_reggroup; else if (is_sme_pseudo_register (gdbarch, regnum)) @@ -3285,7 +3301,7 @@ aarch64_pseudo_read_value (gdbarch *gdbarch, const frame_info_ptr &next_frame, return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, pseudo_offset - AARCH64_B0_REGNUM); - if (tdep->has_sve () && pseudo_offset >= AARCH64_SVE_V0_REGNUM + if (tdep->has_sve && pseudo_offset >= AARCH64_SVE_V0_REGNUM && pseudo_offset < AARCH64_SVE_V0_REGNUM + 32) return aarch64_pseudo_read_value_1 (next_frame, pseudo_reg_num, pseudo_offset - AARCH64_SVE_V0_REGNUM); @@ -3425,7 +3441,7 @@ aarch64_pseudo_write (gdbarch *gdbarch, const frame_info_ptr &next_frame, return aarch64_pseudo_write_1 (gdbarch, next_frame, pseudo_offset - AARCH64_B0_REGNUM, buf); - if (tdep->has_sve () && pseudo_offset >= AARCH64_SVE_V0_REGNUM + if (tdep->has_sve && pseudo_offset >= AARCH64_SVE_V0_REGNUM && pseudo_offset < AARCH64_SVE_V0_REGNUM + 32) return aarch64_pseudo_write_1 (gdbarch, next_frame, pseudo_offset - AARCH64_SVE_V0_REGNUM, buf); @@ -3941,10 +3957,6 @@ aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch) const target_desc * aarch64_read_description (const aarch64_features &features) { - if (features.vq > AARCH64_MAX_SVE_VQ) - error (_("VQ is %" PRIu64 ", maximum supported value is %d"), features.vq, - AARCH64_MAX_SVE_VQ); - struct target_desc *tdesc = tdesc_aarch64_map[features]; if (tdesc == NULL) @@ -3956,27 +3968,6 @@ aarch64_read_description (const aarch64_features &features) return tdesc; } -/* Return the VQ used when creating the target description TDESC. */ - -static uint64_t -aarch64_get_tdesc_vq (const struct target_desc *tdesc) -{ - const struct tdesc_feature *feature_sve; - - if (!tdesc_has_registers (tdesc)) - return 0; - - feature_sve = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve"); - - if (feature_sve == nullptr) - return 0; - - uint64_t vl = tdesc_register_bitsize (feature_sve, - aarch64_sve_register_names[0]) / 8; - return sve_vq_from_vl (vl); -} - - /* Return the svq (streaming vector quotient) used when creating the target description TDESC. */ @@ -4013,7 +4004,8 @@ aarch64_features_from_target_desc (const struct target_desc *tdesc) if (tdesc == nullptr) return features; - features.vq = aarch64_get_tdesc_vq (tdesc); + features.sve + = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve") != nullptr; /* We need to look for a couple pauth feature name variations. */ features.pauth @@ -4358,13 +4350,11 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int i, num_regs = 0, num_pseudo_regs = 0; int first_pauth_regnum = -1, ra_sign_state_offset = -1; int first_mte_regnum = -1, first_tls_regnum = -1; - uint64_t vq = aarch64_get_tdesc_vq (info.target_desc); + bool has_sve = (info.target_desc == nullptr ? false + : tdesc_find_feature (info.target_desc, + "org.gnu.gdb.aarch64.sve") != nullptr); uint64_t svq = aarch64_get_tdesc_svq (info.target_desc); - if (vq > AARCH64_MAX_SVE_VQ) - internal_error (_("VQ out of bounds: %s (max %d)"), - pulongest (vq), AARCH64_MAX_SVE_VQ); - if (svq > AARCH64_MAX_SVE_VQ) internal_error (_("Streaming vector quotient (svq) out of bounds: %s" " (max %d)"), @@ -4377,18 +4367,17 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { aarch64_gdbarch_tdep *tdep = gdbarch_tdep (best_arch->gdbarch); - if (tdep && tdep->vq == vq && tdep->sme_svq == svq) + if (tdep && tdep->has_sve == has_sve && tdep->sme_svq == svq) return best_arch->gdbarch; } /* Ensure we always have a target descriptor, and that it is for the given VQ value. */ const struct target_desc *tdesc = info.target_desc; - if (!tdesc_has_registers (tdesc) || vq != aarch64_get_tdesc_vq (tdesc) - || svq != aarch64_get_tdesc_svq (tdesc)) + if (!tdesc_has_registers (tdesc)) { aarch64_features features; - features.vq = vq; + features.sve = has_sve; features.svq = svq; tdesc = aarch64_read_description (features); } @@ -4603,7 +4592,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->lowest_pc = 0x20; tdep->jb_pc = -1; /* Longjump support not enabled by default. */ tdep->jb_elt_size = 8; - tdep->vq = vq; + tdep->has_sve = feature_sve != nullptr; tdep->pauth_reg_base = first_pauth_regnum; tdep->pauth_reg_count = pauth_masks; tdep->ra_sign_state_regnum = -1; @@ -4690,7 +4679,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_stack_frame_destroyed_p (gdbarch, aarch64_stack_frame_destroyed_p); /* Internal <-> external register number maps. */ - set_gdbarch_dwarf2_reg_to_regnum (gdbarch, aarch64_dwarf_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, aarch64_tdep_dwarf_reg_to_regnum); + set_gdbarch_regnum_to_dwarf2_reg (gdbarch, aarch64_regnum_to_dwarf_reg); /* Returning results. */ set_gdbarch_return_value_as_value (gdbarch, aarch64_return_value); @@ -4857,6 +4847,9 @@ aarch64_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) gdb_printf (file, _("aarch64_dump_tdep: Lowest pc = 0x%s\n"), paddress (gdbarch, tdep->lowest_pc)); + gdb_printf (file, _ ("aarch64_dump_tdep: has_sve = %s\n"), + tdep->has_sve ? "true" : "false"); + /* SME fields. */ gdb_printf (file, _("aarch64_dump_tdep: sme_tile_type_q = %s\n"), host_address_to_string (tdep->sme_tile_type_q)); diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index 50166fb4f24f..c34027c7f387 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -31,17 +31,6 @@ struct gdbarch; struct regset; -/* AArch64 Dwarf register numbering. */ -#define AARCH64_DWARF_X0 0 -#define AARCH64_DWARF_SP 31 -#define AARCH64_DWARF_PC 32 -#define AARCH64_DWARF_RA_SIGN_STATE 34 -#define AARCH64_DWARF_V0 64 -#define AARCH64_DWARF_SVE_VG 46 -#define AARCH64_DWARF_SVE_FFR 47 -#define AARCH64_DWARF_SVE_P0 48 -#define AARCH64_DWARF_SVE_Z0 96 - /* Size of integer registers. */ #define X_REGISTER_SIZE 8 #define B_REGISTER_SIZE 1 @@ -100,14 +89,8 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep_base int (*aarch64_syscall_record) (struct regcache *regcache, unsigned long svc_number) = nullptr; - /* The VQ value for SVE targets, or zero if SVE is not supported. */ - uint64_t vq = 0; - - /* Returns true if the target supports SVE. */ - bool has_sve () const - { - return vq != 0; - } + /* Whether SVE is supported. */ + bool has_sve = false; int pauth_reg_base = 0; /* Number of pauth masks. */ diff --git a/gdb/arch/aarch64.c b/gdb/arch/aarch64.c index 5526aa1b580b..aa246857a79f 100644 --- a/gdb/arch/aarch64.c +++ b/gdb/arch/aarch64.c @@ -42,10 +42,10 @@ aarch64_create_target_description (const aarch64_features &features) regnum = create_feature_aarch64_core (tdesc.get (), regnum); - if (features.vq == 0) + if (!features.sve) regnum = create_feature_aarch64_fpu (tdesc.get (), regnum); else - regnum = create_feature_aarch64_sve (tdesc.get (), regnum, features.vq); + regnum = create_feature_aarch64_sve (tdesc.get (), regnum); if (features.pauth) regnum = create_feature_aarch64_pauth (tdesc.get (), regnum); @@ -98,3 +98,35 @@ aarch64_mask_from_pac_registers (const CORE_ADDR cmask, const CORE_ADDR dmask) return cmask; } + +/* See arch/aarch64.h. */ + +int +aarch64_dwarf_reg_to_regnum (int reg) +{ + if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30) + return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0; + + if (reg == AARCH64_DWARF_SP) + return AARCH64_SP_REGNUM; + + if (reg == AARCH64_DWARF_PC) + return AARCH64_PC_REGNUM; + + if (reg >= AARCH64_DWARF_V0 && reg <= AARCH64_DWARF_V0 + 31) + return AARCH64_V0_REGNUM + reg - AARCH64_DWARF_V0; + + if (reg == AARCH64_DWARF_SVE_VG) + return AARCH64_SVE_VG_REGNUM; + + if (reg == AARCH64_DWARF_SVE_FFR) + return AARCH64_SVE_FFR_REGNUM; + + if (reg >= AARCH64_DWARF_SVE_P0 && reg <= AARCH64_DWARF_SVE_P0 + 15) + return AARCH64_SVE_P0_REGNUM + reg - AARCH64_DWARF_SVE_P0; + + if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15) + return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0; + + return -1; +} diff --git a/gdb/arch/aarch64.h b/gdb/arch/aarch64.h index b4c0111aeb49..1857fd4802fb 100644 --- a/gdb/arch/aarch64.h +++ b/gdb/arch/aarch64.h @@ -26,12 +26,7 @@ used to select register sets. */ struct aarch64_features { - /* A non zero VQ value indicates both the presence of SVE and the - Vector Quotient - the number of 128-bit chunks in an SVE Z - register. - - The maximum value for VQ is 16 (5 bits). */ - uint64_t vq = 0; + bool sve = false; bool pauth = false; bool mte = false; @@ -55,7 +50,7 @@ struct aarch64_features inline bool operator==(const aarch64_features &lhs, const aarch64_features &rhs) { - return lhs.vq == rhs.vq + return lhs.sve == rhs.sve && lhs.pauth == rhs.pauth && lhs.mte == rhs.mte && lhs.tls == rhs.tls @@ -72,7 +67,7 @@ namespace std { std::size_t h; - h = features.vq; + h = features.sve; h = h << 1 | features.pauth; h = h << 1 | features.mte; /* Shift by two bits for now. We may need to increase this in the future @@ -107,6 +102,9 @@ CORE_ADDR aarch64_remove_top_bits (CORE_ADDR pointer, CORE_ADDR mask); CORE_ADDR aarch64_mask_from_pac_registers (const CORE_ADDR cmask, const CORE_ADDR dmask); +/* Map DWARF reg number to GDB regnum. */ +int aarch64_dwarf_reg_to_regnum (int reg); + /* Register numbers of various important registers. Note that on SVE, the Z registers reuse the V register numbers and the V registers become pseudo registers. */ @@ -136,6 +134,17 @@ enum aarch64_regnum AARCH64_LAST_V_ARG_REGNUM = AARCH64_V0_REGNUM + 7 }; +/* AArch64 Dwarf register numbering. */ +#define AARCH64_DWARF_X0 0 +#define AARCH64_DWARF_SP 31 +#define AARCH64_DWARF_PC 32 +#define AARCH64_DWARF_RA_SIGN_STATE 34 +#define AARCH64_DWARF_V0 64 +#define AARCH64_DWARF_SVE_VG 46 +#define AARCH64_DWARF_SVE_FFR 47 +#define AARCH64_DWARF_SVE_P0 48 +#define AARCH64_DWARF_SVE_Z0 96 + /* Sizes of various AArch64 registers. */ #define AARCH64_TLS_REGISTER_SIZE 8 #define V_REGISTER_SIZE 16 diff --git a/gdb/features/Makefile b/gdb/features/Makefile index 01b327cbce1f..f84debb4f15c 100644 --- a/gdb/features/Makefile +++ b/gdb/features/Makefile @@ -202,6 +202,7 @@ FEATURE_XMLFILES = aarch64-core.xml \ aarch64-fpu.xml \ aarch64-pauth.xml \ aarch64-mte.xml \ + aarch64-sve.xml \ arc/v1-core.xml \ arc/v1-aux.xml \ arc/v2-core.xml \ diff --git a/gdb/features/aarch64-sve.c b/gdb/features/aarch64-sve.c index 67fc801ec70e..1bed5f402376 100644 --- a/gdb/features/aarch64-sve.c +++ b/gdb/features/aarch64-sve.c @@ -1,76 +1,86 @@ -/* Copyright (C) 2018-2024 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: aarch64-sve.xml */ #include "gdbsupport/tdesc.h" - -/* This function is NOT auto generated from xml. Create the aarch64 with SVE - feature into RESULT, where SCALE is the number of 128 bit chunks in a Z - register. */ +#include "dwarf2.h" static int -create_feature_aarch64_sve (struct target_desc *result, long regnum, - uint64_t scale) +create_feature_aarch64_sve (struct target_desc *result, long regnum) { struct tdesc_feature *feature; - tdesc_type *element_type, *field_type; - tdesc_type_with_fields *type_with_fields; feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.sve"); - + tdesc_type *element_type; element_type = tdesc_named_type (feature, "uint128"); - tdesc_create_vector (feature, "svevqu", element_type, scale); + gdb_byte svevq_count_locexpr[5]; + svevq_count_locexpr[0] = DW_OP_bregx; + svevq_count_locexpr[1] = 46; + svevq_count_locexpr[2] = 0; + svevq_count_locexpr[3] = DW_OP_lit2; + svevq_count_locexpr[4] = DW_OP_div; + tdesc_create_vector (feature, "svevqu", element_type, svevq_count_locexpr); element_type = tdesc_named_type (feature, "int128"); - tdesc_create_vector (feature, "svevqs", element_type, scale); + tdesc_create_vector (feature, "svevqs", element_type, svevq_count_locexpr); element_type = tdesc_named_type (feature, "ieee_double"); - tdesc_create_vector (feature, "svevdf", element_type, 2 * scale); + gdb_byte svevd_count_locexpr[3]; + svevd_count_locexpr[0] = DW_OP_bregx; + svevd_count_locexpr[1] = 46; + svevd_count_locexpr[2] = 0; + tdesc_create_vector (feature, "svevdf", element_type, svevd_count_locexpr); element_type = tdesc_named_type (feature, "uint64"); - tdesc_create_vector (feature, "svevdu", element_type, 2 * scale); + tdesc_create_vector (feature, "svevdu", element_type, svevd_count_locexpr); element_type = tdesc_named_type (feature, "int64"); - tdesc_create_vector (feature, "svevds", element_type, 2 * scale); + tdesc_create_vector (feature, "svevds", element_type, svevd_count_locexpr); element_type = tdesc_named_type (feature, "ieee_single"); - tdesc_create_vector (feature, "svevsf", element_type, 4 * scale); + gdb_byte svevs_count_locexpr[5]; + svevs_count_locexpr[0] = DW_OP_bregx; + svevs_count_locexpr[1] = 46; + svevs_count_locexpr[2] = 0; + svevs_count_locexpr[3] = DW_OP_lit2; + svevs_count_locexpr[4] = DW_OP_mul; + tdesc_create_vector (feature, "svevsf", element_type, svevs_count_locexpr); element_type = tdesc_named_type (feature, "uint32"); - tdesc_create_vector (feature, "svevsu", element_type, 4 * scale); + tdesc_create_vector (feature, "svevsu", element_type, svevs_count_locexpr); element_type = tdesc_named_type (feature, "int32"); - tdesc_create_vector (feature, "svevss", element_type, 4 * scale); + tdesc_create_vector (feature, "svevss", element_type, svevs_count_locexpr); element_type = tdesc_named_type (feature, "ieee_half"); - tdesc_create_vector (feature, "svevhf", element_type, 8 * scale); + gdb_byte svevh_count_locexpr[5]; + svevh_count_locexpr[0] = DW_OP_bregx; + svevh_count_locexpr[1] = 46; + svevh_count_locexpr[2] = 0; + svevh_count_locexpr[3] = DW_OP_lit4; + svevh_count_locexpr[4] = DW_OP_mul; + tdesc_create_vector (feature, "svevhf", element_type, svevh_count_locexpr); element_type = tdesc_named_type (feature, "uint16"); - tdesc_create_vector (feature, "svevhu", element_type, 8 * scale); + tdesc_create_vector (feature, "svevhu", element_type, svevh_count_locexpr); element_type = tdesc_named_type (feature, "int16"); - tdesc_create_vector (feature, "svevhs", element_type, 8 * scale); + tdesc_create_vector (feature, "svevhs", element_type, svevh_count_locexpr); element_type = tdesc_named_type (feature, "uint8"); - tdesc_create_vector (feature, "svevbu", element_type, 16 * scale); + gdb_byte svevb_count_locexpr[5]; + svevb_count_locexpr[0] = DW_OP_bregx; + svevb_count_locexpr[1] = 46; + svevb_count_locexpr[2] = 0; + svevb_count_locexpr[3] = DW_OP_lit8; + svevb_count_locexpr[4] = DW_OP_mul; + tdesc_create_vector (feature, "svevbu", element_type, svevb_count_locexpr); element_type = tdesc_named_type (feature, "int8"); - tdesc_create_vector (feature, "svevbs", element_type, 16 * scale); + tdesc_create_vector (feature, "svevbs", element_type, svevb_count_locexpr); + tdesc_type_with_fields *type_with_fields; type_with_fields = tdesc_create_union (feature, "svevnq"); + tdesc_type *field_type; field_type = tdesc_named_type (feature, "svevqu"); tdesc_add_field (type_with_fields, "u", field_type); field_type = tdesc_named_type (feature, "svevqs"); @@ -118,10 +128,15 @@ create_feature_aarch64_sve (struct target_desc *result, long regnum, field_type = tdesc_named_type (feature, "svevnb"); tdesc_add_field (type_with_fields, "b", field_type); - field_type = tdesc_named_type (feature, "uint8"); - tdesc_create_vector (feature, "svep", field_type, 2 * scale); + element_type = tdesc_named_type (feature, "uint8"); + gdb_byte svep_locexpr[5]; + svep_locexpr[0] = DW_OP_bregx; + svep_locexpr[1] = 46; + svep_locexpr[2] = 0; + svep_locexpr[3] = DW_OP_lit4; + svep_locexpr[4] = DW_OP_mul; + tdesc_create_vector (feature, "svep", element_type, svep_locexpr); - /* FPSR register type */ type_with_fields = tdesc_create_flags (feature, "fpsr_flags", 4); tdesc_add_flag (type_with_fields, 0, "IOC"); tdesc_add_flag (type_with_fields, 1, "DZC"); @@ -135,7 +150,6 @@ create_feature_aarch64_sve (struct target_desc *result, long regnum, tdesc_add_flag (type_with_fields, 30, "Z"); tdesc_add_flag (type_with_fields, 31, "N"); - /* FPCR register type */ type_with_fields = tdesc_create_flags (feature, "fpcr_flags", 4); tdesc_add_flag (type_with_fields, 0, "FIZ"); tdesc_add_flag (type_with_fields, 1, "AH"); @@ -155,57 +169,58 @@ create_feature_aarch64_sve (struct target_desc *result, long regnum, tdesc_add_flag (type_with_fields, 25, "DN"); tdesc_add_flag (type_with_fields, 26, "AHP"); - tdesc_create_reg (feature, "z0", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z1", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z2", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z3", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z4", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z5", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z6", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z7", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z8", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z9", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z10", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z11", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z12", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z13", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z14", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z15", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z16", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z17", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z18", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z19", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z20", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z21", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z22", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z23", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z24", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z25", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z26", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z27", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z28", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z29", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z30", regnum++, 1, NULL, 128 * scale, "svev"); - tdesc_create_reg (feature, "z31", regnum++, 1, NULL, 128 * scale, "svev"); + regnum = 34; + tdesc_create_reg (feature, "z0", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z1", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z2", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z3", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z4", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z5", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z6", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z7", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z8", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z9", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z10", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z11", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z12", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z13", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z14", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z15", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z16", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z17", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z18", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z19", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z20", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z21", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z22", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z23", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z24", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z25", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z26", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z27", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z28", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z29", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z30", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); + tdesc_create_reg (feature, "z31", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svev"); tdesc_create_reg (feature, "fpsr", regnum++, 1, NULL, 32, "fpsr_flags"); tdesc_create_reg (feature, "fpcr", regnum++, 1, NULL, 32, "fpcr_flags"); - tdesc_create_reg (feature, "p0", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p1", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p2", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p3", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p4", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p5", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p6", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p7", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p8", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p9", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p10", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p11", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p12", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p13", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p14", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "p15", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "ffr", regnum++, 1, NULL, 16 * scale, "svep"); - tdesc_create_reg (feature, "vg", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "p0", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p1", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p2", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p3", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p4", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p5", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p6", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p7", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p8", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p9", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p10", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p11", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p12", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p13", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p14", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "p15", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "ffr", regnum++, 1, NULL, TDESC_REG_VARIABLE_SIZE, "svep"); + tdesc_create_reg (feature, "vg", regnum++, 1, NULL, 64, "int", true); return regnum; } diff --git a/gdb/features/aarch64-sve.xml b/gdb/features/aarch64-sve.xml new file mode 100644 index 000000000000..b843012b7927 --- /dev/null +++ b/gdb/features/aarch64-sve.xml @@ -0,0 +1,217 @@ + + + + + + aarch64 + + + + + + + 85 + 2 + + + + + + + + + + + + 85 + + + + + + + + + + + + + + + + 85 + 2 + + + + + + + + + + + + + + + + + 85 + 4 + + + + + + + + + + + + + + + + + 85 + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 85 + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index 95359137f4f4..62de58d0c013 100644 --- a/gdbserver/configure.srv +++ b/gdbserver/configure.srv @@ -57,6 +57,7 @@ case "${gdbserver_host}" in srv_tgtobj="${srv_tgtobj} $srv_linux_obj" srv_linux_regsets=yes srv_linux_thread_db=yes + srv_dwarf_reg_to_regnum=yes ipa_obj="linux-aarch64-ipa.o" ipa_obj="${ipa_obj} linux-aarch64-tdesc-ipa.o" ipa_obj="${ipa_obj} arch/aarch64-ipa.o" diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc index 998ad0a9d658..13c891d282ba 100644 --- a/gdbserver/linux-aarch64-low.cc +++ b/gdbserver/linux-aarch64-low.cc @@ -884,11 +884,11 @@ aarch64_adjust_register_sets (const struct aarch64_features &features) break; case NT_FPREGSET: /* This is unavailable when SVE is present. */ - if (features.vq == 0) + if (!features.sve) regset->size = sizeof (struct user_fpsimd_state); break; case NT_ARM_SVE: - if (features.vq > 0) + if (features.sve) regset->size = SVE_PT_SIZE (AARCH64_MAX_SVE_VQ, SVE_PT_REGS_SVE); break; case NT_ARM_PAC_MASK: @@ -938,7 +938,7 @@ aarch64_target::low_arch_setup () struct aarch64_features features; int pid = current_thread->id.pid (); - features.vq = aarch64_sve_get_vq (tid); + features.sve = aarch64_sve_get_vq (tid) != 0; /* A-profile PAC is 64-bit only. */ features.pauth = linux_get_hwcap (pid, 8) & AARCH64_HWCAP_PACA; /* A-profile MTE is 64-bit only. */ diff --git a/gdbserver/linux-aarch64-tdesc.cc b/gdbserver/linux-aarch64-tdesc.cc index 31ec7854cc0b..87f2a484ac32 100644 --- a/gdbserver/linux-aarch64-tdesc.cc +++ b/gdbserver/linux-aarch64-tdesc.cc @@ -37,10 +37,6 @@ aarch64_linux_read_description (const aarch64_features &features) initialised. */ static std::unordered_map tdesc_aarch64_map; - if (features.vq > AARCH64_MAX_SVE_VQ) - error (_("VQ is %" PRIu64 ", maximum supported value is %d"), features.vq, - AARCH64_MAX_SVE_VQ); - if (features.svq > AARCH64_MAX_SVE_VQ) error (_("Streaming svq is %" PRIu8 ", maximum supported value is %d"), features.svq, @@ -60,8 +56,6 @@ aarch64_linux_read_description (const aarch64_features &features) expedited_registers.push_back ("sp"); expedited_registers.push_back ("pc"); - if (features.vq > 0) - expedited_registers.push_back ("vg"); if (features.svq > 0) expedited_registers.push_back ("svg"); @@ -74,3 +68,14 @@ aarch64_linux_read_description (const aarch64_features &features) return tdesc; } + +/* See gdbsupport/tdesc.h. */ + +int +tdesc_dwarf_reg_to_regnum (const char *arch, int dwarf_reg) +{ + if (!strcmp (arch, "aarch64")) + return aarch64_dwarf_reg_to_regnum (dwarf_reg); + + return -1; +}