comparison gcc/expmed.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
comparison
equal deleted inserted replaced
56:3c8a44c06a95 63:b7f97abdc517
1 /* Medium-level subroutines: convert bit-field store and extract 1 /* Medium-level subroutines: convert bit-field store and extract
2 and shifts, multiplies and divides to rtl instructions. 2 and shifts, multiplies and divides to rtl instructions.
3 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 4 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 Free Software Foundation, Inc. 5 Free Software Foundation, Inc.
6 6
7 This file is part of GCC. 7 This file is part of GCC.
8 8
9 GCC is free software; you can redistribute it and/or modify it under 9 GCC is free software; you can redistribute it and/or modify it under
31 #include "tm_p.h" 31 #include "tm_p.h"
32 #include "flags.h" 32 #include "flags.h"
33 #include "insn-config.h" 33 #include "insn-config.h"
34 #include "expr.h" 34 #include "expr.h"
35 #include "optabs.h" 35 #include "optabs.h"
36 #include "real.h"
37 #include "recog.h" 36 #include "recog.h"
38 #include "langhooks.h" 37 #include "langhooks.h"
39 #include "df.h" 38 #include "df.h"
40 #include "target.h" 39 #include "target.h"
41 40
696 if (GET_CODE (xop0) == SUBREG) 695 if (GET_CODE (xop0) == SUBREG)
697 /* We can't just change the mode, because this might clobber op0, 696 /* We can't just change the mode, because this might clobber op0,
698 and we will need the original value of op0 if insv fails. */ 697 and we will need the original value of op0 if insv fails. */
699 xop0 = gen_rtx_SUBREG (op_mode, SUBREG_REG (xop0), SUBREG_BYTE (xop0)); 698 xop0 = gen_rtx_SUBREG (op_mode, SUBREG_REG (xop0), SUBREG_BYTE (xop0));
700 if (REG_P (xop0) && GET_MODE (xop0) != op_mode) 699 if (REG_P (xop0) && GET_MODE (xop0) != op_mode)
701 xop0 = gen_rtx_SUBREG (op_mode, xop0, 0); 700 xop0 = gen_lowpart_SUBREG (op_mode, xop0);
702 701
703 /* If the destination is a paradoxical subreg such that we need a 702 /* If the destination is a paradoxical subreg such that we need a
704 truncate to the inner mode, perform the insertion on a temporary and 703 truncate to the inner mode, perform the insertion on a temporary and
705 truncate the result to the original destination. Note that we can't 704 truncate the result to the original destination. Note that we can't
706 just truncate the paradoxical subreg as (truncate:N (subreg:W (reg:N 705 just truncate the paradoxical subreg as (truncate:N (subreg:W (reg:N
1540 rtx pat; 1539 rtx pat;
1541 1540
1542 /* If op0 is a register, we need it in EXT_MODE to make it 1541 /* If op0 is a register, we need it in EXT_MODE to make it
1543 acceptable to the format of ext(z)v. */ 1542 acceptable to the format of ext(z)v. */
1544 if (REG_P (xop0) && GET_MODE (xop0) != ext_mode) 1543 if (REG_P (xop0) && GET_MODE (xop0) != ext_mode)
1545 xop0 = gen_rtx_SUBREG (ext_mode, xop0, 0); 1544 xop0 = gen_lowpart_SUBREG (ext_mode, xop0);
1546 if (MEM_P (xop0)) 1545 if (MEM_P (xop0))
1547 /* Get ref to first byte containing part of the field. */ 1546 /* Get ref to first byte containing part of the field. */
1548 xop0 = adjust_address (xop0, byte_mode, xoffset); 1547 xop0 = adjust_address (xop0, byte_mode, xoffset);
1549 1548
1550 /* On big-endian machines, we count bits from the most significant. 1549 /* On big-endian machines, we count bits from the most significant.
1837 BITSIZE+BITPOS is too small for MODE. */ 1836 BITSIZE+BITPOS is too small for MODE. */
1838 1837
1839 static rtx 1838 static rtx
1840 mask_rtx (enum machine_mode mode, int bitpos, int bitsize, int complement) 1839 mask_rtx (enum machine_mode mode, int bitpos, int bitsize, int complement)
1841 { 1840 {
1842 HOST_WIDE_INT masklow, maskhigh; 1841 double_int mask;
1843 1842
1844 if (bitsize == 0) 1843 mask = double_int_mask (bitsize);
1845 masklow = 0; 1844 mask = double_int_lshift (mask, bitpos, HOST_BITS_PER_DOUBLE_INT, false);
1846 else if (bitpos < HOST_BITS_PER_WIDE_INT)
1847 masklow = (HOST_WIDE_INT) -1 << bitpos;
1848 else
1849 masklow = 0;
1850
1851 if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT)
1852 masklow &= ((unsigned HOST_WIDE_INT) -1
1853 >> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1854
1855 if (bitpos <= HOST_BITS_PER_WIDE_INT)
1856 maskhigh = -1;
1857 else
1858 maskhigh = (HOST_WIDE_INT) -1 << (bitpos - HOST_BITS_PER_WIDE_INT);
1859
1860 if (bitsize == 0)
1861 maskhigh = 0;
1862 else if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT)
1863 maskhigh &= ((unsigned HOST_WIDE_INT) -1
1864 >> (2 * HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1865 else
1866 maskhigh = 0;
1867 1845
1868 if (complement) 1846 if (complement)
1869 { 1847 mask = double_int_not (mask);
1870 maskhigh = ~maskhigh; 1848
1871 masklow = ~masklow; 1849 return immed_double_int_const (mask, mode);
1872 }
1873
1874 return immed_double_const (masklow, maskhigh, mode);
1875 } 1850 }
1876 1851
1877 /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value 1852 /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
1878 VALUE truncated to BITSIZE bits and then shifted left BITPOS bits. */ 1853 VALUE truncated to BITSIZE bits and then shifted left BITPOS bits. */
1879 1854
1880 static rtx 1855 static rtx
1881 lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize) 1856 lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize)
1882 { 1857 {
1883 unsigned HOST_WIDE_INT v = INTVAL (value); 1858 double_int val;
1884 HOST_WIDE_INT low, high; 1859
1885 1860 val = double_int_zext (uhwi_to_double_int (INTVAL (value)), bitsize);
1886 if (bitsize < HOST_BITS_PER_WIDE_INT) 1861 val = double_int_lshift (val, bitpos, HOST_BITS_PER_DOUBLE_INT, false);
1887 v &= ~((HOST_WIDE_INT) -1 << bitsize); 1862
1888 1863 return immed_double_int_const (val, mode);
1889 if (bitpos < HOST_BITS_PER_WIDE_INT)
1890 {
1891 low = v << bitpos;
1892 high = (bitpos > 0 ? (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) : 0);
1893 }
1894 else
1895 {
1896 low = 0;
1897 high = v << (bitpos - HOST_BITS_PER_WIDE_INT);
1898 }
1899
1900 return immed_double_const (low, high, mode);
1901 } 1864 }
1902 1865
1903 /* Extract a bit field that is split across two words 1866 /* Extract a bit field that is split across two words
1904 and return an RTX for the result. 1867 and return an RTX for the result.
1905 1868
3250 && flag_trapv && (GET_MODE_CLASS(mode) == MODE_INT) 3213 && flag_trapv && (GET_MODE_CLASS(mode) == MODE_INT)
3251 ? smulv_optab : smul_optab, 3214 ? smulv_optab : smul_optab,
3252 op0, op1, target, unsignedp, OPTAB_LIB_WIDEN); 3215 op0, op1, target, unsignedp, OPTAB_LIB_WIDEN);
3253 gcc_assert (op0); 3216 gcc_assert (op0);
3254 return op0; 3217 return op0;
3218 }
3219
3220 /* Perform a widening multiplication and return an rtx for the result.
3221 MODE is mode of value; OP0 and OP1 are what to multiply (rtx's);
3222 TARGET is a suggestion for where to store the result (an rtx).
3223 THIS_OPTAB is the optab we should use, it must be either umul_widen_optab
3224 or smul_widen_optab.
3225
3226 We check specially for a constant integer as OP1, comparing the
3227 cost of a widening multiply against the cost of a sequence of shifts
3228 and adds. */
3229
3230 rtx
3231 expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3232 int unsignedp, optab this_optab)
3233 {
3234 bool speed = optimize_insn_for_speed_p ();
3235
3236 if (CONST_INT_P (op1)
3237 && (INTVAL (op1) >= 0
3238 || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT))
3239 {
3240 HOST_WIDE_INT coeff = INTVAL (op1);
3241 int max_cost;
3242 enum mult_variant variant;
3243 struct algorithm algorithm;
3244
3245 /* Special case powers of two. */
3246 if (EXACT_POWER_OF_2_OR_ZERO_P (coeff))
3247 {
3248 op0 = convert_to_mode (mode, op0, this_optab == umul_widen_optab);
3249 return expand_shift (LSHIFT_EXPR, mode, op0,
3250 build_int_cst (NULL_TREE, floor_log2 (coeff)),
3251 target, unsignedp);
3252 }
3253
3254 /* Exclude cost of op0 from max_cost to match the cost
3255 calculation of the synth_mult. */
3256 max_cost = mul_widen_cost[speed][mode];
3257 if (choose_mult_variant (mode, coeff, &algorithm, &variant,
3258 max_cost))
3259 {
3260 op0 = convert_to_mode (mode, op0, this_optab == umul_widen_optab);
3261 return expand_mult_const (mode, op0, coeff, target,
3262 &algorithm, variant);
3263 }
3264 }
3265 return expand_binop (mode, this_optab, op0, op1, target,
3266 unsignedp, OPTAB_LIB_WIDEN);
3255 } 3267 }
3256 3268
3257 /* Return the smallest n such that 2**n >= X. */ 3269 /* Return the smallest n such that 2**n >= X. */
3258 3270
3259 int 3271 int
5790 && op0 == target 5802 && op0 == target
5791 && op1 == const0_rtx) 5803 && op1 == const0_rtx)
5792 { 5804 {
5793 label = gen_label_rtx (); 5805 label = gen_label_rtx ();
5794 do_compare_rtx_and_jump (target, const0_rtx, EQ, unsignedp, 5806 do_compare_rtx_and_jump (target, const0_rtx, EQ, unsignedp,
5795 mode, NULL_RTX, NULL_RTX, label); 5807 mode, NULL_RTX, NULL_RTX, label, -1);
5796 emit_move_insn (target, trueval); 5808 emit_move_insn (target, trueval);
5797 emit_label (label); 5809 emit_label (label);
5798 return target; 5810 return target;
5799 } 5811 }
5800 5812
5828 } 5840 }
5829 5841
5830 emit_move_insn (target, trueval); 5842 emit_move_insn (target, trueval);
5831 label = gen_label_rtx (); 5843 label = gen_label_rtx ();
5832 do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, NULL_RTX, 5844 do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, NULL_RTX,
5833 NULL_RTX, label); 5845 NULL_RTX, label, -1);
5834 5846
5835 emit_move_insn (target, falseval); 5847 emit_move_insn (target, falseval);
5836 emit_label (label); 5848 emit_label (label);
5837 5849
5838 return target; 5850 return target;
5846 do_cmp_and_jump (rtx arg1, rtx arg2, enum rtx_code op, enum machine_mode mode, 5858 do_cmp_and_jump (rtx arg1, rtx arg2, enum rtx_code op, enum machine_mode mode,
5847 rtx label) 5859 rtx label)
5848 { 5860 {
5849 int unsignedp = (op == LTU || op == LEU || op == GTU || op == GEU); 5861 int unsignedp = (op == LTU || op == LEU || op == GTU || op == GEU);
5850 do_compare_rtx_and_jump (arg1, arg2, op, unsignedp, mode, 5862 do_compare_rtx_and_jump (arg1, arg2, op, unsignedp, mode,
5851 NULL_RTX, NULL_RTX, label); 5863 NULL_RTX, NULL_RTX, label, -1);
5852 } 5864 }