From patchwork Wed Jun 29 23:42:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 642264 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rfzkd1kczz9sDG for ; Thu, 30 Jun 2016 09:43:04 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Ez+J3PnN; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=XDL6xQ9SN2B+ LOll5BdirbwK1NJugGLad4cotsqOqoVgMDaJAkDwAT73iSnwbYgatGXqv9V5AqJy 7QgXRMwWngAKa9acf5//PGwWfIawcE5AhV3fEDafGZy20axrtnL7UvzWYsR3t26a wINzaavjVDVf1egihB7kYsWxGJo/AjQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=Ji0fXHXIsyKLMgrklU uen4rdeYA=; b=Ez+J3PnNGgcIlUehtFjBhRIUTt17TEboJzY5v/GSTMIfdjnjPK wScRuWKiNMSX+wX2WmW2aud05PzXpV2rRr7EaPVdvKA/WuuB6Q1EgGaTxD81TpkC 7YLlSiGVbiHnvIE0S1SCDIcJ44XS3otNXZYiq35QGbH7qxM34HRx9Easg= Received: (qmail 41308 invoked by alias); 29 Jun 2016 23:42:56 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 41263 invoked by uid 89); 29 Jun 2016 23:42:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=H*MI:andrew, match_test, unalign, pcl X-HELO: mail-wm0-f51.google.com Received: from mail-wm0-f51.google.com (HELO mail-wm0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 29 Jun 2016 23:42:44 +0000 Received: by mail-wm0-f51.google.com with SMTP id r201so94814536wme.1 for ; Wed, 29 Jun 2016 16:42:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=cOSRaUi9lVQ27yJda1CpxWkYikZTJg6Bn02einsD3ss=; b=T0hNHC+eMT8+EV84FM1Q2YaQFSZtESIZQhcISPeReAfw5pVgzQA0/TzIoLDoqZ3KYZ ulyCV5Tn5lUt1AebqIQAkOTz0+Xu5MT4h/Q3Yyp3Ztf/3sfgaidNyZa4ruy0+Fcxiuk7 OoxcxNTPyigBVx/9QgNa/mKyk0umEJt22Lb8VwCtGW/VuWruj3XAipwbjrj8z/d+YDCV FMjD0Snfeq1cnehmDCzWrdVf4QnqHrNHAiPdhaAbS/f0juknQFkiGLlkJmKbqkNp6pYD P4H9I866YOa37XTi94qf7aWJxZG59NAqrfTQyIAjE3Dmx0J8a4CM9YwV0q7nzZbzW5KF 0hJg== X-Gm-Message-State: ALyK8tKFHAbifauZ8QnjUMVf8ryZGAr3GFRTrafmZQMVzYam5KbxOjiNfCOTk/npv4kTFg== X-Received: by 10.28.71.74 with SMTP id u71mr12023360wma.0.1467243760919; Wed, 29 Jun 2016 16:42:40 -0700 (PDT) Received: from localhost (host81-140-212-11.range81-140.btcentralplus.com. [81.140.212.11]) by smtp.gmail.com with ESMTPSA id r190sm1485840wme.17.2016.06.29.16.42.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jun 2016 16:42:40 -0700 (PDT) From: Andrew Burgess To: gcc-patches@gcc.gnu.org, gnu@amylaar.uk Cc: Claudiu.Zissulescu@synopsys.com, Andrew Burgess Subject: [PATCH] gcc/arc: Avoid add_s REG,REG,pcl on ARCv2 targets Date: Thu, 30 Jun 2016 00:42:38 +0100 Message-Id: <1467243758-12913-1-git-send-email-andrew.burgess@embecosm.com> X-IsSubscribed: yes The ARCv2 targets don't support add_s REG,REG,pcl like earlier ARC targets did. This instruction format is used when generating case jump tables. This commit updates the code so that ARCv2 targets avoid the unsupported instruction. This does mean the code is slightly longer on ARCv2, so the instruction length has changed accordingly. gcc/ChangeLog: * config/arc/arc.md (casesi_compact_jump): Avoid generating add_s REG,REG,pcl on ARCv2 targets. gcc/testsuite/ChangeLog: * gcc.target/arc/switch-1.c: New file. --- gcc/ChangeLog | 5 ++++ gcc/config/arc/arc.md | 50 ++++++++++++++++++--------------- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.target/arc/switch-1.c | 42 +++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arc/switch-1.c diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index 1102c53..0f39d49 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -3950,6 +3950,7 @@ int unalign = arc_get_unalign (); rtx xop[3]; const char *s; + int vec_offset = TARGET_V2 ? 12 : 10; xop[0] = operands[0]; xop[2] = operands[2]; @@ -3962,11 +3963,11 @@ 2 of these are for alignment, and are anticipated in the length of the ADDR_DIFF_VEC. */ if (unalign && !satisfies_constraint_Rcq (xop[0])) - s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\"; + s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\"; /* Length = 6 bytes. */ else if (unalign) - s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\"; + s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\"; /* Length = 6 bytes. */ else - s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\"; + s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\"; /* Length = 8 bytes. */ arc_clear_unalign (); break; case HImode: @@ -3974,26 +3975,26 @@ { if (satisfies_constraint_Rcq (xop[0])) { - s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\"; - xop[1] = GEN_INT ((10 - unalign) / 2U); + s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\"; /* Length = 6 bytes. */ + xop[1] = GEN_INT ((vec_offset - unalign) / 2U); } else { - s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\"; - xop[1] = GEN_INT (10 + unalign); + s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\"; /* Length = 6 bytes. */ + xop[1] = GEN_INT (vec_offset + unalign); } } else { if (satisfies_constraint_Rcq (xop[0])) { - s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\"; - xop[1] = GEN_INT ((10 - unalign) / 2U); + s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\"; /* Length = 6 bytes. */ + xop[1] = GEN_INT ((vec_offset - unalign) / 2U); } else { - s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\"; - xop[1] = GEN_INT (10 + unalign); + s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\"; /* Length = 6 bytes. */ + xop[1] = GEN_INT (vec_offset + unalign); } } arc_toggle_unalign (); @@ -4001,17 +4002,18 @@ case QImode: if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) { - if ((rtx_equal_p (xop[2], xop[0]) - || find_reg_note (insn, REG_DEAD, xop[0])) + if (!TARGET_V2 + && (rtx_equal_p (xop[2], xop[0]) + || find_reg_note (insn, REG_DEAD, xop[0])) && satisfies_constraint_Rcq (xop[0])) { - s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\"; - xop[1] = GEN_INT (8 + unalign); + s = \"add %0,%0,pcl\n\tldb_s %2,[%0,%1]\"; /* Length = 6 bytes. */ + xop[1] = GEN_INT ((vec_offset - 2) + unalign); } else { - s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\"; - xop[1] = GEN_INT (10 + unalign); + s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\"; /* Length = 6 bytes. */ + xop[1] = GEN_INT (vec_offset + unalign); arc_toggle_unalign (); } } @@ -4019,14 +4021,14 @@ || find_reg_note (insn, REG_DEAD, xop[0])) && satisfies_constraint_Rcq (xop[0])) { - s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\"; - xop[1] = GEN_INT (10 - unalign); + s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\"; /* Length = 6 bytes. */ + xop[1] = GEN_INT (vec_offset - unalign); arc_toggle_unalign (); } else { /* ??? Length is 12. */ - s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\"; + s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\"; /* Length = 8 bytes. */ xop[1] = GEN_INT (8 + unalign); } break; @@ -4034,9 +4036,13 @@ gcc_unreachable (); } output_asm_insn (s, xop); - return \"add_s %2,%2,pcl\n\tj_s%* [%2]\"; + if (TARGET_V2) + return \"add %2,%2,pcl\n\tj_s%* [%2]\"; /* Length = 6 bytes. */ + else + return \"add_s %2,%2,pcl\n\tj_s%* [%2]\"; /* Length = 4 bytes. */ }" - [(set_attr "length" "10") + [(set (attr "length") + (if_then_else (match_test "TARGET_V2") (const_int 12) (const_int 10))) (set_attr "type" "jump") (set_attr "iscompact" "true") (set_attr "cond" "nocond")]) diff --git a/gcc/testsuite/gcc.target/arc/switch-1.c b/gcc/testsuite/gcc.target/arc/switch-1.c new file mode 100644 index 0000000..f68b719 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/switch-1.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=arcem -Os -Wall -Werror" } */ + +/* { dg-final { scan-assembler-not "add_s\[ \t\]+r\[0-9\]+,r\[0-9\]+,pcl" } } */ + +/* Unfortunately the following pragma is required in order to allow + compiling with -Wall -Werror, but still skip one of the possible switch + cases in this test. */ +#pragma GCC diagnostic ignored "-Wswitch" + +typedef struct { + struct { + struct { + enum { + REG_SAVED_OFFSET, + REG_SAVED_REG, + REG_SAVED_EXP, + REG_SAVED_VAL_OFFSET, + REG_SAVED_VAL_EXP + } how; + } reg[1]; + } regs; +} _Unwind_FrameState; + +_Unwind_FrameState a; + +extern void fn2 (void); + +void fn1() { + switch (a.regs.reg[0].how) { + case REG_SAVED_OFFSET: + /* Specifically don't handle REG_SAVED_REG in this switch statement, + this causes GCC to generate the specific switch-jump-vector table + that triggered a bug on ARCv2 targets. */ + /* case REG_SAVED_REG: */ + case REG_SAVED_EXP: + case REG_SAVED_VAL_OFFSET: + fn2(); + case REG_SAVED_VAL_EXP: + fn2(); + } +}