Mercurial > hg > CbC > CbC_gcc
comparison gcc/expmed.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
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, 2010 | 4 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, |
5 2011 | |
5 Free Software Foundation, Inc. | 6 Free Software Foundation, Inc. |
6 | 7 |
7 This file is part of GCC. | 8 This file is part of GCC. |
8 | 9 |
9 GCC is free software; you can redistribute it and/or modify it under | 10 GCC is free software; you can redistribute it and/or modify it under |
23 | 24 |
24 #include "config.h" | 25 #include "config.h" |
25 #include "system.h" | 26 #include "system.h" |
26 #include "coretypes.h" | 27 #include "coretypes.h" |
27 #include "tm.h" | 28 #include "tm.h" |
28 #include "toplev.h" | 29 #include "diagnostic-core.h" |
29 #include "rtl.h" | 30 #include "rtl.h" |
30 #include "tree.h" | 31 #include "tree.h" |
31 #include "tm_p.h" | 32 #include "tm_p.h" |
32 #include "flags.h" | 33 #include "flags.h" |
33 #include "insn-config.h" | 34 #include "insn-config.h" |
35 #include "optabs.h" | 36 #include "optabs.h" |
36 #include "recog.h" | 37 #include "recog.h" |
37 #include "langhooks.h" | 38 #include "langhooks.h" |
38 #include "df.h" | 39 #include "df.h" |
39 #include "target.h" | 40 #include "target.h" |
41 #include "expmed.h" | |
42 | |
43 struct target_expmed default_target_expmed; | |
44 #if SWITCHABLE_TARGET | |
45 struct target_expmed *this_target_expmed = &default_target_expmed; | |
46 #endif | |
40 | 47 |
41 static void store_fixed_bit_field (rtx, unsigned HOST_WIDE_INT, | 48 static void store_fixed_bit_field (rtx, unsigned HOST_WIDE_INT, |
42 unsigned HOST_WIDE_INT, | 49 unsigned HOST_WIDE_INT, |
43 unsigned HOST_WIDE_INT, rtx); | 50 unsigned HOST_WIDE_INT, rtx); |
44 static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT, | 51 static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT, |
45 unsigned HOST_WIDE_INT, rtx); | 52 unsigned HOST_WIDE_INT, rtx); |
46 static rtx extract_fixed_bit_field (enum machine_mode, rtx, | 53 static rtx extract_fixed_bit_field (enum machine_mode, rtx, |
47 unsigned HOST_WIDE_INT, | 54 unsigned HOST_WIDE_INT, |
48 unsigned HOST_WIDE_INT, | 55 unsigned HOST_WIDE_INT, |
49 unsigned HOST_WIDE_INT, rtx, int); | 56 unsigned HOST_WIDE_INT, rtx, int, bool); |
50 static rtx mask_rtx (enum machine_mode, int, int, int); | 57 static rtx mask_rtx (enum machine_mode, int, int, int); |
51 static rtx lshift_value (enum machine_mode, rtx, int, int); | 58 static rtx lshift_value (enum machine_mode, rtx, int, int); |
52 static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT, | 59 static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT, |
53 unsigned HOST_WIDE_INT, int); | 60 unsigned HOST_WIDE_INT, int); |
54 static void do_cmp_and_jump (rtx, rtx, enum rtx_code, enum machine_mode, rtx); | 61 static void do_cmp_and_jump (rtx, rtx, enum rtx_code, enum machine_mode, rtx); |
56 static rtx expand_sdiv_pow2 (enum machine_mode, rtx, HOST_WIDE_INT); | 63 static rtx expand_sdiv_pow2 (enum machine_mode, rtx, HOST_WIDE_INT); |
57 | 64 |
58 /* Test whether a value is zero of a power of two. */ | 65 /* Test whether a value is zero of a power of two. */ |
59 #define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0) | 66 #define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0) |
60 | 67 |
61 /* Nonzero means divides or modulus operations are relatively cheap for | |
62 powers of two, so don't use branches; emit the operation instead. | |
63 Usually, this will mean that the MD file will emit non-branch | |
64 sequences. */ | |
65 | |
66 static bool sdiv_pow2_cheap[2][NUM_MACHINE_MODES]; | |
67 static bool smod_pow2_cheap[2][NUM_MACHINE_MODES]; | |
68 | |
69 #ifndef SLOW_UNALIGNED_ACCESS | 68 #ifndef SLOW_UNALIGNED_ACCESS |
70 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT | 69 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT |
71 #endif | 70 #endif |
72 | 71 |
73 /* For compilers that support multiple targets with different word sizes, | |
74 MAX_BITS_PER_WORD contains the biggest value of BITS_PER_WORD. An example | |
75 is the H8/300(H) compiler. */ | |
76 | |
77 #ifndef MAX_BITS_PER_WORD | |
78 #define MAX_BITS_PER_WORD BITS_PER_WORD | |
79 #endif | |
80 | 72 |
81 /* Reduce conditional compilation elsewhere. */ | 73 /* Reduce conditional compilation elsewhere. */ |
82 #ifndef HAVE_insv | 74 #ifndef HAVE_insv |
83 #define HAVE_insv 0 | 75 #define HAVE_insv 0 |
84 #define CODE_FOR_insv CODE_FOR_nothing | 76 #define CODE_FOR_insv CODE_FOR_nothing |
92 #ifndef HAVE_extzv | 84 #ifndef HAVE_extzv |
93 #define HAVE_extzv 0 | 85 #define HAVE_extzv 0 |
94 #define CODE_FOR_extzv CODE_FOR_nothing | 86 #define CODE_FOR_extzv CODE_FOR_nothing |
95 #define gen_extzv(a,b,c,d) NULL_RTX | 87 #define gen_extzv(a,b,c,d) NULL_RTX |
96 #endif | 88 #endif |
97 | |
98 /* Cost of various pieces of RTL. Note that some of these are indexed by | |
99 shift count and some by mode. */ | |
100 static int zero_cost[2]; | |
101 static int add_cost[2][NUM_MACHINE_MODES]; | |
102 static int neg_cost[2][NUM_MACHINE_MODES]; | |
103 static int shift_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; | |
104 static int shiftadd_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; | |
105 static int shiftsub0_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; | |
106 static int shiftsub1_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; | |
107 static int mul_cost[2][NUM_MACHINE_MODES]; | |
108 static int sdiv_cost[2][NUM_MACHINE_MODES]; | |
109 static int udiv_cost[2][NUM_MACHINE_MODES]; | |
110 static int mul_widen_cost[2][NUM_MACHINE_MODES]; | |
111 static int mul_highpart_cost[2][NUM_MACHINE_MODES]; | |
112 | 89 |
113 void | 90 void |
114 init_expmed (void) | 91 init_expmed (void) |
115 { | 92 { |
116 struct | 93 struct |
274 shiftsub0_cost[speed][mode][m] = rtx_cost (&all.shift_sub0, SET, speed); | 251 shiftsub0_cost[speed][mode][m] = rtx_cost (&all.shift_sub0, SET, speed); |
275 shiftsub1_cost[speed][mode][m] = rtx_cost (&all.shift_sub1, SET, speed); | 252 shiftsub1_cost[speed][mode][m] = rtx_cost (&all.shift_sub1, SET, speed); |
276 } | 253 } |
277 } | 254 } |
278 } | 255 } |
256 if (alg_hash_used_p) | |
257 memset (alg_hash, 0, sizeof (alg_hash)); | |
258 else | |
259 alg_hash_used_p = true; | |
279 default_rtl_profile (); | 260 default_rtl_profile (); |
280 } | 261 } |
281 | 262 |
282 /* Return an rtx representing minus the value of X. | 263 /* Return an rtx representing minus the value of X. |
283 MODE is the intended mode of the result, | 264 MODE is the intended mode of the result, |
299 is false; else the mode of the specified operand. If OPNO is -1, | 280 is false; else the mode of the specified operand. If OPNO is -1, |
300 all the caller cares about is whether the insn is available. */ | 281 all the caller cares about is whether the insn is available. */ |
301 enum machine_mode | 282 enum machine_mode |
302 mode_for_extraction (enum extraction_pattern pattern, int opno) | 283 mode_for_extraction (enum extraction_pattern pattern, int opno) |
303 { | 284 { |
304 const struct insn_data *data; | 285 const struct insn_data_d *data; |
305 | 286 |
306 switch (pattern) | 287 switch (pattern) |
307 { | 288 { |
308 case EP_insv: | 289 case EP_insv: |
309 if (HAVE_insv) | 290 if (HAVE_insv) |
417 | 398 |
418 /* Use vec_set patterns for inserting parts of vectors whenever | 399 /* Use vec_set patterns for inserting parts of vectors whenever |
419 available. */ | 400 available. */ |
420 if (VECTOR_MODE_P (GET_MODE (op0)) | 401 if (VECTOR_MODE_P (GET_MODE (op0)) |
421 && !MEM_P (op0) | 402 && !MEM_P (op0) |
422 && (optab_handler (vec_set_optab, GET_MODE (op0))->insn_code | 403 && optab_handler (vec_set_optab, GET_MODE (op0)) != CODE_FOR_nothing |
423 != CODE_FOR_nothing) | |
424 && fieldmode == GET_MODE_INNER (GET_MODE (op0)) | 404 && fieldmode == GET_MODE_INNER (GET_MODE (op0)) |
425 && bitsize == GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0))) | 405 && bitsize == GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0))) |
426 && !(bitnum % GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0))))) | 406 && !(bitnum % GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0))))) |
427 { | 407 { |
428 enum machine_mode outermode = GET_MODE (op0); | 408 enum machine_mode outermode = GET_MODE (op0); |
429 enum machine_mode innermode = GET_MODE_INNER (outermode); | 409 enum machine_mode innermode = GET_MODE_INNER (outermode); |
430 int icode = (int) optab_handler (vec_set_optab, outermode)->insn_code; | 410 int icode = (int) optab_handler (vec_set_optab, outermode); |
431 int pos = bitnum / GET_MODE_BITSIZE (innermode); | 411 int pos = bitnum / GET_MODE_BITSIZE (innermode); |
432 rtx rtxpos = GEN_INT (pos); | 412 rtx rtxpos = GEN_INT (pos); |
433 rtx src = value; | 413 rtx src = value; |
434 rtx dest = op0; | 414 rtx dest = op0; |
435 rtx pat, seq; | 415 rtx pat, seq; |
531 can be done with a movestrict instruction. */ | 511 can be done with a movestrict instruction. */ |
532 | 512 |
533 if (!MEM_P (op0) | 513 if (!MEM_P (op0) |
534 && (BYTES_BIG_ENDIAN ? bitpos + bitsize == unit : bitpos == 0) | 514 && (BYTES_BIG_ENDIAN ? bitpos + bitsize == unit : bitpos == 0) |
535 && bitsize == GET_MODE_BITSIZE (fieldmode) | 515 && bitsize == GET_MODE_BITSIZE (fieldmode) |
536 && (optab_handler (movstrict_optab, fieldmode)->insn_code | 516 && optab_handler (movstrict_optab, fieldmode) != CODE_FOR_nothing) |
537 != CODE_FOR_nothing)) | 517 { |
538 { | 518 int icode = optab_handler (movstrict_optab, fieldmode); |
539 int icode = optab_handler (movstrict_optab, fieldmode)->insn_code; | |
540 rtx insn; | 519 rtx insn; |
541 rtx start = get_last_insn (); | 520 rtx start = get_last_insn (); |
542 rtx arg0 = op0; | 521 rtx arg0 = op0; |
543 | 522 |
544 /* Get appropriate low part of the value being stored. */ | 523 /* Get appropriate low part of the value being stored. */ |
901 | 880 |
902 mode = GET_MODE (op0); | 881 mode = GET_MODE (op0); |
903 if (GET_MODE_BITSIZE (mode) == 0 | 882 if (GET_MODE_BITSIZE (mode) == 0 |
904 || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode)) | 883 || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode)) |
905 mode = word_mode; | 884 mode = word_mode; |
906 mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, | 885 |
907 MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0)); | 886 if (MEM_VOLATILE_P (op0) |
887 && GET_MODE_BITSIZE (GET_MODE (op0)) > 0 | |
888 && flag_strict_volatile_bitfields > 0) | |
889 mode = GET_MODE (op0); | |
890 else | |
891 mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, | |
892 MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0)); | |
908 | 893 |
909 if (mode == VOIDmode) | 894 if (mode == VOIDmode) |
910 { | 895 { |
911 /* The only way this should occur is if the field spans word | 896 /* The only way this should occur is if the field spans word |
912 boundaries. */ | 897 boundaries. */ |
1096 /* The args are chosen so that the last part includes the | 1081 /* The args are chosen so that the last part includes the |
1097 lsb. Give extract_bit_field the value it needs (with | 1082 lsb. Give extract_bit_field the value it needs (with |
1098 endianness compensation) to fetch the piece we want. */ | 1083 endianness compensation) to fetch the piece we want. */ |
1099 part = extract_fixed_bit_field (word_mode, value, 0, thissize, | 1084 part = extract_fixed_bit_field (word_mode, value, 0, thissize, |
1100 total_bits - bitsize + bitsdone, | 1085 total_bits - bitsize + bitsdone, |
1101 NULL_RTX, 1); | 1086 NULL_RTX, 1, false); |
1102 } | 1087 } |
1103 else | 1088 else |
1104 { | 1089 { |
1105 /* Fetch successively more significant portions. */ | 1090 /* Fetch successively more significant portions. */ |
1106 if (CONST_INT_P (value)) | 1091 if (CONST_INT_P (value)) |
1107 part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value)) | 1092 part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value)) |
1108 >> bitsdone) | 1093 >> bitsdone) |
1109 & (((HOST_WIDE_INT) 1 << thissize) - 1)); | 1094 & (((HOST_WIDE_INT) 1 << thissize) - 1)); |
1110 else | 1095 else |
1111 part = extract_fixed_bit_field (word_mode, value, 0, thissize, | 1096 part = extract_fixed_bit_field (word_mode, value, 0, thissize, |
1112 bitsdone, NULL_RTX, 1); | 1097 bitsdone, NULL_RTX, 1, false); |
1113 } | 1098 } |
1114 | 1099 |
1115 /* If OP0 is a register, then handle OFFSET here. | 1100 /* If OP0 is a register, then handle OFFSET here. |
1116 | 1101 |
1117 When handling multiword bitfields, extract_bit_field may pass | 1102 When handling multiword bitfields, extract_bit_field may pass |
1173 if we can find no other means of implementing the operation. | 1158 if we can find no other means of implementing the operation. |
1174 if FALLBACK_P is false, return NULL instead. */ | 1159 if FALLBACK_P is false, return NULL instead. */ |
1175 | 1160 |
1176 static rtx | 1161 static rtx |
1177 extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, | 1162 extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, |
1178 unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, | 1163 unsigned HOST_WIDE_INT bitnum, |
1164 int unsignedp, bool packedp, rtx target, | |
1179 enum machine_mode mode, enum machine_mode tmode, | 1165 enum machine_mode mode, enum machine_mode tmode, |
1180 bool fallback_p) | 1166 bool fallback_p) |
1181 { | 1167 { |
1182 unsigned int unit | 1168 unsigned int unit |
1183 = (MEM_P (str_rtx)) ? BITS_PER_UNIT : BITS_PER_WORD; | 1169 = (MEM_P (str_rtx)) ? BITS_PER_UNIT : BITS_PER_WORD; |
1217 if (VECTOR_MODE_P (GET_MODE (op0)) | 1203 if (VECTOR_MODE_P (GET_MODE (op0)) |
1218 && !MEM_P (op0) | 1204 && !MEM_P (op0) |
1219 && GET_MODE_INNER (GET_MODE (op0)) != tmode) | 1205 && GET_MODE_INNER (GET_MODE (op0)) != tmode) |
1220 { | 1206 { |
1221 enum machine_mode new_mode; | 1207 enum machine_mode new_mode; |
1222 int nunits = GET_MODE_NUNITS (GET_MODE (op0)); | |
1223 | 1208 |
1224 if (GET_MODE_CLASS (tmode) == MODE_FLOAT) | 1209 if (GET_MODE_CLASS (tmode) == MODE_FLOAT) |
1225 new_mode = MIN_MODE_VECTOR_FLOAT; | 1210 new_mode = MIN_MODE_VECTOR_FLOAT; |
1226 else if (GET_MODE_CLASS (tmode) == MODE_FRACT) | 1211 else if (GET_MODE_CLASS (tmode) == MODE_FRACT) |
1227 new_mode = MIN_MODE_VECTOR_FRACT; | 1212 new_mode = MIN_MODE_VECTOR_FRACT; |
1233 new_mode = MIN_MODE_VECTOR_UACCUM; | 1218 new_mode = MIN_MODE_VECTOR_UACCUM; |
1234 else | 1219 else |
1235 new_mode = MIN_MODE_VECTOR_INT; | 1220 new_mode = MIN_MODE_VECTOR_INT; |
1236 | 1221 |
1237 for (; new_mode != VOIDmode ; new_mode = GET_MODE_WIDER_MODE (new_mode)) | 1222 for (; new_mode != VOIDmode ; new_mode = GET_MODE_WIDER_MODE (new_mode)) |
1238 if (GET_MODE_NUNITS (new_mode) == nunits | 1223 if (GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0)) |
1239 && GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0)) | |
1240 && targetm.vector_mode_supported_p (new_mode)) | 1224 && targetm.vector_mode_supported_p (new_mode)) |
1241 break; | 1225 break; |
1242 if (new_mode != VOIDmode) | 1226 if (new_mode != VOIDmode) |
1243 op0 = gen_lowpart (new_mode, op0); | 1227 op0 = gen_lowpart (new_mode, op0); |
1244 } | 1228 } |
1245 | 1229 |
1246 /* Use vec_extract patterns for extracting parts of vectors whenever | 1230 /* Use vec_extract patterns for extracting parts of vectors whenever |
1247 available. */ | 1231 available. */ |
1248 if (VECTOR_MODE_P (GET_MODE (op0)) | 1232 if (VECTOR_MODE_P (GET_MODE (op0)) |
1249 && !MEM_P (op0) | 1233 && !MEM_P (op0) |
1250 && (optab_handler (vec_extract_optab, GET_MODE (op0))->insn_code | 1234 && optab_handler (vec_extract_optab, GET_MODE (op0)) != CODE_FOR_nothing |
1251 != CODE_FOR_nothing) | |
1252 && ((bitnum + bitsize - 1) / GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0))) | 1235 && ((bitnum + bitsize - 1) / GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0))) |
1253 == bitnum / GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0))))) | 1236 == bitnum / GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0))))) |
1254 { | 1237 { |
1255 enum machine_mode outermode = GET_MODE (op0); | 1238 enum machine_mode outermode = GET_MODE (op0); |
1256 enum machine_mode innermode = GET_MODE_INNER (outermode); | 1239 enum machine_mode innermode = GET_MODE_INNER (outermode); |
1257 int icode = (int) optab_handler (vec_extract_optab, outermode)->insn_code; | 1240 int icode = (int) optab_handler (vec_extract_optab, outermode); |
1258 unsigned HOST_WIDE_INT pos = bitnum / GET_MODE_BITSIZE (innermode); | 1241 unsigned HOST_WIDE_INT pos = bitnum / GET_MODE_BITSIZE (innermode); |
1259 rtx rtxpos = GEN_INT (pos); | 1242 rtx rtxpos = GEN_INT (pos); |
1260 rtx src = op0; | 1243 rtx src = op0; |
1261 rtx dest = NULL, pat, seq; | 1244 rtx dest = NULL, pat, seq; |
1262 enum machine_mode mode0 = insn_data[icode].operand[0].mode; | 1245 enum machine_mode mode0 = insn_data[icode].operand[0].mode; |
1375 modes. */ | 1358 modes. */ |
1376 mode1 = (SCALAR_INT_MODE_P (tmode) | 1359 mode1 = (SCALAR_INT_MODE_P (tmode) |
1377 ? mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) | 1360 ? mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) |
1378 : mode); | 1361 : mode); |
1379 | 1362 |
1363 /* If the bitfield is volatile, we need to make sure the access | |
1364 remains on a type-aligned boundary. */ | |
1365 if (GET_CODE (op0) == MEM | |
1366 && MEM_VOLATILE_P (op0) | |
1367 && GET_MODE_BITSIZE (GET_MODE (op0)) > 0 | |
1368 && flag_strict_volatile_bitfields > 0) | |
1369 goto no_subreg_mode_swap; | |
1370 | |
1380 if (((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode) | 1371 if (((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode) |
1381 && bitpos % BITS_PER_WORD == 0) | 1372 && bitpos % BITS_PER_WORD == 0) |
1382 || (mode1 != BLKmode | 1373 || (mode1 != BLKmode |
1383 /* ??? The big endian test here is wrong. This is correct | 1374 /* ??? The big endian test here is wrong. This is correct |
1384 if the value is in a register, and if mode_for_size is not | 1375 if the value is in a register, and if mode_for_size is not |
1447 : (int) i * BITS_PER_WORD); | 1438 : (int) i * BITS_PER_WORD); |
1448 rtx target_part = operand_subword (target, wordnum, 1, VOIDmode); | 1439 rtx target_part = operand_subword (target, wordnum, 1, VOIDmode); |
1449 rtx result_part | 1440 rtx result_part |
1450 = extract_bit_field (op0, MIN (BITS_PER_WORD, | 1441 = extract_bit_field (op0, MIN (BITS_PER_WORD, |
1451 bitsize - i * BITS_PER_WORD), | 1442 bitsize - i * BITS_PER_WORD), |
1452 bitnum + bit_offset, 1, target_part, mode, | 1443 bitnum + bit_offset, 1, false, target_part, mode, |
1453 word_mode); | 1444 word_mode); |
1454 | 1445 |
1455 gcc_assert (target_part); | 1446 gcc_assert (target_part); |
1456 | 1447 |
1457 if (result_part != target_part) | 1448 if (result_part != target_part) |
1646 | 1637 |
1647 /* Fetch it to a register in that size. */ | 1638 /* Fetch it to a register in that size. */ |
1648 xop0 = adjust_address (op0, bestmode, xoffset); | 1639 xop0 = adjust_address (op0, bestmode, xoffset); |
1649 xop0 = force_reg (bestmode, xop0); | 1640 xop0 = force_reg (bestmode, xop0); |
1650 result = extract_bit_field_1 (xop0, bitsize, xbitpos, | 1641 result = extract_bit_field_1 (xop0, bitsize, xbitpos, |
1651 unsignedp, target, | 1642 unsignedp, packedp, target, |
1652 mode, tmode, false); | 1643 mode, tmode, false); |
1653 if (result) | 1644 if (result) |
1654 return result; | 1645 return result; |
1655 | 1646 |
1656 delete_insns_since (last); | 1647 delete_insns_since (last); |
1660 | 1651 |
1661 if (!fallback_p) | 1652 if (!fallback_p) |
1662 return NULL; | 1653 return NULL; |
1663 | 1654 |
1664 target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, | 1655 target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, |
1665 bitpos, target, unsignedp); | 1656 bitpos, target, unsignedp, packedp); |
1666 return convert_extracted_bit_field (target, mode, tmode, unsignedp); | 1657 return convert_extracted_bit_field (target, mode, tmode, unsignedp); |
1667 } | 1658 } |
1668 | 1659 |
1669 /* Generate code to extract a byte-field from STR_RTX | 1660 /* Generate code to extract a byte-field from STR_RTX |
1670 containing BITSIZE bits, starting at BITNUM, | 1661 containing BITSIZE bits, starting at BITNUM, |
1671 and put it in TARGET if possible (if TARGET is nonzero). | 1662 and put it in TARGET if possible (if TARGET is nonzero). |
1672 Regardless of TARGET, we return the rtx for where the value is placed. | 1663 Regardless of TARGET, we return the rtx for where the value is placed. |
1673 | 1664 |
1674 STR_RTX is the structure containing the byte (a REG or MEM). | 1665 STR_RTX is the structure containing the byte (a REG or MEM). |
1675 UNSIGNEDP is nonzero if this is an unsigned bit field. | 1666 UNSIGNEDP is nonzero if this is an unsigned bit field. |
1667 PACKEDP is nonzero if the field has the packed attribute. | |
1676 MODE is the natural mode of the field value once extracted. | 1668 MODE is the natural mode of the field value once extracted. |
1677 TMODE is the mode the caller would like the value to have; | 1669 TMODE is the mode the caller would like the value to have; |
1678 but the value may be returned with type MODE instead. | 1670 but the value may be returned with type MODE instead. |
1679 | 1671 |
1680 If a TARGET is specified and we can store in it at no extra cost, | 1672 If a TARGET is specified and we can store in it at no extra cost, |
1682 Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred | 1674 Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred |
1683 if they are equally easy. */ | 1675 if they are equally easy. */ |
1684 | 1676 |
1685 rtx | 1677 rtx |
1686 extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, | 1678 extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, |
1687 unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, | 1679 unsigned HOST_WIDE_INT bitnum, int unsignedp, bool packedp, |
1688 enum machine_mode mode, enum machine_mode tmode) | 1680 rtx target, enum machine_mode mode, enum machine_mode tmode) |
1689 { | 1681 { |
1690 return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, | 1682 return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, packedp, |
1691 target, mode, tmode, true); | 1683 target, mode, tmode, true); |
1692 } | 1684 } |
1693 | 1685 |
1694 /* Extract a bit field using shifts and boolean operations | 1686 /* Extract a bit field using shifts and boolean operations |
1695 Returns an rtx to represent the value. | 1687 Returns an rtx to represent the value. |
1701 (If OP0 is a register, it may be narrower than a full word, | 1693 (If OP0 is a register, it may be narrower than a full word, |
1702 but BITPOS still counts within a full word, | 1694 but BITPOS still counts within a full word, |
1703 which is significant on bigendian machines.) | 1695 which is significant on bigendian machines.) |
1704 | 1696 |
1705 UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value). | 1697 UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value). |
1698 PACKEDP is true if the field has the packed attribute. | |
1699 | |
1706 If TARGET is nonzero, attempts to store the value there | 1700 If TARGET is nonzero, attempts to store the value there |
1707 and return TARGET, but this is not guaranteed. | 1701 and return TARGET, but this is not guaranteed. |
1708 If TARGET is not used, create a pseudo-reg of mode TMODE for the value. */ | 1702 If TARGET is not used, create a pseudo-reg of mode TMODE for the value. */ |
1709 | 1703 |
1710 static rtx | 1704 static rtx |
1711 extract_fixed_bit_field (enum machine_mode tmode, rtx op0, | 1705 extract_fixed_bit_field (enum machine_mode tmode, rtx op0, |
1712 unsigned HOST_WIDE_INT offset, | 1706 unsigned HOST_WIDE_INT offset, |
1713 unsigned HOST_WIDE_INT bitsize, | 1707 unsigned HOST_WIDE_INT bitsize, |
1714 unsigned HOST_WIDE_INT bitpos, rtx target, | 1708 unsigned HOST_WIDE_INT bitpos, rtx target, |
1715 int unsignedp) | 1709 int unsignedp, bool packedp) |
1716 { | 1710 { |
1717 unsigned int total_bits = BITS_PER_WORD; | 1711 unsigned int total_bits = BITS_PER_WORD; |
1718 enum machine_mode mode; | 1712 enum machine_mode mode; |
1719 | 1713 |
1720 if (GET_CODE (op0) == SUBREG || REG_P (op0)) | 1714 if (GET_CODE (op0) == SUBREG || REG_P (op0)) |
1727 { | 1721 { |
1728 /* Get the proper mode to use for this field. We want a mode that | 1722 /* Get the proper mode to use for this field. We want a mode that |
1729 includes the entire field. If such a mode would be larger than | 1723 includes the entire field. If such a mode would be larger than |
1730 a word, we won't be doing the extraction the normal way. */ | 1724 a word, we won't be doing the extraction the normal way. */ |
1731 | 1725 |
1732 mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, | 1726 if (MEM_VOLATILE_P (op0) |
1733 MEM_ALIGN (op0), word_mode, MEM_VOLATILE_P (op0)); | 1727 && flag_strict_volatile_bitfields > 0) |
1728 { | |
1729 if (GET_MODE_BITSIZE (GET_MODE (op0)) > 0) | |
1730 mode = GET_MODE (op0); | |
1731 else if (target && GET_MODE_BITSIZE (GET_MODE (target)) > 0) | |
1732 mode = GET_MODE (target); | |
1733 else | |
1734 mode = tmode; | |
1735 } | |
1736 else | |
1737 mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, | |
1738 MEM_ALIGN (op0), word_mode, MEM_VOLATILE_P (op0)); | |
1734 | 1739 |
1735 if (mode == VOIDmode) | 1740 if (mode == VOIDmode) |
1736 /* The only way this should occur is if the field spans word | 1741 /* The only way this should occur is if the field spans word |
1737 boundaries. */ | 1742 boundaries. */ |
1738 return extract_split_bit_field (op0, bitsize, | 1743 return extract_split_bit_field (op0, bitsize, |
1749 offset += (bitpos / total_bits) * (total_bits / BITS_PER_UNIT); | 1754 offset += (bitpos / total_bits) * (total_bits / BITS_PER_UNIT); |
1750 bitpos -= ((bitpos / total_bits) * (total_bits / BITS_PER_UNIT) | 1755 bitpos -= ((bitpos / total_bits) * (total_bits / BITS_PER_UNIT) |
1751 * BITS_PER_UNIT); | 1756 * BITS_PER_UNIT); |
1752 } | 1757 } |
1753 | 1758 |
1754 /* Get ref to an aligned byte, halfword, or word containing the field. | 1759 /* If we're accessing a volatile MEM, we can't do the next |
1755 Adjust BITPOS to be position within a word, | 1760 alignment step if it results in a multi-word access where we |
1756 and OFFSET to be the offset of that word. | 1761 otherwise wouldn't have one. So, check for that case |
1757 Then alter OP0 to refer to that word. */ | 1762 here. */ |
1758 bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT; | 1763 if (MEM_P (op0) |
1759 offset -= (offset % (total_bits / BITS_PER_UNIT)); | 1764 && MEM_VOLATILE_P (op0) |
1765 && flag_strict_volatile_bitfields > 0 | |
1766 && bitpos + bitsize <= total_bits | |
1767 && bitpos + bitsize + (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT > total_bits) | |
1768 { | |
1769 if (STRICT_ALIGNMENT) | |
1770 { | |
1771 static bool informed_about_misalignment = false; | |
1772 bool warned; | |
1773 | |
1774 if (packedp) | |
1775 { | |
1776 if (bitsize == total_bits) | |
1777 warned = warning_at (input_location, OPT_fstrict_volatile_bitfields, | |
1778 "multiple accesses to volatile structure member" | |
1779 " because of packed attribute"); | |
1780 else | |
1781 warned = warning_at (input_location, OPT_fstrict_volatile_bitfields, | |
1782 "multiple accesses to volatile structure bitfield" | |
1783 " because of packed attribute"); | |
1784 | |
1785 return extract_split_bit_field (op0, bitsize, | |
1786 bitpos + offset * BITS_PER_UNIT, | |
1787 unsignedp); | |
1788 } | |
1789 | |
1790 if (bitsize == total_bits) | |
1791 warned = warning_at (input_location, OPT_fstrict_volatile_bitfields, | |
1792 "mis-aligned access used for structure member"); | |
1793 else | |
1794 warned = warning_at (input_location, OPT_fstrict_volatile_bitfields, | |
1795 "mis-aligned access used for structure bitfield"); | |
1796 | |
1797 if (! informed_about_misalignment && warned) | |
1798 { | |
1799 informed_about_misalignment = true; | |
1800 inform (input_location, | |
1801 "when a volatile object spans multiple type-sized locations," | |
1802 " the compiler must choose between using a single mis-aligned access to" | |
1803 " preserve the volatility, or using multiple aligned accesses to avoid" | |
1804 " runtime faults; this code may fail at runtime if the hardware does" | |
1805 " not allow this access"); | |
1806 } | |
1807 } | |
1808 } | |
1809 else | |
1810 { | |
1811 | |
1812 /* Get ref to an aligned byte, halfword, or word containing the field. | |
1813 Adjust BITPOS to be position within a word, | |
1814 and OFFSET to be the offset of that word. | |
1815 Then alter OP0 to refer to that word. */ | |
1816 bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT; | |
1817 offset -= (offset % (total_bits / BITS_PER_UNIT)); | |
1818 } | |
1819 | |
1760 op0 = adjust_address (op0, mode, offset); | 1820 op0 = adjust_address (op0, mode, offset); |
1761 } | 1821 } |
1762 | 1822 |
1763 mode = GET_MODE (op0); | 1823 mode = GET_MODE (op0); |
1764 | 1824 |
1927 whose meaning is determined by BYTES_PER_UNIT. | 1987 whose meaning is determined by BYTES_PER_UNIT. |
1928 OFFSET is in UNITs, and UNIT is in bits. | 1988 OFFSET is in UNITs, and UNIT is in bits. |
1929 extract_fixed_bit_field wants offset in bytes. */ | 1989 extract_fixed_bit_field wants offset in bytes. */ |
1930 part = extract_fixed_bit_field (word_mode, word, | 1990 part = extract_fixed_bit_field (word_mode, word, |
1931 offset * unit / BITS_PER_UNIT, | 1991 offset * unit / BITS_PER_UNIT, |
1932 thissize, thispos, 0, 1); | 1992 thissize, thispos, 0, 1, false); |
1933 bitsdone += thissize; | 1993 bitsdone += thissize; |
1934 | 1994 |
1935 /* Shift this part into place for the result. */ | 1995 /* Shift this part into place for the result. */ |
1936 if (BYTES_BIG_ENDIAN) | 1996 if (BYTES_BIG_ENDIAN) |
1937 { | 1997 { |
2236 | 2296 |
2237 gcc_assert (temp); | 2297 gcc_assert (temp); |
2238 return temp; | 2298 return temp; |
2239 } | 2299 } |
2240 | 2300 |
2241 enum alg_code { | |
2242 alg_unknown, | |
2243 alg_zero, | |
2244 alg_m, alg_shift, | |
2245 alg_add_t_m2, | |
2246 alg_sub_t_m2, | |
2247 alg_add_factor, | |
2248 alg_sub_factor, | |
2249 alg_add_t2_m, | |
2250 alg_sub_t2_m, | |
2251 alg_impossible | |
2252 }; | |
2253 | |
2254 /* This structure holds the "cost" of a multiply sequence. The | |
2255 "cost" field holds the total rtx_cost of every operator in the | |
2256 synthetic multiplication sequence, hence cost(a op b) is defined | |
2257 as rtx_cost(op) + cost(a) + cost(b), where cost(leaf) is zero. | |
2258 The "latency" field holds the minimum possible latency of the | |
2259 synthetic multiply, on a hypothetical infinitely parallel CPU. | |
2260 This is the critical path, or the maximum height, of the expression | |
2261 tree which is the sum of rtx_costs on the most expensive path from | |
2262 any leaf to the root. Hence latency(a op b) is defined as zero for | |
2263 leaves and rtx_cost(op) + max(latency(a), latency(b)) otherwise. */ | |
2264 | |
2265 struct mult_cost { | |
2266 short cost; /* Total rtx_cost of the multiplication sequence. */ | |
2267 short latency; /* The latency of the multiplication sequence. */ | |
2268 }; | |
2269 | |
2270 /* This macro is used to compare a pointer to a mult_cost against an | |
2271 single integer "rtx_cost" value. This is equivalent to the macro | |
2272 CHEAPER_MULT_COST(X,Z) where Z = {Y,Y}. */ | |
2273 #define MULT_COST_LESS(X,Y) ((X)->cost < (Y) \ | |
2274 || ((X)->cost == (Y) && (X)->latency < (Y))) | |
2275 | |
2276 /* This macro is used to compare two pointers to mult_costs against | |
2277 each other. The macro returns true if X is cheaper than Y. | |
2278 Currently, the cheaper of two mult_costs is the one with the | |
2279 lower "cost". If "cost"s are tied, the lower latency is cheaper. */ | |
2280 #define CHEAPER_MULT_COST(X,Y) ((X)->cost < (Y)->cost \ | |
2281 || ((X)->cost == (Y)->cost \ | |
2282 && (X)->latency < (Y)->latency)) | |
2283 | |
2284 /* This structure records a sequence of operations. | |
2285 `ops' is the number of operations recorded. | |
2286 `cost' is their total cost. | |
2287 The operations are stored in `op' and the corresponding | |
2288 logarithms of the integer coefficients in `log'. | |
2289 | |
2290 These are the operations: | |
2291 alg_zero total := 0; | |
2292 alg_m total := multiplicand; | |
2293 alg_shift total := total * coeff | |
2294 alg_add_t_m2 total := total + multiplicand * coeff; | |
2295 alg_sub_t_m2 total := total - multiplicand * coeff; | |
2296 alg_add_factor total := total * coeff + total; | |
2297 alg_sub_factor total := total * coeff - total; | |
2298 alg_add_t2_m total := total * coeff + multiplicand; | |
2299 alg_sub_t2_m total := total * coeff - multiplicand; | |
2300 | |
2301 The first operand must be either alg_zero or alg_m. */ | |
2302 | |
2303 struct algorithm | |
2304 { | |
2305 struct mult_cost cost; | |
2306 short ops; | |
2307 /* The size of the OP and LOG fields are not directly related to the | |
2308 word size, but the worst-case algorithms will be if we have few | |
2309 consecutive ones or zeros, i.e., a multiplicand like 10101010101... | |
2310 In that case we will generate shift-by-2, add, shift-by-2, add,..., | |
2311 in total wordsize operations. */ | |
2312 enum alg_code op[MAX_BITS_PER_WORD]; | |
2313 char log[MAX_BITS_PER_WORD]; | |
2314 }; | |
2315 | |
2316 /* The entry for our multiplication cache/hash table. */ | |
2317 struct alg_hash_entry { | |
2318 /* The number we are multiplying by. */ | |
2319 unsigned HOST_WIDE_INT t; | |
2320 | |
2321 /* The mode in which we are multiplying something by T. */ | |
2322 enum machine_mode mode; | |
2323 | |
2324 /* The best multiplication algorithm for t. */ | |
2325 enum alg_code alg; | |
2326 | |
2327 /* The cost of multiplication if ALG_CODE is not alg_impossible. | |
2328 Otherwise, the cost within which multiplication by T is | |
2329 impossible. */ | |
2330 struct mult_cost cost; | |
2331 | |
2332 /* OPtimized for speed? */ | |
2333 bool speed; | |
2334 }; | |
2335 | |
2336 /* The number of cache/hash entries. */ | |
2337 #if HOST_BITS_PER_WIDE_INT == 64 | |
2338 #define NUM_ALG_HASH_ENTRIES 1031 | |
2339 #else | |
2340 #define NUM_ALG_HASH_ENTRIES 307 | |
2341 #endif | |
2342 | |
2343 /* Each entry of ALG_HASH caches alg_code for some integer. This is | |
2344 actually a hash table. If we have a collision, that the older | |
2345 entry is kicked out. */ | |
2346 static struct alg_hash_entry alg_hash[NUM_ALG_HASH_ENTRIES]; | |
2347 | |
2348 /* Indicates the type of fixup needed after a constant multiplication. | 2301 /* Indicates the type of fixup needed after a constant multiplication. |
2349 BASIC_VARIANT means no fixup is needed, NEGATE_VARIANT means that | 2302 BASIC_VARIANT means no fixup is needed, NEGATE_VARIANT means that |
2350 the result should be negated, and ADD_VARIANT means that the | 2303 the result should be negated, and ADD_VARIANT means that the |
2351 multiplicand should be added to the result. */ | 2304 multiplicand should be added to the result. */ |
2352 enum mult_variant {basic_variant, negate_variant, add_variant}; | 2305 enum mult_variant {basic_variant, negate_variant, add_variant}; |
2967 rtx accum_target = optimize ? 0 : accum; | 2920 rtx accum_target = optimize ? 0 : accum; |
2968 | 2921 |
2969 switch (alg->op[opno]) | 2922 switch (alg->op[opno]) |
2970 { | 2923 { |
2971 case alg_shift: | 2924 case alg_shift: |
2972 accum = expand_shift (LSHIFT_EXPR, mode, accum, | 2925 tem = expand_shift (LSHIFT_EXPR, mode, accum, |
2973 build_int_cst (NULL_TREE, log), | 2926 build_int_cst (NULL_TREE, log), |
2974 NULL_RTX, 0); | 2927 NULL_RTX, 0); |
2928 /* REG_EQUAL note will be attached to the following insn. */ | |
2929 emit_move_insn (accum, tem); | |
2975 val_so_far <<= log; | 2930 val_so_far <<= log; |
2976 break; | 2931 break; |
2977 | 2932 |
2978 case alg_add_t_m2: | 2933 case alg_add_t_m2: |
2979 tem = expand_shift (LSHIFT_EXPR, mode, op0, | 2934 tem = expand_shift (LSHIFT_EXPR, mode, op0, |
3230 rtx | 3185 rtx |
3231 expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, | 3186 expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, |
3232 int unsignedp, optab this_optab) | 3187 int unsignedp, optab this_optab) |
3233 { | 3188 { |
3234 bool speed = optimize_insn_for_speed_p (); | 3189 bool speed = optimize_insn_for_speed_p (); |
3190 rtx cop1; | |
3235 | 3191 |
3236 if (CONST_INT_P (op1) | 3192 if (CONST_INT_P (op1) |
3237 && (INTVAL (op1) >= 0 | 3193 && GET_MODE (op0) != VOIDmode |
3194 && (cop1 = convert_modes (mode, GET_MODE (op0), op1, | |
3195 this_optab == umul_widen_optab)) | |
3196 && CONST_INT_P (cop1) | |
3197 && (INTVAL (cop1) >= 0 | |
3238 || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)) | 3198 || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)) |
3239 { | 3199 { |
3240 HOST_WIDE_INT coeff = INTVAL (op1); | 3200 HOST_WIDE_INT coeff = INTVAL (cop1); |
3241 int max_cost; | 3201 int max_cost; |
3242 enum mult_variant variant; | 3202 enum mult_variant variant; |
3243 struct algorithm algorithm; | 3203 struct algorithm algorithm; |
3244 | 3204 |
3245 /* Special case powers of two. */ | 3205 /* Special case powers of two. */ |
3501 tem, unsignedp); | 3461 tem, unsignedp); |
3502 } | 3462 } |
3503 | 3463 |
3504 /* Try widening multiplication. */ | 3464 /* Try widening multiplication. */ |
3505 moptab = unsignedp ? umul_widen_optab : smul_widen_optab; | 3465 moptab = unsignedp ? umul_widen_optab : smul_widen_optab; |
3506 if (optab_handler (moptab, wider_mode)->insn_code != CODE_FOR_nothing | 3466 if (optab_handler (moptab, wider_mode) != CODE_FOR_nothing |
3507 && mul_widen_cost[speed][wider_mode] < max_cost) | 3467 && mul_widen_cost[speed][wider_mode] < max_cost) |
3508 { | 3468 { |
3509 tem = expand_binop (wider_mode, moptab, op0, narrow_op1, 0, | 3469 tem = expand_binop (wider_mode, moptab, op0, narrow_op1, 0, |
3510 unsignedp, OPTAB_WIDEN); | 3470 unsignedp, OPTAB_WIDEN); |
3511 if (tem) | 3471 if (tem) |
3512 return extract_high_half (mode, tem); | 3472 return extract_high_half (mode, tem); |
3513 } | 3473 } |
3514 | 3474 |
3515 /* Try widening the mode and perform a non-widening multiplication. */ | 3475 /* Try widening the mode and perform a non-widening multiplication. */ |
3516 if (optab_handler (smul_optab, wider_mode)->insn_code != CODE_FOR_nothing | 3476 if (optab_handler (smul_optab, wider_mode) != CODE_FOR_nothing |
3517 && size - 1 < BITS_PER_WORD | 3477 && size - 1 < BITS_PER_WORD |
3518 && mul_cost[speed][wider_mode] + shift_cost[speed][mode][size-1] < max_cost) | 3478 && mul_cost[speed][wider_mode] + shift_cost[speed][mode][size-1] < max_cost) |
3519 { | 3479 { |
3520 rtx insns, wop0, wop1; | 3480 rtx insns, wop0, wop1; |
3521 | 3481 |
3538 } | 3498 } |
3539 } | 3499 } |
3540 | 3500 |
3541 /* Try widening multiplication of opposite signedness, and adjust. */ | 3501 /* Try widening multiplication of opposite signedness, and adjust. */ |
3542 moptab = unsignedp ? smul_widen_optab : umul_widen_optab; | 3502 moptab = unsignedp ? smul_widen_optab : umul_widen_optab; |
3543 if (optab_handler (moptab, wider_mode)->insn_code != CODE_FOR_nothing | 3503 if (optab_handler (moptab, wider_mode) != CODE_FOR_nothing |
3544 && size - 1 < BITS_PER_WORD | 3504 && size - 1 < BITS_PER_WORD |
3545 && (mul_widen_cost[speed][wider_mode] + 2 * shift_cost[speed][mode][size-1] | 3505 && (mul_widen_cost[speed][wider_mode] + 2 * shift_cost[speed][mode][size-1] |
3546 + 4 * add_cost[speed][mode] < max_cost)) | 3506 + 4 * add_cost[speed][mode] < max_cost)) |
3547 { | 3507 { |
3548 tem = expand_binop (wider_mode, moptab, op0, narrow_op1, | 3508 tem = expand_binop (wider_mode, moptab, op0, narrow_op1, |
3660 which instruction sequence to use. If logical right shifts | 3620 which instruction sequence to use. If logical right shifts |
3661 are expensive the use 2 XORs, 2 SUBs and an AND, otherwise | 3621 are expensive the use 2 XORs, 2 SUBs and an AND, otherwise |
3662 use a LSHIFTRT, 1 ADD, 1 SUB and an AND. */ | 3622 use a LSHIFTRT, 1 ADD, 1 SUB and an AND. */ |
3663 | 3623 |
3664 temp = gen_rtx_LSHIFTRT (mode, result, shift); | 3624 temp = gen_rtx_LSHIFTRT (mode, result, shift); |
3665 if (optab_handler (lshr_optab, mode)->insn_code == CODE_FOR_nothing | 3625 if (optab_handler (lshr_optab, mode) == CODE_FOR_nothing |
3666 || rtx_cost (temp, SET, optimize_insn_for_speed_p ()) > COSTS_N_INSNS (2)) | 3626 || rtx_cost (temp, SET, optimize_insn_for_speed_p ()) > COSTS_N_INSNS (2)) |
3667 { | 3627 { |
3668 temp = expand_binop (mode, xor_optab, op0, signmask, | 3628 temp = expand_binop (mode, xor_optab, op0, signmask, |
3669 NULL_RTX, 1, OPTAB_LIB_WIDEN); | 3629 NULL_RTX, 1, OPTAB_LIB_WIDEN); |
3670 temp = expand_binop (mode, sub_optab, temp, signmask, | 3630 temp = expand_binop (mode, sub_optab, temp, signmask, |
3964 ? optab1 | 3924 ? optab1 |
3965 : (unsignedp ? udivmod_optab : sdivmod_optab)); | 3925 : (unsignedp ? udivmod_optab : sdivmod_optab)); |
3966 | 3926 |
3967 for (compute_mode = mode; compute_mode != VOIDmode; | 3927 for (compute_mode = mode; compute_mode != VOIDmode; |
3968 compute_mode = GET_MODE_WIDER_MODE (compute_mode)) | 3928 compute_mode = GET_MODE_WIDER_MODE (compute_mode)) |
3969 if (optab_handler (optab1, compute_mode)->insn_code != CODE_FOR_nothing | 3929 if (optab_handler (optab1, compute_mode) != CODE_FOR_nothing |
3970 || optab_handler (optab2, compute_mode)->insn_code != CODE_FOR_nothing) | 3930 || optab_handler (optab2, compute_mode) != CODE_FOR_nothing) |
3971 break; | 3931 break; |
3972 | 3932 |
3973 if (compute_mode == VOIDmode) | 3933 if (compute_mode == VOIDmode) |
3974 for (compute_mode = mode; compute_mode != VOIDmode; | 3934 for (compute_mode = mode; compute_mode != VOIDmode; |
3975 compute_mode = GET_MODE_WIDER_MODE (compute_mode)) | 3935 compute_mode = GET_MODE_WIDER_MODE (compute_mode)) |
4127 if (t1 == 0) | 4087 if (t1 == 0) |
4128 goto fail1; | 4088 goto fail1; |
4129 t2 = force_operand (gen_rtx_MINUS (compute_mode, | 4089 t2 = force_operand (gen_rtx_MINUS (compute_mode, |
4130 op0, t1), | 4090 op0, t1), |
4131 NULL_RTX); | 4091 NULL_RTX); |
4132 t3 = expand_shift | 4092 t3 = expand_shift (RSHIFT_EXPR, compute_mode, t2, |
4133 (RSHIFT_EXPR, compute_mode, t2, | 4093 integer_one_node, NULL_RTX, 1); |
4134 build_int_cst (NULL_TREE, 1), | |
4135 NULL_RTX,1); | |
4136 t4 = force_operand (gen_rtx_PLUS (compute_mode, | 4094 t4 = force_operand (gen_rtx_PLUS (compute_mode, |
4137 t1, t3), | 4095 t1, t3), |
4138 NULL_RTX); | 4096 NULL_RTX); |
4139 quotient = expand_shift | 4097 quotient = expand_shift |
4140 (RSHIFT_EXPR, compute_mode, t4, | 4098 (RSHIFT_EXPR, compute_mode, t4, |
4220 : sdiv_pow2_cheap[speed][compute_mode]) | 4178 : sdiv_pow2_cheap[speed][compute_mode]) |
4221 /* We assume that cheap metric is true if the | 4179 /* We assume that cheap metric is true if the |
4222 optab has an expander for this mode. */ | 4180 optab has an expander for this mode. */ |
4223 && ((optab_handler ((rem_flag ? smod_optab | 4181 && ((optab_handler ((rem_flag ? smod_optab |
4224 : sdiv_optab), | 4182 : sdiv_optab), |
4225 compute_mode)->insn_code | 4183 compute_mode) |
4226 != CODE_FOR_nothing) | 4184 != CODE_FOR_nothing) |
4227 || (optab_handler(sdivmod_optab, | 4185 || (optab_handler (sdivmod_optab, |
4228 compute_mode) | 4186 compute_mode) |
4229 ->insn_code != CODE_FOR_nothing))) | 4187 != CODE_FOR_nothing))) |
4230 ; | 4188 ; |
4231 else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d)) | 4189 else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d)) |
4232 { | 4190 { |
4233 if (rem_flag) | 4191 if (rem_flag) |
4234 { | 4192 { |
4236 if (remainder) | 4194 if (remainder) |
4237 return gen_lowpart (mode, remainder); | 4195 return gen_lowpart (mode, remainder); |
4238 } | 4196 } |
4239 | 4197 |
4240 if (sdiv_pow2_cheap[speed][compute_mode] | 4198 if (sdiv_pow2_cheap[speed][compute_mode] |
4241 && ((optab_handler (sdiv_optab, compute_mode)->insn_code | 4199 && ((optab_handler (sdiv_optab, compute_mode) |
4242 != CODE_FOR_nothing) | 4200 != CODE_FOR_nothing) |
4243 || (optab_handler (sdivmod_optab, compute_mode)->insn_code | 4201 || (optab_handler (sdivmod_optab, compute_mode) |
4244 != CODE_FOR_nothing))) | 4202 != CODE_FOR_nothing))) |
4245 quotient = expand_divmod (0, TRUNC_DIV_EXPR, | 4203 quotient = expand_divmod (0, TRUNC_DIV_EXPR, |
4246 compute_mode, op0, | 4204 compute_mode, op0, |
4247 gen_int_mode (abs_d, | 4205 gen_int_mode (abs_d, |
4248 compute_mode), | 4206 compute_mode), |
4814 remainder = expand_binop (compute_mode, sub_optab, op0, tem, | 4772 remainder = expand_binop (compute_mode, sub_optab, op0, tem, |
4815 remainder, 1, OPTAB_LIB_WIDEN); | 4773 remainder, 1, OPTAB_LIB_WIDEN); |
4816 } | 4774 } |
4817 tem = plus_constant (op1, -1); | 4775 tem = plus_constant (op1, -1); |
4818 tem = expand_shift (RSHIFT_EXPR, compute_mode, tem, | 4776 tem = expand_shift (RSHIFT_EXPR, compute_mode, tem, |
4819 build_int_cst (NULL_TREE, 1), | 4777 integer_one_node, NULL_RTX, 1); |
4820 NULL_RTX, 1); | |
4821 do_cmp_and_jump (remainder, tem, LEU, compute_mode, label); | 4778 do_cmp_and_jump (remainder, tem, LEU, compute_mode, label); |
4822 expand_inc (quotient, const1_rtx); | 4779 expand_inc (quotient, const1_rtx); |
4823 expand_dec (remainder, op1); | 4780 expand_dec (remainder, op1); |
4824 emit_label (label); | 4781 emit_label (label); |
4825 } | 4782 } |
4840 remainder, 0, OPTAB_LIB_WIDEN); | 4797 remainder, 0, OPTAB_LIB_WIDEN); |
4841 } | 4798 } |
4842 abs_rem = expand_abs (compute_mode, remainder, NULL_RTX, 1, 0); | 4799 abs_rem = expand_abs (compute_mode, remainder, NULL_RTX, 1, 0); |
4843 abs_op1 = expand_abs (compute_mode, op1, NULL_RTX, 1, 0); | 4800 abs_op1 = expand_abs (compute_mode, op1, NULL_RTX, 1, 0); |
4844 tem = expand_shift (LSHIFT_EXPR, compute_mode, abs_rem, | 4801 tem = expand_shift (LSHIFT_EXPR, compute_mode, abs_rem, |
4845 build_int_cst (NULL_TREE, 1), | 4802 integer_one_node, NULL_RTX, 1); |
4846 NULL_RTX, 1); | |
4847 do_cmp_and_jump (tem, abs_op1, LTU, compute_mode, label); | 4803 do_cmp_and_jump (tem, abs_op1, LTU, compute_mode, label); |
4848 tem = expand_binop (compute_mode, xor_optab, op0, op1, | 4804 tem = expand_binop (compute_mode, xor_optab, op0, op1, |
4849 NULL_RTX, 0, OPTAB_WIDEN); | 4805 NULL_RTX, 0, OPTAB_WIDEN); |
4850 mask = expand_shift (RSHIFT_EXPR, compute_mode, tem, | 4806 mask = expand_shift (RSHIFT_EXPR, compute_mode, tem, |
4851 build_int_cst (NULL_TREE, size - 1), | 4807 build_int_cst (NULL_TREE, size - 1), |
4886 4) try the same things with widening allowed. */ | 4842 4) try the same things with widening allowed. */ |
4887 remainder | 4843 remainder |
4888 = sign_expand_binop (compute_mode, umod_optab, smod_optab, | 4844 = sign_expand_binop (compute_mode, umod_optab, smod_optab, |
4889 op0, op1, target, | 4845 op0, op1, target, |
4890 unsignedp, | 4846 unsignedp, |
4891 ((optab_handler (optab2, compute_mode)->insn_code | 4847 ((optab_handler (optab2, compute_mode) |
4892 != CODE_FOR_nothing) | 4848 != CODE_FOR_nothing) |
4893 ? OPTAB_DIRECT : OPTAB_WIDEN)); | 4849 ? OPTAB_DIRECT : OPTAB_WIDEN)); |
4894 if (remainder == 0) | 4850 if (remainder == 0) |
4895 { | 4851 { |
4896 /* No luck there. Can we do remainder and divide at once | 4852 /* No luck there. Can we do remainder and divide at once |
4914 is set to the one of the two optabs that the call below will use. */ | 4870 is set to the one of the two optabs that the call below will use. */ |
4915 quotient | 4871 quotient |
4916 = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab, | 4872 = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab, |
4917 op0, op1, rem_flag ? NULL_RTX : target, | 4873 op0, op1, rem_flag ? NULL_RTX : target, |
4918 unsignedp, | 4874 unsignedp, |
4919 ((optab_handler (optab2, compute_mode)->insn_code | 4875 ((optab_handler (optab2, compute_mode) |
4920 != CODE_FOR_nothing) | 4876 != CODE_FOR_nothing) |
4921 ? OPTAB_DIRECT : OPTAB_WIDEN)); | 4877 ? OPTAB_DIRECT : OPTAB_WIDEN)); |
4922 | 4878 |
4923 if (quotient == 0) | 4879 if (quotient == 0) |
4924 { | 4880 { |
5413 mclass = GET_MODE_CLASS (mode); | 5369 mclass = GET_MODE_CLASS (mode); |
5414 for (compare_mode = mode; compare_mode != VOIDmode; | 5370 for (compare_mode = mode; compare_mode != VOIDmode; |
5415 compare_mode = GET_MODE_WIDER_MODE (compare_mode)) | 5371 compare_mode = GET_MODE_WIDER_MODE (compare_mode)) |
5416 { | 5372 { |
5417 enum machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode; | 5373 enum machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode; |
5418 icode = optab_handler (cstore_optab, optab_mode)->insn_code; | 5374 icode = optab_handler (cstore_optab, optab_mode); |
5419 if (icode != CODE_FOR_nothing) | 5375 if (icode != CODE_FOR_nothing) |
5420 { | 5376 { |
5421 do_pending_stack_adjust (); | 5377 do_pending_stack_adjust (); |
5422 tem = emit_cstore (target, icode, code, mode, compare_mode, | 5378 tem = emit_cstore (target, icode, code, mode, compare_mode, |
5423 unsignedp, op0, op1, normalizep, target_mode); | 5379 unsignedp, op0, op1, normalizep, target_mode); |
5608 /* For integer comparisons, try the reverse comparison. However, for | 5564 /* For integer comparisons, try the reverse comparison. However, for |
5609 small X and if we'd have anyway to extend, implementing "X != 0" | 5565 small X and if we'd have anyway to extend, implementing "X != 0" |
5610 as "-(int)X >> 31" is still cheaper than inverting "(int)X == 0". */ | 5566 as "-(int)X >> 31" is still cheaper than inverting "(int)X == 0". */ |
5611 rcode = reverse_condition (code); | 5567 rcode = reverse_condition (code); |
5612 if (can_compare_p (rcode, mode, ccp_store_flag) | 5568 if (can_compare_p (rcode, mode, ccp_store_flag) |
5613 && ! (optab_handler (cstore_optab, mode)->insn_code == CODE_FOR_nothing | 5569 && ! (optab_handler (cstore_optab, mode) == CODE_FOR_nothing |
5614 && code == NE | 5570 && code == NE |
5615 && GET_MODE_SIZE (mode) < UNITS_PER_WORD | 5571 && GET_MODE_SIZE (mode) < UNITS_PER_WORD |
5616 && op1 == const0_rtx)) | 5572 && op1 == const0_rtx)) |
5617 { | 5573 { |
5618 int want_add = ((STORE_FLAG_VALUE == 1 && normalizep == -1) | 5574 int want_add = ((STORE_FLAG_VALUE == 1 && normalizep == -1) |
5707 | 5663 |
5708 /* Note that ABS doesn't yield a positive number for INT_MIN, but | 5664 /* Note that ABS doesn't yield a positive number for INT_MIN, but |
5709 that is compensated by the subsequent overflow when subtracting | 5665 that is compensated by the subsequent overflow when subtracting |
5710 one / negating. */ | 5666 one / negating. */ |
5711 | 5667 |
5712 if (optab_handler (abs_optab, mode)->insn_code != CODE_FOR_nothing) | 5668 if (optab_handler (abs_optab, mode) != CODE_FOR_nothing) |
5713 tem = expand_unop (mode, abs_optab, op0, subtarget, 1); | 5669 tem = expand_unop (mode, abs_optab, op0, subtarget, 1); |
5714 else if (optab_handler (ffs_optab, mode)->insn_code != CODE_FOR_nothing) | 5670 else if (optab_handler (ffs_optab, mode) != CODE_FOR_nothing) |
5715 tem = expand_unop (mode, ffs_optab, op0, subtarget, 1); | 5671 tem = expand_unop (mode, ffs_optab, op0, subtarget, 1); |
5716 else if (GET_MODE_SIZE (mode) < UNITS_PER_WORD) | 5672 else if (GET_MODE_SIZE (mode) < UNITS_PER_WORD) |
5717 { | 5673 { |
5718 tem = convert_modes (word_mode, mode, op0, 1); | 5674 tem = convert_modes (word_mode, mode, op0, 1); |
5719 mode = word_mode; | 5675 mode = word_mode; |