From patchwork Thu May 7 21:39:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 469804 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 BCCC71401B5 for ; Fri, 8 May 2015 07:40:22 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=catmUWfN; 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:in-reply-to:references; q=dns; s= default; b=JHuX2fxd9cuUBwyc4N/yXWv/bfcySclJf257CpgxDQj1GUtgKlt+D BwCDLffbc/M16C+NkUyNVZyV52N5PR84D9gsGHOZ1wETcczidkviWAiBRreGRg69 KXW5MQOmjFmla4rBIE4lAwT1HMAhqpSiyYnqS6Um/DoUtS7T8z+yMk= 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:in-reply-to:references; s= default; bh=jkN8r+sCBis1iCTX04fx4XWCAkg=; b=catmUWfNkbywq05om8Rq JdG4isS17XyvOeLUofy3c5VnvmcF+g/aUrHFMIYoXeL5Sf08Y7qVpFFekrepFSX7 qZtmKMfPp2OEl1vVcmGJU5Fm9aHs1ua4vYQu41WHZAV8+6z3O0fzbG77qZI+gyCr ZYCAJz0pwVRVAB+HeH5td6A= Received: (qmail 87340 invoked by alias); 7 May 2015 21:39:18 -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 87283 invoked by uid 89); 7 May 2015 21:39:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f51.google.com Received: from mail-pa0-f51.google.com (HELO mail-pa0-f51.google.com) (209.85.220.51) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 07 May 2015 21:39:15 +0000 Received: by pacyx8 with SMTP id yx8so50811847pac.1 for ; Thu, 07 May 2015 14:39:13 -0700 (PDT) X-Received: by 10.68.170.229 with SMTP id ap5mr1123108pbc.132.1431034753714; Thu, 07 May 2015 14:39:13 -0700 (PDT) Received: from anchor.twiddle.net (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPSA id ph4sm3091291pdb.43.2015.05.07.14.39.12 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 May 2015 14:39:12 -0700 (PDT) From: Richard Henderson To: gcc-patches@gcc.gnu.org Cc: law@redhat.com, peterz@infradead.org, hpa@zytor.com, torvalds@linux-foundation.org, jakub@redhat.com Subject: [PATCH 6/6] i386: Implement asm flag outputs Date: Thu, 7 May 2015 14:39:00 -0700 Message-Id: <1431034740-5375-7-git-send-email-rth@redhat.com> In-Reply-To: <1431034740-5375-1-git-send-email-rth@redhat.com> References: <1431034740-5375-1-git-send-email-rth@redhat.com> X-IsSubscribed: yes All j mnemonics implemented as =@cc to make it easy for someone reading the manual to figure out what condition is desired. --- gcc/config/i386/constraints.md | 5 ++ gcc/config/i386/i386.c | 132 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 130 insertions(+), 7 deletions(-) diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 2271bd1..d16e728 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -146,10 +146,15 @@ "@internal Lower SSE register when avoiding REX prefix and all SSE registers otherwise.") ;; We use the B prefix to denote any number of internal operands: +;; f FLAGS_REG ;; s Sibcall memory operand, not valid for TARGET_X32 ;; w Call memory operand, not valid for TARGET_X32 ;; z Constant call address operand. +(define_constraint "Bf" + "@internal Flags register operand." + (match_operand 0 "flags_reg_operand")) + (define_constraint "Bs" "@internal Sibcall memory operand." (and (not (match_test "TARGET_X32")) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7cbb465..352884d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -45433,21 +45433,139 @@ ix86_c_mode_for_suffix (char suffix) /* Worker function for TARGET_MD_ASM_ADJUST. - We do this in the new i386 backend to maintain source compatibility + We implement asm flag outputs, and maintain source compatibility with the old cc0-based compiler. */ static rtx_insn * -ix86_md_asm_adjust (vec &/*outputs*/, vec &/*inputs*/, - vec &/*constraints*/, +ix86_md_asm_adjust (vec &outputs, vec &/*inputs*/, + vec &constraints, vec &clobbers, HARD_REG_SET &clobbered_regs) { - clobbers.safe_push (gen_rtx_REG (CCmode, FLAGS_REG)); clobbers.safe_push (gen_rtx_REG (CCFPmode, FPSR_REG)); - - SET_HARD_REG_BIT (clobbered_regs, FLAGS_REG); SET_HARD_REG_BIT (clobbered_regs, FPSR_REG); - return NULL; + bool saw_asm_flag = false; + + start_sequence (); + for (unsigned i = 0, n = outputs.length (); i < n; ++i) + { + const char *con = constraints[i]; + if (strncmp (con, "=@cc", 4) != 0) + continue; + con += 4; + if (strchr (con, ',') != NULL) + { + error ("alternatives not allowed in asm flag output"); + continue; + } + + bool invert = false; + if (con[0] == 'n') + invert = true, con++; + + machine_mode mode = CCmode; + rtx_code code = UNKNOWN; + + switch (con[0]) + { + case 'a': + if (con[1] == 0) + mode = CCAmode, code = EQ; + else if (con[1] == 'e' && con[2] == 0) + mode = CCCmode, code = EQ; + break; + case 'b': + if (con[1] == 0) + mode = CCCmode, code = EQ; + else if (con[1] == 'e' && con[2] == 0) + mode = CCAmode, code = NE; + break; + case 'c': + if (con[1] == 0) + mode = CCCmode, code = EQ; + break; + case 'e': + if (con[1] == 0) + mode = CCZmode, code = EQ; + break; + case 'g': + if (con[1] == 0) + mode = CCGCmode, code = GT; + else if (con[1] == 'e' && con[2] == 0) + mode = CCGCmode, code = GE; + break; + case 'l': + if (con[1] == 0) + mode = CCGCmode, code = LT; + else if (con[1] == 'e' && con[2] == 0) + mode = CCGCmode, code = LE; + break; + case 'o': + if (con[1] == 0) + mode = CCOmode, code = EQ; + break; + case 'p': + if (con[1] == 0) + mode = CCPmode, code = EQ; + break; + case 's': + if (con[1] == 0) + mode = CCSmode, code = EQ; + break; + case 'z': + if (con[1] == 0) + mode = CCZmode, code = EQ; + break; + } + if (code == UNKNOWN) + { + error ("unknown asm flag output %qs", constraints[i]); + continue; + } + if (invert) + code = reverse_condition (code); + + rtx dest = outputs[i]; + if (!saw_asm_flag) + { + /* This is the first asm flag output. Here we put the flags + register in as the real output and adjust the condition to + allow it. */ + constraints[i] = "=Bf"; + outputs[i] = gen_rtx_REG (CCmode, FLAGS_REG); + saw_asm_flag = true; + } + else + { + /* We don't need the flags register as output twice. */ + constraints[i] = "=X"; + outputs[i] = gen_rtx_SCRATCH (SImode); + } + + rtx x = gen_rtx_REG (mode, FLAGS_REG); + x = gen_rtx_fmt_ee (code, QImode, x, const0_rtx); + + machine_mode dest_mode = GET_MODE (dest); + if (dest_mode != QImode) + { + rtx destqi = gen_reg_rtx (QImode); + emit_insn (gen_rtx_SET (VOIDmode, destqi, x)); + x = gen_rtx_ZERO_EXTEND (dest_mode, destqi); + } + emit_insn (gen_rtx_SET (VOIDmode, dest, x)); + } + rtx_insn *seq = get_insns (); + end_sequence (); + + if (saw_asm_flag) + return seq; + else + { + /* If we had no asm flag outputs, clobber the flags. */ + clobbers.safe_push (gen_rtx_REG (CCmode, FLAGS_REG)); + SET_HARD_REG_BIT (clobbered_regs, FLAGS_REG); + return NULL; + } } /* Implements target vector targetm.asm.encode_section_info. */