From patchwork Sun Sep 19 12:45:31 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 65156 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]) by ozlabs.org (Postfix) with SMTP id 0CB02B70D0 for ; Sun, 19 Sep 2010 22:45:43 +1000 (EST) Received: (qmail 24542 invoked by alias); 19 Sep 2010 12:45:41 -0000 Received: (qmail 24533 invoked by uid 22791); 19 Sep 2010 12:45:39 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, TW_ZJ, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-qw0-f47.google.com (HELO mail-qw0-f47.google.com) (209.85.216.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 19 Sep 2010 12:45:33 +0000 Received: by qwa26 with SMTP id 26so12707qwa.20 for ; Sun, 19 Sep 2010 05:45:31 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.218.69 with SMTP id hp5mr5384412qcb.18.1284900331679; Sun, 19 Sep 2010 05:45:31 -0700 (PDT) Received: by 10.229.182.15 with HTTP; Sun, 19 Sep 2010 05:45:31 -0700 (PDT) Date: Sun, 19 Sep 2010 14:45:31 +0200 Message-ID: Subject: [PATCH, i386]: Introduce split_double_mode From: Uros Bizjak To: gcc-patches@gcc.gnu.org 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 Hello! This function substitutes both split_di and split_ti, mainly to avoid constructs like: (mode == DImode ? split_di : split_ti) (...) 2010-09-19 Uros Bizjak * config/i386/i386-protos.h (split_double_mode): New prototype. (split_di, split_ti): Remove prototypes. * config/i386/i386.c (split_double_mode): New function. (split_di, split_ti): Remove. (ix86_expand_branch): Use split_double_mode. (ix86_split_to_parts): Ditto. (ix86_split_ashl): Ditto. (ix86_split_ashr): Ditto. (ix86_split_lshr): Ditto. (ix86_force_to_memory): Ditto. * config/i386/i386.md: Use split_double_mode in double-mode splitters. Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN. Uros. Index: i386.md =================================================================== --- i386.md (revision 164410) +++ i386.md (working copy) @@ -1640,7 +1640,7 @@ [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (match_dup 3))] { - split_di (&operands[1], 1, &operands[2], &operands[3]); + split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); operands[1] = gen_lowpart (DImode, operands[2]); operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, @@ -1657,7 +1657,7 @@ [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (match_dup 3))] { - split_di (&operands[1], 1, &operands[2], &operands[3]); + split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); operands[1] = gen_lowpart (DImode, operands[2]); operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, @@ -2050,7 +2050,7 @@ && !x86_64_immediate_operand (operands[1], DImode) && 1" [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))] - "split_di (&operands[0], 2, &operands[2], &operands[4]);") + "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);") (define_split [(set (match_operand:DI 0 "memory_operand" "") @@ -2061,7 +2061,7 @@ && !x86_64_immediate_operand (operands[1], DImode)" [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))] - "split_di (&operands[0], 2, &operands[2], &operands[4]);") + "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);") (define_insn "*movdi_internal" [(set (match_operand:DI 0 "nonimmediate_operand" @@ -3598,7 +3598,7 @@ (zero_extend:DI (match_dup 0)))] "TARGET_64BIT" [(set (match_dup 4) (const_int 0))] - "split_di (&operands[0], 1, &operands[3], &operands[4]);") + "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") ;; %%% Kill me once multi-word ops are sane. (define_insn "zero_extendsidi2_1" @@ -3626,7 +3626,7 @@ "!TARGET_64BIT && reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])" [(set (match_dup 4) (const_int 0))] - "split_di (&operands[0], 1, &operands[3], &operands[4]);") + "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") (define_split [(set (match_operand:DI 0 "nonimmediate_operand" "") @@ -3636,7 +3636,7 @@ && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))" [(set (match_dup 3) (match_dup 1)) (set (match_dup 4) (const_int 0))] - "split_di (&operands[0], 1, &operands[3], &operands[4]);") + "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") (define_insn "zero_extenddi2" [(set (match_operand:DI 0 "register_operand" "=r") @@ -3801,7 +3801,7 @@ (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) (clobber (reg:CC FLAGS_REG))]) (set (match_dup 4) (match_dup 1))] - "split_di (&operands[0], 1, &operands[3], &operands[4]);") + "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") ;; Extend to memory case when source register does not die. (define_split @@ -3812,7 +3812,7 @@ "reload_completed" [(const_int 0)] { - split_di (&operands[0], 1, &operands[3], &operands[4]); + split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); emit_move_insn (operands[3], operands[1]); @@ -3842,7 +3842,7 @@ "reload_completed" [(const_int 0)] { - split_di (&operands[0], 1, &operands[3], &operands[4]); + split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); if (true_regnum (operands[3]) != true_regnum (operands[1])) emit_move_insn (operands[3], operands[1]); @@ -5570,7 +5570,7 @@ (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) (match_dup 5)))) (clobber (reg:CC FLAGS_REG))])] - "split_ (&operands[0], 3, &operands[0], &operands[3]);") + "split_double_mode (mode, &operands[0], 3, &operands[0], &operands[3]);") (define_insn "*add3_cc" [(set (reg:CC FLAGS_REG) @@ -6600,7 +6600,7 @@ (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) (match_dup 5)))) (clobber (reg:CC FLAGS_REG))])] - "split_ (&operands[0], 3, &operands[0], &operands[3]);") + "split_double_mode (mode, &operands[0], 3, &operands[0], &operands[3]);") (define_insn "*sub_1" [(set (match_operand:SWI 0 "nonimmediate_operand" "=m,") @@ -8593,7 +8593,7 @@ [(set (match_dup 2) (neg:DWIH (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] - "split_ (&operands[0], 2, &operands[0], &operands[2]);") + "split_double_mode (mode, &operands[0], 2, &operands[0], &operands[2]);") (define_insn "*neg2_1" [(set (match_operand:SWI 0 "nonimmediate_operand" "=m") @@ -10072,7 +10072,7 @@ { operands[6] = GEN_INT (GET_MODE_BITSIZE (mode)); - split_ (&operands[0], 1, &operands[4], &operands[5]); + split_double_mode (mode, &operands[0], 1, &operands[4], &operands[5]); }) (define_insn_and_split "ix86_rotr3_doubleword" @@ -10100,7 +10100,7 @@ { operands[6] = GEN_INT (GET_MODE_BITSIZE (mode)); - split_ (&operands[0], 1, &operands[4], &operands[5]); + split_double_mode (mode, &operands[0], 1, &operands[4], &operands[5]); }) (define_insn "*3_1" @@ -16055,8 +16055,8 @@ (match_dup 7) (match_dup 8)))] { - split_di (&operands[2], 2, &operands[5], &operands[7]); - split_di (&operands[0], 1, &operands[2], &operands[3]); + split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]); + split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]); }) (define_insn "*movxfcc_1" Index: i386-protos.h =================================================================== --- i386-protos.h (revision 164410) +++ i386-protos.h (working copy) @@ -64,8 +64,7 @@ extern bool legitimate_pic_address_disp_ extern void print_reg (rtx, int, FILE*); extern void ix86_print_operand (FILE *, rtx, int); -extern void split_di (rtx[], int, rtx[], rtx[]); -extern void split_ti (rtx[], int, rtx[], rtx[]); +extern void split_double_mode (enum machine_mode, rtx[], int, rtx[], rtx[]); extern const char *output_set_got (rtx, rtx); extern const char *output_387_binary_op (rtx, rtx*); Index: i386.c =================================================================== --- i386.c (revision 164410) +++ i386.c (working copy) @@ -13248,15 +13248,33 @@ i386_asm_output_addr_const_extra (FILE * return true; } -/* Split one or more DImode RTL references into pairs of SImode +/* Split one or more double-mode RTL references into pairs of half-mode references. The RTL can be REG, offsettable MEM, integer constant, or - CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to + CONST_DOUBLE. "operands" is a pointer to an array of double-mode RTLs to split and "num" is its length. lo_half and hi_half are output arrays that parallel "operands". */ void -split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[]) +split_double_mode (enum machine_mode mode, rtx operands[], + int num, rtx lo_half[], rtx hi_half[]) { + enum machine_mode half_mode; + unsigned int byte; + + switch (mode) + { + case TImode: + half_mode = DImode; + break; + case DImode: + half_mode = SImode; + break; + default: + gcc_unreachable (); + } + + byte = GET_MODE_SIZE (half_mode); + while (num--) { rtx op = operands[num]; @@ -13265,44 +13283,17 @@ split_di (rtx operands[], int num, rtx l but we still have to handle it. */ if (MEM_P (op)) { - lo_half[num] = adjust_address (op, SImode, 0); - hi_half[num] = adjust_address (op, SImode, 4); + lo_half[num] = adjust_address (op, half_mode, 0); + hi_half[num] = adjust_address (op, half_mode, byte); } else { - lo_half[num] = simplify_gen_subreg (SImode, op, + lo_half[num] = simplify_gen_subreg (half_mode, op, GET_MODE (op) == VOIDmode - ? DImode : GET_MODE (op), 0); - hi_half[num] = simplify_gen_subreg (SImode, op, + ? mode : GET_MODE (op), 0); + hi_half[num] = simplify_gen_subreg (half_mode, op, GET_MODE (op) == VOIDmode - ? DImode : GET_MODE (op), 4); - } - } -} -/* Split one or more TImode RTL references into pairs of DImode - references. The RTL can be REG, offsettable MEM, integer constant, or - CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to - split and "num" is its length. lo_half and hi_half are output arrays - that parallel "operands". */ - -void -split_ti (rtx operands[], int num, rtx lo_half[], rtx hi_half[]) -{ - while (num--) - { - rtx op = operands[num]; - - /* simplify_subreg refuse to split volatile memory addresses, but we - still have to handle it. */ - if (MEM_P (op)) - { - lo_half[num] = adjust_address (op, DImode, 0); - hi_half[num] = adjust_address (op, DImode, 8); - } - else - { - lo_half[num] = simplify_gen_subreg (DImode, op, TImode, 0); - hi_half[num] = simplify_gen_subreg (DImode, op, TImode, 8); + ? mode : GET_MODE (op), byte); } } } @@ -16273,9 +16264,10 @@ ix86_expand_compare (enum rtx_code code, void ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label) { + enum machine_mode mode = GET_MODE (op0); rtx tmp; - switch (GET_MODE (op0)) + switch (mode) { case SFmode: case DFmode: @@ -16306,18 +16298,11 @@ ix86_expand_branch (enum rtx_code code, tmp = op0, op0 = op1, op1 = tmp; code = swap_condition (code); } - if (GET_MODE (op0) == DImode) - { - split_di (&op0, 1, lo+0, hi+0); - split_di (&op1, 1, lo+1, hi+1); - submode = SImode; - } - else - { - split_ti (&op0, 1, lo+0, hi+0); - split_ti (&op1, 1, lo+1, hi+1); - submode = DImode; - } + + split_double_mode (mode, &op0, 1, lo+0, hi+0); + split_double_mode (mode, &op1, 1, lo+1, hi+1); + + submode = mode == DImode ? SImode : DImode; /* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to avoid two branches. This costs one extra insn, so disable when @@ -16474,7 +16459,7 @@ ix86_expand_carry_flag_compare (enum rtx enum machine_mode mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1); - /* Do not handle DImode compares that go through special path. */ + /* Do not handle double-mode compares that go through special path. */ if (mode == (TARGET_64BIT ? TImode : DImode)) return false; @@ -17686,8 +17671,8 @@ ix86_expand_int_addcc (rtx operands[]) } -/* Split operands 0 and 1 into SImode parts. Similar to split_di, but - works for floating pointer parameters and nonoffsetable memories. +/* Split operands 0 and 1 into half-mode parts. Similar to split_double_mode, + but works for floating pointer parameters and nonoffsetable memories. For pushes, it returns just stack offsets; the values will be saved in the right order. Maximally three parts are generated. */ @@ -17740,7 +17725,7 @@ ix86_split_to_parts (rtx operand, rtx *p if (!TARGET_64BIT) { if (mode == DImode) - split_di (&operand, 1, &parts[0], &parts[1]); + split_double_mode (mode, &operand, 1, &parts[0], &parts[1]); else { int i; @@ -17791,7 +17776,7 @@ ix86_split_to_parts (rtx operand, rtx *p else { if (mode == TImode) - split_ti (&operand, 1, &parts[0], &parts[1]); + split_double_mode (mode, &operand, 1, &parts[0], &parts[1]); if (mode == XFmode || mode == TFmode) { enum machine_mode upper_mode = mode==XFmode ? SImode : DImode; @@ -17862,7 +17847,7 @@ ix86_split_long_move (rtx operands[]) /* The DFmode expanders may ask us to move double. For 64bit target this is single move. By hiding the fact here we simplify i386.md splitters. */ - if (GET_MODE_SIZE (GET_MODE (operands[0])) == 8 && TARGET_64BIT) + if (TARGET_64BIT && GET_MODE_SIZE (GET_MODE (operands[0])) == 8) { /* Optimize constant pool reference to immediates. This is used by fp moves, that force all constants to memory to allow combining. */ @@ -18104,7 +18089,7 @@ ix86_split_ashl (rtx *operands, rtx scra if (CONST_INT_P (operands[2])) { - (mode == DImode ? split_di : split_ti) (operands, 2, low, high); + split_double_mode (mode, operands, 2, low, high); count = INTVAL (operands[2]) & (single_width * 2 - 1); if (count >= single_width) @@ -18127,7 +18112,7 @@ ix86_split_ashl (rtx *operands, rtx scra return; } - (mode == DImode ? split_di : split_ti) (operands, 1, low, high); + split_double_mode (mode, operands, 1, low, high); if (operands[1] == const1_rtx) { @@ -18204,7 +18189,7 @@ ix86_split_ashl (rtx *operands, rtx scra if (!rtx_equal_p (operands[0], operands[1])) emit_move_insn (operands[0], operands[1]); - (mode == DImode ? split_di : split_ti) (operands, 1, low, high); + split_double_mode (mode, operands, 1, low, high); emit_insn ((mode == DImode ? gen_x86_shld : gen_x86_64_shld) (high[0], low[0], operands[2])); @@ -18237,7 +18222,7 @@ ix86_split_ashr (rtx *operands, rtx scra if (CONST_INT_P (operands[2])) { - (mode == DImode ? split_di : split_ti) (operands, 2, low, high); + split_double_mode (mode, operands, 2, low, high); count = INTVAL (operands[2]) & (single_width * 2 - 1); if (count == single_width * 2 - 1) @@ -18281,7 +18266,7 @@ ix86_split_ashr (rtx *operands, rtx scra if (!rtx_equal_p (operands[0], operands[1])) emit_move_insn (operands[0], operands[1]); - (mode == DImode ? split_di : split_ti) (operands, 1, low, high); + split_double_mode (mode, operands, 1, low, high); emit_insn ((mode == DImode ? gen_x86_shrd @@ -18318,7 +18303,7 @@ ix86_split_lshr (rtx *operands, rtx scra if (CONST_INT_P (operands[2])) { - (mode == DImode ? split_di : split_ti) (operands, 2, low, high); + split_double_mode (mode, operands, 2, low, high); count = INTVAL (operands[2]) & (single_width * 2 - 1); if (count >= single_width) @@ -18349,7 +18334,7 @@ ix86_split_lshr (rtx *operands, rtx scra if (!rtx_equal_p (operands[0], operands[1])) emit_move_insn (operands[0], operands[1]); - (mode == DImode ? split_di : split_ti) (operands, 1, low, high); + split_double_mode (mode, operands, 1, low, high); emit_insn ((mode == DImode ? gen_x86_shrd @@ -26144,7 +26129,7 @@ ix86_force_to_memory (enum machine_mode case DImode: { rtx operands[2]; - split_di (&operand, 1, operands, operands + 1); + split_double_mode (mode, &operand, 1, operands, operands + 1); emit_insn ( gen_rtx_SET (VOIDmode, gen_rtx_MEM (SImode,