|
|
1.1 ! root 1: /* Medium-level subroutines: convert bit-field store and extract ! 2: and shifts, multiplies and divides to rtl instructions. ! 3: Copyright (C) 1987, 88, 89, 92, 93, 1994 Free Software Foundation, Inc. ! 4: ! 5: This file is part of GNU CC. ! 6: ! 7: GNU CC is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 2, or (at your option) ! 10: any later version. ! 11: ! 12: GNU CC is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU CC; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: ! 22: #include "config.h" ! 23: #include "rtl.h" ! 24: #include "tree.h" ! 25: #include "flags.h" ! 26: #include "insn-flags.h" ! 27: #include "insn-codes.h" ! 28: #include "insn-config.h" ! 29: #include "expr.h" ! 30: #include "real.h" ! 31: #include "recog.h" ! 32: ! 33: static rtx extract_split_bit_field (); ! 34: static rtx extract_fixed_bit_field (); ! 35: static void store_split_bit_field (); ! 36: static void store_fixed_bit_field (); ! 37: static rtx mask_rtx (); ! 38: static rtx lshift_value (); ! 39: ! 40: #define CEIL(x,y) (((x) + (y) - 1) / (y)) ! 41: ! 42: /* Non-zero means divides or modulus operations are relatively cheap for ! 43: powers of two, so don't use branches; emit the operation instead. ! 44: Usually, this will mean that the MD file will emit non-branch ! 45: sequences. */ ! 46: ! 47: static int sdiv_pow2_cheap, smod_pow2_cheap; ! 48: ! 49: #ifndef SLOW_UNALIGNED_ACCESS ! 50: #define SLOW_UNALIGNED_ACCESS STRICT_ALIGNMENT ! 51: #endif ! 52: ! 53: /* For compilers that support multiple targets with different word sizes, ! 54: MAX_BITS_PER_WORD contains the biggest value of BITS_PER_WORD. An example ! 55: is the H8/300(H) compiler. */ ! 56: ! 57: #ifndef MAX_BITS_PER_WORD ! 58: #define MAX_BITS_PER_WORD BITS_PER_WORD ! 59: #endif ! 60: ! 61: /* Cost of various pieces of RTL. */ ! 62: static int add_cost, negate_cost, zero_cost; ! 63: static int shift_cost[MAX_BITS_PER_WORD]; ! 64: static int shiftadd_cost[MAX_BITS_PER_WORD]; ! 65: static int shiftsub_cost[MAX_BITS_PER_WORD]; ! 66: ! 67: void ! 68: init_expmed () ! 69: { ! 70: char *free_point; ! 71: /* This is "some random pseudo register" for purposes of calling recog ! 72: to see what insns exist. */ ! 73: rtx reg = gen_rtx (REG, word_mode, 10000); ! 74: rtx shift_insn, shiftadd_insn, shiftsub_insn; ! 75: int dummy; ! 76: int m; ! 77: ! 78: start_sequence (); ! 79: ! 80: /* Since we are on the permanent obstack, we must be sure we save this ! 81: spot AFTER we call start_sequence, since it will reuse the rtl it ! 82: makes. */ ! 83: ! 84: free_point = (char *) oballoc (0); ! 85: ! 86: zero_cost = rtx_cost (const0_rtx, 0); ! 87: add_cost = rtx_cost (gen_rtx (PLUS, word_mode, reg, reg), SET); ! 88: ! 89: shift_insn = emit_insn (gen_rtx (SET, VOIDmode, reg, ! 90: gen_rtx (ASHIFT, word_mode, reg, ! 91: const0_rtx))); ! 92: ! 93: shiftadd_insn = emit_insn (gen_rtx (SET, VOIDmode, reg, ! 94: gen_rtx (PLUS, word_mode, ! 95: gen_rtx (MULT, word_mode, ! 96: reg, const0_rtx), ! 97: reg))); ! 98: ! 99: shiftsub_insn = emit_insn (gen_rtx (SET, VOIDmode, reg, ! 100: gen_rtx (MINUS, word_mode, ! 101: gen_rtx (MULT, word_mode, ! 102: reg, const0_rtx), ! 103: reg))); ! 104: ! 105: init_recog (); ! 106: ! 107: shift_cost[0] = 0; ! 108: shiftadd_cost[0] = shiftsub_cost[0] = add_cost; ! 109: ! 110: for (m = 1; m < BITS_PER_WORD; m++) ! 111: { ! 112: shift_cost[m] = shiftadd_cost[m] = shiftsub_cost[m] = 32000; ! 113: ! 114: XEXP (SET_SRC (PATTERN (shift_insn)), 1) = GEN_INT (m); ! 115: if (recog (PATTERN (shift_insn), shift_insn, &dummy) >= 0) ! 116: shift_cost[m] = rtx_cost (SET_SRC (PATTERN (shift_insn)), SET); ! 117: ! 118: XEXP (XEXP (SET_SRC (PATTERN (shiftadd_insn)), 0), 1) ! 119: = GEN_INT ((HOST_WIDE_INT) 1 << m); ! 120: if (recog (PATTERN (shiftadd_insn), shiftadd_insn, &dummy) >= 0) ! 121: shiftadd_cost[m] = rtx_cost (SET_SRC (PATTERN (shiftadd_insn)), SET); ! 122: ! 123: XEXP (XEXP (SET_SRC (PATTERN (shiftsub_insn)), 0), 1) ! 124: = GEN_INT ((HOST_WIDE_INT) 1 << m); ! 125: if (recog (PATTERN (shiftsub_insn), shiftsub_insn, &dummy) >= 0) ! 126: shiftsub_cost[m] = rtx_cost (SET_SRC (PATTERN (shiftsub_insn)), SET); ! 127: } ! 128: ! 129: negate_cost = rtx_cost (gen_rtx (NEG, word_mode, reg), SET); ! 130: ! 131: sdiv_pow2_cheap ! 132: = (rtx_cost (gen_rtx (DIV, word_mode, reg, GEN_INT (32)), SET) ! 133: <= 2 * add_cost); ! 134: smod_pow2_cheap ! 135: = (rtx_cost (gen_rtx (MOD, word_mode, reg, GEN_INT (32)), SET) ! 136: <= 2 * add_cost); ! 137: ! 138: /* Free the objects we just allocated. */ ! 139: end_sequence (); ! 140: obfree (free_point); ! 141: } ! 142: ! 143: /* Return an rtx representing minus the value of X. ! 144: MODE is the intended mode of the result, ! 145: useful if X is a CONST_INT. */ ! 146: ! 147: rtx ! 148: negate_rtx (mode, x) ! 149: enum machine_mode mode; ! 150: rtx x; ! 151: { ! 152: if (GET_CODE (x) == CONST_INT) ! 153: { ! 154: HOST_WIDE_INT val = - INTVAL (x); ! 155: if (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_WIDE_INT) ! 156: { ! 157: /* Sign extend the value from the bits that are significant. */ ! 158: if (val & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))) ! 159: val |= (HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (mode); ! 160: else ! 161: val &= ((HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1; ! 162: } ! 163: return GEN_INT (val); ! 164: } ! 165: else ! 166: return expand_unop (GET_MODE (x), neg_optab, x, NULL_RTX, 0); ! 167: } ! 168: ! 169: /* Generate code to store value from rtx VALUE ! 170: into a bit-field within structure STR_RTX ! 171: containing BITSIZE bits starting at bit BITNUM. ! 172: FIELDMODE is the machine-mode of the FIELD_DECL node for this field. ! 173: ALIGN is the alignment that STR_RTX is known to have, measured in bytes. ! 174: TOTAL_SIZE is the size of the structure in bytes, or -1 if varying. */ ! 175: ! 176: /* ??? Note that there are two different ideas here for how ! 177: to determine the size to count bits within, for a register. ! 178: One is BITS_PER_WORD, and the other is the size of operand 3 ! 179: of the insv pattern. (The latter assumes that an n-bit machine ! 180: will be able to insert bit fields up to n bits wide.) ! 181: It isn't certain that either of these is right. ! 182: extract_bit_field has the same quandary. */ ! 183: ! 184: rtx ! 185: store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ! 186: rtx str_rtx; ! 187: register int bitsize; ! 188: int bitnum; ! 189: enum machine_mode fieldmode; ! 190: rtx value; ! 191: int align; ! 192: int total_size; ! 193: { ! 194: int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD; ! 195: register int offset = bitnum / unit; ! 196: register int bitpos = bitnum % unit; ! 197: register rtx op0 = str_rtx; ! 198: ! 199: if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx)) ! 200: abort (); ! 201: ! 202: /* Discount the part of the structure before the desired byte. ! 203: We need to know how many bytes are safe to reference after it. */ ! 204: if (total_size >= 0) ! 205: total_size -= (bitpos / BIGGEST_ALIGNMENT ! 206: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); ! 207: ! 208: while (GET_CODE (op0) == SUBREG) ! 209: { ! 210: /* The following line once was done only if WORDS_BIG_ENDIAN, ! 211: but I think that is a mistake. WORDS_BIG_ENDIAN is ! 212: meaningful at a much higher level; when structures are copied ! 213: between memory and regs, the higher-numbered regs ! 214: always get higher addresses. */ ! 215: offset += SUBREG_WORD (op0); ! 216: /* We used to adjust BITPOS here, but now we do the whole adjustment ! 217: right after the loop. */ ! 218: op0 = SUBREG_REG (op0); ! 219: } ! 220: ! 221: #if BYTES_BIG_ENDIAN ! 222: /* If OP0 is a register, BITPOS must count within a word. ! 223: But as we have it, it counts within whatever size OP0 now has. ! 224: On a bigendian machine, these are not the same, so convert. */ ! 225: if (GET_CODE (op0) != MEM && unit > GET_MODE_BITSIZE (GET_MODE (op0))) ! 226: bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0)); ! 227: #endif ! 228: ! 229: value = protect_from_queue (value, 0); ! 230: ! 231: if (flag_force_mem) ! 232: value = force_not_mem (value); ! 233: ! 234: /* Note that the adjustment of BITPOS above has no effect on whether ! 235: BITPOS is 0 in a REG bigger than a word. */ ! 236: if (GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD ! 237: && (GET_CODE (op0) != MEM ! 238: || ! SLOW_UNALIGNED_ACCESS ! 239: || (offset * BITS_PER_UNIT % bitsize == 0 ! 240: && align % GET_MODE_SIZE (fieldmode) == 0)) ! 241: && bitpos == 0 && bitsize == GET_MODE_BITSIZE (fieldmode)) ! 242: { ! 243: /* Storing in a full-word or multi-word field in a register ! 244: can be done with just SUBREG. */ ! 245: if (GET_MODE (op0) != fieldmode) ! 246: { ! 247: if (GET_CODE (op0) == REG) ! 248: op0 = gen_rtx (SUBREG, fieldmode, op0, offset); ! 249: else ! 250: op0 = change_address (op0, fieldmode, ! 251: plus_constant (XEXP (op0, 0), offset)); ! 252: } ! 253: emit_move_insn (op0, value); ! 254: return value; ! 255: } ! 256: ! 257: /* Storing an lsb-aligned field in a register ! 258: can be done with a movestrict instruction. */ ! 259: ! 260: if (GET_CODE (op0) != MEM ! 261: #if BYTES_BIG_ENDIAN ! 262: && bitpos + bitsize == unit ! 263: #else ! 264: && bitpos == 0 ! 265: #endif ! 266: && bitsize == GET_MODE_BITSIZE (fieldmode) ! 267: && (GET_MODE (op0) == fieldmode ! 268: || (movstrict_optab->handlers[(int) fieldmode].insn_code ! 269: != CODE_FOR_nothing))) ! 270: { ! 271: /* Get appropriate low part of the value being stored. */ ! 272: if (GET_CODE (value) == CONST_INT || GET_CODE (value) == REG) ! 273: value = gen_lowpart (fieldmode, value); ! 274: else if (!(GET_CODE (value) == SYMBOL_REF ! 275: || GET_CODE (value) == LABEL_REF ! 276: || GET_CODE (value) == CONST)) ! 277: value = convert_to_mode (fieldmode, value, 0); ! 278: ! 279: if (GET_MODE (op0) == fieldmode) ! 280: emit_move_insn (op0, value); ! 281: else ! 282: { ! 283: int icode = movstrict_optab->handlers[(int) fieldmode].insn_code; ! 284: if(! (*insn_operand_predicate[icode][1]) (value, fieldmode)) ! 285: value = copy_to_mode_reg (fieldmode, value); ! 286: emit_insn (GEN_FCN (icode) ! 287: (gen_rtx (SUBREG, fieldmode, op0, offset), value)); ! 288: } ! 289: return value; ! 290: } ! 291: ! 292: /* Handle fields bigger than a word. */ ! 293: ! 294: if (bitsize > BITS_PER_WORD) ! 295: { ! 296: /* Here we transfer the words of the field ! 297: in the order least significant first. ! 298: This is because the most significant word is the one which may ! 299: be less than full. */ ! 300: ! 301: int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD; ! 302: int i; ! 303: ! 304: /* This is the mode we must force value to, so that there will be enough ! 305: subwords to extract. Note that fieldmode will often (always?) be ! 306: VOIDmode, because that is what store_field uses to indicate that this ! 307: is a bit field, but passing VOIDmode to operand_subword_force will ! 308: result in an abort. */ ! 309: fieldmode = mode_for_size (nwords * BITS_PER_WORD, MODE_INT, 0); ! 310: ! 311: for (i = 0; i < nwords; i++) ! 312: { ! 313: /* If I is 0, use the low-order word in both field and target; ! 314: if I is 1, use the next to lowest word; and so on. */ ! 315: int wordnum = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i); ! 316: int bit_offset = (WORDS_BIG_ENDIAN ! 317: ? MAX (bitsize - (i + 1) * BITS_PER_WORD, 0) ! 318: : i * BITS_PER_WORD); ! 319: store_bit_field (op0, MIN (BITS_PER_WORD, ! 320: bitsize - i * BITS_PER_WORD), ! 321: bitnum + bit_offset, word_mode, ! 322: operand_subword_force (value, wordnum, ! 323: (GET_MODE (value) == VOIDmode ! 324: ? fieldmode ! 325: : GET_MODE (value))), ! 326: align, total_size); ! 327: } ! 328: return value; ! 329: } ! 330: ! 331: /* From here on we can assume that the field to be stored in is ! 332: a full-word (whatever type that is), since it is shorter than a word. */ ! 333: ! 334: /* OFFSET is the number of words or bytes (UNIT says which) ! 335: from STR_RTX to the first word or byte containing part of the field. */ ! 336: ! 337: if (GET_CODE (op0) == REG) ! 338: { ! 339: if (offset != 0 ! 340: || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD) ! 341: op0 = gen_rtx (SUBREG, TYPE_MODE (type_for_size (BITS_PER_WORD, 0)), ! 342: op0, offset); ! 343: offset = 0; ! 344: } ! 345: else ! 346: { ! 347: op0 = protect_from_queue (op0, 1); ! 348: } ! 349: ! 350: /* Now OFFSET is nonzero only if OP0 is memory ! 351: and is therefore always measured in bytes. */ ! 352: ! 353: #ifdef HAVE_insv ! 354: if (HAVE_insv ! 355: && !(bitsize == 1 && GET_CODE (value) == CONST_INT) ! 356: /* Ensure insv's size is wide enough for this field. */ ! 357: && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]) ! 358: >= bitsize)) ! 359: { ! 360: int xbitpos = bitpos; ! 361: rtx value1; ! 362: rtx xop0 = op0; ! 363: rtx last = get_last_insn (); ! 364: rtx pat; ! 365: enum machine_mode maxmode ! 366: = insn_operand_mode[(int) CODE_FOR_insv][3]; ! 367: ! 368: int save_volatile_ok = volatile_ok; ! 369: volatile_ok = 1; ! 370: ! 371: /* If this machine's insv can only insert into a register, or if we ! 372: are to force MEMs into a register, copy OP0 into a register and ! 373: save it back later. */ ! 374: if (GET_CODE (op0) == MEM ! 375: && (flag_force_mem ! 376: || ! ((*insn_operand_predicate[(int) CODE_FOR_insv][0]) ! 377: (op0, VOIDmode)))) ! 378: { ! 379: rtx tempreg; ! 380: enum machine_mode bestmode; ! 381: ! 382: /* Get the mode to use for inserting into this field. If OP0 is ! 383: BLKmode, get the smallest mode consistent with the alignment. If ! 384: OP0 is a non-BLKmode object that is no wider than MAXMODE, use its ! 385: mode. Otherwise, use the smallest mode containing the field. */ ! 386: ! 387: if (GET_MODE (op0) == BLKmode ! 388: || GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (maxmode)) ! 389: bestmode ! 390: = get_best_mode (bitsize, bitnum, align * BITS_PER_UNIT, maxmode, ! 391: MEM_VOLATILE_P (op0)); ! 392: else ! 393: bestmode = GET_MODE (op0); ! 394: ! 395: if (bestmode == VOIDmode ! 396: || (STRICT_ALIGNMENT && GET_MODE_SIZE (bestmode) > align)) ! 397: goto insv_loses; ! 398: ! 399: /* Adjust address to point to the containing unit of that mode. */ ! 400: unit = GET_MODE_BITSIZE (bestmode); ! 401: /* Compute offset as multiple of this unit, counting in bytes. */ ! 402: offset = (bitnum / unit) * GET_MODE_SIZE (bestmode); ! 403: bitpos = bitnum % unit; ! 404: op0 = change_address (op0, bestmode, ! 405: plus_constant (XEXP (op0, 0), offset)); ! 406: ! 407: /* Fetch that unit, store the bitfield in it, then store the unit. */ ! 408: tempreg = copy_to_reg (op0); ! 409: store_bit_field (tempreg, bitsize, bitpos, fieldmode, value, ! 410: align, total_size); ! 411: emit_move_insn (op0, tempreg); ! 412: return value; ! 413: } ! 414: volatile_ok = save_volatile_ok; ! 415: ! 416: /* Add OFFSET into OP0's address. */ ! 417: if (GET_CODE (xop0) == MEM) ! 418: xop0 = change_address (xop0, byte_mode, ! 419: plus_constant (XEXP (xop0, 0), offset)); ! 420: ! 421: /* If xop0 is a register, we need it in MAXMODE ! 422: to make it acceptable to the format of insv. */ ! 423: if (GET_CODE (xop0) == SUBREG) ! 424: PUT_MODE (xop0, maxmode); ! 425: if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode) ! 426: xop0 = gen_rtx (SUBREG, maxmode, xop0, 0); ! 427: ! 428: /* On big-endian machines, we count bits from the most significant. ! 429: If the bit field insn does not, we must invert. */ ! 430: ! 431: #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN ! 432: xbitpos = unit - bitsize - xbitpos; ! 433: #endif ! 434: /* We have been counting XBITPOS within UNIT. ! 435: Count instead within the size of the register. */ ! 436: #if BITS_BIG_ENDIAN ! 437: if (GET_CODE (xop0) != MEM) ! 438: xbitpos += GET_MODE_BITSIZE (maxmode) - unit; ! 439: #endif ! 440: unit = GET_MODE_BITSIZE (maxmode); ! 441: ! 442: /* Convert VALUE to maxmode (which insv insn wants) in VALUE1. */ ! 443: value1 = value; ! 444: if (GET_MODE (value) != maxmode) ! 445: { ! 446: if (GET_MODE_BITSIZE (GET_MODE (value)) >= bitsize) ! 447: { ! 448: /* Optimization: Don't bother really extending VALUE ! 449: if it has all the bits we will actually use. However, ! 450: if we must narrow it, be sure we do it correctly. */ ! 451: ! 452: if (GET_MODE_SIZE (GET_MODE (value)) < GET_MODE_SIZE (maxmode)) ! 453: { ! 454: /* Avoid making subreg of a subreg, or of a mem. */ ! 455: if (GET_CODE (value1) != REG) ! 456: value1 = copy_to_reg (value1); ! 457: value1 = gen_rtx (SUBREG, maxmode, value1, 0); ! 458: } ! 459: else ! 460: value1 = gen_lowpart (maxmode, value1); ! 461: } ! 462: else if (!CONSTANT_P (value)) ! 463: /* Parse phase is supposed to make VALUE's data type ! 464: match that of the component reference, which is a type ! 465: at least as wide as the field; so VALUE should have ! 466: a mode that corresponds to that type. */ ! 467: abort (); ! 468: } ! 469: ! 470: /* If this machine's insv insists on a register, ! 471: get VALUE1 into a register. */ ! 472: if (! ((*insn_operand_predicate[(int) CODE_FOR_insv][3]) ! 473: (value1, maxmode))) ! 474: value1 = force_reg (maxmode, value1); ! 475: ! 476: pat = gen_insv (xop0, GEN_INT (bitsize), GEN_INT (xbitpos), value1); ! 477: if (pat) ! 478: emit_insn (pat); ! 479: else ! 480: { ! 481: delete_insns_since (last); ! 482: store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align); ! 483: } ! 484: } ! 485: else ! 486: insv_loses: ! 487: #endif ! 488: /* Insv is not available; store using shifts and boolean ops. */ ! 489: store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align); ! 490: return value; ! 491: } ! 492: ! 493: /* Use shifts and boolean operations to store VALUE ! 494: into a bit field of width BITSIZE ! 495: in a memory location specified by OP0 except offset by OFFSET bytes. ! 496: (OFFSET must be 0 if OP0 is a register.) ! 497: The field starts at position BITPOS within the byte. ! 498: (If OP0 is a register, it may be a full word or a narrower mode, ! 499: but BITPOS still counts within a full word, ! 500: which is significant on bigendian machines.) ! 501: STRUCT_ALIGN is the alignment the structure is known to have (in bytes). ! 502: ! 503: Note that protect_from_queue has already been done on OP0 and VALUE. */ ! 504: ! 505: static void ! 506: store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align) ! 507: register rtx op0; ! 508: register int offset, bitsize, bitpos; ! 509: register rtx value; ! 510: int struct_align; ! 511: { ! 512: register enum machine_mode mode; ! 513: int total_bits = BITS_PER_WORD; ! 514: rtx subtarget, temp; ! 515: int all_zero = 0; ! 516: int all_one = 0; ! 517: ! 518: /* There is a case not handled here: ! 519: a structure with a known alignment of just a halfword ! 520: and a field split across two aligned halfwords within the structure. ! 521: Or likewise a structure with a known alignment of just a byte ! 522: and a field split across two bytes. ! 523: Such cases are not supposed to be able to occur. */ ! 524: ! 525: if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG) ! 526: { ! 527: if (offset != 0) ! 528: abort (); ! 529: /* Special treatment for a bit field split across two registers. */ ! 530: if (bitsize + bitpos > BITS_PER_WORD) ! 531: { ! 532: store_split_bit_field (op0, bitsize, bitpos, ! 533: value, BITS_PER_WORD); ! 534: return; ! 535: } ! 536: } ! 537: else ! 538: { ! 539: /* Get the proper mode to use for this field. We want a mode that ! 540: includes the entire field. If such a mode would be larger than ! 541: a word, we won't be doing the extraction the normal way. */ ! 542: ! 543: mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, ! 544: struct_align * BITS_PER_UNIT, word_mode, ! 545: GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0)); ! 546: ! 547: if (mode == VOIDmode) ! 548: { ! 549: /* The only way this should occur is if the field spans word ! 550: boundaries. */ ! 551: store_split_bit_field (op0, ! 552: bitsize, bitpos + offset * BITS_PER_UNIT, ! 553: value, struct_align); ! 554: return; ! 555: } ! 556: ! 557: total_bits = GET_MODE_BITSIZE (mode); ! 558: ! 559: /* Get ref to an aligned byte, halfword, or word containing the field. ! 560: Adjust BITPOS to be position within a word, ! 561: and OFFSET to be the offset of that word. ! 562: Then alter OP0 to refer to that word. */ ! 563: bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT; ! 564: offset -= (offset % (total_bits / BITS_PER_UNIT)); ! 565: op0 = change_address (op0, mode, ! 566: plus_constant (XEXP (op0, 0), offset)); ! 567: } ! 568: ! 569: mode = GET_MODE (op0); ! 570: ! 571: /* Now MODE is either some integral mode for a MEM as OP0, ! 572: or is a full-word for a REG as OP0. TOTAL_BITS corresponds. ! 573: The bit field is contained entirely within OP0. ! 574: BITPOS is the starting bit number within OP0. ! 575: (OP0's mode may actually be narrower than MODE.) */ ! 576: ! 577: #if BYTES_BIG_ENDIAN ! 578: /* BITPOS is the distance between our msb ! 579: and that of the containing datum. ! 580: Convert it to the distance from the lsb. */ ! 581: ! 582: bitpos = total_bits - bitsize - bitpos; ! 583: #endif ! 584: /* Now BITPOS is always the distance between our lsb ! 585: and that of OP0. */ ! 586: ! 587: /* Shift VALUE left by BITPOS bits. If VALUE is not constant, ! 588: we must first convert its mode to MODE. */ ! 589: ! 590: if (GET_CODE (value) == CONST_INT) ! 591: { ! 592: register HOST_WIDE_INT v = INTVAL (value); ! 593: ! 594: if (bitsize < HOST_BITS_PER_WIDE_INT) ! 595: v &= ((HOST_WIDE_INT) 1 << bitsize) - 1; ! 596: ! 597: if (v == 0) ! 598: all_zero = 1; ! 599: else if ((bitsize < HOST_BITS_PER_WIDE_INT ! 600: && v == ((HOST_WIDE_INT) 1 << bitsize) - 1) ! 601: || (bitsize == HOST_BITS_PER_WIDE_INT && v == -1)) ! 602: all_one = 1; ! 603: ! 604: value = lshift_value (mode, value, bitpos, bitsize); ! 605: } ! 606: else ! 607: { ! 608: int must_and = (GET_MODE_BITSIZE (GET_MODE (value)) != bitsize ! 609: && bitpos + bitsize != GET_MODE_BITSIZE (mode)); ! 610: ! 611: if (GET_MODE (value) != mode) ! 612: { ! 613: /* If VALUE is a floating-point mode, access it as an integer ! 614: of the corresponding size, then convert it. This can occur on ! 615: a machine with 64 bit registers that uses SFmode for float. */ ! 616: if (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT) ! 617: { ! 618: if (GET_CODE (value) != REG) ! 619: value = copy_to_reg (value); ! 620: value ! 621: = gen_rtx (SUBREG, word_mode, value, 0); ! 622: } ! 623: ! 624: if ((GET_CODE (value) == REG || GET_CODE (value) == SUBREG) ! 625: && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (value))) ! 626: value = gen_lowpart (mode, value); ! 627: else ! 628: value = convert_to_mode (mode, value, 1); ! 629: } ! 630: ! 631: if (must_and) ! 632: value = expand_binop (mode, and_optab, value, ! 633: mask_rtx (mode, 0, bitsize, 0), ! 634: NULL_RTX, 1, OPTAB_LIB_WIDEN); ! 635: if (bitpos > 0) ! 636: value = expand_shift (LSHIFT_EXPR, mode, value, ! 637: build_int_2 (bitpos, 0), NULL_RTX, 1); ! 638: } ! 639: ! 640: /* Now clear the chosen bits in OP0, ! 641: except that if VALUE is -1 we need not bother. */ ! 642: ! 643: subtarget = (GET_CODE (op0) == REG || ! flag_force_mem) ? op0 : 0; ! 644: ! 645: if (! all_one) ! 646: { ! 647: temp = expand_binop (mode, and_optab, op0, ! 648: mask_rtx (mode, bitpos, bitsize, 1), ! 649: subtarget, 1, OPTAB_LIB_WIDEN); ! 650: subtarget = temp; ! 651: } ! 652: else ! 653: temp = op0; ! 654: ! 655: /* Now logical-or VALUE into OP0, unless it is zero. */ ! 656: ! 657: if (! all_zero) ! 658: temp = expand_binop (mode, ior_optab, temp, value, ! 659: subtarget, 1, OPTAB_LIB_WIDEN); ! 660: if (op0 != temp) ! 661: emit_move_insn (op0, temp); ! 662: } ! 663: ! 664: /* Store a bit field that is split across multiple accessible memory objects. ! 665: ! 666: OP0 is the REG, SUBREG or MEM rtx for the first of the objects. ! 667: BITSIZE is the field width; BITPOS the position of its first bit ! 668: (within the word). ! 669: VALUE is the value to store. ! 670: ALIGN is the known alignment of OP0, measured in bytes. ! 671: This is also the size of the memory objects to be used. ! 672: ! 673: This does not yet handle fields wider than BITS_PER_WORD. */ ! 674: ! 675: static void ! 676: store_split_bit_field (op0, bitsize, bitpos, value, align) ! 677: rtx op0; ! 678: int bitsize, bitpos; ! 679: rtx value; ! 680: int align; ! 681: { ! 682: /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that ! 683: much at a time. */ ! 684: int unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD); ! 685: int bitsdone = 0; ! 686: ! 687: /* If VALUE is a constant other than a CONST_INT, get it into a register in ! 688: WORD_MODE. If we can do this using gen_lowpart_common, do so. Note ! 689: that VALUE might be a floating-point constant. */ ! 690: if (CONSTANT_P (value) && GET_CODE (value) != CONST_INT) ! 691: { ! 692: rtx word = gen_lowpart_common (word_mode, value); ! 693: ! 694: if (word) ! 695: value = word; ! 696: else ! 697: value = gen_lowpart_common (word_mode, ! 698: force_reg (GET_MODE (value), value)); ! 699: } ! 700: ! 701: while (bitsdone < bitsize) ! 702: { ! 703: int thissize; ! 704: rtx part, word; ! 705: int thispos; ! 706: int offset; ! 707: ! 708: offset = (bitpos + bitsdone) / unit; ! 709: thispos = (bitpos + bitsdone) % unit; ! 710: ! 711: /* THISSIZE must not overrun a word boundary. Otherwise, ! 712: store_fixed_bit_field will call us again, and we will mutually ! 713: recurse forever. */ ! 714: thissize = MIN (bitsize - bitsdone, BITS_PER_WORD); ! 715: thissize = MIN (thissize, unit - thispos); ! 716: ! 717: #if BYTES_BIG_ENDIAN ! 718: /* Fetch successively less significant portions. */ ! 719: if (GET_CODE (value) == CONST_INT) ! 720: part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value)) ! 721: >> (bitsize - bitsdone - thissize)) ! 722: & (((HOST_WIDE_INT) 1 << thissize) - 1)); ! 723: else ! 724: /* The args are chosen so that the last part ! 725: includes the lsb. */ ! 726: part = extract_fixed_bit_field (word_mode, value, 0, thissize, ! 727: BITS_PER_WORD - bitsize + bitsdone, ! 728: NULL_RTX, 1, align); ! 729: #else ! 730: /* Fetch successively more significant portions. */ ! 731: if (GET_CODE (value) == CONST_INT) ! 732: part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value)) >> bitsdone) ! 733: & (((HOST_WIDE_INT) 1 << thissize) - 1)); ! 734: else ! 735: part = extract_fixed_bit_field (word_mode, value, 0, thissize, ! 736: bitsdone, NULL_RTX, 1, align); ! 737: #endif ! 738: ! 739: /* If OP0 is a register, then handle OFFSET here. ! 740: In the register case, UNIT must be a whole word. */ ! 741: if (GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG) ! 742: { ! 743: word = operand_subword (op0, offset, 1, GET_MODE (op0)); ! 744: offset = 0; ! 745: } ! 746: else ! 747: word = op0; ! 748: ! 749: if (word == 0) ! 750: abort (); ! 751: ! 752: /* OFFSET is in UNITs, and UNIT is in bits. ! 753: store_fixed_bit_field wants offset in bytes. */ ! 754: store_fixed_bit_field (word, offset * unit / BITS_PER_UNIT, ! 755: thissize, thispos, part, align); ! 756: bitsdone += thissize; ! 757: } ! 758: } ! 759: ! 760: /* Generate code to extract a byte-field from STR_RTX ! 761: containing BITSIZE bits, starting at BITNUM, ! 762: and put it in TARGET if possible (if TARGET is nonzero). ! 763: Regardless of TARGET, we return the rtx for where the value is placed. ! 764: It may be a QUEUED. ! 765: ! 766: STR_RTX is the structure containing the byte (a REG or MEM). ! 767: UNSIGNEDP is nonzero if this is an unsigned bit field. ! 768: MODE is the natural mode of the field value once extracted. ! 769: TMODE is the mode the caller would like the value to have; ! 770: but the value may be returned with type MODE instead. ! 771: ! 772: ALIGN is the alignment that STR_RTX is known to have, measured in bytes. ! 773: TOTAL_SIZE is the size in bytes of the containing structure, ! 774: or -1 if varying. ! 775: ! 776: If a TARGET is specified and we can store in it at no extra cost, ! 777: we do so, and return TARGET. ! 778: Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred ! 779: if they are equally easy. */ ! 780: ! 781: rtx ! 782: extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ! 783: target, mode, tmode, align, total_size) ! 784: rtx str_rtx; ! 785: register int bitsize; ! 786: int bitnum; ! 787: int unsignedp; ! 788: rtx target; ! 789: enum machine_mode mode, tmode; ! 790: int align; ! 791: int total_size; ! 792: { ! 793: int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD; ! 794: register int offset = bitnum / unit; ! 795: register int bitpos = bitnum % unit; ! 796: register rtx op0 = str_rtx; ! 797: rtx spec_target = target; ! 798: rtx spec_target_subreg = 0; ! 799: ! 800: if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx)) ! 801: abort (); ! 802: ! 803: /* Discount the part of the structure before the desired byte. ! 804: We need to know how many bytes are safe to reference after it. */ ! 805: if (total_size >= 0) ! 806: total_size -= (bitpos / BIGGEST_ALIGNMENT ! 807: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); ! 808: ! 809: if (tmode == VOIDmode) ! 810: tmode = mode; ! 811: while (GET_CODE (op0) == SUBREG) ! 812: { ! 813: offset += SUBREG_WORD (op0); ! 814: op0 = SUBREG_REG (op0); ! 815: } ! 816: ! 817: #if BYTES_BIG_ENDIAN ! 818: /* If OP0 is a register, BITPOS must count within a word. ! 819: But as we have it, it counts within whatever size OP0 now has. ! 820: On a bigendian machine, these are not the same, so convert. */ ! 821: if (GET_CODE (op0) != MEM && unit > GET_MODE_BITSIZE (GET_MODE (op0))) ! 822: bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0)); ! 823: #endif ! 824: ! 825: /* Extracting a full-word or multi-word value ! 826: from a structure in a register or aligned memory. ! 827: This can be done with just SUBREG. ! 828: So too extracting a subword value in ! 829: the least significant part of the register. */ ! 830: ! 831: if ((GET_CODE (op0) == REG ! 832: || (GET_CODE (op0) == MEM ! 833: && (! SLOW_UNALIGNED_ACCESS ! 834: || (offset * BITS_PER_UNIT % bitsize == 0 ! 835: && align * BITS_PER_UNIT % bitsize == 0)))) ! 836: && ((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode) ! 837: && bitpos % BITS_PER_WORD == 0) ! 838: || (mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) != BLKmode ! 839: #if BYTES_BIG_ENDIAN ! 840: && bitpos + bitsize == BITS_PER_WORD ! 841: #else ! 842: && bitpos == 0 ! 843: #endif ! 844: ))) ! 845: { ! 846: enum machine_mode mode1 ! 847: = mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0); ! 848: ! 849: if (mode1 != GET_MODE (op0)) ! 850: { ! 851: if (GET_CODE (op0) == REG) ! 852: op0 = gen_rtx (SUBREG, mode1, op0, offset); ! 853: else ! 854: op0 = change_address (op0, mode1, ! 855: plus_constant (XEXP (op0, 0), offset)); ! 856: } ! 857: if (mode1 != mode) ! 858: return convert_to_mode (tmode, op0, unsignedp); ! 859: return op0; ! 860: } ! 861: ! 862: /* Handle fields bigger than a word. */ ! 863: ! 864: if (bitsize > BITS_PER_WORD) ! 865: { ! 866: /* Here we transfer the words of the field ! 867: in the order least significant first. ! 868: This is because the most significant word is the one which may ! 869: be less than full. */ ! 870: ! 871: int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD; ! 872: int i; ! 873: ! 874: if (target == 0 || GET_CODE (target) != REG) ! 875: target = gen_reg_rtx (mode); ! 876: ! 877: for (i = 0; i < nwords; i++) ! 878: { ! 879: /* If I is 0, use the low-order word in both field and target; ! 880: if I is 1, use the next to lowest word; and so on. */ ! 881: int wordnum = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i); ! 882: int bit_offset = (WORDS_BIG_ENDIAN ! 883: ? MAX (0, bitsize - (i + 1) * BITS_PER_WORD) ! 884: : i * BITS_PER_WORD); ! 885: rtx target_part = operand_subword (target, wordnum, 1, VOIDmode); ! 886: rtx result_part ! 887: = extract_bit_field (op0, MIN (BITS_PER_WORD, ! 888: bitsize - i * BITS_PER_WORD), ! 889: bitnum + bit_offset, ! 890: 1, target_part, mode, word_mode, ! 891: align, total_size); ! 892: ! 893: if (target_part == 0) ! 894: abort (); ! 895: ! 896: if (result_part != target_part) ! 897: emit_move_insn (target_part, result_part); ! 898: } ! 899: ! 900: return target; ! 901: } ! 902: ! 903: /* From here on we know the desired field is smaller than a word ! 904: so we can assume it is an integer. So we can safely extract it as one ! 905: size of integer, if necessary, and then truncate or extend ! 906: to the size that is wanted. */ ! 907: ! 908: /* OFFSET is the number of words or bytes (UNIT says which) ! 909: from STR_RTX to the first word or byte containing part of the field. */ ! 910: ! 911: if (GET_CODE (op0) == REG) ! 912: { ! 913: if (offset != 0 ! 914: || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD) ! 915: op0 = gen_rtx (SUBREG, TYPE_MODE (type_for_size (BITS_PER_WORD, 0)), ! 916: op0, offset); ! 917: offset = 0; ! 918: } ! 919: else ! 920: { ! 921: op0 = protect_from_queue (str_rtx, 1); ! 922: } ! 923: ! 924: /* Now OFFSET is nonzero only for memory operands. */ ! 925: ! 926: if (unsignedp) ! 927: { ! 928: #ifdef HAVE_extzv ! 929: if (HAVE_extzv ! 930: && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]) ! 931: >= bitsize)) ! 932: { ! 933: int xbitpos = bitpos, xoffset = offset; ! 934: rtx bitsize_rtx, bitpos_rtx; ! 935: rtx last = get_last_insn(); ! 936: rtx xop0 = op0; ! 937: rtx xtarget = target; ! 938: rtx xspec_target = spec_target; ! 939: rtx xspec_target_subreg = spec_target_subreg; ! 940: rtx pat; ! 941: enum machine_mode maxmode ! 942: = insn_operand_mode[(int) CODE_FOR_extzv][0]; ! 943: ! 944: if (GET_CODE (xop0) == MEM) ! 945: { ! 946: int save_volatile_ok = volatile_ok; ! 947: volatile_ok = 1; ! 948: ! 949: /* Is the memory operand acceptable? */ ! 950: if (flag_force_mem ! 951: || ! ((*insn_operand_predicate[(int) CODE_FOR_extzv][1]) ! 952: (xop0, GET_MODE (xop0)))) ! 953: { ! 954: /* No, load into a reg and extract from there. */ ! 955: enum machine_mode bestmode; ! 956: ! 957: /* Get the mode to use for inserting into this field. If ! 958: OP0 is BLKmode, get the smallest mode consistent with the ! 959: alignment. If OP0 is a non-BLKmode object that is no ! 960: wider than MAXMODE, use its mode. Otherwise, use the ! 961: smallest mode containing the field. */ ! 962: ! 963: if (GET_MODE (xop0) == BLKmode ! 964: || (GET_MODE_SIZE (GET_MODE (op0)) ! 965: > GET_MODE_SIZE (maxmode))) ! 966: bestmode = get_best_mode (bitsize, bitnum, ! 967: align * BITS_PER_UNIT, maxmode, ! 968: MEM_VOLATILE_P (xop0)); ! 969: else ! 970: bestmode = GET_MODE (xop0); ! 971: ! 972: if (bestmode == VOIDmode ! 973: || (STRICT_ALIGNMENT && GET_MODE_SIZE (bestmode) > align)) ! 974: goto extzv_loses; ! 975: ! 976: /* Compute offset as multiple of this unit, ! 977: counting in bytes. */ ! 978: unit = GET_MODE_BITSIZE (bestmode); ! 979: xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode); ! 980: xbitpos = bitnum % unit; ! 981: xop0 = change_address (xop0, bestmode, ! 982: plus_constant (XEXP (xop0, 0), ! 983: xoffset)); ! 984: /* Fetch it to a register in that size. */ ! 985: xop0 = force_reg (bestmode, xop0); ! 986: ! 987: /* XBITPOS counts within UNIT, which is what is expected. */ ! 988: } ! 989: else ! 990: /* Get ref to first byte containing part of the field. */ ! 991: xop0 = change_address (xop0, byte_mode, ! 992: plus_constant (XEXP (xop0, 0), xoffset)); ! 993: ! 994: volatile_ok = save_volatile_ok; ! 995: } ! 996: ! 997: /* If op0 is a register, we need it in MAXMODE (which is usually ! 998: SImode). to make it acceptable to the format of extzv. */ ! 999: if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode) ! 1000: abort (); ! 1001: if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode) ! 1002: xop0 = gen_rtx (SUBREG, maxmode, xop0, 0); ! 1003: ! 1004: /* On big-endian machines, we count bits from the most significant. ! 1005: If the bit field insn does not, we must invert. */ ! 1006: #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN ! 1007: xbitpos = unit - bitsize - xbitpos; ! 1008: #endif ! 1009: /* Now convert from counting within UNIT to counting in MAXMODE. */ ! 1010: #if BITS_BIG_ENDIAN ! 1011: if (GET_CODE (xop0) != MEM) ! 1012: xbitpos += GET_MODE_BITSIZE (maxmode) - unit; ! 1013: #endif ! 1014: unit = GET_MODE_BITSIZE (maxmode); ! 1015: ! 1016: if (xtarget == 0 ! 1017: || (flag_force_mem && GET_CODE (xtarget) == MEM)) ! 1018: xtarget = xspec_target = gen_reg_rtx (tmode); ! 1019: ! 1020: if (GET_MODE (xtarget) != maxmode) ! 1021: { ! 1022: if (GET_CODE (xtarget) == REG) ! 1023: { ! 1024: int wider = (GET_MODE_SIZE (maxmode) ! 1025: > GET_MODE_SIZE (GET_MODE (xtarget))); ! 1026: xtarget = gen_lowpart (maxmode, xtarget); ! 1027: if (wider) ! 1028: xspec_target_subreg = xtarget; ! 1029: } ! 1030: else ! 1031: xtarget = gen_reg_rtx (maxmode); ! 1032: } ! 1033: ! 1034: /* If this machine's extzv insists on a register target, ! 1035: make sure we have one. */ ! 1036: if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0]) ! 1037: (xtarget, maxmode))) ! 1038: xtarget = gen_reg_rtx (maxmode); ! 1039: ! 1040: bitsize_rtx = GEN_INT (bitsize); ! 1041: bitpos_rtx = GEN_INT (xbitpos); ! 1042: ! 1043: pat = gen_extzv (protect_from_queue (xtarget, 1), ! 1044: xop0, bitsize_rtx, bitpos_rtx); ! 1045: if (pat) ! 1046: { ! 1047: emit_insn (pat); ! 1048: target = xtarget; ! 1049: spec_target = xspec_target; ! 1050: spec_target_subreg = xspec_target_subreg; ! 1051: } ! 1052: else ! 1053: { ! 1054: delete_insns_since (last); ! 1055: target = extract_fixed_bit_field (tmode, op0, offset, bitsize, ! 1056: bitpos, target, 1, align); ! 1057: } ! 1058: } ! 1059: else ! 1060: extzv_loses: ! 1061: #endif ! 1062: target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos, ! 1063: target, 1, align); ! 1064: } ! 1065: else ! 1066: { ! 1067: #ifdef HAVE_extv ! 1068: if (HAVE_extv ! 1069: && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]) ! 1070: >= bitsize)) ! 1071: { ! 1072: int xbitpos = bitpos, xoffset = offset; ! 1073: rtx bitsize_rtx, bitpos_rtx; ! 1074: rtx last = get_last_insn(); ! 1075: rtx xop0 = op0, xtarget = target; ! 1076: rtx xspec_target = spec_target; ! 1077: rtx xspec_target_subreg = spec_target_subreg; ! 1078: rtx pat; ! 1079: enum machine_mode maxmode ! 1080: = insn_operand_mode[(int) CODE_FOR_extv][0]; ! 1081: ! 1082: if (GET_CODE (xop0) == MEM) ! 1083: { ! 1084: /* Is the memory operand acceptable? */ ! 1085: if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][1]) ! 1086: (xop0, GET_MODE (xop0)))) ! 1087: { ! 1088: /* No, load into a reg and extract from there. */ ! 1089: enum machine_mode bestmode; ! 1090: ! 1091: /* Get the mode to use for inserting into this field. If ! 1092: OP0 is BLKmode, get the smallest mode consistent with the ! 1093: alignment. If OP0 is a non-BLKmode object that is no ! 1094: wider than MAXMODE, use its mode. Otherwise, use the ! 1095: smallest mode containing the field. */ ! 1096: ! 1097: if (GET_MODE (xop0) == BLKmode ! 1098: || (GET_MODE_SIZE (GET_MODE (op0)) ! 1099: > GET_MODE_SIZE (maxmode))) ! 1100: bestmode = get_best_mode (bitsize, bitnum, ! 1101: align * BITS_PER_UNIT, maxmode, ! 1102: MEM_VOLATILE_P (xop0)); ! 1103: else ! 1104: bestmode = GET_MODE (xop0); ! 1105: ! 1106: if (bestmode == VOIDmode ! 1107: || (STRICT_ALIGNMENT && GET_MODE_SIZE (bestmode) > align)) ! 1108: goto extv_loses; ! 1109: ! 1110: /* Compute offset as multiple of this unit, ! 1111: counting in bytes. */ ! 1112: unit = GET_MODE_BITSIZE (bestmode); ! 1113: xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode); ! 1114: xbitpos = bitnum % unit; ! 1115: xop0 = change_address (xop0, bestmode, ! 1116: plus_constant (XEXP (xop0, 0), ! 1117: xoffset)); ! 1118: /* Fetch it to a register in that size. */ ! 1119: xop0 = force_reg (bestmode, xop0); ! 1120: ! 1121: /* XBITPOS counts within UNIT, which is what is expected. */ ! 1122: } ! 1123: else ! 1124: /* Get ref to first byte containing part of the field. */ ! 1125: xop0 = change_address (xop0, byte_mode, ! 1126: plus_constant (XEXP (xop0, 0), xoffset)); ! 1127: } ! 1128: ! 1129: /* If op0 is a register, we need it in MAXMODE (which is usually ! 1130: SImode) to make it acceptable to the format of extv. */ ! 1131: if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode) ! 1132: abort (); ! 1133: if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode) ! 1134: xop0 = gen_rtx (SUBREG, maxmode, xop0, 0); ! 1135: ! 1136: /* On big-endian machines, we count bits from the most significant. ! 1137: If the bit field insn does not, we must invert. */ ! 1138: #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN ! 1139: xbitpos = unit - bitsize - xbitpos; ! 1140: #endif ! 1141: /* XBITPOS counts within a size of UNIT. ! 1142: Adjust to count within a size of MAXMODE. */ ! 1143: #if BITS_BIG_ENDIAN ! 1144: if (GET_CODE (xop0) != MEM) ! 1145: xbitpos += (GET_MODE_BITSIZE (maxmode) - unit); ! 1146: #endif ! 1147: unit = GET_MODE_BITSIZE (maxmode); ! 1148: ! 1149: if (xtarget == 0 ! 1150: || (flag_force_mem && GET_CODE (xtarget) == MEM)) ! 1151: xtarget = xspec_target = gen_reg_rtx (tmode); ! 1152: ! 1153: if (GET_MODE (xtarget) != maxmode) ! 1154: { ! 1155: if (GET_CODE (xtarget) == REG) ! 1156: { ! 1157: int wider = (GET_MODE_SIZE (maxmode) ! 1158: > GET_MODE_SIZE (GET_MODE (xtarget))); ! 1159: xtarget = gen_lowpart (maxmode, xtarget); ! 1160: if (wider) ! 1161: xspec_target_subreg = xtarget; ! 1162: } ! 1163: else ! 1164: xtarget = gen_reg_rtx (maxmode); ! 1165: } ! 1166: ! 1167: /* If this machine's extv insists on a register target, ! 1168: make sure we have one. */ ! 1169: if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][0]) ! 1170: (xtarget, maxmode))) ! 1171: xtarget = gen_reg_rtx (maxmode); ! 1172: ! 1173: bitsize_rtx = GEN_INT (bitsize); ! 1174: bitpos_rtx = GEN_INT (xbitpos); ! 1175: ! 1176: pat = gen_extv (protect_from_queue (xtarget, 1), ! 1177: xop0, bitsize_rtx, bitpos_rtx); ! 1178: if (pat) ! 1179: { ! 1180: emit_insn (pat); ! 1181: target = xtarget; ! 1182: spec_target = xspec_target; ! 1183: spec_target_subreg = xspec_target_subreg; ! 1184: } ! 1185: else ! 1186: { ! 1187: delete_insns_since (last); ! 1188: target = extract_fixed_bit_field (tmode, op0, offset, bitsize, ! 1189: bitpos, target, 0, align); ! 1190: } ! 1191: } ! 1192: else ! 1193: extv_loses: ! 1194: #endif ! 1195: target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos, ! 1196: target, 0, align); ! 1197: } ! 1198: if (target == spec_target) ! 1199: return target; ! 1200: if (target == spec_target_subreg) ! 1201: return spec_target; ! 1202: if (GET_MODE (target) != tmode && GET_MODE (target) != mode) ! 1203: { ! 1204: /* If the target mode is floating-point, first convert to the ! 1205: integer mode of that size and then access it as a floating-point ! 1206: value via a SUBREG. */ ! 1207: if (GET_MODE_CLASS (tmode) == MODE_FLOAT) ! 1208: { ! 1209: target = convert_to_mode (mode_for_size (GET_MODE_BITSIZE (tmode), ! 1210: MODE_INT, 0), ! 1211: target, unsignedp); ! 1212: if (GET_CODE (target) != REG) ! 1213: target = copy_to_reg (target); ! 1214: return gen_rtx (SUBREG, tmode, target, 0); ! 1215: } ! 1216: else ! 1217: return convert_to_mode (tmode, target, unsignedp); ! 1218: } ! 1219: return target; ! 1220: } ! 1221: ! 1222: /* Extract a bit field using shifts and boolean operations ! 1223: Returns an rtx to represent the value. ! 1224: OP0 addresses a register (word) or memory (byte). ! 1225: BITPOS says which bit within the word or byte the bit field starts in. ! 1226: OFFSET says how many bytes farther the bit field starts; ! 1227: it is 0 if OP0 is a register. ! 1228: BITSIZE says how many bits long the bit field is. ! 1229: (If OP0 is a register, it may be narrower than a full word, ! 1230: but BITPOS still counts within a full word, ! 1231: which is significant on bigendian machines.) ! 1232: ! 1233: UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value). ! 1234: If TARGET is nonzero, attempts to store the value there ! 1235: and return TARGET, but this is not guaranteed. ! 1236: If TARGET is not used, create a pseudo-reg of mode TMODE for the value. ! 1237: ! 1238: ALIGN is the alignment that STR_RTX is known to have, measured in bytes. */ ! 1239: ! 1240: static rtx ! 1241: extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos, ! 1242: target, unsignedp, align) ! 1243: enum machine_mode tmode; ! 1244: register rtx op0, target; ! 1245: register int offset, bitsize, bitpos; ! 1246: int unsignedp; ! 1247: int align; ! 1248: { ! 1249: int total_bits = BITS_PER_WORD; ! 1250: enum machine_mode mode; ! 1251: ! 1252: if (GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG) ! 1253: { ! 1254: /* Special treatment for a bit field split across two registers. */ ! 1255: if (bitsize + bitpos > BITS_PER_WORD) ! 1256: return extract_split_bit_field (op0, bitsize, bitpos, ! 1257: unsignedp, align); ! 1258: } ! 1259: else ! 1260: { ! 1261: /* Get the proper mode to use for this field. We want a mode that ! 1262: includes the entire field. If such a mode would be larger than ! 1263: a word, we won't be doing the extraction the normal way. */ ! 1264: ! 1265: mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, ! 1266: align * BITS_PER_UNIT, word_mode, ! 1267: GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0)); ! 1268: ! 1269: if (mode == VOIDmode) ! 1270: /* The only way this should occur is if the field spans word ! 1271: boundaries. */ ! 1272: return extract_split_bit_field (op0, bitsize, ! 1273: bitpos + offset * BITS_PER_UNIT, ! 1274: unsignedp, align); ! 1275: ! 1276: total_bits = GET_MODE_BITSIZE (mode); ! 1277: ! 1278: /* Make sure bitpos is valid for the chosen mode. Adjust BITPOS to ! 1279: be be in the range 0 to total_bits-1, and put any excess bytes in ! 1280: OFFSET. */ ! 1281: if (bitpos >= total_bits) ! 1282: { ! 1283: offset += (bitpos / total_bits) * (total_bits / BITS_PER_UNIT); ! 1284: bitpos -= ((bitpos / total_bits) * (total_bits / BITS_PER_UNIT) ! 1285: * BITS_PER_UNIT); ! 1286: } ! 1287: ! 1288: /* Get ref to an aligned byte, halfword, or word containing the field. ! 1289: Adjust BITPOS to be position within a word, ! 1290: and OFFSET to be the offset of that word. ! 1291: Then alter OP0 to refer to that word. */ ! 1292: bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT; ! 1293: offset -= (offset % (total_bits / BITS_PER_UNIT)); ! 1294: op0 = change_address (op0, mode, ! 1295: plus_constant (XEXP (op0, 0), offset)); ! 1296: } ! 1297: ! 1298: mode = GET_MODE (op0); ! 1299: ! 1300: #if BYTES_BIG_ENDIAN ! 1301: /* BITPOS is the distance between our msb and that of OP0. ! 1302: Convert it to the distance from the lsb. */ ! 1303: ! 1304: bitpos = total_bits - bitsize - bitpos; ! 1305: #endif ! 1306: /* Now BITPOS is always the distance between the field's lsb and that of OP0. ! 1307: We have reduced the big-endian case to the little-endian case. */ ! 1308: ! 1309: if (unsignedp) ! 1310: { ! 1311: if (bitpos) ! 1312: { ! 1313: /* If the field does not already start at the lsb, ! 1314: shift it so it does. */ ! 1315: tree amount = build_int_2 (bitpos, 0); ! 1316: /* Maybe propagate the target for the shift. */ ! 1317: /* But not if we will return it--could confuse integrate.c. */ ! 1318: rtx subtarget = (target != 0 && GET_CODE (target) == REG ! 1319: && !REG_FUNCTION_VALUE_P (target) ! 1320: ? target : 0); ! 1321: if (tmode != mode) subtarget = 0; ! 1322: op0 = expand_shift (RSHIFT_EXPR, mode, op0, amount, subtarget, 1); ! 1323: } ! 1324: /* Convert the value to the desired mode. */ ! 1325: if (mode != tmode) ! 1326: op0 = convert_to_mode (tmode, op0, 1); ! 1327: ! 1328: /* Unless the msb of the field used to be the msb when we shifted, ! 1329: mask out the upper bits. */ ! 1330: ! 1331: if (GET_MODE_BITSIZE (mode) != bitpos + bitsize ! 1332: #if 0 ! 1333: #ifdef SLOW_ZERO_EXTEND ! 1334: /* Always generate an `and' if ! 1335: we just zero-extended op0 and SLOW_ZERO_EXTEND, since it ! 1336: will combine fruitfully with the zero-extend. */ ! 1337: || tmode != mode ! 1338: #endif ! 1339: #endif ! 1340: ) ! 1341: return expand_binop (GET_MODE (op0), and_optab, op0, ! 1342: mask_rtx (GET_MODE (op0), 0, bitsize, 0), ! 1343: target, 1, OPTAB_LIB_WIDEN); ! 1344: return op0; ! 1345: } ! 1346: ! 1347: /* To extract a signed bit-field, first shift its msb to the msb of the word, ! 1348: then arithmetic-shift its lsb to the lsb of the word. */ ! 1349: op0 = force_reg (mode, op0); ! 1350: if (mode != tmode) ! 1351: target = 0; ! 1352: ! 1353: /* Find the narrowest integer mode that contains the field. */ ! 1354: ! 1355: for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode; ! 1356: mode = GET_MODE_WIDER_MODE (mode)) ! 1357: if (GET_MODE_BITSIZE (mode) >= bitsize + bitpos) ! 1358: { ! 1359: op0 = convert_to_mode (mode, op0, 0); ! 1360: break; ! 1361: } ! 1362: ! 1363: if (GET_MODE_BITSIZE (mode) != (bitsize + bitpos)) ! 1364: { ! 1365: tree amount = build_int_2 (GET_MODE_BITSIZE (mode) - (bitsize + bitpos), 0); ! 1366: /* Maybe propagate the target for the shift. */ ! 1367: /* But not if we will return the result--could confuse integrate.c. */ ! 1368: rtx subtarget = (target != 0 && GET_CODE (target) == REG ! 1369: && ! REG_FUNCTION_VALUE_P (target) ! 1370: ? target : 0); ! 1371: op0 = expand_shift (LSHIFT_EXPR, mode, op0, amount, subtarget, 1); ! 1372: } ! 1373: ! 1374: return expand_shift (RSHIFT_EXPR, mode, op0, ! 1375: build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0), ! 1376: target, 0); ! 1377: } ! 1378: ! 1379: /* Return a constant integer (CONST_INT or CONST_DOUBLE) mask value ! 1380: of mode MODE with BITSIZE ones followed by BITPOS zeros, or the ! 1381: complement of that if COMPLEMENT. The mask is truncated if ! 1382: necessary to the width of mode MODE. */ ! 1383: ! 1384: static rtx ! 1385: mask_rtx (mode, bitpos, bitsize, complement) ! 1386: enum machine_mode mode; ! 1387: int bitpos, bitsize, complement; ! 1388: { ! 1389: HOST_WIDE_INT masklow, maskhigh; ! 1390: ! 1391: if (bitpos < HOST_BITS_PER_WIDE_INT) ! 1392: masklow = (HOST_WIDE_INT) -1 << bitpos; ! 1393: else ! 1394: masklow = 0; ! 1395: ! 1396: if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT) ! 1397: masklow &= ((unsigned HOST_WIDE_INT) -1 ! 1398: >> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize)); ! 1399: ! 1400: if (bitpos <= HOST_BITS_PER_WIDE_INT) ! 1401: maskhigh = -1; ! 1402: else ! 1403: maskhigh = (HOST_WIDE_INT) -1 << (bitpos - HOST_BITS_PER_WIDE_INT); ! 1404: ! 1405: if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT) ! 1406: maskhigh &= ((unsigned HOST_WIDE_INT) -1 ! 1407: >> (2 * HOST_BITS_PER_WIDE_INT - bitpos - bitsize)); ! 1408: else ! 1409: maskhigh = 0; ! 1410: ! 1411: if (complement) ! 1412: { ! 1413: maskhigh = ~maskhigh; ! 1414: masklow = ~masklow; ! 1415: } ! 1416: ! 1417: return immed_double_const (masklow, maskhigh, mode); ! 1418: } ! 1419: ! 1420: /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value ! 1421: VALUE truncated to BITSIZE bits and then shifted left BITPOS bits. */ ! 1422: ! 1423: static rtx ! 1424: lshift_value (mode, value, bitpos, bitsize) ! 1425: enum machine_mode mode; ! 1426: rtx value; ! 1427: int bitpos, bitsize; ! 1428: { ! 1429: unsigned HOST_WIDE_INT v = INTVAL (value); ! 1430: HOST_WIDE_INT low, high; ! 1431: ! 1432: if (bitsize < HOST_BITS_PER_WIDE_INT) ! 1433: v &= ~((HOST_WIDE_INT) -1 << bitsize); ! 1434: ! 1435: if (bitpos < HOST_BITS_PER_WIDE_INT) ! 1436: { ! 1437: low = v << bitpos; ! 1438: high = (bitpos > 0 ? (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) : 0); ! 1439: } ! 1440: else ! 1441: { ! 1442: low = 0; ! 1443: high = v << (bitpos - HOST_BITS_PER_WIDE_INT); ! 1444: } ! 1445: ! 1446: return immed_double_const (low, high, mode); ! 1447: } ! 1448: ! 1449: /* Extract a bit field that is split across two words ! 1450: and return an RTX for the result. ! 1451: ! 1452: OP0 is the REG, SUBREG or MEM rtx for the first of the two words. ! 1453: BITSIZE is the field width; BITPOS, position of its first bit, in the word. ! 1454: UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend. ! 1455: ! 1456: ALIGN is the known alignment of OP0, measured in bytes. ! 1457: This is also the size of the memory objects to be used. */ ! 1458: ! 1459: static rtx ! 1460: extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align) ! 1461: rtx op0; ! 1462: int bitsize, bitpos, unsignedp, align; ! 1463: { ! 1464: /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that ! 1465: much at a time. */ ! 1466: int unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD); ! 1467: int bitsdone = 0; ! 1468: rtx result; ! 1469: int first = 1; ! 1470: ! 1471: while (bitsdone < bitsize) ! 1472: { ! 1473: int thissize; ! 1474: rtx part, word; ! 1475: int thispos; ! 1476: int offset; ! 1477: ! 1478: offset = (bitpos + bitsdone) / unit; ! 1479: thispos = (bitpos + bitsdone) % unit; ! 1480: ! 1481: /* THISSIZE must not overrun a word boundary. Otherwise, ! 1482: extract_fixed_bit_field will call us again, and we will mutually ! 1483: recurse forever. */ ! 1484: thissize = MIN (bitsize - bitsdone, BITS_PER_WORD); ! 1485: thissize = MIN (thissize, unit - thispos); ! 1486: ! 1487: /* If OP0 is a register, then handle OFFSET here. ! 1488: In the register case, UNIT must be a whole word. */ ! 1489: if (GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG) ! 1490: { ! 1491: word = operand_subword_force (op0, offset, GET_MODE (op0)); ! 1492: offset = 0; ! 1493: } ! 1494: else ! 1495: word = op0; ! 1496: ! 1497: if (word == 0) ! 1498: abort (); ! 1499: ! 1500: /* Extract the parts in bit-counting order, ! 1501: whose meaning is determined by BYTES_PER_UNIT. ! 1502: OFFSET is in UNITs, and UNIT is in bits. ! 1503: extract_fixed_bit_field wants offset in bytes. */ ! 1504: part = extract_fixed_bit_field (word_mode, word, ! 1505: offset * unit / BITS_PER_UNIT, ! 1506: thissize, thispos, 0, 1, align); ! 1507: bitsdone += thissize; ! 1508: ! 1509: /* Shift this part into place for the result. */ ! 1510: #if BYTES_BIG_ENDIAN ! 1511: if (bitsize != bitsdone) ! 1512: part = expand_shift (LSHIFT_EXPR, word_mode, part, ! 1513: build_int_2 (bitsize - bitsdone, 0), 0, 1); ! 1514: #else ! 1515: if (bitsdone != thissize) ! 1516: part = expand_shift (LSHIFT_EXPR, word_mode, part, ! 1517: build_int_2 (bitsdone - thissize, 0), 0, 1); ! 1518: #endif ! 1519: ! 1520: if (first) ! 1521: result = part; ! 1522: else ! 1523: /* Combine the parts with bitwise or. This works ! 1524: because we extracted each part as an unsigned bit field. */ ! 1525: result = expand_binop (word_mode, ior_optab, part, result, NULL_RTX, 1, ! 1526: OPTAB_LIB_WIDEN); ! 1527: ! 1528: first = 0; ! 1529: } ! 1530: ! 1531: /* Unsigned bit field: we are done. */ ! 1532: if (unsignedp) ! 1533: return result; ! 1534: /* Signed bit field: sign-extend with two arithmetic shifts. */ ! 1535: result = expand_shift (LSHIFT_EXPR, word_mode, result, ! 1536: build_int_2 (BITS_PER_WORD - bitsize, 0), ! 1537: NULL_RTX, 0); ! 1538: return expand_shift (RSHIFT_EXPR, word_mode, result, ! 1539: build_int_2 (BITS_PER_WORD - bitsize, 0), NULL_RTX, 0); ! 1540: } ! 1541: ! 1542: /* Add INC into TARGET. */ ! 1543: ! 1544: void ! 1545: expand_inc (target, inc) ! 1546: rtx target, inc; ! 1547: { ! 1548: rtx value = expand_binop (GET_MODE (target), add_optab, ! 1549: target, inc, ! 1550: target, 0, OPTAB_LIB_WIDEN); ! 1551: if (value != target) ! 1552: emit_move_insn (target, value); ! 1553: } ! 1554: ! 1555: /* Subtract DEC from TARGET. */ ! 1556: ! 1557: void ! 1558: expand_dec (target, dec) ! 1559: rtx target, dec; ! 1560: { ! 1561: rtx value = expand_binop (GET_MODE (target), sub_optab, ! 1562: target, dec, ! 1563: target, 0, OPTAB_LIB_WIDEN); ! 1564: if (value != target) ! 1565: emit_move_insn (target, value); ! 1566: } ! 1567: ! 1568: /* Output a shift instruction for expression code CODE, ! 1569: with SHIFTED being the rtx for the value to shift, ! 1570: and AMOUNT the tree for the amount to shift by. ! 1571: Store the result in the rtx TARGET, if that is convenient. ! 1572: If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic. ! 1573: Return the rtx for where the value is. */ ! 1574: ! 1575: rtx ! 1576: expand_shift (code, mode, shifted, amount, target, unsignedp) ! 1577: enum tree_code code; ! 1578: register enum machine_mode mode; ! 1579: rtx shifted; ! 1580: tree amount; ! 1581: register rtx target; ! 1582: int unsignedp; ! 1583: { ! 1584: register rtx op1, temp = 0; ! 1585: register int left = (code == LSHIFT_EXPR || code == LROTATE_EXPR); ! 1586: register int rotate = (code == LROTATE_EXPR || code == RROTATE_EXPR); ! 1587: int try; ! 1588: ! 1589: /* Previously detected shift-counts computed by NEGATE_EXPR ! 1590: and shifted in the other direction; but that does not work ! 1591: on all machines. */ ! 1592: ! 1593: op1 = expand_expr (amount, NULL_RTX, VOIDmode, 0); ! 1594: ! 1595: if (op1 == const0_rtx) ! 1596: return shifted; ! 1597: ! 1598: for (try = 0; temp == 0 && try < 3; try++) ! 1599: { ! 1600: enum optab_methods methods; ! 1601: ! 1602: if (try == 0) ! 1603: methods = OPTAB_DIRECT; ! 1604: else if (try == 1) ! 1605: methods = OPTAB_WIDEN; ! 1606: else ! 1607: methods = OPTAB_LIB_WIDEN; ! 1608: ! 1609: if (rotate) ! 1610: { ! 1611: /* Widening does not work for rotation. */ ! 1612: if (methods == OPTAB_WIDEN) ! 1613: continue; ! 1614: else if (methods == OPTAB_LIB_WIDEN) ! 1615: { ! 1616: /* If we are rotating by a constant that is valid and ! 1617: we have been unable to open-code this by a rotation, ! 1618: do it as the IOR of two shifts. I.e., to rotate A ! 1619: by N bits, compute (A << N) | ((unsigned) A >> (C - N)) ! 1620: where C is the bitsize of A. ! 1621: ! 1622: It is theoretically possible that the target machine might ! 1623: not be able to perform either shift and hence we would ! 1624: be making two libcalls rather than just the one for the ! 1625: shift (similarly if IOR could not be done). We will allow ! 1626: this extremely unlikely lossage to avoid complicating the ! 1627: code below. */ ! 1628: ! 1629: if (GET_CODE (op1) == CONST_INT && INTVAL (op1) > 0 ! 1630: && INTVAL (op1) < GET_MODE_BITSIZE (mode)) ! 1631: { ! 1632: rtx subtarget = target == shifted ? 0 : target; ! 1633: rtx temp1; ! 1634: tree other_amount ! 1635: = build_int_2 (GET_MODE_BITSIZE (mode) - INTVAL (op1), 0); ! 1636: ! 1637: shifted = force_reg (mode, shifted); ! 1638: ! 1639: temp = expand_shift (left ? LSHIFT_EXPR : RSHIFT_EXPR, ! 1640: mode, shifted, amount, subtarget, 1); ! 1641: temp1 = expand_shift (left ? RSHIFT_EXPR : LSHIFT_EXPR, ! 1642: mode, shifted, other_amount, 0, 1); ! 1643: return expand_binop (mode, ior_optab, temp, temp1, target, ! 1644: unsignedp, methods); ! 1645: } ! 1646: else ! 1647: methods = OPTAB_LIB; ! 1648: } ! 1649: ! 1650: temp = expand_binop (mode, ! 1651: left ? rotl_optab : rotr_optab, ! 1652: shifted, op1, target, unsignedp, methods); ! 1653: ! 1654: /* If we don't have the rotate, but we are rotating by a constant ! 1655: that is in range, try a rotate in the opposite direction. */ ! 1656: ! 1657: if (temp == 0 && GET_CODE (op1) == CONST_INT ! 1658: && INTVAL (op1) > 0 && INTVAL (op1) < GET_MODE_BITSIZE (mode)) ! 1659: temp = expand_binop (mode, ! 1660: left ? rotr_optab : rotl_optab, ! 1661: shifted, ! 1662: GEN_INT (GET_MODE_BITSIZE (mode) ! 1663: - INTVAL (op1)), ! 1664: target, unsignedp, methods); ! 1665: } ! 1666: else if (unsignedp) ! 1667: { ! 1668: temp = expand_binop (mode, ! 1669: left ? lshl_optab : lshr_optab, ! 1670: shifted, op1, target, unsignedp, methods); ! 1671: if (temp == 0 && left) ! 1672: temp = expand_binop (mode, ashl_optab, ! 1673: shifted, op1, target, unsignedp, methods); ! 1674: } ! 1675: ! 1676: /* Do arithmetic shifts. ! 1677: Also, if we are going to widen the operand, we can just as well ! 1678: use an arithmetic right-shift instead of a logical one. */ ! 1679: if (temp == 0 && ! rotate ! 1680: && (! unsignedp || (! left && methods == OPTAB_WIDEN))) ! 1681: { ! 1682: enum optab_methods methods1 = methods; ! 1683: ! 1684: /* If trying to widen a log shift to an arithmetic shift, ! 1685: don't accept an arithmetic shift of the same size. */ ! 1686: if (unsignedp) ! 1687: methods1 = OPTAB_MUST_WIDEN; ! 1688: ! 1689: /* Arithmetic shift */ ! 1690: ! 1691: temp = expand_binop (mode, ! 1692: left ? ashl_optab : ashr_optab, ! 1693: shifted, op1, target, unsignedp, methods1); ! 1694: } ! 1695: ! 1696: #ifdef HAVE_extzv ! 1697: /* We can do a logical (unsigned) right shift with a bit-field ! 1698: extract insn. But first check if one of the above methods worked. */ ! 1699: if (temp != 0) ! 1700: return temp; ! 1701: ! 1702: if (unsignedp && code == RSHIFT_EXPR && ! BITS_BIG_ENDIAN && HAVE_extzv) ! 1703: { ! 1704: enum machine_mode output_mode ! 1705: = insn_operand_mode[(int) CODE_FOR_extzv][0]; ! 1706: ! 1707: if ((methods == OPTAB_DIRECT && mode == output_mode) ! 1708: || (methods == OPTAB_WIDEN ! 1709: && GET_MODE_SIZE (mode) < GET_MODE_SIZE (output_mode))) ! 1710: { ! 1711: rtx shifted1 = convert_modes (output_mode, mode, ! 1712: protect_from_queue (shifted, 0), ! 1713: 1); ! 1714: enum machine_mode length_mode ! 1715: = insn_operand_mode[(int) CODE_FOR_extzv][2]; ! 1716: enum machine_mode pos_mode ! 1717: = insn_operand_mode[(int) CODE_FOR_extzv][3]; ! 1718: rtx target1 = 0; ! 1719: rtx last = get_last_insn (); ! 1720: rtx width; ! 1721: rtx xop1 = op1; ! 1722: rtx pat; ! 1723: ! 1724: if (target != 0) ! 1725: target1 = protect_from_queue (target, 1); ! 1726: ! 1727: /* We define extract insns as having OUTPUT_MODE in a register ! 1728: and the mode of operand 1 in memory. Since we want ! 1729: OUTPUT_MODE, we will always force the operand into a ! 1730: register. At some point we might want to support MEM ! 1731: directly. */ ! 1732: shifted1 = force_reg (output_mode, shifted1); ! 1733: ! 1734: /* If we don't have or cannot use a suggested target, ! 1735: make a place for the result, in the proper mode. */ ! 1736: if (methods == OPTAB_WIDEN || target1 == 0 ! 1737: || ! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0]) ! 1738: (target1, output_mode))) ! 1739: target1 = gen_reg_rtx (output_mode); ! 1740: ! 1741: xop1 = protect_from_queue (xop1, 0); ! 1742: xop1 = convert_modes (pos_mode, TYPE_MODE (TREE_TYPE (amount)), ! 1743: xop1, TREE_UNSIGNED (TREE_TYPE (amount))); ! 1744: ! 1745: /* If this machine's extzv insists on a register for ! 1746: operand 3 (position), arrange for that. */ ! 1747: if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][3]) ! 1748: (xop1, pos_mode))) ! 1749: xop1 = force_reg (pos_mode, xop1); ! 1750: ! 1751: /* WIDTH gets the width of the bit field to extract: ! 1752: wordsize minus # bits to shift by. */ ! 1753: if (GET_CODE (xop1) == CONST_INT) ! 1754: width = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1)); ! 1755: else ! 1756: { ! 1757: /* Now get the width in the proper mode. */ ! 1758: op1 = protect_from_queue (op1, 0); ! 1759: width = convert_to_mode (length_mode, op1, ! 1760: TREE_UNSIGNED (TREE_TYPE (amount))); ! 1761: ! 1762: width = expand_binop (length_mode, sub_optab, ! 1763: GEN_INT (GET_MODE_BITSIZE (mode)), ! 1764: width, NULL_RTX, 0, OPTAB_LIB_WIDEN); ! 1765: } ! 1766: ! 1767: /* If this machine's extzv insists on a register for ! 1768: operand 2 (length), arrange for that. */ ! 1769: if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][2]) ! 1770: (width, length_mode))) ! 1771: width = force_reg (length_mode, width); ! 1772: ! 1773: /* Now extract with WIDTH, omitting OP1 least sig bits. */ ! 1774: pat = gen_extzv (target1, shifted1, width, xop1); ! 1775: if (pat) ! 1776: { ! 1777: emit_insn (pat); ! 1778: temp = convert_to_mode (mode, target1, 1); ! 1779: } ! 1780: else ! 1781: delete_insns_since (last); ! 1782: } ! 1783: ! 1784: /* Can also do logical shift with signed bit-field extract ! 1785: followed by inserting the bit-field at a different position. ! 1786: That strategy is not yet implemented. */ ! 1787: } ! 1788: #endif /* HAVE_extzv */ ! 1789: } ! 1790: ! 1791: if (temp == 0) ! 1792: abort (); ! 1793: return temp; ! 1794: } ! 1795: ! 1796: enum alg_code { alg_zero, alg_m, alg_shift, ! 1797: alg_add_t_m2, alg_sub_t_m2, ! 1798: alg_add_factor, alg_sub_factor, ! 1799: alg_add_t2_m, alg_sub_t2_m, ! 1800: alg_add, alg_subtract, alg_factor, alg_shiftop }; ! 1801: ! 1802: /* This structure records a sequence of operations. ! 1803: `ops' is the number of operations recorded. ! 1804: `cost' is their total cost. ! 1805: The operations are stored in `op' and the corresponding ! 1806: logarithms of the integer coefficients in `log'. ! 1807: ! 1808: These are the operations: ! 1809: alg_zero total := 0; ! 1810: alg_m total := multiplicand; ! 1811: alg_shift total := total * coeff ! 1812: alg_add_t_m2 total := total + multiplicand * coeff; ! 1813: alg_sub_t_m2 total := total - multiplicand * coeff; ! 1814: alg_add_factor total := total * coeff + total; ! 1815: alg_sub_factor total := total * coeff - total; ! 1816: alg_add_t2_m total := total * coeff + multiplicand; ! 1817: alg_sub_t2_m total := total * coeff - multiplicand; ! 1818: ! 1819: The first operand must be either alg_zero or alg_m. */ ! 1820: ! 1821: struct algorithm ! 1822: { ! 1823: short cost; ! 1824: short ops; ! 1825: /* The size of the OP and LOG fields are not directly related to the ! 1826: word size, but the worst-case algorithms will be if we have few ! 1827: consecutive ones or zeros, i.e., a multiplicand like 10101010101... ! 1828: In that case we will generate shift-by-2, add, shift-by-2, add,..., ! 1829: in total wordsize operations. */ ! 1830: enum alg_code op[MAX_BITS_PER_WORD]; ! 1831: char log[MAX_BITS_PER_WORD]; ! 1832: }; ! 1833: ! 1834: /* Compute and return the best algorithm for multiplying by T. ! 1835: The algorithm must cost less than cost_limit ! 1836: If retval.cost >= COST_LIMIT, no algorithm was found and all ! 1837: other field of the returned struct are undefined. */ ! 1838: ! 1839: static void ! 1840: synth_mult (alg_out, t, cost_limit) ! 1841: struct algorithm *alg_out; ! 1842: unsigned HOST_WIDE_INT t; ! 1843: int cost_limit; ! 1844: { ! 1845: int m; ! 1846: struct algorithm *alg_in, *best_alg; ! 1847: unsigned int cost; ! 1848: unsigned HOST_WIDE_INT q; ! 1849: ! 1850: /* Indicate that no algorithm is yet found. If no algorithm ! 1851: is found, this value will be returned and indicate failure. */ ! 1852: alg_out->cost = cost_limit; ! 1853: ! 1854: if (cost_limit <= 0) ! 1855: return; ! 1856: ! 1857: /* t == 1 can be done in zero cost. */ ! 1858: if (t == 1) ! 1859: { ! 1860: alg_out->ops = 1; ! 1861: alg_out->cost = 0; ! 1862: alg_out->op[0] = alg_m; ! 1863: return; ! 1864: } ! 1865: ! 1866: /* t == 0 sometimes has a cost. If it does and it exceeds our limit, ! 1867: fail now. */ ! 1868: if (t == 0) ! 1869: { ! 1870: if (zero_cost >= cost_limit) ! 1871: return; ! 1872: else ! 1873: { ! 1874: alg_out->ops = 1; ! 1875: alg_out->cost = zero_cost; ! 1876: alg_out->op[0] = alg_zero; ! 1877: return; ! 1878: } ! 1879: } ! 1880: ! 1881: /* We'll be needing a couple extra algorithm structures now. */ ! 1882: ! 1883: alg_in = (struct algorithm *)alloca (sizeof (struct algorithm)); ! 1884: best_alg = (struct algorithm *)alloca (sizeof (struct algorithm)); ! 1885: ! 1886: /* If we have a group of zero bits at the low-order part of T, try ! 1887: multiplying by the remaining bits and then doing a shift. */ ! 1888: ! 1889: if ((t & 1) == 0) ! 1890: { ! 1891: m = floor_log2 (t & -t); /* m = number of low zero bits */ ! 1892: q = t >> m; ! 1893: cost = shift_cost[m]; ! 1894: synth_mult (alg_in, q, cost_limit - cost); ! 1895: ! 1896: cost += alg_in->cost; ! 1897: if (cost < cost_limit) ! 1898: { ! 1899: struct algorithm *x; ! 1900: x = alg_in, alg_in = best_alg, best_alg = x; ! 1901: best_alg->log[best_alg->ops] = m; ! 1902: best_alg->op[best_alg->ops] = alg_shift; ! 1903: cost_limit = cost; ! 1904: } ! 1905: } ! 1906: ! 1907: /* If we have an odd number, add or subtract one. */ ! 1908: if ((t & 1) != 0) ! 1909: { ! 1910: unsigned HOST_WIDE_INT w; ! 1911: ! 1912: for (w = 1; (w & t) != 0; w <<= 1) ! 1913: ; ! 1914: if (w > 2 ! 1915: /* Reject the case where t is 3. ! 1916: Thus we prefer addition in that case. */ ! 1917: && t != 3) ! 1918: { ! 1919: /* T ends with ...111. Multiply by (T + 1) and subtract 1. */ ! 1920: ! 1921: cost = add_cost; ! 1922: synth_mult (alg_in, t + 1, cost_limit - cost); ! 1923: ! 1924: cost += alg_in->cost; ! 1925: if (cost < cost_limit) ! 1926: { ! 1927: struct algorithm *x; ! 1928: x = alg_in, alg_in = best_alg, best_alg = x; ! 1929: best_alg->log[best_alg->ops] = 0; ! 1930: best_alg->op[best_alg->ops] = alg_sub_t_m2; ! 1931: cost_limit = cost; ! 1932: } ! 1933: } ! 1934: else ! 1935: { ! 1936: /* T ends with ...01 or ...011. Multiply by (T - 1) and add 1. */ ! 1937: ! 1938: cost = add_cost; ! 1939: synth_mult (alg_in, t - 1, cost_limit - cost); ! 1940: ! 1941: cost += alg_in->cost; ! 1942: if (cost < cost_limit) ! 1943: { ! 1944: struct algorithm *x; ! 1945: x = alg_in, alg_in = best_alg, best_alg = x; ! 1946: best_alg->log[best_alg->ops] = 0; ! 1947: best_alg->op[best_alg->ops] = alg_add_t_m2; ! 1948: cost_limit = cost; ! 1949: } ! 1950: } ! 1951: } ! 1952: ! 1953: /* Look for factors of t of the form ! 1954: t = q(2**m +- 1), 2 <= m <= floor(log2(t - 1)). ! 1955: If we find such a factor, we can multiply by t using an algorithm that ! 1956: multiplies by q, shift the result by m and add/subtract it to itself. ! 1957: ! 1958: We search for large factors first and loop down, even if large factors ! 1959: are less probable than small; if we find a large factor we will find a ! 1960: good sequence quickly, and therefore be able to prune (by decreasing ! 1961: COST_LIMIT) the search. */ ! 1962: ! 1963: for (m = floor_log2 (t - 1); m >= 2; m--) ! 1964: { ! 1965: unsigned HOST_WIDE_INT d; ! 1966: ! 1967: d = ((unsigned HOST_WIDE_INT) 1 << m) + 1; ! 1968: if (t % d == 0 && t > d) ! 1969: { ! 1970: cost = MIN (shiftadd_cost[m], add_cost + shift_cost[m]); ! 1971: synth_mult (alg_in, t / d, cost_limit - cost); ! 1972: ! 1973: cost += alg_in->cost; ! 1974: if (cost < cost_limit) ! 1975: { ! 1976: struct algorithm *x; ! 1977: x = alg_in, alg_in = best_alg, best_alg = x; ! 1978: best_alg->log[best_alg->ops] = m; ! 1979: best_alg->op[best_alg->ops] = alg_add_factor; ! 1980: cost_limit = cost; ! 1981: } ! 1982: /* Other factors will have been taken care of in the recursion. */ ! 1983: break; ! 1984: } ! 1985: ! 1986: d = ((unsigned HOST_WIDE_INT) 1 << m) - 1; ! 1987: if (t % d == 0 && t > d) ! 1988: { ! 1989: cost = MIN (shiftsub_cost[m], add_cost + shift_cost[m]); ! 1990: synth_mult (alg_in, t / d, cost_limit - cost); ! 1991: ! 1992: cost += alg_in->cost; ! 1993: if (cost < cost_limit) ! 1994: { ! 1995: struct algorithm *x; ! 1996: x = alg_in, alg_in = best_alg, best_alg = x; ! 1997: best_alg->log[best_alg->ops] = m; ! 1998: best_alg->op[best_alg->ops] = alg_sub_factor; ! 1999: cost_limit = cost; ! 2000: } ! 2001: break; ! 2002: } ! 2003: } ! 2004: ! 2005: /* Try shift-and-add (load effective address) instructions, ! 2006: i.e. do a*3, a*5, a*9. */ ! 2007: if ((t & 1) != 0) ! 2008: { ! 2009: q = t - 1; ! 2010: q = q & -q; ! 2011: m = exact_log2 (q); ! 2012: if (m >= 0) ! 2013: { ! 2014: cost = shiftadd_cost[m]; ! 2015: synth_mult (alg_in, (t - 1) >> m, cost_limit - cost); ! 2016: ! 2017: cost += alg_in->cost; ! 2018: if (cost < cost_limit) ! 2019: { ! 2020: struct algorithm *x; ! 2021: x = alg_in, alg_in = best_alg, best_alg = x; ! 2022: best_alg->log[best_alg->ops] = m; ! 2023: best_alg->op[best_alg->ops] = alg_add_t2_m; ! 2024: cost_limit = cost; ! 2025: } ! 2026: } ! 2027: ! 2028: q = t + 1; ! 2029: q = q & -q; ! 2030: m = exact_log2 (q); ! 2031: if (m >= 0) ! 2032: { ! 2033: cost = shiftsub_cost[m]; ! 2034: synth_mult (alg_in, (t + 1) >> m, cost_limit - cost); ! 2035: ! 2036: cost += alg_in->cost; ! 2037: if (cost < cost_limit) ! 2038: { ! 2039: struct algorithm *x; ! 2040: x = alg_in, alg_in = best_alg, best_alg = x; ! 2041: best_alg->log[best_alg->ops] = m; ! 2042: best_alg->op[best_alg->ops] = alg_sub_t2_m; ! 2043: cost_limit = cost; ! 2044: } ! 2045: } ! 2046: } ! 2047: ! 2048: /* If cost_limit has not decreased since we stored it in alg_out->cost, ! 2049: we have not found any algorithm. */ ! 2050: if (cost_limit == alg_out->cost) ! 2051: return; ! 2052: ! 2053: /* If we are getting a too long sequence for `struct algorithm' ! 2054: to record, make this search fail. */ ! 2055: if (best_alg->ops == MAX_BITS_PER_WORD) ! 2056: return; ! 2057: ! 2058: /* Copy the algorithm from temporary space to the space at alg_out. ! 2059: We avoid using structure assignment because the majority of ! 2060: best_alg is normally undefined, and this is a critical function. */ ! 2061: alg_out->ops = best_alg->ops + 1; ! 2062: alg_out->cost = cost_limit; ! 2063: bcopy (best_alg->op, alg_out->op, alg_out->ops * sizeof *alg_out->op); ! 2064: bcopy (best_alg->log, alg_out->log, alg_out->ops * sizeof *alg_out->log); ! 2065: } ! 2066: ! 2067: /* Perform a multiplication and return an rtx for the result. ! 2068: MODE is mode of value; OP0 and OP1 are what to multiply (rtx's); ! 2069: TARGET is a suggestion for where to store the result (an rtx). ! 2070: ! 2071: We check specially for a constant integer as OP1. ! 2072: If you want this check for OP0 as well, then before calling ! 2073: you should swap the two operands if OP0 would be constant. */ ! 2074: ! 2075: rtx ! 2076: expand_mult (mode, op0, op1, target, unsignedp) ! 2077: enum machine_mode mode; ! 2078: register rtx op0, op1, target; ! 2079: int unsignedp; ! 2080: { ! 2081: rtx const_op1 = op1; ! 2082: ! 2083: /* If we are multiplying in DImode, it may still be a win ! 2084: to try to work with shifts and adds. */ ! 2085: if (GET_CODE (op1) == CONST_DOUBLE ! 2086: && GET_MODE_CLASS (GET_MODE (op1)) == MODE_INT ! 2087: && HOST_BITS_PER_INT <= BITS_PER_WORD) ! 2088: { ! 2089: if ((CONST_DOUBLE_HIGH (op1) == 0 && CONST_DOUBLE_LOW (op1) >= 0) ! 2090: || (CONST_DOUBLE_HIGH (op1) == -1 && CONST_DOUBLE_LOW (op1) < 0)) ! 2091: const_op1 = GEN_INT (CONST_DOUBLE_LOW (op1)); ! 2092: } ! 2093: ! 2094: /* We used to test optimize here, on the grounds that it's better to ! 2095: produce a smaller program when -O is not used. ! 2096: But this causes such a terrible slowdown sometimes ! 2097: that it seems better to use synth_mult always. */ ! 2098: ! 2099: if (GET_CODE (const_op1) == CONST_INT) ! 2100: { ! 2101: struct algorithm alg; ! 2102: struct algorithm neg_alg; ! 2103: int negate = 0; ! 2104: HOST_WIDE_INT val = INTVAL (op1); ! 2105: HOST_WIDE_INT val_so_far; ! 2106: rtx insn; ! 2107: int mult_cost; ! 2108: ! 2109: /* Try to do the computation two ways: multiply by the negative of OP1 ! 2110: and then negate, or do the multiplication directly. The latter is ! 2111: usually faster for positive numbers and the former for negative ! 2112: numbers, but the opposite can be faster if the original value ! 2113: has a factor of 2**m +/- 1, while the negated value does not or ! 2114: vice versa. */ ! 2115: ! 2116: mult_cost = rtx_cost (gen_rtx (MULT, mode, op0, op1), SET); ! 2117: mult_cost = MIN (12 * add_cost, mult_cost); ! 2118: ! 2119: synth_mult (&alg, val, mult_cost); ! 2120: synth_mult (&neg_alg, - val, ! 2121: (alg.cost < mult_cost ? alg.cost : mult_cost) - negate_cost); ! 2122: ! 2123: if (neg_alg.cost + negate_cost < alg.cost) ! 2124: alg = neg_alg, negate = 1; ! 2125: ! 2126: if (alg.cost < mult_cost) ! 2127: { ! 2128: /* We found something cheaper than a multiply insn. */ ! 2129: int opno; ! 2130: rtx accum, tem; ! 2131: ! 2132: op0 = protect_from_queue (op0, 0); ! 2133: ! 2134: /* Avoid referencing memory over and over. ! 2135: For speed, but also for correctness when mem is volatile. */ ! 2136: if (GET_CODE (op0) == MEM) ! 2137: op0 = force_reg (mode, op0); ! 2138: ! 2139: /* ACCUM starts out either as OP0 or as a zero, depending on ! 2140: the first operation. */ ! 2141: ! 2142: if (alg.op[0] == alg_zero) ! 2143: { ! 2144: accum = copy_to_mode_reg (mode, const0_rtx); ! 2145: val_so_far = 0; ! 2146: } ! 2147: else if (alg.op[0] == alg_m) ! 2148: { ! 2149: accum = copy_to_mode_reg (mode, op0); ! 2150: val_so_far = 1; ! 2151: } ! 2152: else ! 2153: abort (); ! 2154: ! 2155: for (opno = 1; opno < alg.ops; opno++) ! 2156: { ! 2157: int log = alg.log[opno]; ! 2158: int preserve = preserve_subexpressions_p (); ! 2159: rtx shift_subtarget = preserve ? 0 : accum; ! 2160: rtx add_target = opno == alg.ops - 1 && target != 0 ? target : 0; ! 2161: rtx accum_target = preserve ? 0 : accum; ! 2162: ! 2163: switch (alg.op[opno]) ! 2164: { ! 2165: case alg_shift: ! 2166: accum = expand_shift (LSHIFT_EXPR, mode, accum, ! 2167: build_int_2 (log, 0), NULL_RTX, 0); ! 2168: val_so_far <<= log; ! 2169: break; ! 2170: ! 2171: case alg_add_t_m2: ! 2172: tem = expand_shift (LSHIFT_EXPR, mode, op0, ! 2173: build_int_2 (log, 0), NULL_RTX, 0); ! 2174: accum = force_operand (gen_rtx (PLUS, mode, accum, tem), ! 2175: add_target ? add_target : accum_target); ! 2176: val_so_far += (HOST_WIDE_INT) 1 << log; ! 2177: break; ! 2178: ! 2179: case alg_sub_t_m2: ! 2180: tem = expand_shift (LSHIFT_EXPR, mode, op0, ! 2181: build_int_2 (log, 0), NULL_RTX, 0); ! 2182: accum = force_operand (gen_rtx (MINUS, mode, accum, tem), ! 2183: add_target ? add_target : accum_target); ! 2184: val_so_far -= (HOST_WIDE_INT) 1 << log; ! 2185: break; ! 2186: ! 2187: case alg_add_t2_m: ! 2188: accum = expand_shift (LSHIFT_EXPR, mode, accum, ! 2189: build_int_2 (log, 0), shift_subtarget, ! 2190: 0); ! 2191: accum = force_operand (gen_rtx (PLUS, mode, accum, op0), ! 2192: add_target ? add_target : accum_target); ! 2193: val_so_far = (val_so_far << log) + 1; ! 2194: break; ! 2195: ! 2196: case alg_sub_t2_m: ! 2197: accum = expand_shift (LSHIFT_EXPR, mode, accum, ! 2198: build_int_2 (log, 0), shift_subtarget, ! 2199: 0); ! 2200: accum = force_operand (gen_rtx (MINUS, mode, accum, op0), ! 2201: add_target ? add_target : accum_target); ! 2202: val_so_far = (val_so_far << log) - 1; ! 2203: break; ! 2204: ! 2205: case alg_add_factor: ! 2206: tem = expand_shift (LSHIFT_EXPR, mode, accum, ! 2207: build_int_2 (log, 0), NULL_RTX, 0); ! 2208: accum = force_operand (gen_rtx (PLUS, mode, accum, tem), ! 2209: add_target ? add_target : accum_target); ! 2210: val_so_far += val_so_far << log; ! 2211: break; ! 2212: ! 2213: case alg_sub_factor: ! 2214: tem = expand_shift (LSHIFT_EXPR, mode, accum, ! 2215: build_int_2 (log, 0), NULL_RTX, 0); ! 2216: accum = force_operand (gen_rtx (MINUS, mode, tem, accum), ! 2217: (add_target ? add_target ! 2218: : preserve ? 0 : tem)); ! 2219: val_so_far = (val_so_far << log) - val_so_far; ! 2220: break; ! 2221: ! 2222: default: ! 2223: abort ();; ! 2224: } ! 2225: ! 2226: /* Write a REG_EQUAL note on the last insn so that we can cse ! 2227: multiplication sequences. */ ! 2228: ! 2229: insn = get_last_insn (); ! 2230: REG_NOTES (insn) ! 2231: = gen_rtx (EXPR_LIST, REG_EQUAL, ! 2232: gen_rtx (MULT, mode, op0, GEN_INT (val_so_far)), ! 2233: REG_NOTES (insn)); ! 2234: } ! 2235: ! 2236: if (negate) ! 2237: { ! 2238: val_so_far = - val_so_far; ! 2239: accum = expand_unop (mode, neg_optab, accum, target, 0); ! 2240: } ! 2241: ! 2242: if (val != val_so_far) ! 2243: abort (); ! 2244: ! 2245: return accum; ! 2246: } ! 2247: } ! 2248: ! 2249: /* This used to use umul_optab if unsigned, but for non-widening multiply ! 2250: there is no difference between signed and unsigned. */ ! 2251: op0 = expand_binop (mode, smul_optab, ! 2252: op0, op1, target, unsignedp, OPTAB_LIB_WIDEN); ! 2253: if (op0 == 0) ! 2254: abort (); ! 2255: return op0; ! 2256: } ! 2257: ! 2258: /* Emit the code to divide OP0 by OP1, putting the result in TARGET ! 2259: if that is convenient, and returning where the result is. ! 2260: You may request either the quotient or the remainder as the result; ! 2261: specify REM_FLAG nonzero to get the remainder. ! 2262: ! 2263: CODE is the expression code for which kind of division this is; ! 2264: it controls how rounding is done. MODE is the machine mode to use. ! 2265: UNSIGNEDP nonzero means do unsigned division. */ ! 2266: ! 2267: /* ??? For CEIL_MOD_EXPR, can compute incorrect remainder with ANDI ! 2268: and then correct it by or'ing in missing high bits ! 2269: if result of ANDI is nonzero. ! 2270: For ROUND_MOD_EXPR, can use ANDI and then sign-extend the result. ! 2271: This could optimize to a bfexts instruction. ! 2272: But C doesn't use these operations, so their optimizations are ! 2273: left for later. */ ! 2274: ! 2275: rtx ! 2276: expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) ! 2277: int rem_flag; ! 2278: enum tree_code code; ! 2279: enum machine_mode mode; ! 2280: register rtx op0, op1, target; ! 2281: int unsignedp; ! 2282: { ! 2283: register rtx result = 0; ! 2284: enum machine_mode compute_mode; ! 2285: int log = -1; ! 2286: int size; ! 2287: int can_clobber_op0; ! 2288: int mod_insn_no_good = 0; ! 2289: rtx adjusted_op0 = op0; ! 2290: optab optab1, optab2; ! 2291: ! 2292: /* We shouldn't be called with op1 == const1_rtx, but some of the ! 2293: code below will malfunction if we are, so check here and handle ! 2294: the special case if so. */ ! 2295: if (op1 == const1_rtx) ! 2296: return rem_flag ? const0_rtx : op0; ! 2297: ! 2298: if (target ! 2299: /* Don't use the function value register as a target ! 2300: since we have to read it as well as write it, ! 2301: and function-inlining gets confused by this. */ ! 2302: && ((REG_P (target) && REG_FUNCTION_VALUE_P (target)) ! 2303: /* Don't clobber an operand while doing a multi-step calculation. */ ! 2304: || (rem_flag ! 2305: && (reg_mentioned_p (target, op0) ! 2306: || (GET_CODE (op0) == MEM && GET_CODE (target) == MEM))) ! 2307: || reg_mentioned_p (target, op1) ! 2308: || (GET_CODE (op1) == MEM && GET_CODE (target) == MEM))) ! 2309: target = 0; ! 2310: ! 2311: /* See if we are dividing by 2**log, and hence will do it by shifting, ! 2312: which is really floor-division, or if we will really do a divide, ! 2313: and we assume that is trunc-division. ! 2314: ! 2315: We must correct the dividend by adding or subtracting something ! 2316: based on the divisor, in order to do the kind of rounding specified ! 2317: by CODE. The correction depends on what kind of rounding is actually ! 2318: available, and that depends on whether we will shift or divide. ! 2319: ! 2320: In many of these cases it is possible to perform the operation by a ! 2321: clever series of logical operations (shifts and/or exclusive-ors). ! 2322: Although avoiding the jump has the advantage that it extends the basic ! 2323: block and allows further optimization, the branch-free code is normally ! 2324: at least one instruction longer in the (most common) case where the ! 2325: dividend is non-negative. Performance measurements of the two ! 2326: alternatives show that the branch-free code is slightly faster on the ! 2327: IBM ROMP but slower on CISC processors (significantly slower on the ! 2328: VAX). Accordingly, the jump code has been retained when BRANCH_COST ! 2329: is small. ! 2330: ! 2331: On machines where the jump code is slower, the cost of a DIV or MOD ! 2332: operation can be set small (less than twice that of an addition); in ! 2333: that case, we pretend that we don't have a power of two and perform ! 2334: a normal division or modulus operation. */ ! 2335: ! 2336: if (GET_CODE (op1) == CONST_INT ! 2337: && ! ((code == TRUNC_MOD_EXPR || code == TRUNC_DIV_EXPR) ! 2338: && ! unsignedp ! 2339: && (rem_flag ? smod_pow2_cheap : sdiv_pow2_cheap))) ! 2340: log = exact_log2 (INTVAL (op1)); ! 2341: ! 2342: /* Get the mode in which to perform this computation. Normally it will ! 2343: be MODE, but sometimes we can't do the desired operation in MODE. ! 2344: If so, pick a wider mode in which we can do the operation. Convert ! 2345: to that mode at the start to avoid repeated conversions. ! 2346: ! 2347: First see what operations we need. These depend on the expression ! 2348: we are evaluating. (We assume that divxx3 insns exist under the ! 2349: same conditions that modxx3 insns and that these insns don't normally ! 2350: fail. If these assumptions are not correct, we may generate less ! 2351: efficient code in some cases.) ! 2352: ! 2353: Then see if we find a mode in which we can open-code that operation ! 2354: (either a division, modulus, or shift). Finally, check for the smallest ! 2355: mode for which we can do the operation with a library call. */ ! 2356: ! 2357: optab1 = (log >= 0 ? (unsignedp ? lshr_optab : ashr_optab) ! 2358: : (unsignedp ? udiv_optab : sdiv_optab)); ! 2359: optab2 = (log >= 0 ? optab1 : (unsignedp ? udivmod_optab : sdivmod_optab)); ! 2360: ! 2361: for (compute_mode = mode; compute_mode != VOIDmode; ! 2362: compute_mode = GET_MODE_WIDER_MODE (compute_mode)) ! 2363: if (optab1->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing ! 2364: || optab2->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing) ! 2365: break; ! 2366: ! 2367: if (compute_mode == VOIDmode) ! 2368: for (compute_mode = mode; compute_mode != VOIDmode; ! 2369: compute_mode = GET_MODE_WIDER_MODE (compute_mode)) ! 2370: if (optab1->handlers[(int) compute_mode].libfunc ! 2371: || optab2->handlers[(int) compute_mode].libfunc) ! 2372: break; ! 2373: ! 2374: /* If we still couldn't find a mode, use MODE, but we'll probably abort ! 2375: in expand_binop. */ ! 2376: if (compute_mode == VOIDmode) ! 2377: compute_mode = mode; ! 2378: ! 2379: size = GET_MODE_BITSIZE (compute_mode); ! 2380: ! 2381: /* If OP0 is a register that is used as the target, we can modify ! 2382: it in place; otherwise, we have to ensure we copy OP0 before ! 2383: modifying it. */ ! 2384: can_clobber_op0 = (GET_CODE (op0) == REG && op0 == target); ! 2385: ! 2386: /* Now convert to the best mode to use. Show we made a copy of OP0 ! 2387: and hence we can clobber it (we cannot use a SUBREG to widen ! 2388: something. */ ! 2389: if (compute_mode != mode) ! 2390: { ! 2391: adjusted_op0 = op0 = convert_modes (compute_mode, mode, op0, unsignedp); ! 2392: can_clobber_op0 = 1; ! 2393: op1 = convert_modes (compute_mode, mode, op1, unsignedp); ! 2394: } ! 2395: ! 2396: /* If we are computing the remainder and one of the operands is a volatile ! 2397: MEM, copy it into a register. */ ! 2398: ! 2399: if (rem_flag && GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0)) ! 2400: adjusted_op0 = op0 = force_reg (compute_mode, op0), can_clobber_op0 = 1; ! 2401: if (rem_flag && GET_CODE (op1) == MEM && MEM_VOLATILE_P (op1)) ! 2402: op1 = force_reg (compute_mode, op1); ! 2403: ! 2404: /* If we are computing the remainder, op0 will be needed later to calculate ! 2405: X - Y * (X / Y), therefore cannot be clobbered. */ ! 2406: if (rem_flag) ! 2407: can_clobber_op0 = 0; ! 2408: ! 2409: /* See if we will need to modify ADJUSTED_OP0. Note that this code ! 2410: must agree with that in the switch below. */ ! 2411: if (((code == TRUNC_MOD_EXPR || code == TRUNC_DIV_EXPR) ! 2412: && log >= 0 && ! unsignedp) ! 2413: || ((code == FLOOR_MOD_EXPR || code == FLOOR_DIV_EXPR) ! 2414: && log < 0 && ! unsignedp) ! 2415: || code == CEIL_MOD_EXPR || code == CEIL_DIV_EXPR ! 2416: || code == ROUND_MOD_EXPR || code == ROUND_DIV_EXPR) ! 2417: { ! 2418: /* If we want the remainder, we may need to use OP0, so make sure ! 2419: it and ADJUSTED_OP0 are in different registers. We force OP0 ! 2420: to a register in case it has any queued subexpressions, because ! 2421: emit_cmp_insn will call emit_queue. ! 2422: ! 2423: If we don't want the remainder, we aren't going to use OP0 anymore. ! 2424: However, if we cannot clobber OP0 (and hence ADJUSTED_OP0), we must ! 2425: make a copy of it, hopefully to TARGET. ! 2426: ! 2427: This code is somewhat tricky. Note that if REM_FLAG is nonzero, ! 2428: CAN_CLOBBER_OP0 will be zero and we know that OP0 cannot ! 2429: equal TARGET. */ ! 2430: ! 2431: if (rem_flag) ! 2432: op0 = force_reg (compute_mode, op0); ! 2433: ! 2434: if (! can_clobber_op0) ! 2435: { ! 2436: if (target && GET_MODE (target) == compute_mode) ! 2437: adjusted_op0 = target; ! 2438: else ! 2439: adjusted_op0 = 0; ! 2440: adjusted_op0 = copy_to_suggested_reg (op0, adjusted_op0, ! 2441: compute_mode); ! 2442: } ! 2443: } ! 2444: ! 2445: /* Adjust ADJUSTED_OP0 as described above. Unless CAN_CLOBBER_OP0 ! 2446: is now non-zero, OP0 will retain it's original value. */ ! 2447: ! 2448: switch (code) ! 2449: { ! 2450: case TRUNC_MOD_EXPR: ! 2451: case TRUNC_DIV_EXPR: ! 2452: if (log >= 0 && ! unsignedp) ! 2453: { ! 2454: /* Here we need to add OP1-1 if OP0 is negative, 0 otherwise. ! 2455: This can be computed without jumps by arithmetically shifting ! 2456: OP0 right LOG-1 places and then shifting right logically ! 2457: SIZE-LOG bits. The resulting value is unconditionally added ! 2458: to OP0. ! 2459: ! 2460: If OP0 cannot be modified in place, copy it, possibly to ! 2461: TARGET. Note that we will have previously only allowed ! 2462: it to be modified in place if it is a register, so that ! 2463: after this `if', ADJUSTED_OP0 is known to be a ! 2464: register. */ ! 2465: if (log == 1 || BRANCH_COST >= 3) ! 2466: { ! 2467: rtx temp; ! 2468: ! 2469: temp = expand_shift (RSHIFT_EXPR, compute_mode, adjusted_op0, ! 2470: build_int_2 (log - 1, 0), NULL_RTX, 0); ! 2471: ! 2472: /* We cannot allow TEMP to be ADJUSTED_OP0 here. */ ! 2473: temp = expand_shift (RSHIFT_EXPR, compute_mode, temp, ! 2474: build_int_2 (size - log, 0), ! 2475: temp != adjusted_op0 ? temp : NULL_RTX, 1); ! 2476: ! 2477: adjusted_op0 = expand_binop (compute_mode, add_optab, ! 2478: adjusted_op0, temp, adjusted_op0, ! 2479: 0, OPTAB_LIB_WIDEN); ! 2480: } ! 2481: else ! 2482: { ! 2483: rtx label = gen_label_rtx (); ! 2484: ! 2485: emit_cmp_insn (adjusted_op0, const0_rtx, GE, ! 2486: NULL_RTX, compute_mode, 0, 0); ! 2487: emit_jump_insn (gen_bge (label)); ! 2488: expand_inc (adjusted_op0, plus_constant (op1, -1)); ! 2489: emit_label (label); ! 2490: } ! 2491: mod_insn_no_good = 1; ! 2492: } ! 2493: break; ! 2494: ! 2495: case FLOOR_DIV_EXPR: ! 2496: case FLOOR_MOD_EXPR: ! 2497: if (log < 0 && ! unsignedp) ! 2498: { ! 2499: rtx label = gen_label_rtx (); ! 2500: ! 2501: emit_cmp_insn (adjusted_op0, const0_rtx, GE, ! 2502: NULL_RTX, compute_mode, 0, 0); ! 2503: emit_jump_insn (gen_bge (label)); ! 2504: expand_dec (adjusted_op0, op1); ! 2505: expand_inc (adjusted_op0, const1_rtx); ! 2506: emit_label (label); ! 2507: mod_insn_no_good = 1; ! 2508: } ! 2509: break; ! 2510: ! 2511: case CEIL_DIV_EXPR: ! 2512: case CEIL_MOD_EXPR: ! 2513: if (log < 0) ! 2514: { ! 2515: rtx label = 0; ! 2516: if (! unsignedp) ! 2517: { ! 2518: label = gen_label_rtx (); ! 2519: emit_cmp_insn (adjusted_op0, const0_rtx, LE, ! 2520: NULL_RTX, compute_mode, 0, 0); ! 2521: emit_jump_insn (gen_ble (label)); ! 2522: } ! 2523: expand_inc (adjusted_op0, op1); ! 2524: expand_dec (adjusted_op0, const1_rtx); ! 2525: if (! unsignedp) ! 2526: emit_label (label); ! 2527: } ! 2528: else ! 2529: adjusted_op0 = expand_binop (compute_mode, add_optab, ! 2530: adjusted_op0, plus_constant (op1, -1), ! 2531: adjusted_op0, 0, OPTAB_LIB_WIDEN); ! 2532: ! 2533: mod_insn_no_good = 1; ! 2534: break; ! 2535: ! 2536: case ROUND_DIV_EXPR: ! 2537: case ROUND_MOD_EXPR: ! 2538: if (log < 0) ! 2539: { ! 2540: op1 = expand_shift (RSHIFT_EXPR, compute_mode, op1, ! 2541: integer_one_node, NULL_RTX, 0); ! 2542: if (! unsignedp) ! 2543: { ! 2544: if (BRANCH_COST >= 2) ! 2545: { ! 2546: /* Negate OP1 if OP0 < 0. Do this by computing a temporary ! 2547: that has all bits equal to the sign bit and exclusive ! 2548: or-ing it with OP1. */ ! 2549: rtx temp = expand_shift (RSHIFT_EXPR, compute_mode, ! 2550: adjusted_op0, ! 2551: build_int_2 (size - 1, 0), ! 2552: NULL_RTX, 0); ! 2553: op1 = expand_binop (compute_mode, xor_optab, op1, temp, op1, ! 2554: unsignedp, OPTAB_LIB_WIDEN); ! 2555: } ! 2556: else ! 2557: { ! 2558: rtx label = gen_label_rtx (); ! 2559: emit_cmp_insn (adjusted_op0, const0_rtx, GE, NULL_RTX, ! 2560: compute_mode, 0, 0); ! 2561: emit_jump_insn (gen_bge (label)); ! 2562: expand_unop (compute_mode, neg_optab, op1, op1, 0); ! 2563: emit_label (label); ! 2564: } ! 2565: } ! 2566: expand_inc (adjusted_op0, op1); ! 2567: } ! 2568: else ! 2569: expand_inc (adjusted_op0, GEN_INT (((HOST_WIDE_INT) 1 << log) / 2)); ! 2570: ! 2571: mod_insn_no_good = 1; ! 2572: break; ! 2573: } ! 2574: ! 2575: if (rem_flag && !mod_insn_no_good) ! 2576: { ! 2577: /* Try to produce the remainder directly */ ! 2578: if (log >= 0) ! 2579: result = expand_binop (compute_mode, and_optab, adjusted_op0, ! 2580: GEN_INT (((HOST_WIDE_INT) 1 << log) - 1), ! 2581: target, 1, OPTAB_LIB_WIDEN); ! 2582: else ! 2583: { ! 2584: /* See if we can do remainder without a library call. */ ! 2585: result = sign_expand_binop (mode, umod_optab, smod_optab, ! 2586: adjusted_op0, op1, target, ! 2587: unsignedp, OPTAB_WIDEN); ! 2588: if (result == 0) ! 2589: { ! 2590: /* No luck there. Can we do remainder and divide at once ! 2591: without a library call? */ ! 2592: result = gen_reg_rtx (compute_mode); ! 2593: if (! expand_twoval_binop (unsignedp ! 2594: ? udivmod_optab : sdivmod_optab, ! 2595: adjusted_op0, op1, ! 2596: NULL_RTX, result, unsignedp)) ! 2597: result = 0; ! 2598: } ! 2599: } ! 2600: } ! 2601: ! 2602: if (result) ! 2603: return gen_lowpart (mode, result); ! 2604: ! 2605: /* Produce the quotient. */ ! 2606: if (log >= 0) ! 2607: result = expand_shift (RSHIFT_EXPR, compute_mode, adjusted_op0, ! 2608: build_int_2 (log, 0), target, unsignedp); ! 2609: else if (rem_flag && !mod_insn_no_good) ! 2610: /* If producing quotient in order to subtract for remainder, ! 2611: and a remainder subroutine would be ok, ! 2612: don't use a divide subroutine. */ ! 2613: result = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab, ! 2614: adjusted_op0, op1, NULL_RTX, unsignedp, ! 2615: OPTAB_WIDEN); ! 2616: else ! 2617: { ! 2618: /* Try a quotient insn, but not a library call. */ ! 2619: result = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab, ! 2620: adjusted_op0, op1, ! 2621: rem_flag ? NULL_RTX : target, ! 2622: unsignedp, OPTAB_WIDEN); ! 2623: if (result == 0) ! 2624: { ! 2625: /* No luck there. Try a quotient-and-remainder insn, ! 2626: keeping the quotient alone. */ ! 2627: result = gen_reg_rtx (compute_mode); ! 2628: if (! expand_twoval_binop (unsignedp ? udivmod_optab : sdivmod_optab, ! 2629: adjusted_op0, op1, ! 2630: result, NULL_RTX, unsignedp)) ! 2631: result = 0; ! 2632: } ! 2633: ! 2634: /* If still no luck, use a library call. */ ! 2635: if (result == 0) ! 2636: result = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab, ! 2637: adjusted_op0, op1, ! 2638: rem_flag ? NULL_RTX : target, ! 2639: unsignedp, OPTAB_LIB_WIDEN); ! 2640: } ! 2641: ! 2642: /* If we really want the remainder, get it by subtraction. */ ! 2643: if (rem_flag) ! 2644: { ! 2645: if (result == 0) ! 2646: /* No divide instruction either. Use library for remainder. */ ! 2647: result = sign_expand_binop (compute_mode, umod_optab, smod_optab, ! 2648: op0, op1, target, ! 2649: unsignedp, OPTAB_LIB_WIDEN); ! 2650: else ! 2651: { ! 2652: /* We divided. Now finish doing X - Y * (X / Y). */ ! 2653: result = expand_mult (compute_mode, result, op1, target, unsignedp); ! 2654: if (! result) abort (); ! 2655: result = expand_binop (compute_mode, sub_optab, op0, ! 2656: result, target, unsignedp, OPTAB_LIB_WIDEN); ! 2657: } ! 2658: } ! 2659: ! 2660: if (result == 0) ! 2661: abort (); ! 2662: ! 2663: return gen_lowpart (mode, result); ! 2664: } ! 2665: ! 2666: /* Return a tree node with data type TYPE, describing the value of X. ! 2667: Usually this is an RTL_EXPR, if there is no obvious better choice. ! 2668: X may be an expression, however we only support those expressions ! 2669: generated by loop.c. */ ! 2670: ! 2671: tree ! 2672: make_tree (type, x) ! 2673: tree type; ! 2674: rtx x; ! 2675: { ! 2676: tree t; ! 2677: ! 2678: switch (GET_CODE (x)) ! 2679: { ! 2680: case CONST_INT: ! 2681: t = build_int_2 (INTVAL (x), ! 2682: TREE_UNSIGNED (type) || INTVAL (x) >= 0 ? 0 : -1); ! 2683: TREE_TYPE (t) = type; ! 2684: return t; ! 2685: ! 2686: case CONST_DOUBLE: ! 2687: if (GET_MODE (x) == VOIDmode) ! 2688: { ! 2689: t = build_int_2 (CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x)); ! 2690: TREE_TYPE (t) = type; ! 2691: } ! 2692: else ! 2693: { ! 2694: REAL_VALUE_TYPE d; ! 2695: ! 2696: REAL_VALUE_FROM_CONST_DOUBLE (d, x); ! 2697: t = build_real (type, d); ! 2698: } ! 2699: ! 2700: return t; ! 2701: ! 2702: case PLUS: ! 2703: return fold (build (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)), ! 2704: make_tree (type, XEXP (x, 1)))); ! 2705: ! 2706: case MINUS: ! 2707: return fold (build (MINUS_EXPR, type, make_tree (type, XEXP (x, 0)), ! 2708: make_tree (type, XEXP (x, 1)))); ! 2709: ! 2710: case NEG: ! 2711: return fold (build1 (NEGATE_EXPR, type, make_tree (type, XEXP (x, 0)))); ! 2712: ! 2713: case MULT: ! 2714: return fold (build (MULT_EXPR, type, make_tree (type, XEXP (x, 0)), ! 2715: make_tree (type, XEXP (x, 1)))); ! 2716: ! 2717: case ASHIFT: ! 2718: return fold (build (LSHIFT_EXPR, type, make_tree (type, XEXP (x, 0)), ! 2719: make_tree (type, XEXP (x, 1)))); ! 2720: ! 2721: case LSHIFTRT: ! 2722: return fold (convert (type, ! 2723: build (RSHIFT_EXPR, unsigned_type (type), ! 2724: make_tree (unsigned_type (type), ! 2725: XEXP (x, 0)), ! 2726: make_tree (type, XEXP (x, 1))))); ! 2727: ! 2728: case ASHIFTRT: ! 2729: return fold (convert (type, ! 2730: build (RSHIFT_EXPR, signed_type (type), ! 2731: make_tree (signed_type (type), XEXP (x, 0)), ! 2732: make_tree (type, XEXP (x, 1))))); ! 2733: ! 2734: case DIV: ! 2735: if (TREE_CODE (type) != REAL_TYPE) ! 2736: t = signed_type (type); ! 2737: else ! 2738: t = type; ! 2739: ! 2740: return fold (convert (type, ! 2741: build (TRUNC_DIV_EXPR, t, ! 2742: make_tree (t, XEXP (x, 0)), ! 2743: make_tree (t, XEXP (x, 1))))); ! 2744: case UDIV: ! 2745: t = unsigned_type (type); ! 2746: return fold (convert (type, ! 2747: build (TRUNC_DIV_EXPR, t, ! 2748: make_tree (t, XEXP (x, 0)), ! 2749: make_tree (t, XEXP (x, 1))))); ! 2750: default: ! 2751: t = make_node (RTL_EXPR); ! 2752: TREE_TYPE (t) = type; ! 2753: RTL_EXPR_RTL (t) = x; ! 2754: /* There are no insns to be output ! 2755: when this rtl_expr is used. */ ! 2756: RTL_EXPR_SEQUENCE (t) = 0; ! 2757: return t; ! 2758: } ! 2759: } ! 2760: ! 2761: /* Return an rtx representing the value of X * MULT + ADD. ! 2762: TARGET is a suggestion for where to store the result (an rtx). ! 2763: MODE is the machine mode for the computation. ! 2764: X and MULT must have mode MODE. ADD may have a different mode. ! 2765: So can X (defaults to same as MODE). ! 2766: UNSIGNEDP is non-zero to do unsigned multiplication. ! 2767: This may emit insns. */ ! 2768: ! 2769: rtx ! 2770: expand_mult_add (x, target, mult, add, mode, unsignedp) ! 2771: rtx x, target, mult, add; ! 2772: enum machine_mode mode; ! 2773: int unsignedp; ! 2774: { ! 2775: tree type = type_for_mode (mode, unsignedp); ! 2776: tree add_type = (GET_MODE (add) == VOIDmode ! 2777: ? type : type_for_mode (GET_MODE (add), unsignedp)); ! 2778: tree result = fold (build (PLUS_EXPR, type, ! 2779: fold (build (MULT_EXPR, type, ! 2780: make_tree (type, x), ! 2781: make_tree (type, mult))), ! 2782: make_tree (add_type, add))); ! 2783: ! 2784: return expand_expr (result, target, VOIDmode, 0); ! 2785: } ! 2786: ! 2787: /* Compute the logical-and of OP0 and OP1, storing it in TARGET ! 2788: and returning TARGET. ! 2789: ! 2790: If TARGET is 0, a pseudo-register or constant is returned. */ ! 2791: ! 2792: rtx ! 2793: expand_and (op0, op1, target) ! 2794: rtx op0, op1, target; ! 2795: { ! 2796: enum machine_mode mode = VOIDmode; ! 2797: rtx tem; ! 2798: ! 2799: if (GET_MODE (op0) != VOIDmode) ! 2800: mode = GET_MODE (op0); ! 2801: else if (GET_MODE (op1) != VOIDmode) ! 2802: mode = GET_MODE (op1); ! 2803: ! 2804: if (mode != VOIDmode) ! 2805: tem = expand_binop (mode, and_optab, op0, op1, target, 0, OPTAB_LIB_WIDEN); ! 2806: else if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT) ! 2807: tem = GEN_INT (INTVAL (op0) & INTVAL (op1)); ! 2808: else ! 2809: abort (); ! 2810: ! 2811: if (target == 0) ! 2812: target = tem; ! 2813: else if (tem != target) ! 2814: emit_move_insn (target, tem); ! 2815: return target; ! 2816: } ! 2817: ! 2818: /* Emit a store-flags instruction for comparison CODE on OP0 and OP1 ! 2819: and storing in TARGET. Normally return TARGET. ! 2820: Return 0 if that cannot be done. ! 2821: ! 2822: MODE is the mode to use for OP0 and OP1 should they be CONST_INTs. If ! 2823: it is VOIDmode, they cannot both be CONST_INT. ! 2824: ! 2825: UNSIGNEDP is for the case where we have to widen the operands ! 2826: to perform the operation. It says to use zero-extension. ! 2827: ! 2828: NORMALIZEP is 1 if we should convert the result to be either zero ! 2829: or one one. Normalize is -1 if we should convert the result to be ! 2830: either zero or -1. If NORMALIZEP is zero, the result will be left ! 2831: "raw" out of the scc insn. */ ! 2832: ! 2833: rtx ! 2834: emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep) ! 2835: rtx target; ! 2836: enum rtx_code code; ! 2837: rtx op0, op1; ! 2838: enum machine_mode mode; ! 2839: int unsignedp; ! 2840: int normalizep; ! 2841: { ! 2842: rtx subtarget; ! 2843: enum insn_code icode; ! 2844: enum machine_mode compare_mode; ! 2845: enum machine_mode target_mode = GET_MODE (target); ! 2846: rtx tem; ! 2847: rtx last = 0; ! 2848: rtx pattern, comparison; ! 2849: ! 2850: if (mode == VOIDmode) ! 2851: mode = GET_MODE (op0); ! 2852: ! 2853: /* If one operand is constant, make it the second one. Only do this ! 2854: if the other operand is not constant as well. */ ! 2855: ! 2856: if ((CONSTANT_P (op0) && ! CONSTANT_P (op1)) ! 2857: || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT)) ! 2858: { ! 2859: tem = op0; ! 2860: op0 = op1; ! 2861: op1 = tem; ! 2862: code = swap_condition (code); ! 2863: } ! 2864: ! 2865: /* For some comparisons with 1 and -1, we can convert this to ! 2866: comparisons with zero. This will often produce more opportunities for ! 2867: store-flag insns. */ ! 2868: ! 2869: switch (code) ! 2870: { ! 2871: case LT: ! 2872: if (op1 == const1_rtx) ! 2873: op1 = const0_rtx, code = LE; ! 2874: break; ! 2875: case LE: ! 2876: if (op1 == constm1_rtx) ! 2877: op1 = const0_rtx, code = LT; ! 2878: break; ! 2879: case GE: ! 2880: if (op1 == const1_rtx) ! 2881: op1 = const0_rtx, code = GT; ! 2882: break; ! 2883: case GT: ! 2884: if (op1 == constm1_rtx) ! 2885: op1 = const0_rtx, code = GE; ! 2886: break; ! 2887: case GEU: ! 2888: if (op1 == const1_rtx) ! 2889: op1 = const0_rtx, code = NE; ! 2890: break; ! 2891: case LTU: ! 2892: if (op1 == const1_rtx) ! 2893: op1 = const0_rtx, code = EQ; ! 2894: break; ! 2895: } ! 2896: ! 2897: /* From now on, we won't change CODE, so set ICODE now. */ ! 2898: icode = setcc_gen_code[(int) code]; ! 2899: ! 2900: /* If this is A < 0 or A >= 0, we can do this by taking the ones ! 2901: complement of A (for GE) and shifting the sign bit to the low bit. */ ! 2902: if (op1 == const0_rtx && (code == LT || code == GE) ! 2903: && GET_MODE_CLASS (mode) == MODE_INT ! 2904: && (normalizep || STORE_FLAG_VALUE == 1 ! 2905: || (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT ! 2906: && (STORE_FLAG_VALUE ! 2907: == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))))) ! 2908: { ! 2909: subtarget = target; ! 2910: ! 2911: /* If the result is to be wider than OP0, it is best to convert it ! 2912: first. If it is to be narrower, it is *incorrect* to convert it ! 2913: first. */ ! 2914: if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (mode)) ! 2915: { ! 2916: op0 = protect_from_queue (op0, 0); ! 2917: op0 = convert_modes (target_mode, mode, op0, 0); ! 2918: mode = target_mode; ! 2919: } ! 2920: ! 2921: if (target_mode != mode) ! 2922: subtarget = 0; ! 2923: ! 2924: if (code == GE) ! 2925: op0 = expand_unop (mode, one_cmpl_optab, op0, subtarget, 0); ! 2926: ! 2927: if (normalizep || STORE_FLAG_VALUE == 1) ! 2928: /* If we are supposed to produce a 0/1 value, we want to do ! 2929: a logical shift from the sign bit to the low-order bit; for ! 2930: a -1/0 value, we do an arithmetic shift. */ ! 2931: op0 = expand_shift (RSHIFT_EXPR, mode, op0, ! 2932: size_int (GET_MODE_BITSIZE (mode) - 1), ! 2933: subtarget, normalizep != -1); ! 2934: ! 2935: if (mode != target_mode) ! 2936: op0 = convert_modes (target_mode, mode, op0, 0); ! 2937: ! 2938: return op0; ! 2939: } ! 2940: ! 2941: if (icode != CODE_FOR_nothing) ! 2942: { ! 2943: /* We think we may be able to do this with a scc insn. Emit the ! 2944: comparison and then the scc insn. ! 2945: ! 2946: compare_from_rtx may call emit_queue, which would be deleted below ! 2947: if the scc insn fails. So call it ourselves before setting LAST. */ ! 2948: ! 2949: emit_queue (); ! 2950: last = get_last_insn (); ! 2951: ! 2952: comparison ! 2953: = compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX, 0); ! 2954: if (GET_CODE (comparison) == CONST_INT) ! 2955: return (comparison == const0_rtx ? const0_rtx ! 2956: : normalizep == 1 ? const1_rtx ! 2957: : normalizep == -1 ? constm1_rtx ! 2958: : const_true_rtx); ! 2959: ! 2960: /* If the code of COMPARISON doesn't match CODE, something is ! 2961: wrong; we can no longer be sure that we have the operation. ! 2962: We could handle this case, but it should not happen. */ ! 2963: ! 2964: if (GET_CODE (comparison) != code) ! 2965: abort (); ! 2966: ! 2967: /* Get a reference to the target in the proper mode for this insn. */ ! 2968: compare_mode = insn_operand_mode[(int) icode][0]; ! 2969: subtarget = target; ! 2970: if (preserve_subexpressions_p () ! 2971: || ! (*insn_operand_predicate[(int) icode][0]) (subtarget, compare_mode)) ! 2972: subtarget = gen_reg_rtx (compare_mode); ! 2973: ! 2974: pattern = GEN_FCN (icode) (subtarget); ! 2975: if (pattern) ! 2976: { ! 2977: emit_insn (pattern); ! 2978: ! 2979: /* If we are converting to a wider mode, first convert to ! 2980: TARGET_MODE, then normalize. This produces better combining ! 2981: opportunities on machines that have a SIGN_EXTRACT when we are ! 2982: testing a single bit. This mostly benefits the 68k. ! 2983: ! 2984: If STORE_FLAG_VALUE does not have the sign bit set when ! 2985: interpreted in COMPARE_MODE, we can do this conversion as ! 2986: unsigned, which is usually more efficient. */ ! 2987: if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (compare_mode)) ! 2988: { ! 2989: convert_move (target, subtarget, ! 2990: (GET_MODE_BITSIZE (compare_mode) ! 2991: <= HOST_BITS_PER_WIDE_INT) ! 2992: && 0 == (STORE_FLAG_VALUE ! 2993: & ((HOST_WIDE_INT) 1 ! 2994: << (GET_MODE_BITSIZE (compare_mode) -1)))); ! 2995: op0 = target; ! 2996: compare_mode = target_mode; ! 2997: } ! 2998: else ! 2999: op0 = subtarget; ! 3000: ! 3001: /* If we want to keep subexpressions around, don't reuse our ! 3002: last target. */ ! 3003: ! 3004: if (preserve_subexpressions_p ()) ! 3005: subtarget = 0; ! 3006: ! 3007: /* Now normalize to the proper value in COMPARE_MODE. Sometimes ! 3008: we don't have to do anything. */ ! 3009: if (normalizep == 0 || normalizep == STORE_FLAG_VALUE) ! 3010: ; ! 3011: else if (normalizep == - STORE_FLAG_VALUE) ! 3012: op0 = expand_unop (compare_mode, neg_optab, op0, subtarget, 0); ! 3013: ! 3014: /* We don't want to use STORE_FLAG_VALUE < 0 below since this ! 3015: makes it hard to use a value of just the sign bit due to ! 3016: ANSI integer constant typing rules. */ ! 3017: else if (GET_MODE_BITSIZE (compare_mode) <= HOST_BITS_PER_WIDE_INT ! 3018: && (STORE_FLAG_VALUE ! 3019: & ((HOST_WIDE_INT) 1 ! 3020: << (GET_MODE_BITSIZE (compare_mode) - 1)))) ! 3021: op0 = expand_shift (RSHIFT_EXPR, compare_mode, op0, ! 3022: size_int (GET_MODE_BITSIZE (compare_mode) - 1), ! 3023: subtarget, normalizep == 1); ! 3024: else if (STORE_FLAG_VALUE & 1) ! 3025: { ! 3026: op0 = expand_and (op0, const1_rtx, subtarget); ! 3027: if (normalizep == -1) ! 3028: op0 = expand_unop (compare_mode, neg_optab, op0, op0, 0); ! 3029: } ! 3030: else ! 3031: abort (); ! 3032: ! 3033: /* If we were converting to a smaller mode, do the ! 3034: conversion now. */ ! 3035: if (target_mode != compare_mode) ! 3036: { ! 3037: convert_move (target, op0, 0); ! 3038: return target; ! 3039: } ! 3040: else ! 3041: return op0; ! 3042: } ! 3043: } ! 3044: ! 3045: if (last) ! 3046: delete_insns_since (last); ! 3047: ! 3048: subtarget = target_mode == mode ? target : 0; ! 3049: ! 3050: /* If we reached here, we can't do this with a scc insn. However, there ! 3051: are some comparisons that can be done directly. For example, if ! 3052: this is an equality comparison of integers, we can try to exclusive-or ! 3053: (or subtract) the two operands and use a recursive call to try the ! 3054: comparison with zero. Don't do any of these cases if branches are ! 3055: very cheap. */ ! 3056: ! 3057: if (BRANCH_COST > 0 ! 3058: && GET_MODE_CLASS (mode) == MODE_INT && (code == EQ || code == NE) ! 3059: && op1 != const0_rtx) ! 3060: { ! 3061: tem = expand_binop (mode, xor_optab, op0, op1, subtarget, 1, ! 3062: OPTAB_WIDEN); ! 3063: ! 3064: if (tem == 0) ! 3065: tem = expand_binop (mode, sub_optab, op0, op1, subtarget, 1, ! 3066: OPTAB_WIDEN); ! 3067: if (tem != 0) ! 3068: tem = emit_store_flag (target, code, tem, const0_rtx, ! 3069: mode, unsignedp, normalizep); ! 3070: if (tem == 0) ! 3071: delete_insns_since (last); ! 3072: return tem; ! 3073: } ! 3074: ! 3075: /* Some other cases we can do are EQ, NE, LE, and GT comparisons with ! 3076: the constant zero. Reject all other comparisons at this point. Only ! 3077: do LE and GT if branches are expensive since they are expensive on ! 3078: 2-operand machines. */ ! 3079: ! 3080: if (BRANCH_COST == 0 ! 3081: || GET_MODE_CLASS (mode) != MODE_INT || op1 != const0_rtx ! 3082: || (code != EQ && code != NE ! 3083: && (BRANCH_COST <= 1 || (code != LE && code != GT)))) ! 3084: return 0; ! 3085: ! 3086: /* See what we need to return. We can only return a 1, -1, or the ! 3087: sign bit. */ ! 3088: ! 3089: if (normalizep == 0) ! 3090: { ! 3091: if (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1) ! 3092: normalizep = STORE_FLAG_VALUE; ! 3093: ! 3094: else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT ! 3095: && (STORE_FLAG_VALUE ! 3096: == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))) ! 3097: ; ! 3098: else ! 3099: return 0; ! 3100: } ! 3101: ! 3102: /* Try to put the result of the comparison in the sign bit. Assume we can't ! 3103: do the necessary operation below. */ ! 3104: ! 3105: tem = 0; ! 3106: ! 3107: /* To see if A <= 0, compute (A | (A - 1)). A <= 0 iff that result has ! 3108: the sign bit set. */ ! 3109: ! 3110: if (code == LE) ! 3111: { ! 3112: /* This is destructive, so SUBTARGET can't be OP0. */ ! 3113: if (rtx_equal_p (subtarget, op0)) ! 3114: subtarget = 0; ! 3115: ! 3116: tem = expand_binop (mode, sub_optab, op0, const1_rtx, subtarget, 0, ! 3117: OPTAB_WIDEN); ! 3118: if (tem) ! 3119: tem = expand_binop (mode, ior_optab, op0, tem, subtarget, 0, ! 3120: OPTAB_WIDEN); ! 3121: } ! 3122: ! 3123: /* To see if A > 0, compute (((signed) A) << BITS) - A, where BITS is the ! 3124: number of bits in the mode of OP0, minus one. */ ! 3125: ! 3126: if (code == GT) ! 3127: { ! 3128: if (rtx_equal_p (subtarget, op0)) ! 3129: subtarget = 0; ! 3130: ! 3131: tem = expand_shift (RSHIFT_EXPR, mode, op0, ! 3132: size_int (GET_MODE_BITSIZE (mode) - 1), ! 3133: subtarget, 0); ! 3134: tem = expand_binop (mode, sub_optab, tem, op0, subtarget, 0, ! 3135: OPTAB_WIDEN); ! 3136: } ! 3137: ! 3138: if (code == EQ || code == NE) ! 3139: { ! 3140: /* For EQ or NE, one way to do the comparison is to apply an operation ! 3141: that converts the operand into a positive number if it is non-zero ! 3142: or zero if it was originally zero. Then, for EQ, we subtract 1 and ! 3143: for NE we negate. This puts the result in the sign bit. Then we ! 3144: normalize with a shift, if needed. ! 3145: ! 3146: Two operations that can do the above actions are ABS and FFS, so try ! 3147: them. If that doesn't work, and MODE is smaller than a full word, ! 3148: we can use zero-extension to the wider mode (an unsigned conversion) ! 3149: as the operation. */ ! 3150: ! 3151: if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) ! 3152: tem = expand_unop (mode, abs_optab, op0, subtarget, 1); ! 3153: else if (ffs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) ! 3154: tem = expand_unop (mode, ffs_optab, op0, subtarget, 1); ! 3155: else if (GET_MODE_SIZE (mode) < UNITS_PER_WORD) ! 3156: { ! 3157: op0 = protect_from_queue (op0, 0); ! 3158: tem = convert_modes (word_mode, mode, op0, 1); ! 3159: mode = word_mode; ! 3160: } ! 3161: ! 3162: if (tem != 0) ! 3163: { ! 3164: if (code == EQ) ! 3165: tem = expand_binop (mode, sub_optab, tem, const1_rtx, subtarget, ! 3166: 0, OPTAB_WIDEN); ! 3167: else ! 3168: tem = expand_unop (mode, neg_optab, tem, subtarget, 0); ! 3169: } ! 3170: ! 3171: /* If we couldn't do it that way, for NE we can "or" the two's complement ! 3172: of the value with itself. For EQ, we take the one's complement of ! 3173: that "or", which is an extra insn, so we only handle EQ if branches ! 3174: are expensive. */ ! 3175: ! 3176: if (tem == 0 && (code == NE || BRANCH_COST > 1)) ! 3177: { ! 3178: if (rtx_equal_p (subtarget, op0)) ! 3179: subtarget = 0; ! 3180: ! 3181: tem = expand_unop (mode, neg_optab, op0, subtarget, 0); ! 3182: tem = expand_binop (mode, ior_optab, tem, op0, subtarget, 0, ! 3183: OPTAB_WIDEN); ! 3184: ! 3185: if (tem && code == EQ) ! 3186: tem = expand_unop (mode, one_cmpl_optab, tem, subtarget, 0); ! 3187: } ! 3188: } ! 3189: ! 3190: if (tem && normalizep) ! 3191: tem = expand_shift (RSHIFT_EXPR, mode, tem, ! 3192: size_int (GET_MODE_BITSIZE (mode) - 1), ! 3193: tem, normalizep == 1); ! 3194: ! 3195: if (tem && GET_MODE (tem) != target_mode) ! 3196: { ! 3197: convert_move (target, tem, 0); ! 3198: tem = target; ! 3199: } ! 3200: ! 3201: if (tem == 0) ! 3202: delete_insns_since (last); ! 3203: ! 3204: return tem; ! 3205: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.