From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by sourceware.org (Postfix) with ESMTPS id 2BF993835690 for ; Fri, 22 Jul 2022 09:09:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2BF993835690 Received: by mail-pj1-x1029.google.com with SMTP id p6-20020a17090a680600b001f2267a1c84so5938293pjj.5 for ; Fri, 22 Jul 2022 02:09:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=y6/ZZZ5flWFd0HtgAO2UleTxB3H/8miuhFhROhpVNaE=; b=MuXrdk3FZVqlufxwZpgLrX7QRmDLOrAiJtJ98jRY215dEfWLZYjAJDcnqP2xYVEZRJ fGbtecHhpo5co5lTc5pLB8pZqboz4g9QtjdK9yzeYrFBW1OhTKQUu9Id901DVKa7RGYA Hjl6+2MRgI05uhc6jTYQf7d6jPGKtiiLC5Ce94oAqHt+Flp/uOMyNQ7TMfYPpXdCmeB5 G5Cn6qnkp5Wnkj6zQwdWRI2u7j3n5iBIYHDgqxHX+vQbjLktBl71cGxglqezM42S5Ekr IqsJFE76QKfpECtp/PaxFmTOW0PpP9q/c/ISXgAoEngRM8B3FkUv34ly+TIYzjMYjGZS Cv8w== X-Gm-Message-State: AJIora+tpdMwOshGuC7INNR8gW7a4aC9x6oQBovO/KDTf4Grdd+IPke9 XU2owS4OFwnCW1J2ZiU3ZIY= X-Google-Smtp-Source: AGRyM1s4aEfSaJ00SkwilBA2djp0zcLUrplkAtITJXeyzk9K1IrVrzxjQPZysVLBi08I16Dk9QX2ng== X-Received: by 2002:a17:902:b593:b0:16c:4d8a:c8b0 with SMTP id a19-20020a170902b59300b0016c4d8ac8b0mr2706459pls.9.1658480988012; Fri, 22 Jul 2022 02:09:48 -0700 (PDT) Received: from localhost.localdomain ([112.20.110.136]) by smtp.gmail.com with ESMTPSA id h193-20020a6283ca000000b00528baea53afsm3312780pfe.46.2022.07.22.02.09.44 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Fri, 22 Jul 2022 02:09:46 -0700 (PDT) From: Feiyang Chen X-Google-Original-From: Feiyang Chen To: yangtiezhu@loongson.cn Cc: Feiyang Chen , chris.chenfeiyang@gmail.com, gdb-patches@sourceware.org Subject: [PATCH] gdb/gdbserver: LoongArch: Improve implementation of fcc registers Date: Fri, 22 Jul 2022 17:08:59 +0800 Message-Id: <20220722090859.41050-1-chenfeiyang@loongson.cn> X-Mailer: git-send-email 2.37.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: , X-List-Received-Date: Fri, 22 Jul 2022 09:09:52 -0000 According to "Condition Flag Register" in "LoongArch Reference Manual" [1], there are 8 condition flag registers of size 1. The fcc register is now a 64-bit fputype register, which is a little confusing. Use 8 registers of uint8 to make it easier for users to view the register groups. [1] 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 | 70 ++++++++++++++++++++++++++------ gdb/loongarch-tdep.c | 6 ++- gdbserver/linux-loongarch-low.cc | 26 +++++++++++- 6 files changed, 105 insertions(+), 22 deletions(-) diff --git a/gdb/arch/loongarch.h b/gdb/arch/loongarch.h index 799595b3e60..6a97cb3dbd2 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_FP = 32, + LOONGARCH_FIRST_FCC_REGNUM = LOONGARCH_FIRST_FP_REGNUM + LOONGARCH_LINUX_NUM_FP, + 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..df2b7031c69 100644 --- a/gdb/loongarch-linux-tdep.c +++ b/gdb/loongarch-linux-tdep.c @@ -122,19 +122,40 @@ loongarch_supply_fpregset (const struct regset *r, const void *fprs, size_t len) { const gdb_byte *buf = nullptr; - int fprsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM); + int fpsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM); + int fccsize = register_size (regcache->arch (), LOONGARCH_FIRST_FCC_REGNUM); if (regnum == -1) { - for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++) + for (int i = 0; i < LOONGARCH_LINUX_NUM_FP; i++) { - buf = (const gdb_byte *)fprs + fprsize * i; + buf = (const gdb_byte *)fprs + fpsize * 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 + fpsize * LOONGARCH_LINUX_NUM_FP + fccsize * i; + regcache->raw_supply (LOONGARCH_FIRST_FCC_REGNUM + i, (const void *)buf); + } + buf = (const gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_supply (LOONGARCH_FCSR_REGNUM, (const void *)buf); + } + else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIRST_FCC_REGNUM) + { + buf = (const gdb_byte *)fprs + fpsize * (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 + fpsize * LOONGARCH_LINUX_NUM_FP + + fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM); + regcache->raw_supply (regnum, (const void *)buf); } - else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM) + else if (regnum == LOONGARCH_FCSR_REGNUM) { - buf = (const gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_REGNUM); + buf = (const gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP + + fccsize * LOONGARCH_LINUX_NUM_FCC; regcache->raw_supply (regnum, (const void *)buf); } } @@ -146,19 +167,40 @@ loongarch_fill_fpregset (const struct regset *r, void *fprs, size_t len) { gdb_byte *buf = nullptr; - int fprsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM); + int fpsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM); + int fccsize = register_size (regcache->arch (), LOONGARCH_FIRST_FCC_REGNUM); if (regnum == -1) { - for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++) + for (int i = 0; i < LOONGARCH_LINUX_NUM_FP; i++) { - buf = (gdb_byte *)fprs + fprsize * i; + buf = (gdb_byte *)fprs + fpsize * 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 + fpsize * LOONGARCH_LINUX_NUM_FP + fccsize * i; + regcache->raw_collect (LOONGARCH_FIRST_FCC_REGNUM + i, (void *)buf); + } + buf = (gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_collect (LOONGARCH_FCSR_REGNUM, (void *)buf); + } + else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIRST_FCC_REGNUM) + { + buf = (gdb_byte *)fprs + fpsize * (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 + fpsize * LOONGARCH_LINUX_NUM_FP + + fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM); + regcache->raw_collect (regnum, (void *)buf); } - else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM) + else if (regnum == LOONGARCH_FCSR_REGNUM) { - buf = (gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_REGNUM); + buf = (gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP + + fccsize * LOONGARCH_LINUX_NUM_FCC; regcache->raw_collect (regnum, (void *)buf); } } @@ -220,12 +262,14 @@ loongarch_iterate_over_regset_sections (struct gdbarch *gdbarch, const struct regcache *regcache) { int gprsize = register_size (gdbarch, 0); - int fprsize = register_size (gdbarch, LOONGARCH_FIRST_FP_REGNUM); + int fpsize = 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 fprsize = fpsize * LOONGARCH_LINUX_NUM_FP + 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", fprsize, fprsize, &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 5711e6f05d7..334dad518b9 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -1194,10 +1194,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_FP; 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..d7c18228609 100644 --- a/gdbserver/linux-loongarch-low.cc +++ b/gdbserver/linux-loongarch-low.cc @@ -127,12 +127,23 @@ 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++) + for (int i = 0; i < LOONGARCH_LINUX_NUM_FP; 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_FP + fccsize * i; + collect_register (regcache, LOONGARCH_FIRST_FCC_REGNUM + i, regbuf); + } + + regbuf = (gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FP + + fccsize * LOONGARCH_LINUX_NUM_FCC; + collect_register (regcache, LOONGARCH_FCSR_REGNUM, regbuf); } /* Supply FPRs from BUF into REGCACHE. */ @@ -142,12 +153,23 @@ 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++) + for (int i = 0; i < LOONGARCH_LINUX_NUM_FP; 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_FP + fccsize * i; + supply_register (regcache, LOONGARCH_FIRST_FCC_REGNUM + i, regbuf); + } + + regbuf = (const gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FP + + fccsize * LOONGARCH_LINUX_NUM_FCC; + supply_register (regcache, LOONGARCH_FCSR_REGNUM, regbuf); } /* LoongArch/Linux regsets. */ -- 2.37.1