From patchwork Tue May 14 16:22:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 1099593 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-500660-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Teved3I9"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="eivQv5Pq"; 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 453NJs12Byz9s00 for ; Wed, 15 May 2019 02:23:07 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=kCg1i4KhgfV7FQNVkwE68bjyC7A79dHCSXxnq0JwpSu3mv 7sj6MY35HMifXINykl0ardm3jqvYamB/U2q1+62IX3zUWY24va95ynVKFr2lZTCN 96zlkiBLmizKVaE7RIsfem+Z+XbKjpB7+YYya1F8wUHEhrlZCZLUs5KXAz6bM= 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 :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=PBK7NXFzFMNC2f4SX5hDgtooquA=; b=Teved3I9FYGzKFVInNPW /1/hi2mkWlkQTu37wDR/UhktTstIDckChPLgB0lI4UAvrSmo9z/255WJypOcKImy dAOCO8NyTgavSPhZtLWGu6j8HNcSff3/Qn51FApgC52pq9q1Fa0SD10+OMVLEoRr ypRmPFBLdtrbZPX5L+AQw88= Received: (qmail 96733 invoked by alias); 14 May 2019 16:22:58 -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 95423 invoked by uid 89); 14 May 2019 16:22:58 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-14.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, 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= X-HELO: mail-io1-f41.google.com Received: from mail-io1-f41.google.com (HELO mail-io1-f41.google.com) (209.85.166.41) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 14 May 2019 16:22:53 +0000 Received: by mail-io1-f41.google.com with SMTP id a17so13533505iot.8 for ; Tue, 14 May 2019 09:22:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=ejmqDLLDAsCnTCSAGrO1ToyiS/3ql82ITUcmHQsXUDQ=; b=eivQv5PqYgXgLVJc9deR+4T5KwKJvSwD4wh6nW29WrSvt9L6AxLBq0PNC3N0swRnMZ +SFbshyRizuK254ccNvy1N1+ujUhqit3ED1s7GL5qaHVaYFsDEZYAxLxKLSOwvL7XDwr 5KaWoQKZJDWXWyTNZ2HedFHufqPg//uMuWbZfv4FMLotiol0yxVo7ssbHjXyo6AD6td8 9eakJMZs6HSqKxyGyqO1H2xnGuUX4la2Nta0llimPb8bnu8DngfkJrA9iw00ZZHdkIzz mMyJO6QQDuMzexRwobQpSJ49vz7T3hm5aPRd58ene8eHVn+Zptjd0JyAE8DCfMtY6Hh1 cJXw== MIME-Version: 1.0 From: Uros Bizjak Date: Tue, 14 May 2019 18:22:39 +0200 Message-ID: Subject: [PATCH, i386]: Macroize DIVMOD patterns To: "gcc-patches@gcc.gnu.org" Recent work by Richard Sandiford [1] enabled the possibility to macroize DIVMOD patterns in i386.md. 2019-05-14 Uroš Bizjak * config/i386/i386.md (any_div): New code iterator. (paired_mod): New code attribute. (sgnprefix): Handle DIV and UDIV RTXes. (u): Ditto. (divmod4): Macroize expander from divmod4 and udivmod4 patterns using any_div code iterator. (divmod splitters): Macroize splitters using any_div code iterator. (*udivmodsi4_pow2_zext_1): Use exactl_log2 in insn condition. (*udivmodsi4_pow2_zext_2): Ditto. (*divmod4_noext): Macroize insn from *divmod4_noext and *udivmod4_noext patterns using any_div code iterator. (*divmod4_noext_zext_1): Macroize insn from *divmod4_noext_zext_1 and *udivmod4_noext_zext_1 patterns using any_div code iterator. (*divmod4_noext_zext_2): Macroize insn from *divmod4_noext_zext_2 and *udivmod4_noext_zext_2 patterns using any_div code iterator. (divmodhiqi3): Macroize insn from divmodhiqi3 and udivmodhiqi3 patterns using any_extend code iterator. The patch also reorders DIVMOD patterns a bit. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN. [1] https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00560.html Uros. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index edec0ab0386c..05411221197f 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -933,11 +933,12 @@ (define_code_iterator any_extend [sign_extend zero_extend]) ;; Prefix for insn menmonic. -(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")]) - +(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "") + (div "i") (udiv "")]) ;; Prefix for define_insn -(define_code_attr u [(sign_extend "") (zero_extend "u")]) (define_code_attr s [(sign_extend "s") (zero_extend "u")]) +(define_code_attr u [(sign_extend "") (zero_extend "u") + (div "") (udiv "u")]) (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")]) ;; Used in signed and unsigned truncations. @@ -7475,13 +7476,16 @@ ;; Divmod instructions. -(define_expand "divmod4" +(define_code_iterator any_div [div udiv]) +(define_code_attr paired_mod [(div "mod") (udiv "umod")]) + +(define_expand "divmod4" [(parallel [(set (match_operand:SWIM248 0 "register_operand") - (div:SWIM248 + (any_div:SWIM248 (match_operand:SWIM248 1 "register_operand") (match_operand:SWIM248 2 "nonimmediate_operand"))) (set (match_operand:SWIM248 3 "register_operand") - (mod:SWIM248 (match_dup 1) (match_dup 2))) + (:SWIM248 (match_dup 1) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])]) ;; Split with 8bit unsigned divide: @@ -7491,10 +7495,10 @@ ;; use original integer divide (define_split [(set (match_operand:SWI48 0 "register_operand") - (div:SWI48 (match_operand:SWI48 2 "register_operand") - (match_operand:SWI48 3 "nonimmediate_operand"))) + (any_div:SWI48 (match_operand:SWI48 2 "register_operand") + (match_operand:SWI48 3 "nonimmediate_operand"))) (set (match_operand:SWI48 1 "register_operand") - (mod:SWI48 (match_dup 2) (match_dup 3))) + (:SWI48 (match_dup 2) (match_dup 3))) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_8BIT_IDIV && TARGET_QIMODE_MATH @@ -7506,12 +7510,13 @@ (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI - (div:SI (match_operand:SI 2 "register_operand") - (match_operand:SI 3 "nonimmediate_operand")))) + (any_div:SI (match_operand:SI 2 "register_operand") + (match_operand:SI 3 "nonimmediate_operand")))) (set (match_operand:SI 1 "register_operand") - (mod:SI (match_dup 2) (match_dup 3))) + (:SI (match_dup 2) (match_dup 3))) (clobber (reg:CC FLAGS_REG))] - "TARGET_USE_8BIT_IDIV + "TARGET_64BIT + && TARGET_USE_8BIT_IDIV && TARGET_QIMODE_MATH && can_create_pseudo_p () && !optimize_insn_for_size_p ()" @@ -7521,12 +7526,13 @@ (define_split [(set (match_operand:DI 1 "register_operand") (zero_extend:DI - (mod:SI (match_operand:SI 2 "register_operand") - (match_operand:SI 3 "nonimmediate_operand")))) + (:SI (match_operand:SI 2 "register_operand") + (match_operand:SI 3 "nonimmediate_operand")))) (set (match_operand:SI 0 "register_operand") - (div:SI (match_dup 2) (match_dup 3))) + (any_div:SI (match_dup 2) (match_dup 3))) (clobber (reg:CC FLAGS_REG))] - "TARGET_USE_8BIT_IDIV + "TARGET_64BIT + && TARGET_USE_8BIT_IDIV && TARGET_QIMODE_MATH && can_create_pseudo_p () && !optimize_insn_for_size_p ()" @@ -7568,6 +7574,28 @@ [(set_attr "type" "multi") (set_attr "mode" "")]) +(define_insn_and_split "udivmod4_1" + [(set (match_operand:SWI48 0 "register_operand" "=a") + (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") + (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) + (set (match_operand:SWI48 1 "register_operand" "=&d") + (umod:SWI48 (match_dup 2) (match_dup 3))) + (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) + (clobber (reg:CC FLAGS_REG))] + "" + "#" + "reload_completed" + [(set (match_dup 1) (const_int 0)) + (parallel [(set (match_dup 0) + (udiv:SWI48 (match_dup 2) (match_dup 3))) + (set (match_dup 1) + (umod:SWI48 (match_dup 2) (match_dup 3))) + (use (match_dup 1)) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "type" "multi") + (set_attr "mode" "")]) + (define_insn_and_split "divmodsi4_zext_1" [(set (match_operand:DI 0 "register_operand" "=a") (zero_extend:DI @@ -7579,7 +7607,7 @@ (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" - "reload_completed" + "&& reload_completed" [(parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 4) (match_dup 5))) (clobber (reg:CC FLAGS_REG))]) @@ -7604,6 +7632,29 @@ [(set_attr "type" "multi") (set_attr "mode" "SI")]) +(define_insn_and_split "udivmodsi4_zext_1" + [(set (match_operand:DI 0 "register_operand" "=a") + (zero_extend:DI + (udiv:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (set (match_operand:SI 1 "register_operand" "=&d") + (umod:SI (match_dup 2) (match_dup 3))) + (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 1) (const_int 0)) + (parallel [(set (match_dup 0) + (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) + (set (match_dup 1) + (umod:SI (match_dup 2) (match_dup 3))) + (use (match_dup 1)) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + (define_insn_and_split "divmodsi4_zext_2" [(set (match_operand:DI 1 "register_operand" "=&d") (zero_extend:DI @@ -7615,7 +7666,7 @@ (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" - "reload_completed" + "&& reload_completed" [(parallel [(set (match_dup 6) (ashiftrt:SI (match_dup 4) (match_dup 5))) (clobber (reg:CC FLAGS_REG))]) @@ -7641,6 +7692,29 @@ [(set_attr "type" "multi") (set_attr "mode" "SI")]) +(define_insn_and_split "udivmodsi4_zext_2" + [(set (match_operand:DI 1 "register_operand" "=&d") + (zero_extend:DI + (umod:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (set (match_operand:SI 0 "register_operand" "=a") + (udiv:SI (match_dup 2) (match_dup 3))) + (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 4) (const_int 0)) + (parallel [(set (match_dup 1) + (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) + (set (match_dup 0) + (udiv:SI (match_dup 2) (match_dup 3))) + (use (match_dup 4)) + (clobber (reg:CC FLAGS_REG))])] + "operands[4] = gen_lowpart (SImode, operands[1]);" + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + (define_insn_and_split "*divmod4" [(set (match_operand:SWIM248 0 "register_operand" "=a") (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") @@ -7676,6 +7750,52 @@ [(set_attr "type" "multi") (set_attr "mode" "")]) +(define_insn_and_split "*udivmod4" + [(set (match_operand:SWIM248 0 "register_operand" "=a") + (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") + (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) + (set (match_operand:SWIM248 1 "register_operand" "=&d") + (umod:SWIM248 (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "" + "#" + "reload_completed" + [(set (match_dup 1) (const_int 0)) + (parallel [(set (match_dup 0) + (udiv:SWIM248 (match_dup 2) (match_dup 3))) + (set (match_dup 1) + (umod:SWIM248 (match_dup 2) (match_dup 3))) + (use (match_dup 1)) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "type" "multi") + (set_attr "mode" "")]) + +;; Optimize division or modulo by constant power of 2, if the constant +;; materializes only after expansion. +(define_insn_and_split "*udivmod4_pow2" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") + (match_operand:SWI48 3 "const_int_operand" "n"))) + (set (match_operand:SWI48 1 "register_operand" "=r") + (umod:SWI48 (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)" + "#" + "&& reload_completed" + [(set (match_dup 1) (match_dup 2)) + (parallel [(set (match_dup 0) (lshiftrt: (match_dup 2) (match_dup 4))) + (clobber (reg:CC FLAGS_REG))]) + (parallel [(set (match_dup 1) (and: (match_dup 1) (match_dup 5))) + (clobber (reg:CC FLAGS_REG))])] +{ + int v = exact_log2 (UINTVAL (operands[3])); + operands[4] = GEN_INT (v); + operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); +} + [(set_attr "type" "multi") + (set_attr "mode" "")]) + (define_insn_and_split "*divmodsi4_zext_1" [(set (match_operand:DI 0 "register_operand" "=a") (zero_extend:DI @@ -7686,7 +7806,7 @@ (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" - "reload_completed" + "&& reload_completed" [(parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 4) (match_dup 5))) (clobber (reg:CC FLAGS_REG))]) @@ -7711,6 +7831,54 @@ [(set_attr "type" "multi") (set_attr "mode" "SI")]) +(define_insn_and_split "*udivmodsi4_zext_1" + [(set (match_operand:DI 0 "register_operand" "=a") + (zero_extend:DI + (udiv:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (set (match_operand:SI 1 "register_operand" "=&d") + (umod:SI (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 1) (const_int 0)) + (parallel [(set (match_dup 0) + (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) + (set (match_dup 1) + (umod:SI (match_dup 2) (match_dup 3))) + (use (match_dup 1)) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + +(define_insn_and_split "*udivmodsi4_pow2_zext_1" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (udiv:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "const_int_operand" "n")))) + (set (match_operand:SI 1 "register_operand" "=r") + (umod:SI (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT + && exact_log2 (UINTVAL (operands[3])) > 0" + "#" + "&& reload_completed" + [(set (match_dup 1) (match_dup 2)) + (parallel [(set (match_dup 0) + (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4)))) + (clobber (reg:CC FLAGS_REG))]) + (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5))) + (clobber (reg:CC FLAGS_REG))])] +{ + int v = exact_log2 (UINTVAL (operands[3])); + operands[4] = GEN_INT (v); + operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); +} + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + (define_insn_and_split "*divmodsi4_zext_2" [(set (match_operand:DI 1 "register_operand" "=&d") (zero_extend:DI @@ -7721,7 +7889,7 @@ (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" - "reload_completed" + "&& reload_completed" [(parallel [(set (match_dup 6) (ashiftrt:SI (match_dup 4) (match_dup 5))) (clobber (reg:CC FLAGS_REG))]) @@ -7747,44 +7915,93 @@ [(set_attr "type" "multi") (set_attr "mode" "SI")]) -(define_insn "*divmod4_noext" +(define_insn_and_split "*udivmodsi4_zext_2" + [(set (match_operand:DI 1 "register_operand" "=&d") + (zero_extend:DI + (umod:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (set (match_operand:SI 0 "register_operand" "=a") + (udiv:SI (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 4) (const_int 0)) + (parallel [(set (match_dup 1) + (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) + (set (match_dup 0) + (udiv:SI (match_dup 2) (match_dup 3))) + (use (match_dup 4)) + (clobber (reg:CC FLAGS_REG))])] + "operands[4] = gen_lowpart (SImode, operands[1]);" + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + +(define_insn_and_split "*udivmodsi4_pow2_zext_2" + [(set (match_operand:DI 1 "register_operand" "=r") + (zero_extend:DI + (umod:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "const_int_operand" "n")))) + (set (match_operand:SI 0 "register_operand" "=r") + (umod:SI (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT + && exact_log2 (UINTVAL (operands[3])) > 0" + "#" + "&& reload_completed" + [(set (match_dup 1) (match_dup 2)) + (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4))) + (clobber (reg:CC FLAGS_REG))]) + (parallel [(set (match_dup 1) + (zero_extend:DI (and:SI (match_dup 1) (match_dup 5)))) + (clobber (reg:CC FLAGS_REG))])] +{ + int v = exact_log2 (UINTVAL (operands[3])); + operands[4] = GEN_INT (v); + operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); +} + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + +(define_insn "*divmod4_noext" [(set (match_operand:SWIM248 0 "register_operand" "=a") - (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") - (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) + (any_div:SWIM248 + (match_operand:SWIM248 2 "register_operand" "0") + (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) (set (match_operand:SWIM248 1 "register_operand" "=d") - (mod:SWIM248 (match_dup 2) (match_dup 3))) + (:SWIM248 (match_dup 2) (match_dup 3))) (use (match_operand:SWIM248 4 "register_operand" "1")) (clobber (reg:CC FLAGS_REG))] "" - "idiv{}\t%3" + "div{}\t%3" [(set_attr "type" "idiv") (set_attr "mode" "")]) -(define_insn "*divmodsi4_noext_zext_1" +(define_insn "*divmodsi4_noext_zext_1" [(set (match_operand:DI 0 "register_operand" "=a") (zero_extend:DI - (div:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (any_div:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) (set (match_operand:SI 1 "register_operand" "=d") - (mod:SI (match_dup 2) (match_dup 3))) + (:SI (match_dup 2) (match_dup 3))) (use (match_operand:SI 4 "register_operand" "1")) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" - "idiv{l}\t%3" + "div{l}\t%3" [(set_attr "type" "idiv") (set_attr "mode" "SI")]) -(define_insn "*divmodsi4_noext_zext_2" +(define_insn "*divmodsi4_noext_zext_2" [(set (match_operand:DI 1 "register_operand" "=d") (zero_extend:DI - (mod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) (set (match_operand:SI 0 "register_operand" "=a") - (div:SI (match_dup 2) (match_dup 3))) + (any_div:SI (match_dup 2) (match_dup 3))) (use (match_operand:SI 4 "register_operand" "1")) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" - "idiv{l}\t%3" + "div{l}\t%3" [(set_attr "type" "idiv") (set_attr "mode" "SI")]) @@ -7800,7 +8017,7 @@ { rtx div, mod; rtx tmp0, tmp1; - + tmp0 = gen_reg_rtx (HImode); tmp1 = gen_reg_rtx (HImode); @@ -7825,345 +8042,6 @@ DONE; }) -;; Divide AX by r/m8, with result stored in -;; AL <- Quotient -;; AH <- Remainder -;; Change div/mod to HImode and extend the second argument to HImode -;; so that mode of div/mod matches with mode of arguments. Otherwise -;; combine may fail. -(define_insn "divmodhiqi3" - [(set (match_operand:HI 0 "register_operand" "=a") - (ior:HI - (ashift:HI - (zero_extend:HI - (truncate:QI - (mod:HI (match_operand:HI 1 "register_operand" "0") - (sign_extend:HI - (match_operand:QI 2 "nonimmediate_operand" "qm"))))) - (const_int 8)) - (zero_extend:HI - (truncate:QI - (div:HI (match_dup 1) (sign_extend:HI (match_dup 2))))))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_QIMODE_MATH" - "idiv{b}\t%2" - [(set_attr "type" "idiv") - (set_attr "mode" "QI")]) - -(define_expand "udivmod4" - [(parallel [(set (match_operand:SWIM248 0 "register_operand") - (udiv:SWIM248 - (match_operand:SWIM248 1 "register_operand") - (match_operand:SWIM248 2 "nonimmediate_operand"))) - (set (match_operand:SWIM248 3 "register_operand") - (umod:SWIM248 (match_dup 1) (match_dup 2))) - (clobber (reg:CC FLAGS_REG))])]) - -;; Split with 8bit unsigned divide: -;; if (dividend an divisor are in [0-255]) -;; use 8bit unsigned integer divide -;; else -;; use original integer divide -(define_split - [(set (match_operand:SWI48 0 "register_operand") - (udiv:SWI48 (match_operand:SWI48 2 "register_operand") - (match_operand:SWI48 3 "nonimmediate_operand"))) - (set (match_operand:SWI48 1 "register_operand") - (umod:SWI48 (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_USE_8BIT_IDIV - && TARGET_QIMODE_MATH - && can_create_pseudo_p () - && !optimize_insn_for_size_p ()" - [(const_int 0)] - "ix86_split_idivmod (mode, operands, false); DONE;") - -(define_split - [(set (match_operand:DI 0 "register_operand") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand") - (match_operand:SI 3 "nonimmediate_operand")))) - (set (match_operand:SI 1 "register_operand") - (umod:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && TARGET_USE_8BIT_IDIV - && TARGET_QIMODE_MATH - && can_create_pseudo_p () - && !optimize_insn_for_size_p ()" - [(const_int 0)] - "ix86_split_idivmod (SImode, operands, false); DONE;") - -(define_split - [(set (match_operand:DI 1 "register_operand") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand") - (match_operand:SI 3 "nonimmediate_operand")))) - (set (match_operand:SI 0 "register_operand") - (udiv:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && TARGET_USE_8BIT_IDIV - && TARGET_QIMODE_MATH - && can_create_pseudo_p () - && !optimize_insn_for_size_p ()" - [(const_int 0)] - "ix86_split_idivmod (SImode, operands, false); DONE;") - -(define_insn_and_split "udivmod4_1" - [(set (match_operand:SWI48 0 "register_operand" "=a") - (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") - (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) - (set (match_operand:SWI48 1 "register_operand" "=&d") - (umod:SWI48 (match_dup 2) (match_dup 3))) - (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) - (clobber (reg:CC FLAGS_REG))] - "" - "#" - "reload_completed" - [(set (match_dup 1) (const_int 0)) - (parallel [(set (match_dup 0) - (udiv:SWI48 (match_dup 2) (match_dup 3))) - (set (match_dup 1) - (umod:SWI48 (match_dup 2) (match_dup 3))) - (use (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] - "" - [(set_attr "type" "multi") - (set_attr "mode" "")]) - -(define_insn_and_split "udivmodsi4_zext_1" - [(set (match_operand:DI 0 "register_operand" "=a") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 1 "register_operand" "=&d") - (umod:SI (match_dup 2) (match_dup 3))) - (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "#" - "reload_completed" - [(set (match_dup 1) (const_int 0)) - (parallel [(set (match_dup 0) - (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) - (set (match_dup 1) - (umod:SI (match_dup 2) (match_dup 3))) - (use (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] - "" - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn_and_split "udivmodsi4_zext_2" - [(set (match_operand:DI 1 "register_operand" "=&d") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 0 "register_operand" "=a") - (udiv:SI (match_dup 2) (match_dup 3))) - (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "#" - "reload_completed" - [(set (match_dup 4) (const_int 0)) - (parallel [(set (match_dup 1) - (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) - (set (match_dup 0) - (udiv:SI (match_dup 2) (match_dup 3))) - (use (match_dup 4)) - (clobber (reg:CC FLAGS_REG))])] - "operands[4] = gen_lowpart (SImode, operands[1]);" - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn_and_split "*udivmod4" - [(set (match_operand:SWIM248 0 "register_operand" "=a") - (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") - (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) - (set (match_operand:SWIM248 1 "register_operand" "=&d") - (umod:SWIM248 (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "" - "#" - "reload_completed" - [(set (match_dup 1) (const_int 0)) - (parallel [(set (match_dup 0) - (udiv:SWIM248 (match_dup 2) (match_dup 3))) - (set (match_dup 1) - (umod:SWIM248 (match_dup 2) (match_dup 3))) - (use (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] - "" - [(set_attr "type" "multi") - (set_attr "mode" "")]) - -(define_insn_and_split "*udivmodsi4_zext_1" - [(set (match_operand:DI 0 "register_operand" "=a") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 1 "register_operand" "=&d") - (umod:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "#" - "reload_completed" - [(set (match_dup 1) (const_int 0)) - (parallel [(set (match_dup 0) - (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) - (set (match_dup 1) - (umod:SI (match_dup 2) (match_dup 3))) - (use (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] - "" - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn_and_split "*udivmodsi4_zext_2" - [(set (match_operand:DI 1 "register_operand" "=&d") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 0 "register_operand" "=a") - (udiv:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "#" - "reload_completed" - [(set (match_dup 4) (const_int 0)) - (parallel [(set (match_dup 1) - (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) - (set (match_dup 0) - (udiv:SI (match_dup 2) (match_dup 3))) - (use (match_dup 4)) - (clobber (reg:CC FLAGS_REG))])] - "operands[4] = gen_lowpart (SImode, operands[1]);" - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -;; Optimize division or modulo by constant power of 2, if the constant -;; materializes only after expansion. -(define_insn_and_split "*udivmod4_pow2" - [(set (match_operand:SWI48 0 "register_operand" "=r") - (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") - (match_operand:SWI48 3 "const_int_operand" "n"))) - (set (match_operand:SWI48 1 "register_operand" "=r") - (umod:SWI48 (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) - && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" - "#" - "&& 1" - [(set (match_dup 1) (match_dup 2)) - (parallel [(set (match_dup 0) (lshiftrt: (match_dup 2) (match_dup 4))) - (clobber (reg:CC FLAGS_REG))]) - (parallel [(set (match_dup 1) (and: (match_dup 1) (match_dup 5))) - (clobber (reg:CC FLAGS_REG))])] -{ - int v = exact_log2 (UINTVAL (operands[3])); - operands[4] = GEN_INT (v); - operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); -} - [(set_attr "type" "multi") - (set_attr "mode" "")]) - -(define_insn_and_split "*udivmodsi4_pow2_zext_1" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "const_int_operand" "n")))) - (set (match_operand:SI 1 "register_operand" "=r") - (umod:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) - && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" - "#" - "&& 1" - [(set (match_dup 1) (match_dup 2)) - (parallel [(set (match_dup 0) - (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4)))) - (clobber (reg:CC FLAGS_REG))]) - (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5))) - (clobber (reg:CC FLAGS_REG))])] -{ - int v = exact_log2 (UINTVAL (operands[3])); - operands[4] = GEN_INT (v); - operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); -} - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn_and_split "*udivmodsi4_pow2_zext_2" - [(set (match_operand:DI 1 "register_operand" "=r") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "const_int_operand" "n")))) - (set (match_operand:SI 0 "register_operand" "=r") - (umod:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) - && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" - "#" - "&& 1" - [(set (match_dup 1) (match_dup 2)) - (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4))) - (clobber (reg:CC FLAGS_REG))]) - (parallel [(set (match_dup 1) - (zero_extend:DI (and:SI (match_dup 1) (match_dup 5)))) - (clobber (reg:CC FLAGS_REG))])] -{ - int v = exact_log2 (UINTVAL (operands[3])); - operands[4] = GEN_INT (v); - operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); -} - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn "*udivmod4_noext" - [(set (match_operand:SWIM248 0 "register_operand" "=a") - (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") - (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) - (set (match_operand:SWIM248 1 "register_operand" "=d") - (umod:SWIM248 (match_dup 2) (match_dup 3))) - (use (match_operand:SWIM248 4 "register_operand" "1")) - (clobber (reg:CC FLAGS_REG))] - "" - "div{}\t%3" - [(set_attr "type" "idiv") - (set_attr "mode" "")]) - -(define_insn "*udivmodsi4_noext_zext_1" - [(set (match_operand:DI 0 "register_operand" "=a") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 1 "register_operand" "=d") - (umod:SI (match_dup 2) (match_dup 3))) - (use (match_operand:SI 4 "register_operand" "1")) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "div{l}\t%3" - [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - -(define_insn "*udivmodsi4_noext_zext_2" - [(set (match_operand:DI 1 "register_operand" "=d") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 0 "register_operand" "=a") - (udiv:SI (match_dup 2) (match_dup 3))) - (use (match_operand:SI 4 "register_operand" "1")) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "div{l}\t%3" - [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - (define_expand "udivmodqi4" [(parallel [(set (match_operand:QI 0 "register_operand") (udiv:QI @@ -8176,7 +8054,7 @@ { rtx div, mod; rtx tmp0, tmp1; - + tmp0 = gen_reg_rtx (HImode); tmp1 = gen_reg_rtx (HImode); @@ -8201,22 +8079,28 @@ DONE; }) -(define_insn "udivmodhiqi3" +;; Divide AX by r/m8, with result stored in +;; AL <- Quotient +;; AH <- Remainder +;; Change div/mod to HImode and extend the second argument to HImode +;; so that mode of div/mod matches with mode of arguments. Otherwise +;; combine may fail. +(define_insn "divmodhiqi3" [(set (match_operand:HI 0 "register_operand" "=a") (ior:HI (ashift:HI (zero_extend:HI (truncate:QI (mod:HI (match_operand:HI 1 "register_operand" "0") - (zero_extend:HI + (any_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))) (const_int 8)) (zero_extend:HI (truncate:QI - (div:HI (match_dup 1) (zero_extend:HI (match_dup 2))))))) + (div:HI (match_dup 1) (any_extend:HI (match_dup 2))))))) (clobber (reg:CC FLAGS_REG))] "TARGET_QIMODE_MATH" - "div{b}\t%2" + "div{b}\t%2" [(set_attr "type" "idiv") (set_attr "mode" "QI")])