From patchwork Mon Oct 7 20:28:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jozef Lawrynowicz X-Patchwork-Id: 1172954 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-510421-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mittosystems.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="aqggiPWT"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mittosystems.com header.i=@mittosystems.com header.b="Ok08gPVa"; dkim-atps=neutral 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 46nBs60h0nz9sP7 for ; Tue, 8 Oct 2019 07:28:57 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=ONLB5ZKpBHoMuh1k3L/+qFGe/t4/0pF6OsTo6ugPGaJGSPfAeUUc8 MEwcTb3jl4sBbXl+yY1JzPZw+w1Oty8EXZU4Sje6Z8dypplcwTJAdjOHdibnzbI1 ZBx83Smb8VKFl9NehdZ7Z1SUELFXweBWAHe9YBj2KYcDxAFMV4xXTQ= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=4uCTtRuFDeuab8/mq4Q09WA69gM=; b=aqggiPWT+suG2svykS5J iJeRTcsCmexxLvRY/1Q4Fici8eG1urONzrFfS4jYpz5ArB0FymBfUFZa+UxwSBpV Vbt/jj4zFB2nhUU/HYhbhP0Gj11QiaLPgiGKSzPBpI1DtwoGns80+j3UiT5A0Zvl DcnRRy+nmkmUZH2SBR/m/Sg= Received: (qmail 48245 invoked by alias); 7 Oct 2019 20:28:42 -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 48169 invoked by uid 89); 7 Oct 2019 20:28:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=match_operand, sk:nonimme, deciding, rm X-HELO: mail-wr1-f43.google.com Received: from mail-wr1-f43.google.com (HELO mail-wr1-f43.google.com) (209.85.221.43) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 07 Oct 2019 20:28:36 +0000 Received: by mail-wr1-f43.google.com with SMTP id n14so16778046wrw.9 for ; Mon, 07 Oct 2019 13:28:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mittosystems.com; s=google; h=date:from:to:subject:message-id:mime-version; bh=1oLKKC9uhXsuKEEtRrtILlk94IaR+4L+JBnF9OmIPu8=; b=Ok08gPVa9TK30SROWQ1cfBw1PTeOwhNhbuNc4xlZh0+oGctWI5JPKAYU8MMXJvw91w KznGUjEXcrpFqW+WEVMQJpgQQsw7PY/RL5eLgO/WOtuMAn3hazwrDLqXy24RFPJfJh7v noBpXFHw935gq+3bvhJKraPSdzyPXELoAAv5W5X1zkOjUsiSU27qhZuQqOtYh5bxmdhE +GuWF5XWXuZMmxHTX19lXCYEC3sGWIj6YF4ogahT1ABEQPEJOCWvQTddbT4xDNgU6pxS axybfzDti5PzJLQOjITYlqt/cGU7BOsSMRVxRDN8SI+LPX4V+Asc/Be+7Tv5P5ymPYMu s2zg== Received: from jozef-kubuntu ([2a01:4b00:87fd:900:906b:6db5:b3f5:8817]) by smtp.gmail.com with ESMTPSA id r27sm47649319wrc.55.2019.10.07.13.28.32 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 07 Oct 2019 13:28:32 -0700 (PDT) Date: Mon, 7 Oct 2019 21:28:30 +0100 From: Jozef Lawrynowicz To: "gcc-patches@gcc.gnu.org" Subject: [PATCH][MSP430] Add support for post increment addressing Message-ID: <20191007212830.1685a27a@jozef-kubuntu> MIME-Version: 1.0 X-IsSubscribed: yes MSP430 supports post increment addressing for the source operand only. The attached patch enables post increment addressing for MSP430 in GCC. Regtested on trunk for the small and large memory models. Ok for trunk? From d75e48ba434d7bab141c09d442793b2cb26afa69 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Mon, 16 Sep 2019 16:34:51 +0100 Subject: [PATCH] MSP430: Implement post increment addressing gcc/ChangeLog: 2019-10-07 Jozef Lawrynowicz * config/msp430/constraints.md: Allow post_inc operand for "Ya" constraint. * config/msp430/msp430.c (msp430_legitimate_address_p): Handle POST_INC. (msp430_subreg): Likewise. (msp430_split_addsi): Likewise. (msp430_print_operand_addr): Likewise. * config/msp430/msp430.h (HAVE_POST_INCREMENT): Define. (USE_STORE_POST_INCREMENT): Define. * config/msp430/msp430.md: Use the msp430_general_dst_operand or msp430_general_dst_nonv_operand predicates for the lvalues insns. * config/msp430/predicates.md (msp430_nonpostinc_operand): New. (msp430_general_dst_operand): New. (msp430_general_dst_nonv_operand): New. (msp430_nonsubreg_operand): Remove. (msp430_nonsubreg_dst_operand): New. (msp430_nonsubreg_or_imm_operand): Allow reg or mem operands in place of defunct msp430_nonsubreg_operand. (msp430_nonsubregnonpostinc_or_imm_operand): New. --- gcc/config/msp430/constraints.md | 1 + gcc/config/msp430/msp430.c | 32 +++++- gcc/config/msp430/msp430.h | 12 ++ gcc/config/msp430/msp430.md | 191 ++++++++++++++++--------------- gcc/config/msp430/predicates.md | 46 +++++++- 5 files changed, 183 insertions(+), 99 deletions(-) diff --git a/gcc/config/msp430/constraints.md b/gcc/config/msp430/constraints.md index 4422b2b6454..d01bcf9a242 100644 --- a/gcc/config/msp430/constraints.md +++ b/gcc/config/msp430/constraints.md @@ -60,6 +60,7 @@ (match_code "reg" "00") (match_test ("CONST_INT_P (XEXP (XEXP (op, 0), 1))"))) (match_test "CONSTANT_P (XEXP (op, 0))") + (match_code "post_inc" "0") ))) (define_constraint "Yl" diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index ae763faada3..31029395c3d 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -942,12 +942,17 @@ msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, return false; case PLUS: + case POST_INC: if (REG_P (XEXP (x, 0))) { if (GET_MODE (x) != GET_MODE (XEXP (x, 0))) return false; if (!reg_ok_for_addr (XEXP (x, 0), strict)) return false; + if (GET_CODE (x) == POST_INC) + /* At this point, if the original rtx was a post_inc, we don't have + anything further to check. */ + return true; switch (GET_CODE (XEXP (x, 1))) { case CONST: @@ -2810,6 +2815,7 @@ rtx msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte) { rtx rv; + gcc_assert (mode == HImode); if (GET_CODE (r) == SUBREG && SUBREG_BYTE (r) == 0) @@ -2826,7 +2832,15 @@ msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte) rv = simplify_gen_subreg (mode, ireg, imode, byte); } else if (GET_CODE (r) == MEM) - rv = adjust_address (r, mode, byte); + { + /* When byte == 2, we can be certain that we were already called with an + identical rtx with byte == 0. So we don't need to do anything to + get a 2 byte offset of a (mem (post_inc)) rtx, since the address has + already been offset by the post_inc itself. */ + if (GET_CODE (XEXP (r, 0)) == POST_INC && byte == 2) + byte = 0; + rv = adjust_address (r, mode, byte); + } else if (GET_CODE (r) == SYMBOL_REF && (byte == 0 || byte == 2) && mode == HImode) @@ -2861,6 +2875,18 @@ msp430_split_addsi (rtx *operands) if (GET_CODE (operands[5]) == CONST_INT) operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff); + /* Handle post_inc, for example: + (set (reg:SI) + (plus:SI (reg:SI) + (mem:SI (post_inc:PSI (reg:PSI))))). */ + else if (MEM_P (operands[5]) && GET_CODE (XEXP (operands[5], 0)) == POST_INC) + { + /* Strip out the post_inc from (mem (post_inc (reg))). */ + operands[9] = XEXP (XEXP (operands[5], 0), 0); + operands[9] = gen_rtx_MEM (HImode, operands[9]); + /* Then zero extend as normal. */ + operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[9]); + } else operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]); return 0; @@ -3205,6 +3231,10 @@ msp430_print_operand_addr (FILE * file, machine_mode /*mode*/, rtx addr) fprintf (file, "@"); break; + case POST_INC: + fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]); + return; + case CONST: case CONST_INT: case SYMBOL_REF: diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h index f885de2bb2f..73afe2e2d16 100644 --- a/gcc/config/msp430/msp430.h +++ b/gcc/config/msp430/msp430.h @@ -478,6 +478,18 @@ typedef struct #define ACCUMULATE_OUTGOING_ARGS 1 +#define HAVE_POST_INCREMENT 1 + +/* This (unsurprisingly) improves code size in the vast majority of cases, we + want to prevent any instructions using a "store post increment" from being + generated. These will have to later be reloaded since msp430 does not + support post inc for the destination operand. */ +#define USE_STORE_POST_INCREMENT(MODE) 0 + +/* Many other targets set USE_LOAD_POST_INCREMENT to 0. For msp430-elf + the benefit of disabling it is not clear. When looking at code size, on + average, there is a slight advantage to leaving it enabled. */ + #undef ASM_DECLARE_FUNCTION_NAME #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ msp430_start_function ((FILE), (NAME), (DECL)) diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md index ebd9c85fbb6..a533efa1656 100644 --- a/gcc/config/msp430/msp430.md +++ b/gcc/config/msp430/msp430.md @@ -183,14 +183,14 @@ ) (define_insn "movqi_topbyte" - [(set (match_operand:QI 0 "msp430_nonimmediate_operand" "=r") + [(set (match_operand:QI 0 "msp430_general_dst_operand" "=r") (subreg:QI (match_operand:PSI 1 "msp430_general_operand" "r") 2))] "msp430x" "PUSHM.A\t#1,%1 { POPM.W\t#1,%0 { POPM.W\t#1,%0" ) (define_insn "movqi" - [(set (match_operand:QI 0 "msp430_nonimmediate_operand" "=rYsYx,rm") + [(set (match_operand:QI 0 "msp430_general_dst_operand" "=rYsYx,rm") (match_operand:QI 1 "msp430_general_operand" "riYsYx,rmi"))] "" "@ @@ -199,7 +199,7 @@ ) (define_insn "movhi" - [(set (match_operand:HI 0 "msp430_nonimmediate_operand" "=r,rYsYx,rm") + [(set (match_operand:HI 0 "msp430_general_dst_operand" "=r,rYsYx,rm") (match_operand:HI 1 "msp430_general_operand" "N,riYsYx,rmi"))] "" "@ @@ -209,41 +209,41 @@ ) (define_expand "movsi" - [(set (match_operand:SI 0 "nonimmediate_operand") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand") (match_operand:SI 1 "general_operand"))] "" "" ) (define_insn_and_split "movsi_s" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm") (subreg:SI (match_operand:PSI 1 "msp430_symbol_operand" "i") 0))] "" "" "reload_completed" - [(set (match_operand:HI 2 "nonimmediate_operand") + [(set (match_operand:HI 2 "msp430_general_dst_nonv_operand") (match_operand:HI 4 "general_operand")) - (set (match_operand:HI 3 "nonimmediate_operand") + (set (match_operand:HI 3 "msp430_general_dst_nonv_operand") (match_operand:HI 5 "general_operand"))] "msp430_split_movsi (operands);" ) (define_insn_and_split "movsi_x" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm") (match_operand:SI 1 "general_operand" "rmi"))] "" "#" "reload_completed" - [(set (match_operand:HI 2 "nonimmediate_operand") + [(set (match_operand:HI 2 "msp430_general_dst_nonv_operand") (match_operand:HI 4 "general_operand")) - (set (match_operand:HI 3 "nonimmediate_operand") + (set (match_operand:HI 3 "msp430_general_dst_nonv_operand") (match_operand:HI 5 "general_operand"))] "msp430_split_movsi (operands);" ) ;; FIXME: Some MOVX.A cases can be done with MOVA, this is only a few of them. (define_insn "movpsi" - [(set (match_operand:PSI 0 "msp430_nonimmediate_operand" "=r,r,r,Ya,rm") + [(set (match_operand:PSI 0 "msp430_general_dst_operand" "=r,r,r,Ya,rm") (match_operand:PSI 1 "msp430_general_operand" "N,O,riYa,r,rmi"))] "" "@ @@ -279,8 +279,8 @@ ;; Math (define_insn "addpsi3" - [(set (match_operand:PSI 0 "msp430_nonimmediate_operand" "=r,rm") - (plus:PSI (match_operand:PSI 1 "msp430_nonimmediate_operand" "%0,0") + [(set (match_operand:PSI 0 "msp430_general_dst_operand" "=r,rm") + (plus:PSI (match_operand:PSI 1 "msp430_general_operand" "%0,0") (match_operand:PSI 2 "msp430_general_operand" "rLs,rmi")))] "" "@ @@ -289,8 +289,8 @@ ) (define_insn "addqi3" - [(set (match_operand:QI 0 "msp430_nonimmediate_operand" "=rYsYx,rm") - (plus:QI (match_operand:QI 1 "msp430_nonimmediate_operand" "%0,0") + [(set (match_operand:QI 0 "msp430_general_dst_operand" "=rYsYx,rm") + (plus:QI (match_operand:QI 1 "msp430_general_operand" "%0,0") (match_operand:QI 2 "msp430_general_operand" "riYsYx,rmi")))] "" "@ @@ -299,8 +299,8 @@ ) (define_insn "addhi3" - [(set (match_operand:HI 0 "msp430_nonimmediate_operand" "=rYsYx,rm") - (plus:HI (match_operand:HI 1 "msp430_nonimmediate_operand" "%0,0") + [(set (match_operand:HI 0 "msp430_general_dst_operand" "=rYsYx,rm") + (plus:HI (match_operand:HI 1 "msp430_general_operand" "%0,0") (match_operand:HI 2 "msp430_general_operand" "riYsYx,rmi")))] "" "@ @@ -321,8 +321,8 @@ ) (define_insn "addsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=&rYsYx,rm") - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=&rYsYx,rm") + (plus:SI (match_operand:SI 1 "general_operand" "%0,0") (match_operand:SI 2 "general_operand" "rYsYxi,mi")))] "" "@ @@ -357,13 +357,16 @@ ; increased register pressure. Or possibly reload does not handle ADD patterns ; that are not single_set() very well. +; match_operand 3 is likely to be the same as op2 most of the time - except +; when op2 is a post_inc and we have stripped the post_inc from match_operand 3 + (define_insn "addhi3_cy" - [(set (match_operand:HI 0 "msp430_nonimmediate_operand" "=rYsYx,rm") - (plus:HI (match_operand:HI 1 "msp430_nonimmediate_operand" "%0,0") + [(set (match_operand:HI 0 "msp430_general_dst_operand" "=rYsYx,rm") + (plus:HI (match_operand:HI 1 "msp430_general_operand" "%0,0") (match_operand:HI 2 "msp430_nonimmediate_operand" "rYsYxi,rm"))) (set (reg:BI CARRY) (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1)) - (zero_extend:SI (match_dup 2))) + (zero_extend:SI (match_operand:HI 3 "msp430_nonimmediate_operand" "rYsYxi,rm"))) (const_int 16)))) ] "" @@ -373,8 +376,8 @@ ) (define_insn "addhi3_cy_i" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") + [(set (match_operand:HI 0 "msp430_general_dst_nonv_operand" "=r,rm") + (plus:HI (match_operand:HI 1 "general_operand" "%0,0") (match_operand:HI 2 "immediate_operand" "i,i"))) (set (reg:BI CARRY) (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1)) @@ -389,8 +392,8 @@ ; Version of addhi that adds the carry, for SImode adds. (define_insn "addchi4_cy" - [(set (match_operand:HI 0 "msp430_nonimmediate_operand" "=rYsYx,rm") - (plus:HI (plus:HI (match_operand:HI 1 "msp430_nonimmediate_operand" "%0,0") + [(set (match_operand:HI 0 "msp430_general_dst_operand" "=rYsYx,rm") + (plus:HI (plus:HI (match_operand:HI 1 "msp430_general_operand" "%0,0") (match_operand:HI 2 "msp430_general_operand" "riYsYx,rmi")) (zero_extend:HI (reg:BI CARRY)))) ] @@ -403,13 +406,15 @@ ; Split an SImode add into two HImode adds, keeping track of the carry ; so that gcc knows when it can and can't optimize away the two ; halves. +; We use the ugly predicate "msp430_nonsubregnonpostinc_or_imm_operand" to +; enforce the position of a post_inc into op2 if present (define_split - [(set (match_operand:SI 0 "msp430_nonsubreg_operand") - (plus:SI (match_operand:SI 1 "msp430_nonsubreg_operand") + [(set (match_operand:SI 0 "msp430_nonsubreg_dst_operand") + (plus:SI (match_operand:SI 1 "msp430_nonsubregnonpostinc_or_imm_operand") (match_operand:SI 2 "msp430_nonsubreg_or_imm_operand"))) ] "" - [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm") + [(parallel [(set (match_operand:HI 3 "msp430_general_dst_nonv_operand" "=&rm") (plus:HI (match_dup 4) (match_dup 5))) (set (reg:BI CARRY) @@ -417,7 +422,7 @@ (match_dup 9)) (const_int 16)))) ]) - (set (match_operand:HI 6 "nonimmediate_operand" "=&rm") + (set (match_operand:HI 6 "msp430_general_dst_nonv_operand" "=&rm") (plus:HI (plus:HI (match_dup 7) (match_dup 8)) (zero_extend:HI (reg:BI CARRY)))) @@ -431,9 +436,9 @@ ;; Alternatives 2 and 3 are to handle cases generated by reload. (define_insn "subpsi3" - [(set (match_operand:PSI 0 "nonimmediate_operand" "=r, rm, &?r, ?&r") - (minus:PSI (match_operand:PSI 1 "general_operand" "0, 0, !r, !i") - (match_operand:PSI 2 "general_operand" "rLs, rmi, rmi, r")))] + [(set (match_operand:PSI 0 "msp430_general_dst_nonv_operand" "=r, rm, &?r, ?&r") + (minus:PSI (match_operand:PSI 1 "general_operand" "0, 0, !r, !i") + (match_operand:PSI 2 "general_operand" "rLs, rmi, rmi, r")))] "" "@ SUBA\t%2, %0 @@ -444,7 +449,7 @@ ;; Alternatives 2 and 3 are to handle cases generated by reload. (define_insn "subqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=rYsYx, rm, &?r, ?&r") + [(set (match_operand:QI 0 "msp430_general_dst_nonv_operand" "=rYsYx, rm, &?r, ?&r") (minus:QI (match_operand:QI 1 "general_operand" "0, 0, !r, !i") (match_operand:QI 2 "general_operand" " riYsYx, rmi, rmi, r")))] "" @@ -457,7 +462,7 @@ ;; Alternatives 2 and 3 are to handle cases generated by reload. (define_insn "subhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rYsYx, rm, &?r, ?&r") + [(set (match_operand:HI 0 "msp430_general_dst_nonv_operand" "=rYsYx, rm, &?r, ?&r") (minus:HI (match_operand:HI 1 "general_operand" "0, 0, !r, !i") (match_operand:HI 2 "general_operand" " riYsYx, rmi, rmi, r")))] "" @@ -469,8 +474,8 @@ ) (define_insn "subsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=&rYsYx,m") - (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=&rYsYx,m") + (minus:SI (match_operand:SI 1 "general_operand" "0,0") (match_operand:SI 2 "general_operand" "riYsYx,mi")))] "" "@ @@ -479,7 +484,7 @@ ) (define_insn "*bic_cg" - [(set (match_operand:QHI 0 "msp430_nonimmediate_operand" "=rYs,m") + [(set (match_operand:QHI 0 "msp430_general_dst_operand" "=rYs,m") (and:QHI (match_operand:QHI 1 "msp430_general_operand" "0,0") (match_operand 2 "msp430_inv_constgen_operator" "n,n")))] "" @@ -489,9 +494,9 @@ ) (define_insn "bic3" - [(set (match_operand:QHI 0 "msp430_nonimmediate_operand" "=rYsYx,rm") + [(set (match_operand:QHI 0 "msp430_general_dst_operand" "=rYsYx,rm") (and:QHI (not:QHI (match_operand:QHI 1 "msp430_general_operand" "rYsYx,rmn")) - (match_operand:QHI 2 "msp430_nonimmediate_operand" "0,0")))] + (match_operand:QHI 2 "msp430_general_operand" "0,0")))] "" "@ BIC%x0%b0\t%1, %0 @@ -499,8 +504,8 @@ ) (define_insn "and3" - [(set (match_operand:QHI 0 "msp430_nonimmediate_operand" "=r,rYsYx,rm") - (and:QHI (match_operand:QHI 1 "msp430_nonimmediate_operand" "%0,0,0") + [(set (match_operand:QHI 0 "msp430_general_dst_operand" "=r,rYsYx,rm") + (and:QHI (match_operand:QHI 1 "msp430_general_operand" "%0,0,0") (match_operand:QHI 2 "msp430_general_operand" "N,riYsYx,rmi")))] "" "@ @@ -510,8 +515,8 @@ ) (define_insn "ior3" - [(set (match_operand:QHI 0 "msp430_nonimmediate_operand" "=rYsYx,rm") - (ior:QHI (match_operand:QHI 1 "msp430_nonimmediate_operand" "%0,0") + [(set (match_operand:QHI 0 "msp430_general_dst_operand" "=rYsYx,rm") + (ior:QHI (match_operand:QHI 1 "msp430_general_operand" "%0,0") (match_operand:QHI 2 "msp430_general_operand" "riYsYx,rmi")))] "" "@ @@ -520,8 +525,8 @@ ) (define_insn "xor3" - [(set (match_operand:QHI 0 "msp430_nonimmediate_operand" "=rYsYx,rm") - (xor:QHI (match_operand:QHI 1 "msp430_nonimmediate_operand" "%0,0") + [(set (match_operand:QHI 0 "msp430_general_dst_operand" "=rYsYx,rm") + (xor:QHI (match_operand:QHI 1 "msp430_general_operand" "%0,0") (match_operand:QHI 2 "msp430_general_operand" "riYsYx,rmi")))] "" "@ @@ -531,8 +536,8 @@ ;; Macro : XOR #~0, %0 (define_insn "one_cmpl2" - [(set (match_operand:QHI 0 "msp430_nonimmediate_operand" "=rYs,m") - (not:QHI (match_operand:QHI 1 "msp430_nonimmediate_operand" "0,0")))] + [(set (match_operand:QHI 0 "msp430_general_dst_operand" "=rYs,m") + (not:QHI (match_operand:QHI 1 "msp430_general_operand" "0,0")))] "" "@ INV%x0%b0\t%0 @@ -540,8 +545,8 @@ ) (define_insn "extendqihi2" - [(set (match_operand:HI 0 "msp430_nonimmediate_operand" "=rYs,m") - (sign_extend:HI (match_operand:QI 1 "msp430_nonimmediate_operand" "0,0")))] + [(set (match_operand:HI 0 "msp430_general_dst_operand" "=rYs,m") + (sign_extend:HI (match_operand:QI 1 "msp430_general_operand" "0,0")))] "" "@ SXT%X0\t%0 @@ -549,8 +554,8 @@ ) (define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "msp430_nonimmediate_operand" "=rYs,r,r,m") - (zero_extend:HI (match_operand:QI 1 "msp430_nonimmediate_operand" "0,rYs,m,0")))] + [(set (match_operand:HI 0 "msp430_general_dst_operand" "=rYs,r,r,m") + (zero_extend:HI (match_operand:QI 1 "msp430_general_operand" "0,rYs,m,0")))] "" "@ AND\t#0xff, %0 @@ -571,8 +576,8 @@ ) (define_insn "zero_extendhipsi2" - [(set (match_operand:PSI 0 "msp430_nonimmediate_operand" "=r,m") - (zero_extend:PSI (match_operand:HI 1 "msp430_nonimmediate_operand" "rm,r")))] + [(set (match_operand:PSI 0 "msp430_general_dst_operand" "=r,m") + (zero_extend:PSI (match_operand:HI 1 "msp430_general_operand" "rm,r")))] "" "@ MOVX\t%1, %0 @@ -580,22 +585,22 @@ ) (define_insn "truncpsihi2" - [(set (match_operand:HI 0 "msp430_nonimmediate_operand" "=rm") + [(set (match_operand:HI 0 "msp430_general_dst_operand" "=rm") (truncate:HI (match_operand:PSI 1 "register_operand" "r")))] "" "MOVX\t%1, %0" ) (define_insn "extendhisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=r") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))] "" { return msp430x_extendhisi (operands); } ) (define_insn "extendhipsi2" - [(set (match_operand:PSI 0 "nonimmediate_operand" "=r") - (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))] + [(set (match_operand:PSI 0 "msp430_general_dst_nonv_operand" "=r") + (subreg:PSI (sign_extend:SI (match_operand:HI 1 "general_operand" "0")) 0))] "msp430x" "RLAM.A #4, %0 { RRAM.A #4, %0" ) @@ -606,15 +611,15 @@ ;; paths. (define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=r") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))] "" "MOV%X1.B\t%1,%L0 { CLR\t%H0" ) (define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")))] + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm,r") + (zero_extend:SI (match_operand:HI 1 "general_operand" "0,r")))] "" "@ MOV%X0.W\t#0,%H0 @@ -622,8 +627,8 @@ ) (define_insn "zero_extendhisipsi2" - [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r") - (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))] + [(set (match_operand:PSI 0 "msp430_general_dst_nonv_operand" "=r,r") + (subreg:PSI (zero_extend:SI (match_operand:HI 1 "general_operand" "0,r")) 0))] "msp430x" "@ AND.W\t#-1,%0 @@ -631,16 +636,16 @@ ) (define_insn "extend_and_shift1_hipsi2" - [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0) - (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) + [(set (subreg:SI (match_operand:PSI 0 "msp430_general_dst_nonv_operand" "=r") 0) + (ashift:SI (sign_extend:SI (match_operand:HI 1 "general_operand" "0")) (const_int 1)))] "msp430x" "RLAM.A #4, %0 { RRAM.A #3, %0" ) (define_insn "extend_and_shift2_hipsi2" - [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0) - (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) + [(set (subreg:SI (match_operand:PSI 0 "msp430_general_dst_nonv_operand" "=r") 0) + (ashift:SI (sign_extend:SI (match_operand:HI 1 "general_operand" "0")) (const_int 2)))] "msp430x" "RLAM.A #4, %0 { RRAM.A #2, %0" @@ -739,7 +744,7 @@ ;; signed A << C (define_expand "ashlhi3" - [(set (match_operand:HI 0 "nonimmediate_operand") + [(set (match_operand:HI 0 "msp430_general_dst_nonv_operand") (ashift:HI (match_operand:HI 1 "general_operand") (match_operand:HI 2 "general_operand")))] "" @@ -766,7 +771,7 @@ ) (define_insn "slli_1" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + [(set (match_operand:HI 0 "msp430_general_dst_nonv_operand" "=rm") (ashift:HI (match_operand:HI 1 "general_operand" "0") (const_int 1)))] "" @@ -786,7 +791,7 @@ ) (define_insn "slll_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm") (ashift:SI (match_operand:SI 1 "general_operand" "0") (const_int 1)))] "" @@ -794,7 +799,7 @@ ) (define_insn "slll_2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm") (ashift:SI (match_operand:SI 1 "general_operand" "0") (const_int 2)))] "" @@ -802,7 +807,7 @@ ) (define_expand "ashlsi3" - [(set (match_operand:SI 0 "nonimmediate_operand") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand") (ashift:SI (match_operand:SI 1 "general_operand") (match_operand:SI 2 "general_operand")))] "" @@ -811,7 +816,7 @@ ) (define_expand "ashldi3" - [(set (match_operand:DI 0 "nonimmediate_operand") + [(set (match_operand:DI 0 "msp430_general_dst_nonv_operand") (ashift:DI (match_operand:DI 1 "general_operand") (match_operand:DI 2 "general_operand")))] "" @@ -827,7 +832,7 @@ ;; signed A >> C (define_expand "ashrhi3" - [(set (match_operand:HI 0 "nonimmediate_operand") + [(set (match_operand:HI 0 "msp430_general_dst_nonv_operand") (ashiftrt:HI (match_operand:HI 1 "general_operand") (match_operand:HI 2 "general_operand")))] "" @@ -851,7 +856,7 @@ ) (define_insn "srai_1" - [(set (match_operand:HI 0 "msp430_nonimmediate_operand" "=rm") + [(set (match_operand:HI 0 "msp430_general_dst_operand" "=rm") (ashiftrt:HI (match_operand:HI 1 "msp430_general_operand" "0") (const_int 1)))] "" @@ -887,7 +892,7 @@ ) (define_insn "sral_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm") (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") (const_int 1)))] "" @@ -895,7 +900,7 @@ ) (define_insn "sral_2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm") (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") (const_int 2)))] "" @@ -903,7 +908,7 @@ ) (define_expand "ashrsi3" - [(set (match_operand:SI 0 "nonimmediate_operand") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand") (ashiftrt:SI (match_operand:SI 1 "general_operand") (match_operand:SI 2 "general_operand")))] "" @@ -912,7 +917,7 @@ ) (define_expand "ashrdi3" - [(set (match_operand:DI 0 "nonimmediate_operand") + [(set (match_operand:DI 0 "msp430_general_dst_nonv_operand") (ashift:DI (match_operand:DI 1 "general_operand") (match_operand:DI 2 "general_operand")))] "" @@ -928,7 +933,7 @@ ;; unsigned A >> C (define_expand "lshrhi3" - [(set (match_operand:HI 0 "nonimmediate_operand") + [(set (match_operand:HI 0 "msp430_general_dst_nonv_operand") (lshiftrt:HI (match_operand:HI 1 "general_operand") (match_operand:HI 2 "general_operand")))] "" @@ -952,7 +957,7 @@ ) (define_insn "srli_1" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + [(set (match_operand:HI 0 "msp430_general_dst_nonv_operand" "=rm") (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") (const_int 1)))] "" @@ -978,7 +983,7 @@ ) (define_insn "srll_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm") (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") (const_int 1)))] "" @@ -986,7 +991,7 @@ ) (define_insn "srll_2x" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=r") (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") (const_int 2)))] "msp430x" @@ -994,7 +999,7 @@ ) (define_expand "lshrsi3" - [(set (match_operand:SI 0 "nonimmediate_operand") + [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand") (lshiftrt:SI (match_operand:SI 1 "general_operand") (match_operand:SI 2 "general_operand")))] "" @@ -1003,7 +1008,7 @@ ) (define_expand "lshrdi3" - [(set (match_operand:DI 0 "nonimmediate_operand") + [(set (match_operand:DI 0 "msp430_general_dst_nonv_operand") (ashift:DI (match_operand:DI 1 "general_operand") (match_operand:DI 2 "general_operand")))] "" @@ -1274,7 +1279,7 @@ (define_insn "*bitbranch4" [(set (pc) (if_then_else - (ne (and:QHI (match_operand:QHI 0 "msp430_nonimmediate_operand" "rYsYx,rm") + (ne (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm") (match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi")) (const_int 0)) (label_ref (match_operand 2 "" "")) @@ -1289,7 +1294,7 @@ (define_insn "*bitbranch4" [(set (pc) (if_then_else - (eq (and:QHI (match_operand:QHI 0 "msp430_nonimmediate_operand" "rYsYx,rm") + (eq (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm") (match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi")) (const_int 0)) (label_ref (match_operand 2 "" "")) @@ -1304,7 +1309,7 @@ (define_insn "*bitbranch4" [(set (pc) (if_then_else - (eq (and:QHI (match_operand:QHI 0 "msp430_nonimmediate_operand" "rYsYx,rm") + (eq (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm") (match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi")) (const_int 0)) (pc) @@ -1319,7 +1324,7 @@ (define_insn "*bitbranch4" [(set (pc) (if_then_else - (ne (and:QHI (match_operand:QHI 0 "msp430_nonimmediate_operand" "rYsYx,rm") + (ne (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm") (match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi")) (const_int 0)) (pc) @@ -1337,7 +1342,7 @@ (define_insn "*bitbranch4_z" [(set (pc) (if_then_else - (ne (zero_extract:HI (match_operand:QHI 0 "msp430_nonimmediate_operand" "rYs,rm") + (ne (zero_extract:HI (match_operand:QHI 0 "msp430_general_dst_operand" "rYs,rm") (const_int 1) (match_operand 1 "msp430_bitpos" "i,i")) (const_int 0)) @@ -1353,7 +1358,7 @@ (define_insn "*bitbranch4_z" [(set (pc) (if_then_else - (eq (zero_extract:HI (match_operand:QHI 0 "msp430_nonimmediate_operand" "rm") + (eq (zero_extract:HI (match_operand:QHI 0 "msp430_general_dst_operand" "rm") (const_int 1) (match_operand 1 "msp430_bitpos" "i")) (const_int 0)) @@ -1367,7 +1372,7 @@ (define_insn "*bitbranch4_z" [(set (pc) (if_then_else - (eq (zero_extract:HI (match_operand:QHI 0 "msp430_nonimmediate_operand" "rm") + (eq (zero_extract:HI (match_operand:QHI 0 "msp430_general_dst_operand" "rm") (const_int 1) (match_operand 1 "msp430_bitpos" "i")) (const_int 0)) @@ -1381,7 +1386,7 @@ (define_insn "*bitbranch4_z" [(set (pc) (if_then_else - (ne (zero_extract:HI (match_operand:QHI 0 "msp430_nonimmediate_operand" "rm") + (ne (zero_extract:HI (match_operand:QHI 0 "msp430_general_dst_operand" "rm") (const_int 1) (match_operand 1 "msp430_bitpos" "i")) (const_int 0)) diff --git a/gcc/config/msp430/predicates.md b/gcc/config/msp430/predicates.md index 751548c4ae8..d8cdaba3813 100644 --- a/gcc/config/msp430/predicates.md +++ b/gcc/config/msp430/predicates.md @@ -23,21 +23,50 @@ (match_test ("memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), MEM_ADDR_SPACE (op))"))) ) +; TRUE if neither op nor op0 are a post_inc. We cannot use post_inc for the +; dst operand so this must be used for any predicates which might allow a mem. +; Since we check both op and op0, this will be FALSE for both "(post_inc)" and +; "(mem (post_inc))" +(define_predicate "msp430_nonpostinc_operand" + (not (ior (match_code "post_inc") + (and (ior (match_operand 0 "msp430_volatile_memory_operand") + (match_code "mem")) + (match_code "post_inc" "0"))))) + ; TRUE for any valid general operand. We do this because ; general_operand refuses to match volatile memory refs. - (define_predicate "msp430_general_operand" (ior (match_operand 0 "general_operand") (match_operand 0 "msp430_volatile_memory_operand")) ) ; Likewise for nonimmediate_operand. - (define_predicate "msp430_nonimmediate_operand" (ior (match_operand 0 "nonimmediate_operand") (match_operand 0 "msp430_volatile_memory_operand")) ) +; Similar to msp430_nonimmediate_operand but disallow post_inc operands +(define_predicate "msp430_general_dst_operand" + (and (match_operand 0 "msp430_nonpostinc_operand") + (match_operand 0 "msp430_nonimmediate_operand"))) + +; Similar to msp430_general_dst_operand but disallow volatile memory references +; Note that msp430_nonpostinc_operand will allow a volatile mem but nonimmediate +; will not, so overall this predicate will behave as expected. +; The heuristic for deciding if we can allow volatile memory appears to be: +; "If the number of references to the variable in the source code matches +; the number of references to the variable in the assembly template, we can +; safely allow a volatile memory reference". +; - paraphrasing DJ Delorie here: +; https://gcc.gnu.org/ml/gcc-patches/2014-05/msg00870.html +; When applied to instruction patterns, this means that we can only allow +; volatile memory when the output assembler template contains only one +; instruction which references that volatile address. +(define_predicate "msp430_general_dst_nonv_operand" + (and (match_operand 0 "msp430_nonpostinc_operand") + (match_operand 0 "nonimmediate_operand"))) + (define_predicate "ubyte_operand" (and (match_code "const_int") (match_test "IN_RANGE (INTVAL (op), 0, 255)"))) @@ -70,13 +99,20 @@ || INTVAL (op) == ~8 || INTVAL (op) == ~(-1) ")))) -(define_predicate "msp430_nonsubreg_operand" - (match_code "reg,mem")) +; See above note on post_inc +(define_predicate "msp430_nonsubreg_dst_operand" + (and (match_operand 0 "msp430_nonpostinc_operand") + (match_code "reg,mem"))) (define_predicate "msp430_nonsubreg_or_imm_operand" - (ior (match_operand 0 "msp430_nonsubreg_operand") + (ior (match_code "reg,mem") (match_operand 0 "immediate_operand"))) +(define_predicate "msp430_nonsubregnonpostinc_or_imm_operand" + (and (match_operand 0 "msp430_nonpostinc_operand") + (ior (match_code "reg,mem") + (match_operand 0 "immediate_operand")))) + ; TRUE for constants which are bit positions for zero_extract (define_predicate "msp430_bitpos" (and (match_code "const_int") -- 2.17.1