From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id UKscJq7r6GIT+x4AWB0awg (envelope-from ) for ; Tue, 02 Aug 2022 05:17:34 -0400 Received: by simark.ca (Postfix, from userid 112) id 8C0AE1EA05; Tue, 2 Aug 2022 05:17:34 -0400 (EDT) Authentication-Results: simark.ca; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=UhdYWbN8; dkim-atps=neutral X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RDNS_DYNAMIC,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id E749D1E9EB for ; Tue, 2 Aug 2022 05:17:29 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2C0FD3856DEE for ; Tue, 2 Aug 2022 09:17:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2C0FD3856DEE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1659431849; bh=MD0S3pETDo0uCgBHZ/X/bN+1PtBTSzucT94ZWJ+6xws=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=UhdYWbN86IQB/62BOZ7o0gRTps96jleZnDGWuRsudYsMnG6LV38GnOMd/5HOcZxic G8I5nKWhW2lieXvBxIqq4RC7mGm4Mwzp/8HSU9kt4DTFGZowPHdDpqzhOE6UFaO9rW xI+xtVw5KtFg/zudFUglG4/GC0pVeE04kbPns8IU= Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by sourceware.org (Postfix) with ESMTPS id 492C53857C7A for ; Tue, 2 Aug 2022 09:17:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 492C53857C7A Received: by mail-pj1-x1036.google.com with SMTP id h21-20020a17090aa89500b001f31a61b91dso15017633pjq.4 for ; Tue, 02 Aug 2022 02:17:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc; bh=MD0S3pETDo0uCgBHZ/X/bN+1PtBTSzucT94ZWJ+6xws=; b=7MGAPxD34RSdCJ9BiTvB+cACdqoyMoKjByWie6JWLuIEFJmQOYSiVGiOnBxhnrEyOj w2n3wU2yiWlPiVS6685VSd2TkKPMuSdClXAaruiPeuvJAjY8d8A2cl4M5TwhPHTZeHPH X2I5nNQadbGiZCByU3lDt4cF6BNdkwgDfjk4ZfKwmMdItgp3Nf8+rvQg8ztXFE1YY+tU T7v3TbjRfzCE8Dg7px2xPn4wMAS2NmBZL+4Iy5lzrrTeQZ2KiCT2WdTXQGreh7ZWQi4r +7penWTQd1QzWYVcYXMMB7EB45UpeKtOoST7xt0dVxr+dQ6n/1UacoKXpOQe737vz9GJ AIXw== X-Gm-Message-State: ACgBeo3DGrww36mi1xKmpuI2gACYZKZMrdmVqvfF4+kvKY6V4I25NIYi oRUln8RBSQZImq/SIY7kUS8= X-Google-Smtp-Source: AA6agR4paSUXLNvFGFSDJppfJ2kPyrmqEOxlco2ErFPtYNZzF3AijBmN1wEFAOb2sAE5p3D6qI6NuA== X-Received: by 2002:a17:902:d509:b0:16f:1e1:2067 with SMTP id b9-20020a170902d50900b0016f01e12067mr3737907plg.140.1659431826206; Tue, 02 Aug 2022 02:17:06 -0700 (PDT) Received: from localhost.localdomain ([112.20.110.136]) by smtp.gmail.com with ESMTPSA id x187-20020a6231c4000000b0052c4b3e6f6asm10551475pfx.97.2022.08.02.02.17.02 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Tue, 02 Aug 2022 02:17:05 -0700 (PDT) X-Google-Original-From: Feiyang Chen To: yangtiezhu@loongson.cn Subject: [PATCH v2] gdb/gdbserver: LoongArch: Improve implementation of fcc registers Date: Tue, 2 Aug 2022 17:16:56 +0800 Message-Id: <20220802091656.55802-1-chenfeiyang@loongson.cn> X-Mailer: git-send-email 2.37.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Feiyang Chen via Gdb-patches Reply-To: Feiyang Chen Cc: chris.chenfeiyang@gmail.com, Feiyang Chen , gdb-patches@sourceware.org Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" The current implementation of the fcc register is referenced to the user_fp_state structure of the kernel uapi [1]. But it is mistakenly defined as a 64-bit fputype register, resulting in in a confusing output of "info register". (gdb) info register ... fcc {f = 0x0, d = 0x0} {f = 0, d = 0} ... According to "Condition Flag Register" in "LoongArch Reference Manual" [2], there are 8 condition flag registers of size 1. Use 8 registers of uint8 to make it easier for users to view the fcc register groups. (gdb) info register ... fcc0 0x1 1 fcc1 0x0 0 fcc2 0x0 0 fcc3 0x0 0 fcc4 0x0 0 fcc5 0x0 0 fcc6 0x0 0 fcc7 0x0 0 ... [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/loongarch/include/uapi/asm/ptrace.h [2] https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_condition_flag_register Signed-off-by: Feiyang Chen --- gdb/arch/loongarch.h | 7 ++-- gdb/features/loongarch/fpu.c | 9 +++++- gdb/features/loongarch/fpu.xml | 9 +++++- gdb/loongarch-linux-tdep.c | 55 +++++++++++++++++++++++++++++--- gdb/loongarch-tdep.c | 6 ++-- gdbserver/linux-loongarch-low.cc | 24 ++++++++++++++ 6 files changed, 99 insertions(+), 11 deletions(-) diff --git a/gdb/arch/loongarch.h b/gdb/arch/loongarch.h index 799595b3e60..eae061f7f47 100644 --- a/gdb/arch/loongarch.h +++ b/gdb/arch/loongarch.h @@ -37,9 +37,10 @@ enum loongarch_regnum LOONGARCH_ARG_REGNUM = 8, /* r4-r11: general-purpose argument registers. f0-f7: floating-point argument registers. */ LOONGARCH_FIRST_FP_REGNUM = LOONGARCH_LINUX_NUM_GREGSET, - LOONGARCH_FCC_REGNUM = LOONGARCH_FIRST_FP_REGNUM + 32, - LOONGARCH_FCSR_REGNUM = LOONGARCH_FCC_REGNUM + 1, - LOONGARCH_LINUX_NUM_FPREGSET = 34, + LOONGARCH_LINUX_NUM_FPREGSET = 32, + LOONGARCH_FIRST_FCC_REGNUM = LOONGARCH_FIRST_FP_REGNUM + LOONGARCH_LINUX_NUM_FPREGSET, + LOONGARCH_LINUX_NUM_FCC = 8, + LOONGARCH_FCSR_REGNUM = LOONGARCH_FIRST_FCC_REGNUM + LOONGARCH_LINUX_NUM_FCC, }; enum loongarch_fputype diff --git a/gdb/features/loongarch/fpu.c b/gdb/features/loongarch/fpu.c index ea3e1dd9980..183ed54989f 100644 --- a/gdb/features/loongarch/fpu.c +++ b/gdb/features/loongarch/fpu.c @@ -49,7 +49,14 @@ create_feature_loongarch_fpu (struct target_desc *result, long regnum) tdesc_create_reg (feature, "f29", regnum++, 1, "float", 64, "fputype"); tdesc_create_reg (feature, "f30", regnum++, 1, "float", 64, "fputype"); tdesc_create_reg (feature, "f31", regnum++, 1, "float", 64, "fputype"); - tdesc_create_reg (feature, "fcc", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "fcc0", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc1", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc2", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc3", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc4", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc5", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc6", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc7", regnum++, 1, "float", 8, "uint8"); tdesc_create_reg (feature, "fcsr", regnum++, 1, "float", 32, "uint32"); return regnum; } diff --git a/gdb/features/loongarch/fpu.xml b/gdb/features/loongarch/fpu.xml index a61057ec442..e81e3382e7d 100644 --- a/gdb/features/loongarch/fpu.xml +++ b/gdb/features/loongarch/fpu.xml @@ -45,6 +45,13 @@ - + + + + + + + + diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c index 3a81ff31972..883245bec7e 100644 --- a/gdb/loongarch-linux-tdep.c +++ b/gdb/loongarch-linux-tdep.c @@ -123,6 +123,7 @@ loongarch_supply_fpregset (const struct regset *r, { const gdb_byte *buf = nullptr; int fprsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM); + int fccsize = register_size (regcache->arch (), LOONGARCH_FIRST_FCC_REGNUM); if (regnum == -1) { @@ -131,12 +132,33 @@ loongarch_supply_fpregset (const struct regset *r, buf = (const gdb_byte *)fprs + fprsize * i; regcache->raw_supply (LOONGARCH_FIRST_FP_REGNUM + i, (const void *)buf); } + for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + { + buf = (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * i; + regcache->raw_supply (LOONGARCH_FIRST_FCC_REGNUM + i, (const void *)buf); + } + buf = (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_supply (LOONGARCH_FCSR_REGNUM, (const void *)buf); } - else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM) + else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIRST_FCC_REGNUM) { buf = (const gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_REGNUM); regcache->raw_supply (regnum, (const void *)buf); } + else if (regnum >= LOONGARCH_FIRST_FCC_REGNUM && regnum < LOONGARCH_FCSR_REGNUM) + { + buf = (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM); + regcache->raw_supply (regnum, (const void *)buf); + } + else if (regnum == LOONGARCH_FCSR_REGNUM) + { + buf = (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_supply (regnum, (const void *)buf); + } } /* Pack the GDB's register cache value into an elf_fpregset_t. */ @@ -147,6 +169,7 @@ loongarch_fill_fpregset (const struct regset *r, { gdb_byte *buf = nullptr; int fprsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM); + int fccsize = register_size (regcache->arch (), LOONGARCH_FIRST_FCC_REGNUM); if (regnum == -1) { @@ -155,12 +178,33 @@ loongarch_fill_fpregset (const struct regset *r, buf = (gdb_byte *)fprs + fprsize * i; regcache->raw_collect (LOONGARCH_FIRST_FP_REGNUM + i, (void *)buf); } + for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + { + buf = (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * i; + regcache->raw_collect (LOONGARCH_FIRST_FCC_REGNUM + i, (void *)buf); + } + buf = (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_collect (LOONGARCH_FCSR_REGNUM, (void *)buf); } - else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM) + else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIRST_FCC_REGNUM) { buf = (gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_REGNUM); regcache->raw_collect (regnum, (void *)buf); } + else if (regnum >= LOONGARCH_FIRST_FCC_REGNUM && regnum < LOONGARCH_FCSR_REGNUM) + { + buf = (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM); + regcache->raw_collect (regnum, (void *)buf); + } + else if (regnum == LOONGARCH_FCSR_REGNUM) + { + buf = (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_collect (regnum, (void *)buf); + } } /* Define the FP register regset. */ @@ -221,11 +265,14 @@ loongarch_iterate_over_regset_sections (struct gdbarch *gdbarch, { int gprsize = register_size (gdbarch, 0); int fprsize = register_size (gdbarch, LOONGARCH_FIRST_FP_REGNUM); + int fccsize = register_size (gdbarch, LOONGARCH_FIRST_FCC_REGNUM); + int fcsrsize = register_size (gdbarch, LOONGARCH_FCSR_REGNUM); + int fpsize = fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC + fcsrsize; cb (".reg", LOONGARCH_LINUX_NUM_GREGSET * gprsize, LOONGARCH_LINUX_NUM_GREGSET * gprsize, &loongarch_gregset, nullptr, cb_data); - cb (".reg2", LOONGARCH_LINUX_NUM_FPREGSET * fprsize, - LOONGARCH_LINUX_NUM_FPREGSET * fprsize, &loongarch_fpregset, nullptr, cb_data); + cb (".reg2", fpsize, fpsize, &loongarch_fpregset, nullptr, cb_data); } /* The following value is derived from __NR_rt_sigreturn in diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index 85a1dd70ebd..e63ff01854d 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -1428,10 +1428,12 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Validate the description provides the fpu registers and allocate their numbers. */ regnum = LOONGARCH_FIRST_FP_REGNUM; - for (int i = 0; i < 32; i++) + for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++) valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++, loongarch_f_normal_name[i] + 1); - valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++, "fcc"); + for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++, + loongarch_c_normal_name[i] + 1); valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++, "fcsr"); if (!valid_p) return nullptr; diff --git a/gdbserver/linux-loongarch-low.cc b/gdbserver/linux-loongarch-low.cc index 7180f315b11..cccf1ba780b 100644 --- a/gdbserver/linux-loongarch-low.cc +++ b/gdbserver/linux-loongarch-low.cc @@ -127,12 +127,24 @@ loongarch_fill_fpregset (struct regcache *regcache, void *buf) { gdb_byte *regbuf = nullptr; int fprsize = register_size (regcache->tdesc, LOONGARCH_FIRST_FP_REGNUM); + int fccsize = register_size (regcache->tdesc, LOONGARCH_FIRST_FCC_REGNUM); for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++) { regbuf = (gdb_byte *)buf + fprsize * i; collect_register (regcache, LOONGARCH_FIRST_FP_REGNUM + i, regbuf); } + + for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + { + regbuf = (gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * i; + collect_register (regcache, LOONGARCH_FIRST_FCC_REGNUM + i, regbuf); + } + + regbuf = (gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + collect_register (regcache, LOONGARCH_FCSR_REGNUM, regbuf); } /* Supply FPRs from BUF into REGCACHE. */ @@ -142,12 +154,24 @@ loongarch_store_fpregset (struct regcache *regcache, const void *buf) { const gdb_byte *regbuf = nullptr; int fprsize = register_size (regcache->tdesc, LOONGARCH_FIRST_FP_REGNUM); + int fccsize = register_size (regcache->tdesc, LOONGARCH_FIRST_FCC_REGNUM); for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++) { regbuf = (const gdb_byte *)buf + fprsize * i; supply_register (regcache, LOONGARCH_FIRST_FP_REGNUM + i, regbuf); } + + for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + { + regbuf = (const gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * i; + supply_register (regcache, LOONGARCH_FIRST_FCC_REGNUM + i, regbuf); + } + + regbuf = (const gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + supply_register (regcache, LOONGARCH_FCSR_REGNUM, regbuf); } /* LoongArch/Linux regsets. */ -- 2.37.1