From patchwork Wed Feb 14 18:16:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuriy Kolerov X-Patchwork-Id: 85744 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7A5F13860769 for ; Wed, 14 Feb 2024 18:16:48 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id C2840385829D for ; Wed, 14 Feb 2024 18:16:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C2840385829D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C2840385829D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::62d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707934585; cv=none; b=cBb2rPEjZuKBZARyFPG+5+GsRF3MlFrfWvWkNNNKWtE7yZ8YQ5qJUrBRdxKJ34Ga+F1O5lKCyf6zzA7qZZ/wx1+ANJb5ROkrn4xL/v8bYb4BsK/ke8EkJ4UIFOBBpXtBc1R2Nz6CtxmsejklljPnNW0VPb7DPAW56a5/syE3DP4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707934585; c=relaxed/simple; bh=TrO2M7p26r/m1oQyId5ilKl+G6AoKwaoSwHauQQlxjk=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=NaUdQaQPmt+I7yBkOC3df7wYLnNFIc/rxqO6CL5BN6slYA3oXG2urtG5vR33kAMW3vwfFsUYfVtUU5J7CoRcW4V5cuIqB7e767Yut4ddgFMDLamHQpwXBbidiGCNGD83U0ctaTO/Pn4LHBNutp5TBayfBWEtkvnN5e7FfvOEujE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ej1-x62d.google.com with SMTP id a640c23a62f3a-a3122b70439so741458166b.3 for ; Wed, 14 Feb 2024 10:16:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707934581; x=1708539381; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=uhZhk7qXj8kkaZXuCBe1f+S6HrkgjKX/lEqos2w7tnc=; b=kMLll6zwmHjn+y4YsEXlFpMgpvFG5zRS768OgBLg6fvpcZd51LnC9iHQY/jUfAGpWU E4vOtAJGfz5eE2QQcUV7qNEn6XPQhJY9tPPrtyQgnvjIuM7MMIpDVvz+qVNEmR5ZqjXp KMXqopDGSkgRDINinbLFoVKMtMS5Zmo1GvsLZu7mbF3guL4284AaRl33TrCFfSD857BV XAk1b0OJP92aS4VTCX5n0wcyi8CeWBSDqkp7OEiqXLSSeh/aOWvysVvZVJXjaTD327fD kYUPpTO1lCjnoBAXuz7BC8eMFIoVX18HuYkW8xbKeIWHkVgMeBefJRmJActPNf5DQmKn J0Lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707934581; x=1708539381; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=uhZhk7qXj8kkaZXuCBe1f+S6HrkgjKX/lEqos2w7tnc=; b=B+Mme+VSHflnuX/JFHbwh9xvprAKvJLBPRIm89z9wl/ooAy7CHXB8RrZ+L3PQgNVig LPP2/hKW9c1im5a+TgJzVjinXcfixHalT6xx0EGBfgjCCSRkwpHrxH2RQyF059AaAPvZ p3e2I9MY5wDavtll5mq1IXjD4JhMroDN0secTbAdILy0xgACvKF1ANpU/TcCDHFCgJJm f6HOQZDU+NdFAarDCS1+kGeVfuQfXrGB8g5wO/pJfx/y1Rqdol1QdD8CRuZv44w9X5FB 0qmWIUEaZoMgw2W8XphZzi2h0BC1ZpmvDCpPsgzAP2I+mTja2lYZYosiKFCn73k2khch n5SA== X-Gm-Message-State: AOJu0YyPZKWDoHmohr/IyJobK6jN2jeFvJLdj416LkDruUsKXF0fguFD KkW+nmB7kLRrBBOc1Z1JCiDnf3GorQXin+cz/dAxUIMMsWOvIuAkMZ5wkDtsaCIPAxSO49o= X-Google-Smtp-Source: AGHT+IFmkyWaqgQYDlsR201Ocv0qkqNT6IsYuLKqOH82vMrVRmMsDy5VCLsR5QuzxNMVSSogM6oYfA== X-Received: by 2002:a17:906:f2cc:b0:a3d:6eb4:9768 with SMTP id gz12-20020a170906f2cc00b00a3d6eb49768mr739925ejb.46.1707934580565; Wed, 14 Feb 2024 10:16:20 -0800 (PST) X-Forwarded-Encrypted: i=1; AJvYcCUz5Y8+TP91BkytcnyhcfRotlLL6+Xf+EvJF3axRzKm7cm9lyUryf6PMQ3Kh7eSejKhLyASdVz3HPU8ubE85MUgRPsE Received: from localhost.localdomain ([2a00:cc47:20b1:3000:4f99:fe1f:2a1f:1530]) by smtp.gmail.com with ESMTPSA id lu1-20020a170906fac100b00a3c97e49bc9sm2524762ejb.218.2024.02.14.10.16.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Feb 2024 10:16:20 -0800 (PST) From: Yuriy Kolerov To: gdb-patches@sourceware.org, shahab@synopsys.com Cc: Yuriy Kolerov Subject: [PATCH] arc: Determine a branch target of DBNZ correctly Date: Wed, 14 Feb 2024 18:16:16 +0000 Message-Id: <20240214181616.36502-1-kolerov93@gmail.com> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org DBNZ instruction was moved from BRANCH class to a separate one - DBNZ. Thus, it must be processed separately in arc_insn_get_branch_target to correctly determine an offset for a possible branch. The testsuite for DBNZ instruction verifies these cases: 1. Check that dbnz does not branch and falls through if its source register is 0 after decrementing. GDB must successfully break on the following instruction after stepping over. 2. Check that dbnz branches to the target correctly if its source register is not 0 after decrementing - GDB must successfully break on the target instruction if a forward branch is performed after stepping over. 3. The same as point 2 but for a backward branching case. Signed-off-by: Yuriy Kolerov --- gdb/arc-tdep.c | 10 +++ gdb/testsuite/gdb.arch/arc-dbnz.S | 47 ++++++++++++++ gdb/testsuite/gdb.arch/arc-dbnz.exp | 97 +++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/arc-dbnz.S create mode 100644 gdb/testsuite/gdb.arch/arc-dbnz.exp diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c index 84e211ce9ad..3c31e009f32 100644 --- a/gdb/arc-tdep.c +++ b/gdb/arc-tdep.c @@ -466,6 +466,16 @@ arc_insn_get_branch_target (const struct arc_instruction &insn) instruction, hence last two bits should be truncated. */ return pcrel_addr + align_down (insn.address, 4); } + /* DBNZ is the only branch instruction that keeps a branch address in + the second operand. It must be intercepted and treated differently. */ + else if (insn.insn_class == DBNZ) + { + CORE_ADDR pcrel_addr = arc_insn_get_operand_value_signed (insn, 1); + + /* Offset is relative to the 4-byte aligned address of the current + instruction, hence last two bits should be truncated. */ + return pcrel_addr + align_down (insn.address, 4); + } /* B, Bcc, BL, BLcc, LP, LPcc: PC = currentPC + operand. */ else if (insn.insn_class == BRANCH || insn.insn_class == LOOP) { diff --git a/gdb/testsuite/gdb.arch/arc-dbnz.S b/gdb/testsuite/gdb.arch/arc-dbnz.S new file mode 100644 index 00000000000..45e1dfe8305 --- /dev/null +++ b/gdb/testsuite/gdb.arch/arc-dbnz.S @@ -0,0 +1,47 @@ +; This testcase is part of GDB, the GNU debugger. + +; Copyright 2024 Free Software Foundation, Inc. + +; 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 . + + .section .text + .align 4 + .global main + .type main, @function + +main: + mov r0,1 +dbnz1: + ; r0 == 0 after decrementing. dbnz doesn't do branch. + dbnz r0,@end + + mov r0,5 +dbnz2: + ; r0 == 3 after decrementing and delay slot. dbnz does branch. + dbnz.d r0,@dbnz3 + sub r0,r0,1 + +dbnz4: + ; r0 == 1 after decrementing. dbnz does branch. + dbnz r0,@end + +dbnz3: + ; r0 == 2 after decrementing. dbnz does branch. + dbnz r0,@dbnz4 + +end: + mov r0,0 + j [blink] + + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.arch/arc-dbnz.exp b/gdb/testsuite/gdb.arch/arc-dbnz.exp new file mode 100644 index 00000000000..f1fce0e5a7f --- /dev/null +++ b/gdb/testsuite/gdb.arch/arc-dbnz.exp @@ -0,0 +1,97 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2024 Free Software Foundation, Inc. + +# 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 . + +# Test dbnz instruction. It decrements its source register operand, and if +# the result is non-zero it branches to the location defined by a signed +# half-word displacement operand. +# +# It's necessary to verify these cases: +# +# 1. Check that dbnz does not branch and falls through if its source +# register is 0 after decrementing. GDB must successfully break +# on the following instruction after stepping over. +# 2. Check that dbnz branches to the target correctly if its source register +# is not 0 after decrementing - GDB must successfully break on the target +# instruction if a forward branch is performed after stepping over. +# 3. The same as point 2 but for a backward branching case. + +require {istarget "arc*-*-*"} + +standard_testfile .S + +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { + return -1 +} + +if ![runto_main] { + return 0 +} + +gdb_test "break dbnz1" \ + "Breakpoint $decimal at .*" \ + "set breakpoint on the 1st dbnz" + +gdb_test "break dbnz2" \ + "Breakpoint $decimal at .*" \ + "set breakpoint on the 2nd dbnz" + +gdb_test "break dbnz3" \ + "Breakpoint $decimal at .*" \ + "set breakpoint on the 3rd dbnz" + +gdb_test "break dbnz4" \ + "Breakpoint $decimal at .*" \ + "set breakpoint on the 4th dbnz" + +gdb_test "break end" \ + "Breakpoint $decimal at .*" \ + "set breakpoint at the end" + +gdb_test "continue" \ + "Breakpoint $decimal, dbnz1.*dbnz r0,@end" \ + "continue to the 1st dbnz" + +gdb_test "x /i \$pc" \ + "$hex <.*>:\[ \t\]+dbnz\[ \t\]+r0,24.*" \ + "stayng on the 1st dbnz instruction" + +gdb_test "stepi" \ + "mov r0,5" \ + "step over the 1st dbnz, branch is not taken" + +gdb_test "stepi" \ + "Breakpoint $decimal, dbnz2.*dbnz\\.d r0,@dbnz3" \ + "step over r0 initialization, staying on the 2nd dbnz" + +# Linux steps over delay slot after "stepi", but stubs with hardware stepping +# like nSIM's stub may step right on delay slot. Thus use "continue" instead of +# "stepi" to make this test work for all platforms. +gdb_test "continue" \ + "Breakpoint $decimal, dbnz3.*dbnz r0,@dbnz4" \ + "step over the 2nd dbnz, branch is taken, staying on the 3rd dbnz" + +gdb_test "stepi" \ + "Breakpoint $decimal, dbnz4.*dbnz r0,@end" \ + "step over the 3rd dbnz, branch is taken, staying on the 4th dbnz" + +gdb_test "stepi" \ + "Breakpoint $decimal, end.*mov r0,0" \ + "step over the 4th dbnz, branch is taken, staying on the epilogue" + +gdb_test "info register r0" \ + "r0\[ \t\]+0x1\[ \t\]+1" \ + "r0 contains 1 after all dbnz instructions"