X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fconfig%2Farm%2Farm.c;h=cadbe65fe44bba6f4e274fa59a37fe6e37ead99d;hp=5ec79df9c128704a897fa8af27db63b5821b6002;hb=52068a35b17af1ecee9dc3acba21f351e5ca2414;hpb=8c92d36e8ea9de079789c1e4696d5d2647190206 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 5ec79df9c12..cadbe65fe44 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3389,19 +3389,41 @@ arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer) { unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1)) & (unsigned HOST_WIDE_INT) 0xffffffff); - int add_cost = const_ok_for_arm (i) ? 4 : 8; - int j; + int cost, const_ok = const_ok_for_arm (i); + int j, booth_unit_size; + + if (arm_tune_xscale) + { + unsigned HOST_WIDE_INT masked_const; + + /* The cost will be related to two insns. + First a load of the constant (MOV or LDR), then a multiply. */ + cost = 2; + if (! const_ok) + cost += 1; /* LDR is probably more expensive because + of longer result latency. */ + masked_const = i & 0xffff8000; + if (masked_const != 0 && masked_const != 0xffff8000) + { + masked_const = i & 0xf8000000; + if (masked_const == 0 || masked_const == 0xf8000000) + cost += 1; + else + cost += 2; + } + return cost; + } /* Tune as appropriate. */ - int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2); - + cost = const_ok ? 4 : 8; + booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2); for (j = 0; i && j < 32; j += booth_unit_size) { i >>= booth_unit_size; - add_cost += 2; + cost += 2; } - return add_cost; + return cost; } return (((tune_flags & FL_FAST_MULT) ? 8 : 30)