|
|
1.1 root 1: /* Medium-level subroutines: convert bit-field store and extract
2: and shifts, multiplies and divides to rtl instructions.
1.1.1.8 ! root 3: Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
1.1 root 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
1.1.1.8 ! root 19: the Free Software Foundation, 59 Temple Place - Suite 330,
! 20: Boston, MA 02111-1307, USA. */
1.1 root 21:
22:
23: #include "config.h"
24: #include "rtl.h"
25: #include "tree.h"
26: #include "flags.h"
27: #include "insn-flags.h"
28: #include "insn-codes.h"
29: #include "insn-config.h"
30: #include "expr.h"
31: #include "real.h"
32: #include "recog.h"
33:
1.1.1.7 root 34: static void store_fixed_bit_field PROTO((rtx, int, int, int, rtx, int));
35: static void store_split_bit_field PROTO((rtx, int, int, rtx, int));
36: static rtx extract_fixed_bit_field PROTO((enum machine_mode, rtx, int,
37: int, int, rtx, int, int));
38: static rtx mask_rtx PROTO((enum machine_mode, int,
39: int, int));
40: static rtx lshift_value PROTO((enum machine_mode, rtx,
41: int, int));
42: static rtx extract_split_bit_field PROTO((rtx, int, int, int, int));
1.1 root 43:
44: #define CEIL(x,y) (((x) + (y) - 1) / (y))
45:
46: /* Non-zero means divides or modulus operations are relatively cheap for
47: powers of two, so don't use branches; emit the operation instead.
48: Usually, this will mean that the MD file will emit non-branch
49: sequences. */
50:
51: static int sdiv_pow2_cheap, smod_pow2_cheap;
52:
1.1.1.6 root 53: #ifndef SLOW_UNALIGNED_ACCESS
54: #define SLOW_UNALIGNED_ACCESS STRICT_ALIGNMENT
55: #endif
56:
1.1.1.5 root 57: /* For compilers that support multiple targets with different word sizes,
58: MAX_BITS_PER_WORD contains the biggest value of BITS_PER_WORD. An example
59: is the H8/300(H) compiler. */
60:
61: #ifndef MAX_BITS_PER_WORD
62: #define MAX_BITS_PER_WORD BITS_PER_WORD
63: #endif
1.1 root 64:
1.1.1.8 ! root 65: /* Cost of various pieces of RTL. Note that some of these are indexed by shift count,
! 66: and some by mode. */
1.1.1.6 root 67: static int add_cost, negate_cost, zero_cost;
1.1.1.5 root 68: static int shift_cost[MAX_BITS_PER_WORD];
69: static int shiftadd_cost[MAX_BITS_PER_WORD];
70: static int shiftsub_cost[MAX_BITS_PER_WORD];
1.1.1.8 ! root 71: static int mul_cost[NUM_MACHINE_MODES];
! 72: static int div_cost[NUM_MACHINE_MODES];
! 73: static int mul_widen_cost[NUM_MACHINE_MODES];
! 74: static int mul_highpart_cost[NUM_MACHINE_MODES];
1.1 root 75:
76: void
77: init_expmed ()
78: {
1.1.1.5 root 79: char *free_point;
1.1 root 80: /* This is "some random pseudo register" for purposes of calling recog
81: to see what insns exist. */
1.1.1.6 root 82: rtx reg = gen_rtx (REG, word_mode, 10000);
1.1.1.5 root 83: rtx shift_insn, shiftadd_insn, shiftsub_insn;
1.1.1.4 root 84: int dummy;
1.1.1.5 root 85: int m;
1.1.1.8 ! root 86: enum machine_mode mode, wider_mode;
1.1 root 87:
1.1.1.5 root 88: start_sequence ();
89:
90: /* Since we are on the permanent obstack, we must be sure we save this
91: spot AFTER we call start_sequence, since it will reuse the rtl it
92: makes. */
93:
94: free_point = (char *) oballoc (0);
95:
96: zero_cost = rtx_cost (const0_rtx, 0);
1.1.1.3 root 97: add_cost = rtx_cost (gen_rtx (PLUS, word_mode, reg, reg), SET);
1.1.1.5 root 98:
99: shift_insn = emit_insn (gen_rtx (SET, VOIDmode, reg,
100: gen_rtx (ASHIFT, word_mode, reg,
101: const0_rtx)));
102:
103: shiftadd_insn = emit_insn (gen_rtx (SET, VOIDmode, reg,
104: gen_rtx (PLUS, word_mode,
105: gen_rtx (MULT, word_mode,
106: reg, const0_rtx),
107: reg)));
108:
109: shiftsub_insn = emit_insn (gen_rtx (SET, VOIDmode, reg,
110: gen_rtx (MINUS, word_mode,
111: gen_rtx (MULT, word_mode,
112: reg, const0_rtx),
113: reg)));
114:
115: init_recog ();
116:
117: shift_cost[0] = 0;
118: shiftadd_cost[0] = shiftsub_cost[0] = add_cost;
119:
120: for (m = 1; m < BITS_PER_WORD; m++)
121: {
122: shift_cost[m] = shiftadd_cost[m] = shiftsub_cost[m] = 32000;
123:
124: XEXP (SET_SRC (PATTERN (shift_insn)), 1) = GEN_INT (m);
125: if (recog (PATTERN (shift_insn), shift_insn, &dummy) >= 0)
126: shift_cost[m] = rtx_cost (SET_SRC (PATTERN (shift_insn)), SET);
127:
128: XEXP (XEXP (SET_SRC (PATTERN (shiftadd_insn)), 0), 1)
129: = GEN_INT ((HOST_WIDE_INT) 1 << m);
130: if (recog (PATTERN (shiftadd_insn), shiftadd_insn, &dummy) >= 0)
131: shiftadd_cost[m] = rtx_cost (SET_SRC (PATTERN (shiftadd_insn)), SET);
132:
133: XEXP (XEXP (SET_SRC (PATTERN (shiftsub_insn)), 0), 1)
134: = GEN_INT ((HOST_WIDE_INT) 1 << m);
135: if (recog (PATTERN (shiftsub_insn), shiftsub_insn, &dummy) >= 0)
136: shiftsub_cost[m] = rtx_cost (SET_SRC (PATTERN (shiftsub_insn)), SET);
137: }
138:
1.1.1.3 root 139: negate_cost = rtx_cost (gen_rtx (NEG, word_mode, reg), SET);
1.1 root 140:
141: sdiv_pow2_cheap
1.1.1.5 root 142: = (rtx_cost (gen_rtx (DIV, word_mode, reg, GEN_INT (32)), SET)
143: <= 2 * add_cost);
1.1 root 144: smod_pow2_cheap
1.1.1.5 root 145: = (rtx_cost (gen_rtx (MOD, word_mode, reg, GEN_INT (32)), SET)
146: <= 2 * add_cost);
1.1 root 147:
1.1.1.8 ! root 148: for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
! 149: mode != VOIDmode;
! 150: mode = GET_MODE_WIDER_MODE (mode))
! 151: {
! 152: reg = gen_rtx (REG, mode, 10000);
! 153: div_cost[(int) mode] = rtx_cost (gen_rtx (UDIV, mode, reg, reg), SET);
! 154: mul_cost[(int) mode] = rtx_cost (gen_rtx (MULT, mode, reg, reg), SET);
! 155: wider_mode = GET_MODE_WIDER_MODE (mode);
! 156: if (wider_mode != VOIDmode)
! 157: {
! 158: mul_widen_cost[(int) wider_mode]
! 159: = rtx_cost (gen_rtx (MULT, wider_mode,
! 160: gen_rtx (ZERO_EXTEND, wider_mode, reg),
! 161: gen_rtx (ZERO_EXTEND, wider_mode, reg)),
! 162: SET);
! 163: mul_highpart_cost[(int) mode]
! 164: = rtx_cost (gen_rtx (TRUNCATE, mode,
! 165: gen_rtx (LSHIFTRT, wider_mode,
! 166: gen_rtx (MULT, wider_mode,
! 167: gen_rtx (ZERO_EXTEND, wider_mode, reg),
! 168: gen_rtx (ZERO_EXTEND, wider_mode, reg)),
! 169: GEN_INT (GET_MODE_BITSIZE (mode)))),
! 170: SET);
! 171: }
! 172: }
! 173:
1.1 root 174: /* Free the objects we just allocated. */
1.1.1.5 root 175: end_sequence ();
1.1 root 176: obfree (free_point);
177: }
178:
179: /* Return an rtx representing minus the value of X.
180: MODE is the intended mode of the result,
181: useful if X is a CONST_INT. */
182:
183: rtx
184: negate_rtx (mode, x)
185: enum machine_mode mode;
186: rtx x;
187: {
188: if (GET_CODE (x) == CONST_INT)
189: {
1.1.1.4 root 190: HOST_WIDE_INT val = - INTVAL (x);
191: if (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_WIDE_INT)
1.1 root 192: {
193: /* Sign extend the value from the bits that are significant. */
1.1.1.4 root 194: if (val & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
195: val |= (HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (mode);
1.1 root 196: else
1.1.1.4 root 197: val &= ((HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1;
1.1 root 198: }
1.1.1.4 root 199: return GEN_INT (val);
1.1 root 200: }
201: else
1.1.1.4 root 202: return expand_unop (GET_MODE (x), neg_optab, x, NULL_RTX, 0);
1.1 root 203: }
204:
205: /* Generate code to store value from rtx VALUE
206: into a bit-field within structure STR_RTX
207: containing BITSIZE bits starting at bit BITNUM.
208: FIELDMODE is the machine-mode of the FIELD_DECL node for this field.
209: ALIGN is the alignment that STR_RTX is known to have, measured in bytes.
210: TOTAL_SIZE is the size of the structure in bytes, or -1 if varying. */
211:
212: /* ??? Note that there are two different ideas here for how
213: to determine the size to count bits within, for a register.
214: One is BITS_PER_WORD, and the other is the size of operand 3
215: of the insv pattern. (The latter assumes that an n-bit machine
216: will be able to insert bit fields up to n bits wide.)
217: It isn't certain that either of these is right.
218: extract_bit_field has the same quandary. */
219:
220: rtx
221: store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
222: rtx str_rtx;
223: register int bitsize;
224: int bitnum;
225: enum machine_mode fieldmode;
226: rtx value;
227: int align;
228: int total_size;
229: {
230: int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
231: register int offset = bitnum / unit;
232: register int bitpos = bitnum % unit;
233: register rtx op0 = str_rtx;
234:
235: if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
236: abort ();
237:
238: /* Discount the part of the structure before the desired byte.
239: We need to know how many bytes are safe to reference after it. */
240: if (total_size >= 0)
241: total_size -= (bitpos / BIGGEST_ALIGNMENT
242: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
243:
244: while (GET_CODE (op0) == SUBREG)
245: {
246: /* The following line once was done only if WORDS_BIG_ENDIAN,
247: but I think that is a mistake. WORDS_BIG_ENDIAN is
248: meaningful at a much higher level; when structures are copied
249: between memory and regs, the higher-numbered regs
250: always get higher addresses. */
251: offset += SUBREG_WORD (op0);
252: /* We used to adjust BITPOS here, but now we do the whole adjustment
253: right after the loop. */
254: op0 = SUBREG_REG (op0);
255: }
256:
257: /* If OP0 is a register, BITPOS must count within a word.
258: But as we have it, it counts within whatever size OP0 now has.
259: On a bigendian machine, these are not the same, so convert. */
1.1.1.8 ! root 260: if (BYTES_BIG_ENDIAN
! 261: && GET_CODE (op0) != MEM
! 262: && unit > GET_MODE_BITSIZE (GET_MODE (op0)))
1.1 root 263: bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0));
264:
265: value = protect_from_queue (value, 0);
266:
267: if (flag_force_mem)
268: value = force_not_mem (value);
269:
270: /* Note that the adjustment of BITPOS above has no effect on whether
271: BITPOS is 0 in a REG bigger than a word. */
1.1.1.3 root 272: if (GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
1.1.1.6 root 273: && (GET_CODE (op0) != MEM
274: || ! SLOW_UNALIGNED_ACCESS
275: || (offset * BITS_PER_UNIT % bitsize == 0
276: && align % GET_MODE_SIZE (fieldmode) == 0))
1.1 root 277: && bitpos == 0 && bitsize == GET_MODE_BITSIZE (fieldmode))
278: {
279: /* Storing in a full-word or multi-word field in a register
280: can be done with just SUBREG. */
281: if (GET_MODE (op0) != fieldmode)
1.1.1.6 root 282: {
283: if (GET_CODE (op0) == REG)
284: op0 = gen_rtx (SUBREG, fieldmode, op0, offset);
285: else
286: op0 = change_address (op0, fieldmode,
287: plus_constant (XEXP (op0, 0), offset));
288: }
1.1 root 289: emit_move_insn (op0, value);
290: return value;
291: }
292:
293: /* Storing an lsb-aligned field in a register
294: can be done with a movestrict instruction. */
295:
296: if (GET_CODE (op0) != MEM
1.1.1.8 ! root 297: && (BYTES_BIG_ENDIAN ? bitpos + bitsize == unit : bitpos == 0)
1.1 root 298: && bitsize == GET_MODE_BITSIZE (fieldmode)
299: && (GET_MODE (op0) == fieldmode
300: || (movstrict_optab->handlers[(int) fieldmode].insn_code
301: != CODE_FOR_nothing)))
302: {
303: /* Get appropriate low part of the value being stored. */
304: if (GET_CODE (value) == CONST_INT || GET_CODE (value) == REG)
305: value = gen_lowpart (fieldmode, value);
306: else if (!(GET_CODE (value) == SYMBOL_REF
307: || GET_CODE (value) == LABEL_REF
308: || GET_CODE (value) == CONST))
309: value = convert_to_mode (fieldmode, value, 0);
310:
311: if (GET_MODE (op0) == fieldmode)
312: emit_move_insn (op0, value);
313: else
314: {
315: int icode = movstrict_optab->handlers[(int) fieldmode].insn_code;
316: if(! (*insn_operand_predicate[icode][1]) (value, fieldmode))
317: value = copy_to_mode_reg (fieldmode, value);
318: emit_insn (GEN_FCN (icode)
319: (gen_rtx (SUBREG, fieldmode, op0, offset), value));
320: }
321: return value;
322: }
323:
324: /* Handle fields bigger than a word. */
325:
326: if (bitsize > BITS_PER_WORD)
327: {
328: /* Here we transfer the words of the field
329: in the order least significant first.
330: This is because the most significant word is the one which may
1.1.1.7 root 331: be less than full.
332: However, only do that if the value is not BLKmode. */
333:
334: int backwards = WORDS_BIG_ENDIAN && fieldmode != BLKmode;
1.1 root 335:
336: int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
337: int i;
338:
339: /* This is the mode we must force value to, so that there will be enough
340: subwords to extract. Note that fieldmode will often (always?) be
341: VOIDmode, because that is what store_field uses to indicate that this
342: is a bit field, but passing VOIDmode to operand_subword_force will
343: result in an abort. */
344: fieldmode = mode_for_size (nwords * BITS_PER_WORD, MODE_INT, 0);
345:
346: for (i = 0; i < nwords; i++)
347: {
348: /* If I is 0, use the low-order word in both field and target;
349: if I is 1, use the next to lowest word; and so on. */
1.1.1.7 root 350: int wordnum = (backwards ? nwords - i - 1 : i);
351: int bit_offset = (backwards
1.1 root 352: ? MAX (bitsize - (i + 1) * BITS_PER_WORD, 0)
353: : i * BITS_PER_WORD);
354: store_bit_field (op0, MIN (BITS_PER_WORD,
355: bitsize - i * BITS_PER_WORD),
356: bitnum + bit_offset, word_mode,
1.1.1.6 root 357: operand_subword_force (value, wordnum,
358: (GET_MODE (value) == VOIDmode
359: ? fieldmode
360: : GET_MODE (value))),
1.1 root 361: align, total_size);
362: }
363: return value;
364: }
365:
366: /* From here on we can assume that the field to be stored in is
367: a full-word (whatever type that is), since it is shorter than a word. */
368:
369: /* OFFSET is the number of words or bytes (UNIT says which)
370: from STR_RTX to the first word or byte containing part of the field. */
371:
372: if (GET_CODE (op0) == REG)
373: {
374: if (offset != 0
375: || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
376: op0 = gen_rtx (SUBREG, TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
377: op0, offset);
378: offset = 0;
379: }
380: else
381: {
382: op0 = protect_from_queue (op0, 1);
383: }
384:
1.1.1.7 root 385: /* If VALUE is a floating-point mode, access it as an integer of the
386: corresponding size. This can occur on a machine with 64 bit registers
387: that uses SFmode for float. This can also occur for unaligned float
388: structure fields. */
389: if (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT)
390: {
391: if (GET_CODE (value) != REG)
392: value = copy_to_reg (value);
393: value = gen_rtx (SUBREG, word_mode, value, 0);
394: }
395:
1.1 root 396: /* Now OFFSET is nonzero only if OP0 is memory
397: and is therefore always measured in bytes. */
398:
399: #ifdef HAVE_insv
400: if (HAVE_insv
401: && !(bitsize == 1 && GET_CODE (value) == CONST_INT)
402: /* Ensure insv's size is wide enough for this field. */
403: && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3])
1.1.1.7 root 404: >= bitsize)
405: && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
406: && (bitsize + bitpos
407: > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]))))
1.1 root 408: {
409: int xbitpos = bitpos;
410: rtx value1;
411: rtx xop0 = op0;
412: rtx last = get_last_insn ();
413: rtx pat;
414: enum machine_mode maxmode
415: = insn_operand_mode[(int) CODE_FOR_insv][3];
416:
417: int save_volatile_ok = volatile_ok;
418: volatile_ok = 1;
419:
420: /* If this machine's insv can only insert into a register, or if we
421: are to force MEMs into a register, copy OP0 into a register and
422: save it back later. */
423: if (GET_CODE (op0) == MEM
424: && (flag_force_mem
425: || ! ((*insn_operand_predicate[(int) CODE_FOR_insv][0])
426: (op0, VOIDmode))))
427: {
428: rtx tempreg;
429: enum machine_mode bestmode;
430:
431: /* Get the mode to use for inserting into this field. If OP0 is
432: BLKmode, get the smallest mode consistent with the alignment. If
433: OP0 is a non-BLKmode object that is no wider than MAXMODE, use its
434: mode. Otherwise, use the smallest mode containing the field. */
435:
436: if (GET_MODE (op0) == BLKmode
437: || GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (maxmode))
438: bestmode
1.1.1.3 root 439: = get_best_mode (bitsize, bitnum, align * BITS_PER_UNIT, maxmode,
440: MEM_VOLATILE_P (op0));
1.1 root 441: else
442: bestmode = GET_MODE (op0);
443:
1.1.1.6 root 444: if (bestmode == VOIDmode
1.1.1.8 ! root 445: || (SLOW_UNALIGNED_ACCESS && GET_MODE_SIZE (bestmode) > align))
1.1 root 446: goto insv_loses;
447:
448: /* Adjust address to point to the containing unit of that mode. */
449: unit = GET_MODE_BITSIZE (bestmode);
450: /* Compute offset as multiple of this unit, counting in bytes. */
451: offset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
452: bitpos = bitnum % unit;
453: op0 = change_address (op0, bestmode,
454: plus_constant (XEXP (op0, 0), offset));
455:
456: /* Fetch that unit, store the bitfield in it, then store the unit. */
457: tempreg = copy_to_reg (op0);
458: store_bit_field (tempreg, bitsize, bitpos, fieldmode, value,
459: align, total_size);
460: emit_move_insn (op0, tempreg);
461: return value;
462: }
463: volatile_ok = save_volatile_ok;
464:
465: /* Add OFFSET into OP0's address. */
466: if (GET_CODE (xop0) == MEM)
467: xop0 = change_address (xop0, byte_mode,
468: plus_constant (XEXP (xop0, 0), offset));
469:
470: /* If xop0 is a register, we need it in MAXMODE
471: to make it acceptable to the format of insv. */
472: if (GET_CODE (xop0) == SUBREG)
1.1.1.7 root 473: /* We can't just change the mode, because this might clobber op0,
474: and we will need the original value of op0 if insv fails. */
475: xop0 = gen_rtx (SUBREG, maxmode, SUBREG_REG (xop0), SUBREG_WORD (xop0));
1.1 root 476: if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
477: xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
478:
479: /* On big-endian machines, we count bits from the most significant.
480: If the bit field insn does not, we must invert. */
481:
1.1.1.8 ! root 482: if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
! 483: xbitpos = unit - bitsize - xbitpos;
! 484:
1.1 root 485: /* We have been counting XBITPOS within UNIT.
486: Count instead within the size of the register. */
1.1.1.8 ! root 487: if (BITS_BIG_ENDIAN && GET_CODE (xop0) != MEM)
1.1 root 488: xbitpos += GET_MODE_BITSIZE (maxmode) - unit;
1.1.1.8 ! root 489:
1.1 root 490: unit = GET_MODE_BITSIZE (maxmode);
491:
492: /* Convert VALUE to maxmode (which insv insn wants) in VALUE1. */
493: value1 = value;
494: if (GET_MODE (value) != maxmode)
495: {
496: if (GET_MODE_BITSIZE (GET_MODE (value)) >= bitsize)
497: {
498: /* Optimization: Don't bother really extending VALUE
1.1.1.4 root 499: if it has all the bits we will actually use. However,
500: if we must narrow it, be sure we do it correctly. */
1.1 root 501:
1.1.1.4 root 502: if (GET_MODE_SIZE (GET_MODE (value)) < GET_MODE_SIZE (maxmode))
503: {
504: /* Avoid making subreg of a subreg, or of a mem. */
505: if (GET_CODE (value1) != REG)
1.1 root 506: value1 = copy_to_reg (value1);
1.1.1.4 root 507: value1 = gen_rtx (SUBREG, maxmode, value1, 0);
508: }
509: else
510: value1 = gen_lowpart (maxmode, value1);
1.1 root 511: }
512: else if (!CONSTANT_P (value))
513: /* Parse phase is supposed to make VALUE's data type
514: match that of the component reference, which is a type
515: at least as wide as the field; so VALUE should have
516: a mode that corresponds to that type. */
517: abort ();
518: }
519:
520: /* If this machine's insv insists on a register,
521: get VALUE1 into a register. */
522: if (! ((*insn_operand_predicate[(int) CODE_FOR_insv][3])
523: (value1, maxmode)))
524: value1 = force_reg (maxmode, value1);
525:
1.1.1.4 root 526: pat = gen_insv (xop0, GEN_INT (bitsize), GEN_INT (xbitpos), value1);
1.1 root 527: if (pat)
528: emit_insn (pat);
529: else
530: {
531: delete_insns_since (last);
532: store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align);
533: }
534: }
535: else
536: insv_loses:
537: #endif
538: /* Insv is not available; store using shifts and boolean ops. */
539: store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align);
540: return value;
541: }
542:
543: /* Use shifts and boolean operations to store VALUE
544: into a bit field of width BITSIZE
545: in a memory location specified by OP0 except offset by OFFSET bytes.
546: (OFFSET must be 0 if OP0 is a register.)
547: The field starts at position BITPOS within the byte.
548: (If OP0 is a register, it may be a full word or a narrower mode,
549: but BITPOS still counts within a full word,
550: which is significant on bigendian machines.)
551: STRUCT_ALIGN is the alignment the structure is known to have (in bytes).
552:
553: Note that protect_from_queue has already been done on OP0 and VALUE. */
554:
555: static void
556: store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
557: register rtx op0;
558: register int offset, bitsize, bitpos;
559: register rtx value;
560: int struct_align;
561: {
562: register enum machine_mode mode;
563: int total_bits = BITS_PER_WORD;
564: rtx subtarget, temp;
565: int all_zero = 0;
566: int all_one = 0;
567:
568: /* There is a case not handled here:
569: a structure with a known alignment of just a halfword
570: and a field split across two aligned halfwords within the structure.
571: Or likewise a structure with a known alignment of just a byte
572: and a field split across two bytes.
573: Such cases are not supposed to be able to occur. */
574:
575: if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
576: {
577: if (offset != 0)
578: abort ();
579: /* Special treatment for a bit field split across two registers. */
580: if (bitsize + bitpos > BITS_PER_WORD)
581: {
1.1.1.6 root 582: store_split_bit_field (op0, bitsize, bitpos,
583: value, BITS_PER_WORD);
1.1 root 584: return;
585: }
586: }
587: else
588: {
589: /* Get the proper mode to use for this field. We want a mode that
590: includes the entire field. If such a mode would be larger than
591: a word, we won't be doing the extraction the normal way. */
592:
593: mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
594: struct_align * BITS_PER_UNIT, word_mode,
595: GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
596:
597: if (mode == VOIDmode)
598: {
599: /* The only way this should occur is if the field spans word
600: boundaries. */
1.1.1.6 root 601: store_split_bit_field (op0,
602: bitsize, bitpos + offset * BITS_PER_UNIT,
1.1 root 603: value, struct_align);
604: return;
605: }
606:
607: total_bits = GET_MODE_BITSIZE (mode);
608:
1.1.1.7 root 609: /* Make sure bitpos is valid for the chosen mode. Adjust BITPOS to
610: be be in the range 0 to total_bits-1, and put any excess bytes in
611: OFFSET. */
612: if (bitpos >= total_bits)
613: {
614: offset += (bitpos / total_bits) * (total_bits / BITS_PER_UNIT);
615: bitpos -= ((bitpos / total_bits) * (total_bits / BITS_PER_UNIT)
616: * BITS_PER_UNIT);
617: }
618:
1.1 root 619: /* Get ref to an aligned byte, halfword, or word containing the field.
620: Adjust BITPOS to be position within a word,
621: and OFFSET to be the offset of that word.
622: Then alter OP0 to refer to that word. */
623: bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT;
624: offset -= (offset % (total_bits / BITS_PER_UNIT));
625: op0 = change_address (op0, mode,
626: plus_constant (XEXP (op0, 0), offset));
627: }
628:
629: mode = GET_MODE (op0);
630:
631: /* Now MODE is either some integral mode for a MEM as OP0,
632: or is a full-word for a REG as OP0. TOTAL_BITS corresponds.
633: The bit field is contained entirely within OP0.
634: BITPOS is the starting bit number within OP0.
635: (OP0's mode may actually be narrower than MODE.) */
636:
1.1.1.8 ! root 637: if (BYTES_BIG_ENDIAN)
! 638: /* BITPOS is the distance between our msb
! 639: and that of the containing datum.
! 640: Convert it to the distance from the lsb. */
! 641: bitpos = total_bits - bitsize - bitpos;
1.1 root 642:
643: /* Now BITPOS is always the distance between our lsb
644: and that of OP0. */
645:
646: /* Shift VALUE left by BITPOS bits. If VALUE is not constant,
647: we must first convert its mode to MODE. */
648:
649: if (GET_CODE (value) == CONST_INT)
650: {
1.1.1.4 root 651: register HOST_WIDE_INT v = INTVAL (value);
1.1 root 652:
1.1.1.4 root 653: if (bitsize < HOST_BITS_PER_WIDE_INT)
654: v &= ((HOST_WIDE_INT) 1 << bitsize) - 1;
1.1 root 655:
656: if (v == 0)
657: all_zero = 1;
1.1.1.4 root 658: else if ((bitsize < HOST_BITS_PER_WIDE_INT
659: && v == ((HOST_WIDE_INT) 1 << bitsize) - 1)
660: || (bitsize == HOST_BITS_PER_WIDE_INT && v == -1))
1.1 root 661: all_one = 1;
662:
663: value = lshift_value (mode, value, bitpos, bitsize);
664: }
665: else
666: {
667: int must_and = (GET_MODE_BITSIZE (GET_MODE (value)) != bitsize
668: && bitpos + bitsize != GET_MODE_BITSIZE (mode));
669:
670: if (GET_MODE (value) != mode)
671: {
672: if ((GET_CODE (value) == REG || GET_CODE (value) == SUBREG)
673: && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (value)))
674: value = gen_lowpart (mode, value);
675: else
676: value = convert_to_mode (mode, value, 1);
677: }
678:
679: if (must_and)
680: value = expand_binop (mode, and_optab, value,
681: mask_rtx (mode, 0, bitsize, 0),
1.1.1.4 root 682: NULL_RTX, 1, OPTAB_LIB_WIDEN);
1.1 root 683: if (bitpos > 0)
684: value = expand_shift (LSHIFT_EXPR, mode, value,
1.1.1.4 root 685: build_int_2 (bitpos, 0), NULL_RTX, 1);
1.1 root 686: }
687:
688: /* Now clear the chosen bits in OP0,
689: except that if VALUE is -1 we need not bother. */
690:
691: subtarget = (GET_CODE (op0) == REG || ! flag_force_mem) ? op0 : 0;
692:
693: if (! all_one)
694: {
695: temp = expand_binop (mode, and_optab, op0,
696: mask_rtx (mode, bitpos, bitsize, 1),
697: subtarget, 1, OPTAB_LIB_WIDEN);
698: subtarget = temp;
699: }
700: else
701: temp = op0;
702:
703: /* Now logical-or VALUE into OP0, unless it is zero. */
704:
705: if (! all_zero)
706: temp = expand_binop (mode, ior_optab, temp, value,
707: subtarget, 1, OPTAB_LIB_WIDEN);
708: if (op0 != temp)
709: emit_move_insn (op0, temp);
710: }
711:
1.1.1.6 root 712: /* Store a bit field that is split across multiple accessible memory objects.
1.1 root 713:
1.1.1.6 root 714: OP0 is the REG, SUBREG or MEM rtx for the first of the objects.
1.1 root 715: BITSIZE is the field width; BITPOS the position of its first bit
716: (within the word).
1.1.1.6 root 717: VALUE is the value to store.
718: ALIGN is the known alignment of OP0, measured in bytes.
719: This is also the size of the memory objects to be used.
720:
721: This does not yet handle fields wider than BITS_PER_WORD. */
1.1 root 722:
723: static void
724: store_split_bit_field (op0, bitsize, bitpos, value, align)
725: rtx op0;
726: int bitsize, bitpos;
727: rtx value;
728: int align;
729: {
1.1.1.7 root 730: int unit;
731: int bitsdone = 0;
732:
1.1.1.6 root 733: /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
734: much at a time. */
1.1.1.7 root 735: if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
736: unit = BITS_PER_WORD;
737: else
738: unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD);
1.1.1.6 root 739:
740: /* If VALUE is a constant other than a CONST_INT, get it into a register in
741: WORD_MODE. If we can do this using gen_lowpart_common, do so. Note
742: that VALUE might be a floating-point constant. */
743: if (CONSTANT_P (value) && GET_CODE (value) != CONST_INT)
744: {
745: rtx word = gen_lowpart_common (word_mode, value);
1.1 root 746:
1.1.1.7 root 747: if (word && (value != word))
1.1.1.6 root 748: value = word;
749: else
750: value = gen_lowpart_common (word_mode,
1.1.1.8 ! root 751: force_reg (GET_MODE (value) != VOIDmode
! 752: ? GET_MODE (value)
! 753: : word_mode, value));
1.1.1.6 root 754: }
1.1 root 755:
1.1.1.6 root 756: while (bitsdone < bitsize)
757: {
758: int thissize;
759: rtx part, word;
760: int thispos;
761: int offset;
1.1.1.5 root 762:
1.1.1.6 root 763: offset = (bitpos + bitsdone) / unit;
764: thispos = (bitpos + bitsdone) % unit;
1.1.1.5 root 765:
1.1.1.6 root 766: /* THISSIZE must not overrun a word boundary. Otherwise,
767: store_fixed_bit_field will call us again, and we will mutually
768: recurse forever. */
769: thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
770: thissize = MIN (thissize, unit - thispos);
1.1 root 771:
1.1.1.8 ! root 772: if (BYTES_BIG_ENDIAN)
! 773: {
! 774: int total_bits;
! 775:
! 776: /* We must do an endian conversion exactly the same way as it is
! 777: done in extract_bit_field, so that the two calls to
! 778: extract_fixed_bit_field will have comparable arguments. */
! 779: if (GET_CODE (value) != MEM)
! 780: total_bits = BITS_PER_WORD;
! 781: else
! 782: total_bits = GET_MODE_BITSIZE (GET_MODE (value));
! 783:
! 784: /* Fetch successively less significant portions. */
! 785: if (GET_CODE (value) == CONST_INT)
! 786: part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value))
! 787: >> (bitsize - bitsdone - thissize))
! 788: & (((HOST_WIDE_INT) 1 << thissize) - 1));
! 789: else
! 790: /* The args are chosen so that the last part includes the
! 791: lsb. Give extract_bit_field the value it needs (with
! 792: endianness compensation) to fetch the piece we want. */
! 793: part = extract_fixed_bit_field (word_mode, value, 0, thissize,
! 794: total_bits - bitsize + bitsdone,
! 795: NULL_RTX, 1, align);
! 796: }
1.1.1.6 root 797: else
1.1.1.8 ! root 798: {
! 799: /* Fetch successively more significant portions. */
! 800: if (GET_CODE (value) == CONST_INT)
! 801: part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value))
! 802: >> bitsdone)
! 803: & (((HOST_WIDE_INT) 1 << thissize) - 1));
! 804: else
! 805: part = extract_fixed_bit_field (word_mode, value, 0, thissize,
! 806: bitsdone, NULL_RTX, 1, align);
! 807: }
1.1 root 808:
1.1.1.6 root 809: /* If OP0 is a register, then handle OFFSET here.
1.1.1.7 root 810:
811: When handling multiword bitfields, extract_bit_field may pass
812: down a word_mode SUBREG of a larger REG for a bitfield that actually
813: crosses a word boundary. Thus, for a SUBREG, we must find
814: the current word starting from the base register. */
815: if (GET_CODE (op0) == SUBREG)
816: {
817: word = operand_subword_force (SUBREG_REG (op0),
818: SUBREG_WORD (op0) + offset,
819: GET_MODE (SUBREG_REG (op0)));
820: offset = 0;
821: }
822: else if (GET_CODE (op0) == REG)
1.1.1.6 root 823: {
1.1.1.7 root 824: word = operand_subword_force (op0, offset, GET_MODE (op0));
1.1.1.6 root 825: offset = 0;
826: }
827: else
828: word = op0;
1.1 root 829:
1.1.1.6 root 830: /* OFFSET is in UNITs, and UNIT is in bits.
831: store_fixed_bit_field wants offset in bytes. */
832: store_fixed_bit_field (word, offset * unit / BITS_PER_UNIT,
833: thissize, thispos, part, align);
834: bitsdone += thissize;
835: }
1.1 root 836: }
837:
838: /* Generate code to extract a byte-field from STR_RTX
839: containing BITSIZE bits, starting at BITNUM,
840: and put it in TARGET if possible (if TARGET is nonzero).
841: Regardless of TARGET, we return the rtx for where the value is placed.
842: It may be a QUEUED.
843:
844: STR_RTX is the structure containing the byte (a REG or MEM).
845: UNSIGNEDP is nonzero if this is an unsigned bit field.
846: MODE is the natural mode of the field value once extracted.
847: TMODE is the mode the caller would like the value to have;
848: but the value may be returned with type MODE instead.
849:
850: ALIGN is the alignment that STR_RTX is known to have, measured in bytes.
851: TOTAL_SIZE is the size in bytes of the containing structure,
852: or -1 if varying.
853:
854: If a TARGET is specified and we can store in it at no extra cost,
855: we do so, and return TARGET.
856: Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred
857: if they are equally easy. */
858:
859: rtx
860: extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
861: target, mode, tmode, align, total_size)
862: rtx str_rtx;
863: register int bitsize;
864: int bitnum;
865: int unsignedp;
866: rtx target;
867: enum machine_mode mode, tmode;
868: int align;
869: int total_size;
870: {
871: int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
872: register int offset = bitnum / unit;
873: register int bitpos = bitnum % unit;
874: register rtx op0 = str_rtx;
875: rtx spec_target = target;
876: rtx spec_target_subreg = 0;
877:
878: if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
879: abort ();
880:
881: /* Discount the part of the structure before the desired byte.
882: We need to know how many bytes are safe to reference after it. */
883: if (total_size >= 0)
884: total_size -= (bitpos / BIGGEST_ALIGNMENT
885: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
886:
887: if (tmode == VOIDmode)
888: tmode = mode;
889: while (GET_CODE (op0) == SUBREG)
890: {
1.1.1.8 ! root 891: int outer_size = GET_MODE_BITSIZE (GET_MODE (op0));
! 892: int inner_size = GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)));
! 893:
1.1 root 894: offset += SUBREG_WORD (op0);
1.1.1.8 ! root 895:
! 896: if (BYTES_BIG_ENDIAN && (outer_size < inner_size))
! 897: {
! 898: bitpos += inner_size - outer_size;
! 899: if (bitpos > unit)
! 900: {
! 901: offset += (bitpos / unit);
! 902: bitpos %= unit;
! 903: }
! 904: }
! 905:
1.1 root 906: op0 = SUBREG_REG (op0);
907: }
1.1.1.8 ! root 908:
! 909: /* ??? We currently assume TARGET is at least as big as BITSIZE.
! 910: If that's wrong, the solution is to test for it and set TARGET to 0
! 911: if needed. */
1.1 root 912:
913: /* If OP0 is a register, BITPOS must count within a word.
914: But as we have it, it counts within whatever size OP0 now has.
915: On a bigendian machine, these are not the same, so convert. */
1.1.1.8 ! root 916: if (BYTES_BIG_ENDIAN &&
! 917: GET_CODE (op0) != MEM
! 918: && unit > GET_MODE_BITSIZE (GET_MODE (op0)))
1.1 root 919: bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0));
920:
921: /* Extracting a full-word or multi-word value
1.1.1.6 root 922: from a structure in a register or aligned memory.
1.1 root 923: This can be done with just SUBREG.
924: So too extracting a subword value in
925: the least significant part of the register. */
926:
1.1.1.6 root 927: if ((GET_CODE (op0) == REG
928: || (GET_CODE (op0) == MEM
929: && (! SLOW_UNALIGNED_ACCESS
930: || (offset * BITS_PER_UNIT % bitsize == 0
931: && align * BITS_PER_UNIT % bitsize == 0))))
1.1 root 932: && ((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
933: && bitpos % BITS_PER_WORD == 0)
934: || (mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) != BLKmode
1.1.1.8 ! root 935: && (BYTES_BIG_ENDIAN
! 936: ? bitpos + bitsize == BITS_PER_WORD
! 937: : bitpos == 0))))
1.1 root 938: {
939: enum machine_mode mode1
940: = mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0);
941:
942: if (mode1 != GET_MODE (op0))
1.1.1.6 root 943: {
944: if (GET_CODE (op0) == REG)
945: op0 = gen_rtx (SUBREG, mode1, op0, offset);
946: else
947: op0 = change_address (op0, mode1,
948: plus_constant (XEXP (op0, 0), offset));
949: }
1.1 root 950: if (mode1 != mode)
951: return convert_to_mode (tmode, op0, unsignedp);
952: return op0;
953: }
954:
955: /* Handle fields bigger than a word. */
956:
957: if (bitsize > BITS_PER_WORD)
958: {
959: /* Here we transfer the words of the field
960: in the order least significant first.
961: This is because the most significant word is the one which may
962: be less than full. */
963:
964: int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
965: int i;
966:
967: if (target == 0 || GET_CODE (target) != REG)
968: target = gen_reg_rtx (mode);
969:
970: for (i = 0; i < nwords; i++)
971: {
972: /* If I is 0, use the low-order word in both field and target;
973: if I is 1, use the next to lowest word; and so on. */
1.1.1.8 ! root 974: /* Word number in TARGET to use. */
! 975: int wordnum = (WORDS_BIG_ENDIAN
! 976: ? GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD - i - 1
! 977: : i);
! 978: /* Offset from start of field in OP0. */
1.1 root 979: int bit_offset = (WORDS_BIG_ENDIAN
980: ? MAX (0, bitsize - (i + 1) * BITS_PER_WORD)
981: : i * BITS_PER_WORD);
982: rtx target_part = operand_subword (target, wordnum, 1, VOIDmode);
983: rtx result_part
984: = extract_bit_field (op0, MIN (BITS_PER_WORD,
985: bitsize - i * BITS_PER_WORD),
986: bitnum + bit_offset,
987: 1, target_part, mode, word_mode,
988: align, total_size);
989:
990: if (target_part == 0)
991: abort ();
992:
993: if (result_part != target_part)
994: emit_move_insn (target_part, result_part);
995: }
996:
1.1.1.7 root 997: if (unsignedp)
1.1.1.8 ! root 998: {
! 999: /* Unless we've filled TARGET, the upper regs in a multi-reg value
! 1000: need to be zero'd out. */
! 1001: if (GET_MODE_SIZE (GET_MODE (target)) > nwords * UNITS_PER_WORD)
! 1002: {
! 1003: int i,total_words;
! 1004:
! 1005: total_words = GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD;
! 1006: for (i = nwords; i < total_words; i++)
! 1007: {
! 1008: int wordnum = WORDS_BIG_ENDIAN ? total_words - i - 1 : i;
! 1009: rtx target_part = operand_subword (target, wordnum, 1, VOIDmode);
! 1010: emit_move_insn (target_part, const0_rtx);
! 1011: }
! 1012: }
! 1013: return target;
! 1014: }
! 1015:
1.1.1.7 root 1016: /* Signed bit field: sign-extend with two arithmetic shifts. */
1017: target = expand_shift (LSHIFT_EXPR, mode, target,
1018: build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
1019: NULL_RTX, 0);
1020: return expand_shift (RSHIFT_EXPR, mode, target,
1021: build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
1022: NULL_RTX, 0);
1.1 root 1023: }
1024:
1025: /* From here on we know the desired field is smaller than a word
1026: so we can assume it is an integer. So we can safely extract it as one
1027: size of integer, if necessary, and then truncate or extend
1028: to the size that is wanted. */
1029:
1030: /* OFFSET is the number of words or bytes (UNIT says which)
1031: from STR_RTX to the first word or byte containing part of the field. */
1032:
1033: if (GET_CODE (op0) == REG)
1034: {
1035: if (offset != 0
1036: || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
1037: op0 = gen_rtx (SUBREG, TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
1038: op0, offset);
1039: offset = 0;
1040: }
1041: else
1042: {
1043: op0 = protect_from_queue (str_rtx, 1);
1044: }
1045:
1046: /* Now OFFSET is nonzero only for memory operands. */
1047:
1048: if (unsignedp)
1049: {
1050: #ifdef HAVE_extzv
1051: if (HAVE_extzv
1052: && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0])
1.1.1.7 root 1053: >= bitsize)
1054: && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
1055: && (bitsize + bitpos
1056: > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]))))
1.1 root 1057: {
1058: int xbitpos = bitpos, xoffset = offset;
1059: rtx bitsize_rtx, bitpos_rtx;
1060: rtx last = get_last_insn();
1061: rtx xop0 = op0;
1062: rtx xtarget = target;
1063: rtx xspec_target = spec_target;
1064: rtx xspec_target_subreg = spec_target_subreg;
1065: rtx pat;
1066: enum machine_mode maxmode
1067: = insn_operand_mode[(int) CODE_FOR_extzv][0];
1068:
1069: if (GET_CODE (xop0) == MEM)
1070: {
1071: int save_volatile_ok = volatile_ok;
1072: volatile_ok = 1;
1073:
1074: /* Is the memory operand acceptable? */
1075: if (flag_force_mem
1076: || ! ((*insn_operand_predicate[(int) CODE_FOR_extzv][1])
1077: (xop0, GET_MODE (xop0))))
1078: {
1079: /* No, load into a reg and extract from there. */
1080: enum machine_mode bestmode;
1081:
1082: /* Get the mode to use for inserting into this field. If
1083: OP0 is BLKmode, get the smallest mode consistent with the
1084: alignment. If OP0 is a non-BLKmode object that is no
1085: wider than MAXMODE, use its mode. Otherwise, use the
1086: smallest mode containing the field. */
1087:
1088: if (GET_MODE (xop0) == BLKmode
1089: || (GET_MODE_SIZE (GET_MODE (op0))
1090: > GET_MODE_SIZE (maxmode)))
1091: bestmode = get_best_mode (bitsize, bitnum,
1092: align * BITS_PER_UNIT, maxmode,
1.1.1.3 root 1093: MEM_VOLATILE_P (xop0));
1.1 root 1094: else
1095: bestmode = GET_MODE (xop0);
1096:
1.1.1.6 root 1097: if (bestmode == VOIDmode
1.1.1.8 ! root 1098: || (SLOW_UNALIGNED_ACCESS && GET_MODE_SIZE (bestmode) > align))
1.1 root 1099: goto extzv_loses;
1100:
1101: /* Compute offset as multiple of this unit,
1102: counting in bytes. */
1103: unit = GET_MODE_BITSIZE (bestmode);
1104: xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
1105: xbitpos = bitnum % unit;
1106: xop0 = change_address (xop0, bestmode,
1107: plus_constant (XEXP (xop0, 0),
1108: xoffset));
1109: /* Fetch it to a register in that size. */
1110: xop0 = force_reg (bestmode, xop0);
1111:
1112: /* XBITPOS counts within UNIT, which is what is expected. */
1113: }
1114: else
1115: /* Get ref to first byte containing part of the field. */
1116: xop0 = change_address (xop0, byte_mode,
1117: plus_constant (XEXP (xop0, 0), xoffset));
1118:
1119: volatile_ok = save_volatile_ok;
1120: }
1121:
1122: /* If op0 is a register, we need it in MAXMODE (which is usually
1123: SImode). to make it acceptable to the format of extzv. */
1124: if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode)
1125: abort ();
1126: if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
1127: xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
1128:
1129: /* On big-endian machines, we count bits from the most significant.
1130: If the bit field insn does not, we must invert. */
1.1.1.8 ! root 1131: if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
! 1132: xbitpos = unit - bitsize - xbitpos;
! 1133:
1.1 root 1134: /* Now convert from counting within UNIT to counting in MAXMODE. */
1.1.1.8 ! root 1135: if (BITS_BIG_ENDIAN && GET_CODE (xop0) != MEM)
1.1 root 1136: xbitpos += GET_MODE_BITSIZE (maxmode) - unit;
1.1.1.8 ! root 1137:
1.1 root 1138: unit = GET_MODE_BITSIZE (maxmode);
1139:
1140: if (xtarget == 0
1141: || (flag_force_mem && GET_CODE (xtarget) == MEM))
1142: xtarget = xspec_target = gen_reg_rtx (tmode);
1143:
1144: if (GET_MODE (xtarget) != maxmode)
1145: {
1146: if (GET_CODE (xtarget) == REG)
1.1.1.3 root 1147: {
1148: int wider = (GET_MODE_SIZE (maxmode)
1149: > GET_MODE_SIZE (GET_MODE (xtarget)));
1150: xtarget = gen_lowpart (maxmode, xtarget);
1151: if (wider)
1152: xspec_target_subreg = xtarget;
1153: }
1.1 root 1154: else
1155: xtarget = gen_reg_rtx (maxmode);
1156: }
1157:
1158: /* If this machine's extzv insists on a register target,
1159: make sure we have one. */
1160: if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0])
1161: (xtarget, maxmode)))
1162: xtarget = gen_reg_rtx (maxmode);
1163:
1.1.1.4 root 1164: bitsize_rtx = GEN_INT (bitsize);
1165: bitpos_rtx = GEN_INT (xbitpos);
1.1 root 1166:
1167: pat = gen_extzv (protect_from_queue (xtarget, 1),
1168: xop0, bitsize_rtx, bitpos_rtx);
1169: if (pat)
1170: {
1171: emit_insn (pat);
1172: target = xtarget;
1173: spec_target = xspec_target;
1174: spec_target_subreg = xspec_target_subreg;
1175: }
1176: else
1177: {
1178: delete_insns_since (last);
1179: target = extract_fixed_bit_field (tmode, op0, offset, bitsize,
1180: bitpos, target, 1, align);
1181: }
1182: }
1183: else
1184: extzv_loses:
1185: #endif
1186: target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
1187: target, 1, align);
1188: }
1189: else
1190: {
1191: #ifdef HAVE_extv
1192: if (HAVE_extv
1193: && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0])
1.1.1.7 root 1194: >= bitsize)
1195: && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
1196: && (bitsize + bitpos
1197: > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]))))
1.1 root 1198: {
1199: int xbitpos = bitpos, xoffset = offset;
1200: rtx bitsize_rtx, bitpos_rtx;
1201: rtx last = get_last_insn();
1202: rtx xop0 = op0, xtarget = target;
1203: rtx xspec_target = spec_target;
1204: rtx xspec_target_subreg = spec_target_subreg;
1205: rtx pat;
1206: enum machine_mode maxmode
1207: = insn_operand_mode[(int) CODE_FOR_extv][0];
1208:
1209: if (GET_CODE (xop0) == MEM)
1210: {
1211: /* Is the memory operand acceptable? */
1212: if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][1])
1213: (xop0, GET_MODE (xop0))))
1214: {
1215: /* No, load into a reg and extract from there. */
1216: enum machine_mode bestmode;
1217:
1218: /* Get the mode to use for inserting into this field. If
1219: OP0 is BLKmode, get the smallest mode consistent with the
1220: alignment. If OP0 is a non-BLKmode object that is no
1221: wider than MAXMODE, use its mode. Otherwise, use the
1222: smallest mode containing the field. */
1223:
1224: if (GET_MODE (xop0) == BLKmode
1225: || (GET_MODE_SIZE (GET_MODE (op0))
1226: > GET_MODE_SIZE (maxmode)))
1227: bestmode = get_best_mode (bitsize, bitnum,
1228: align * BITS_PER_UNIT, maxmode,
1.1.1.3 root 1229: MEM_VOLATILE_P (xop0));
1.1 root 1230: else
1231: bestmode = GET_MODE (xop0);
1232:
1.1.1.6 root 1233: if (bestmode == VOIDmode
1.1.1.8 ! root 1234: || (SLOW_UNALIGNED_ACCESS && GET_MODE_SIZE (bestmode) > align))
1.1 root 1235: goto extv_loses;
1236:
1237: /* Compute offset as multiple of this unit,
1238: counting in bytes. */
1239: unit = GET_MODE_BITSIZE (bestmode);
1240: xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
1241: xbitpos = bitnum % unit;
1242: xop0 = change_address (xop0, bestmode,
1243: plus_constant (XEXP (xop0, 0),
1244: xoffset));
1245: /* Fetch it to a register in that size. */
1246: xop0 = force_reg (bestmode, xop0);
1247:
1248: /* XBITPOS counts within UNIT, which is what is expected. */
1249: }
1250: else
1251: /* Get ref to first byte containing part of the field. */
1252: xop0 = change_address (xop0, byte_mode,
1253: plus_constant (XEXP (xop0, 0), xoffset));
1254: }
1255:
1256: /* If op0 is a register, we need it in MAXMODE (which is usually
1257: SImode) to make it acceptable to the format of extv. */
1258: if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode)
1259: abort ();
1260: if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
1261: xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
1262:
1263: /* On big-endian machines, we count bits from the most significant.
1264: If the bit field insn does not, we must invert. */
1.1.1.8 ! root 1265: if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
! 1266: xbitpos = unit - bitsize - xbitpos;
! 1267:
1.1 root 1268: /* XBITPOS counts within a size of UNIT.
1269: Adjust to count within a size of MAXMODE. */
1.1.1.8 ! root 1270: if (BITS_BIG_ENDIAN && GET_CODE (xop0) != MEM)
1.1 root 1271: xbitpos += (GET_MODE_BITSIZE (maxmode) - unit);
1.1.1.8 ! root 1272:
1.1 root 1273: unit = GET_MODE_BITSIZE (maxmode);
1274:
1275: if (xtarget == 0
1276: || (flag_force_mem && GET_CODE (xtarget) == MEM))
1277: xtarget = xspec_target = gen_reg_rtx (tmode);
1278:
1279: if (GET_MODE (xtarget) != maxmode)
1280: {
1281: if (GET_CODE (xtarget) == REG)
1.1.1.3 root 1282: {
1283: int wider = (GET_MODE_SIZE (maxmode)
1284: > GET_MODE_SIZE (GET_MODE (xtarget)));
1285: xtarget = gen_lowpart (maxmode, xtarget);
1286: if (wider)
1287: xspec_target_subreg = xtarget;
1288: }
1.1 root 1289: else
1290: xtarget = gen_reg_rtx (maxmode);
1291: }
1292:
1293: /* If this machine's extv insists on a register target,
1294: make sure we have one. */
1295: if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][0])
1296: (xtarget, maxmode)))
1297: xtarget = gen_reg_rtx (maxmode);
1298:
1.1.1.4 root 1299: bitsize_rtx = GEN_INT (bitsize);
1300: bitpos_rtx = GEN_INT (xbitpos);
1.1 root 1301:
1302: pat = gen_extv (protect_from_queue (xtarget, 1),
1303: xop0, bitsize_rtx, bitpos_rtx);
1304: if (pat)
1305: {
1306: emit_insn (pat);
1307: target = xtarget;
1308: spec_target = xspec_target;
1309: spec_target_subreg = xspec_target_subreg;
1310: }
1311: else
1312: {
1313: delete_insns_since (last);
1314: target = extract_fixed_bit_field (tmode, op0, offset, bitsize,
1315: bitpos, target, 0, align);
1316: }
1317: }
1318: else
1319: extv_loses:
1320: #endif
1321: target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
1322: target, 0, align);
1323: }
1324: if (target == spec_target)
1325: return target;
1326: if (target == spec_target_subreg)
1327: return spec_target;
1328: if (GET_MODE (target) != tmode && GET_MODE (target) != mode)
1329: {
1330: /* If the target mode is floating-point, first convert to the
1331: integer mode of that size and then access it as a floating-point
1332: value via a SUBREG. */
1333: if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
1334: {
1335: target = convert_to_mode (mode_for_size (GET_MODE_BITSIZE (tmode),
1336: MODE_INT, 0),
1337: target, unsignedp);
1338: if (GET_CODE (target) != REG)
1339: target = copy_to_reg (target);
1340: return gen_rtx (SUBREG, tmode, target, 0);
1341: }
1342: else
1343: return convert_to_mode (tmode, target, unsignedp);
1344: }
1345: return target;
1346: }
1347:
1348: /* Extract a bit field using shifts and boolean operations
1349: Returns an rtx to represent the value.
1350: OP0 addresses a register (word) or memory (byte).
1351: BITPOS says which bit within the word or byte the bit field starts in.
1352: OFFSET says how many bytes farther the bit field starts;
1353: it is 0 if OP0 is a register.
1354: BITSIZE says how many bits long the bit field is.
1355: (If OP0 is a register, it may be narrower than a full word,
1356: but BITPOS still counts within a full word,
1357: which is significant on bigendian machines.)
1358:
1359: UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value).
1360: If TARGET is nonzero, attempts to store the value there
1361: and return TARGET, but this is not guaranteed.
1362: If TARGET is not used, create a pseudo-reg of mode TMODE for the value.
1363:
1364: ALIGN is the alignment that STR_RTX is known to have, measured in bytes. */
1365:
1366: static rtx
1367: extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
1368: target, unsignedp, align)
1369: enum machine_mode tmode;
1370: register rtx op0, target;
1371: register int offset, bitsize, bitpos;
1372: int unsignedp;
1373: int align;
1374: {
1375: int total_bits = BITS_PER_WORD;
1376: enum machine_mode mode;
1377:
1378: if (GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
1379: {
1380: /* Special treatment for a bit field split across two registers. */
1381: if (bitsize + bitpos > BITS_PER_WORD)
1382: return extract_split_bit_field (op0, bitsize, bitpos,
1383: unsignedp, align);
1384: }
1385: else
1386: {
1387: /* Get the proper mode to use for this field. We want a mode that
1388: includes the entire field. If such a mode would be larger than
1389: a word, we won't be doing the extraction the normal way. */
1390:
1391: mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
1392: align * BITS_PER_UNIT, word_mode,
1393: GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
1394:
1395: if (mode == VOIDmode)
1396: /* The only way this should occur is if the field spans word
1397: boundaries. */
1398: return extract_split_bit_field (op0, bitsize,
1399: bitpos + offset * BITS_PER_UNIT,
1400: unsignedp, align);
1401:
1402: total_bits = GET_MODE_BITSIZE (mode);
1403:
1.1.1.5 root 1404: /* Make sure bitpos is valid for the chosen mode. Adjust BITPOS to
1405: be be in the range 0 to total_bits-1, and put any excess bytes in
1406: OFFSET. */
1407: if (bitpos >= total_bits)
1408: {
1409: offset += (bitpos / total_bits) * (total_bits / BITS_PER_UNIT);
1410: bitpos -= ((bitpos / total_bits) * (total_bits / BITS_PER_UNIT)
1411: * BITS_PER_UNIT);
1412: }
1413:
1.1 root 1414: /* Get ref to an aligned byte, halfword, or word containing the field.
1415: Adjust BITPOS to be position within a word,
1416: and OFFSET to be the offset of that word.
1417: Then alter OP0 to refer to that word. */
1418: bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT;
1419: offset -= (offset % (total_bits / BITS_PER_UNIT));
1420: op0 = change_address (op0, mode,
1421: plus_constant (XEXP (op0, 0), offset));
1422: }
1423:
1424: mode = GET_MODE (op0);
1425:
1.1.1.8 ! root 1426: if (BYTES_BIG_ENDIAN)
! 1427: {
! 1428: /* BITPOS is the distance between our msb and that of OP0.
! 1429: Convert it to the distance from the lsb. */
! 1430:
! 1431: bitpos = total_bits - bitsize - bitpos;
! 1432: }
1.1 root 1433:
1434: /* Now BITPOS is always the distance between the field's lsb and that of OP0.
1435: We have reduced the big-endian case to the little-endian case. */
1436:
1437: if (unsignedp)
1438: {
1439: if (bitpos)
1440: {
1441: /* If the field does not already start at the lsb,
1442: shift it so it does. */
1443: tree amount = build_int_2 (bitpos, 0);
1444: /* Maybe propagate the target for the shift. */
1445: /* But not if we will return it--could confuse integrate.c. */
1446: rtx subtarget = (target != 0 && GET_CODE (target) == REG
1447: && !REG_FUNCTION_VALUE_P (target)
1448: ? target : 0);
1449: if (tmode != mode) subtarget = 0;
1450: op0 = expand_shift (RSHIFT_EXPR, mode, op0, amount, subtarget, 1);
1451: }
1452: /* Convert the value to the desired mode. */
1453: if (mode != tmode)
1454: op0 = convert_to_mode (tmode, op0, 1);
1455:
1456: /* Unless the msb of the field used to be the msb when we shifted,
1457: mask out the upper bits. */
1458:
1459: if (GET_MODE_BITSIZE (mode) != bitpos + bitsize
1460: #if 0
1461: #ifdef SLOW_ZERO_EXTEND
1462: /* Always generate an `and' if
1463: we just zero-extended op0 and SLOW_ZERO_EXTEND, since it
1464: will combine fruitfully with the zero-extend. */
1465: || tmode != mode
1466: #endif
1467: #endif
1468: )
1469: return expand_binop (GET_MODE (op0), and_optab, op0,
1470: mask_rtx (GET_MODE (op0), 0, bitsize, 0),
1471: target, 1, OPTAB_LIB_WIDEN);
1472: return op0;
1473: }
1474:
1475: /* To extract a signed bit-field, first shift its msb to the msb of the word,
1476: then arithmetic-shift its lsb to the lsb of the word. */
1477: op0 = force_reg (mode, op0);
1478: if (mode != tmode)
1479: target = 0;
1480:
1481: /* Find the narrowest integer mode that contains the field. */
1482:
1483: for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
1484: mode = GET_MODE_WIDER_MODE (mode))
1485: if (GET_MODE_BITSIZE (mode) >= bitsize + bitpos)
1486: {
1487: op0 = convert_to_mode (mode, op0, 0);
1488: break;
1489: }
1490:
1491: if (GET_MODE_BITSIZE (mode) != (bitsize + bitpos))
1492: {
1493: tree amount = build_int_2 (GET_MODE_BITSIZE (mode) - (bitsize + bitpos), 0);
1494: /* Maybe propagate the target for the shift. */
1495: /* But not if we will return the result--could confuse integrate.c. */
1496: rtx subtarget = (target != 0 && GET_CODE (target) == REG
1497: && ! REG_FUNCTION_VALUE_P (target)
1498: ? target : 0);
1499: op0 = expand_shift (LSHIFT_EXPR, mode, op0, amount, subtarget, 1);
1500: }
1501:
1502: return expand_shift (RSHIFT_EXPR, mode, op0,
1503: build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
1504: target, 0);
1505: }
1506:
1507: /* Return a constant integer (CONST_INT or CONST_DOUBLE) mask value
1508: of mode MODE with BITSIZE ones followed by BITPOS zeros, or the
1509: complement of that if COMPLEMENT. The mask is truncated if
1.1.1.8 ! root 1510: necessary to the width of mode MODE. The mask is zero-extended if
! 1511: BITSIZE+BITPOS is too small for MODE. */
1.1 root 1512:
1513: static rtx
1514: mask_rtx (mode, bitpos, bitsize, complement)
1515: enum machine_mode mode;
1516: int bitpos, bitsize, complement;
1517: {
1.1.1.4 root 1518: HOST_WIDE_INT masklow, maskhigh;
1.1 root 1519:
1.1.1.4 root 1520: if (bitpos < HOST_BITS_PER_WIDE_INT)
1521: masklow = (HOST_WIDE_INT) -1 << bitpos;
1.1 root 1522: else
1523: masklow = 0;
1524:
1.1.1.4 root 1525: if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT)
1526: masklow &= ((unsigned HOST_WIDE_INT) -1
1527: >> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1.1 root 1528:
1.1.1.4 root 1529: if (bitpos <= HOST_BITS_PER_WIDE_INT)
1.1 root 1530: maskhigh = -1;
1531: else
1.1.1.4 root 1532: maskhigh = (HOST_WIDE_INT) -1 << (bitpos - HOST_BITS_PER_WIDE_INT);
1.1 root 1533:
1.1.1.4 root 1534: if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT)
1535: maskhigh &= ((unsigned HOST_WIDE_INT) -1
1536: >> (2 * HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1.1 root 1537: else
1538: maskhigh = 0;
1539:
1540: if (complement)
1541: {
1542: maskhigh = ~maskhigh;
1543: masklow = ~masklow;
1544: }
1545:
1546: return immed_double_const (masklow, maskhigh, mode);
1547: }
1548:
1549: /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
1550: VALUE truncated to BITSIZE bits and then shifted left BITPOS bits. */
1551:
1552: static rtx
1553: lshift_value (mode, value, bitpos, bitsize)
1554: enum machine_mode mode;
1555: rtx value;
1556: int bitpos, bitsize;
1557: {
1.1.1.4 root 1558: unsigned HOST_WIDE_INT v = INTVAL (value);
1559: HOST_WIDE_INT low, high;
1.1 root 1560:
1.1.1.4 root 1561: if (bitsize < HOST_BITS_PER_WIDE_INT)
1562: v &= ~((HOST_WIDE_INT) -1 << bitsize);
1.1 root 1563:
1.1.1.4 root 1564: if (bitpos < HOST_BITS_PER_WIDE_INT)
1.1 root 1565: {
1566: low = v << bitpos;
1.1.1.4 root 1567: high = (bitpos > 0 ? (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) : 0);
1.1 root 1568: }
1569: else
1570: {
1571: low = 0;
1.1.1.4 root 1572: high = v << (bitpos - HOST_BITS_PER_WIDE_INT);
1.1 root 1573: }
1574:
1575: return immed_double_const (low, high, mode);
1576: }
1577:
1578: /* Extract a bit field that is split across two words
1579: and return an RTX for the result.
1580:
1581: OP0 is the REG, SUBREG or MEM rtx for the first of the two words.
1582: BITSIZE is the field width; BITPOS, position of its first bit, in the word.
1.1.1.6 root 1583: UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend.
1584:
1585: ALIGN is the known alignment of OP0, measured in bytes.
1586: This is also the size of the memory objects to be used. */
1.1 root 1587:
1588: static rtx
1589: extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
1590: rtx op0;
1591: int bitsize, bitpos, unsignedp, align;
1592: {
1.1.1.7 root 1593: int unit;
1.1.1.6 root 1594: int bitsdone = 0;
1595: rtx result;
1596: int first = 1;
1597:
1.1.1.7 root 1598: /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
1599: much at a time. */
1600: if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
1601: unit = BITS_PER_WORD;
1602: else
1603: unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD);
1604:
1.1.1.6 root 1605: while (bitsdone < bitsize)
1606: {
1607: int thissize;
1608: rtx part, word;
1609: int thispos;
1610: int offset;
1611:
1612: offset = (bitpos + bitsdone) / unit;
1613: thispos = (bitpos + bitsdone) % unit;
1614:
1615: /* THISSIZE must not overrun a word boundary. Otherwise,
1616: extract_fixed_bit_field will call us again, and we will mutually
1617: recurse forever. */
1618: thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
1619: thissize = MIN (thissize, unit - thispos);
1620:
1621: /* If OP0 is a register, then handle OFFSET here.
1.1.1.7 root 1622:
1623: When handling multiword bitfields, extract_bit_field may pass
1624: down a word_mode SUBREG of a larger REG for a bitfield that actually
1625: crosses a word boundary. Thus, for a SUBREG, we must find
1626: the current word starting from the base register. */
1627: if (GET_CODE (op0) == SUBREG)
1628: {
1629: word = operand_subword_force (SUBREG_REG (op0),
1630: SUBREG_WORD (op0) + offset,
1631: GET_MODE (SUBREG_REG (op0)));
1632: offset = 0;
1633: }
1634: else if (GET_CODE (op0) == REG)
1.1.1.6 root 1635: {
1636: word = operand_subword_force (op0, offset, GET_MODE (op0));
1637: offset = 0;
1638: }
1639: else
1640: word = op0;
1.1 root 1641:
1.1.1.6 root 1642: /* Extract the parts in bit-counting order,
1643: whose meaning is determined by BYTES_PER_UNIT.
1644: OFFSET is in UNITs, and UNIT is in bits.
1645: extract_fixed_bit_field wants offset in bytes. */
1646: part = extract_fixed_bit_field (word_mode, word,
1647: offset * unit / BITS_PER_UNIT,
1648: thissize, thispos, 0, 1, align);
1649: bitsdone += thissize;
1.1 root 1650:
1.1.1.6 root 1651: /* Shift this part into place for the result. */
1.1.1.8 ! root 1652: if (BYTES_BIG_ENDIAN)
! 1653: {
! 1654: if (bitsize != bitsdone)
! 1655: part = expand_shift (LSHIFT_EXPR, word_mode, part,
! 1656: build_int_2 (bitsize - bitsdone, 0), 0, 1);
! 1657: }
! 1658: else
! 1659: {
! 1660: if (bitsdone != thissize)
! 1661: part = expand_shift (LSHIFT_EXPR, word_mode, part,
! 1662: build_int_2 (bitsdone - thissize, 0), 0, 1);
! 1663: }
1.1 root 1664:
1.1.1.6 root 1665: if (first)
1666: result = part;
1667: else
1668: /* Combine the parts with bitwise or. This works
1669: because we extracted each part as an unsigned bit field. */
1670: result = expand_binop (word_mode, ior_optab, part, result, NULL_RTX, 1,
1671: OPTAB_LIB_WIDEN);
1672:
1673: first = 0;
1674: }
1.1 root 1675:
1676: /* Unsigned bit field: we are done. */
1677: if (unsignedp)
1678: return result;
1679: /* Signed bit field: sign-extend with two arithmetic shifts. */
1680: result = expand_shift (LSHIFT_EXPR, word_mode, result,
1.1.1.4 root 1681: build_int_2 (BITS_PER_WORD - bitsize, 0),
1682: NULL_RTX, 0);
1.1 root 1683: return expand_shift (RSHIFT_EXPR, word_mode, result,
1.1.1.4 root 1684: build_int_2 (BITS_PER_WORD - bitsize, 0), NULL_RTX, 0);
1.1 root 1685: }
1686:
1687: /* Add INC into TARGET. */
1688:
1689: void
1690: expand_inc (target, inc)
1691: rtx target, inc;
1692: {
1693: rtx value = expand_binop (GET_MODE (target), add_optab,
1694: target, inc,
1695: target, 0, OPTAB_LIB_WIDEN);
1696: if (value != target)
1697: emit_move_insn (target, value);
1698: }
1699:
1.1.1.2 root 1700: /* Subtract DEC from TARGET. */
1.1 root 1701:
1702: void
1703: expand_dec (target, dec)
1704: rtx target, dec;
1705: {
1706: rtx value = expand_binop (GET_MODE (target), sub_optab,
1707: target, dec,
1708: target, 0, OPTAB_LIB_WIDEN);
1709: if (value != target)
1710: emit_move_insn (target, value);
1711: }
1712:
1713: /* Output a shift instruction for expression code CODE,
1714: with SHIFTED being the rtx for the value to shift,
1715: and AMOUNT the tree for the amount to shift by.
1716: Store the result in the rtx TARGET, if that is convenient.
1717: If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
1718: Return the rtx for where the value is. */
1719:
1720: rtx
1721: expand_shift (code, mode, shifted, amount, target, unsignedp)
1722: enum tree_code code;
1723: register enum machine_mode mode;
1724: rtx shifted;
1725: tree amount;
1726: register rtx target;
1727: int unsignedp;
1728: {
1729: register rtx op1, temp = 0;
1730: register int left = (code == LSHIFT_EXPR || code == LROTATE_EXPR);
1731: register int rotate = (code == LROTATE_EXPR || code == RROTATE_EXPR);
1732: int try;
1733:
1734: /* Previously detected shift-counts computed by NEGATE_EXPR
1735: and shifted in the other direction; but that does not work
1736: on all machines. */
1737:
1.1.1.4 root 1738: op1 = expand_expr (amount, NULL_RTX, VOIDmode, 0);
1.1 root 1739:
1.1.1.8 ! root 1740: #ifdef SHIFT_COUNT_TRUNCATED
1.1.1.7 root 1741: if (SHIFT_COUNT_TRUNCATED
1742: && GET_CODE (op1) == CONST_INT
1743: && (unsigned HOST_WIDE_INT) INTVAL (op1) >= GET_MODE_BITSIZE (mode))
1744: op1 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (op1)
1745: % GET_MODE_BITSIZE (mode));
1746: #endif
1747:
1.1 root 1748: if (op1 == const0_rtx)
1749: return shifted;
1750:
1751: for (try = 0; temp == 0 && try < 3; try++)
1752: {
1753: enum optab_methods methods;
1754:
1755: if (try == 0)
1756: methods = OPTAB_DIRECT;
1757: else if (try == 1)
1758: methods = OPTAB_WIDEN;
1759: else
1760: methods = OPTAB_LIB_WIDEN;
1761:
1762: if (rotate)
1763: {
1764: /* Widening does not work for rotation. */
1765: if (methods == OPTAB_WIDEN)
1766: continue;
1767: else if (methods == OPTAB_LIB_WIDEN)
1.1.1.5 root 1768: {
1.1.1.7 root 1769: /* If we have been unable to open-code this by a rotation,
1.1.1.5 root 1770: do it as the IOR of two shifts. I.e., to rotate A
1771: by N bits, compute (A << N) | ((unsigned) A >> (C - N))
1772: where C is the bitsize of A.
1773:
1774: It is theoretically possible that the target machine might
1775: not be able to perform either shift and hence we would
1776: be making two libcalls rather than just the one for the
1777: shift (similarly if IOR could not be done). We will allow
1778: this extremely unlikely lossage to avoid complicating the
1779: code below. */
1780:
1.1.1.7 root 1781: rtx subtarget = target == shifted ? 0 : target;
1782: rtx temp1;
1783: tree type = TREE_TYPE (amount);
1784: tree new_amount = make_tree (type, op1);
1785: tree other_amount
1786: = fold (build (MINUS_EXPR, type,
1787: convert (type,
1788: build_int_2 (GET_MODE_BITSIZE (mode),
1789: 0)),
1790: amount));
1791:
1792: shifted = force_reg (mode, shifted);
1793:
1794: temp = expand_shift (left ? LSHIFT_EXPR : RSHIFT_EXPR,
1795: mode, shifted, new_amount, subtarget, 1);
1796: temp1 = expand_shift (left ? RSHIFT_EXPR : LSHIFT_EXPR,
1797: mode, shifted, other_amount, 0, 1);
1798: return expand_binop (mode, ior_optab, temp, temp1, target,
1799: unsignedp, methods);
1.1.1.5 root 1800: }
1.1 root 1801:
1802: temp = expand_binop (mode,
1803: left ? rotl_optab : rotr_optab,
1804: shifted, op1, target, unsignedp, methods);
1.1.1.5 root 1805:
1806: /* If we don't have the rotate, but we are rotating by a constant
1807: that is in range, try a rotate in the opposite direction. */
1808:
1809: if (temp == 0 && GET_CODE (op1) == CONST_INT
1810: && INTVAL (op1) > 0 && INTVAL (op1) < GET_MODE_BITSIZE (mode))
1811: temp = expand_binop (mode,
1812: left ? rotr_optab : rotl_optab,
1813: shifted,
1814: GEN_INT (GET_MODE_BITSIZE (mode)
1815: - INTVAL (op1)),
1816: target, unsignedp, methods);
1.1 root 1817: }
1818: else if (unsignedp)
1.1.1.7 root 1819: temp = expand_binop (mode,
1820: left ? ashl_optab : lshr_optab,
1821: shifted, op1, target, unsignedp, methods);
1.1 root 1822:
1823: /* Do arithmetic shifts.
1824: Also, if we are going to widen the operand, we can just as well
1825: use an arithmetic right-shift instead of a logical one. */
1826: if (temp == 0 && ! rotate
1827: && (! unsignedp || (! left && methods == OPTAB_WIDEN)))
1828: {
1829: enum optab_methods methods1 = methods;
1830:
1831: /* If trying to widen a log shift to an arithmetic shift,
1832: don't accept an arithmetic shift of the same size. */
1833: if (unsignedp)
1834: methods1 = OPTAB_MUST_WIDEN;
1835:
1836: /* Arithmetic shift */
1837:
1838: temp = expand_binop (mode,
1839: left ? ashl_optab : ashr_optab,
1840: shifted, op1, target, unsignedp, methods1);
1841: }
1842:
1.1.1.7 root 1843: /* We used to try extzv here for logical right shifts, but that was
1844: only useful for one machine, the VAX, and caused poor code
1845: generation there for lshrdi3, so the code was deleted and a
1846: define_expand for lshrsi3 was added to vax.md. */
1.1 root 1847: }
1848:
1849: if (temp == 0)
1850: abort ();
1851: return temp;
1852: }
1853:
1.1.1.5 root 1854: enum alg_code { alg_zero, alg_m, alg_shift,
1855: alg_add_t_m2, alg_sub_t_m2,
1856: alg_add_factor, alg_sub_factor,
1857: alg_add_t2_m, alg_sub_t2_m,
1858: alg_add, alg_subtract, alg_factor, alg_shiftop };
1.1 root 1859:
1860: /* This structure records a sequence of operations.
1861: `ops' is the number of operations recorded.
1862: `cost' is their total cost.
1863: The operations are stored in `op' and the corresponding
1.1.1.5 root 1864: logarithms of the integer coefficients in `log'.
1865:
1.1 root 1866: These are the operations:
1.1.1.5 root 1867: alg_zero total := 0;
1868: alg_m total := multiplicand;
1869: alg_shift total := total * coeff
1870: alg_add_t_m2 total := total + multiplicand * coeff;
1871: alg_sub_t_m2 total := total - multiplicand * coeff;
1872: alg_add_factor total := total * coeff + total;
1873: alg_sub_factor total := total * coeff - total;
1874: alg_add_t2_m total := total * coeff + multiplicand;
1875: alg_sub_t2_m total := total * coeff - multiplicand;
1.1 root 1876:
1.1.1.5 root 1877: The first operand must be either alg_zero or alg_m. */
1.1 root 1878:
1879: struct algorithm
1880: {
1.1.1.5 root 1881: short cost;
1882: short ops;
1883: /* The size of the OP and LOG fields are not directly related to the
1884: word size, but the worst-case algorithms will be if we have few
1885: consecutive ones or zeros, i.e., a multiplicand like 10101010101...
1886: In that case we will generate shift-by-2, add, shift-by-2, add,...,
1887: in total wordsize operations. */
1.1 root 1888: enum alg_code op[MAX_BITS_PER_WORD];
1.1.1.5 root 1889: char log[MAX_BITS_PER_WORD];
1.1 root 1890: };
1891:
1892: /* Compute and return the best algorithm for multiplying by T.
1.1.1.5 root 1893: The algorithm must cost less than cost_limit
1894: If retval.cost >= COST_LIMIT, no algorithm was found and all
1895: other field of the returned struct are undefined. */
1.1 root 1896:
1.1.1.6 root 1897: static void
1898: synth_mult (alg_out, t, cost_limit)
1899: struct algorithm *alg_out;
1.1.1.4 root 1900: unsigned HOST_WIDE_INT t;
1.1.1.5 root 1901: int cost_limit;
1.1 root 1902: {
1.1.1.5 root 1903: int m;
1.1.1.7 root 1904: struct algorithm *alg_in, *best_alg;
1.1 root 1905: unsigned int cost;
1.1.1.5 root 1906: unsigned HOST_WIDE_INT q;
1.1 root 1907:
1.1.1.5 root 1908: /* Indicate that no algorithm is yet found. If no algorithm
1909: is found, this value will be returned and indicate failure. */
1.1.1.6 root 1910: alg_out->cost = cost_limit;
1.1 root 1911:
1.1.1.5 root 1912: if (cost_limit <= 0)
1.1.1.6 root 1913: return;
1.1 root 1914:
1.1.1.5 root 1915: /* t == 1 can be done in zero cost. */
1916: if (t == 1)
1.1 root 1917: {
1.1.1.6 root 1918: alg_out->ops = 1;
1919: alg_out->cost = 0;
1920: alg_out->op[0] = alg_m;
1921: return;
1.1 root 1922: }
1923:
1.1.1.5 root 1924: /* t == 0 sometimes has a cost. If it does and it exceeds our limit,
1925: fail now. */
1.1.1.6 root 1926: if (t == 0)
1.1 root 1927: {
1.1.1.5 root 1928: if (zero_cost >= cost_limit)
1.1.1.6 root 1929: return;
1.1.1.5 root 1930: else
1.1 root 1931: {
1.1.1.6 root 1932: alg_out->ops = 1;
1933: alg_out->cost = zero_cost;
1934: alg_out->op[0] = alg_zero;
1935: return;
1.1 root 1936: }
1.1.1.5 root 1937: }
1.1 root 1938:
1.1.1.7 root 1939: /* We'll be needing a couple extra algorithm structures now. */
1940:
1941: alg_in = (struct algorithm *)alloca (sizeof (struct algorithm));
1942: best_alg = (struct algorithm *)alloca (sizeof (struct algorithm));
1943:
1.1.1.5 root 1944: /* If we have a group of zero bits at the low-order part of T, try
1945: multiplying by the remaining bits and then doing a shift. */
1.1 root 1946:
1.1.1.5 root 1947: if ((t & 1) == 0)
1948: {
1949: m = floor_log2 (t & -t); /* m = number of low zero bits */
1950: q = t >> m;
1951: cost = shift_cost[m];
1.1.1.6 root 1952: synth_mult (alg_in, q, cost_limit - cost);
1953:
1954: cost += alg_in->cost;
1.1.1.5 root 1955: if (cost < cost_limit)
1956: {
1.1.1.6 root 1957: struct algorithm *x;
1958: x = alg_in, alg_in = best_alg, best_alg = x;
1959: best_alg->log[best_alg->ops] = m;
1960: best_alg->op[best_alg->ops] = alg_shift;
1961: cost_limit = cost;
1.1 root 1962: }
1963: }
1964:
1.1.1.5 root 1965: /* If we have an odd number, add or subtract one. */
1966: if ((t & 1) != 0)
1.1.1.6 root 1967: {
1968: unsigned HOST_WIDE_INT w;
1.1 root 1969:
1.1.1.6 root 1970: for (w = 1; (w & t) != 0; w <<= 1)
1971: ;
1972: if (w > 2
1973: /* Reject the case where t is 3.
1974: Thus we prefer addition in that case. */
1975: && t != 3)
1976: {
1977: /* T ends with ...111. Multiply by (T + 1) and subtract 1. */
1.1 root 1978:
1.1.1.6 root 1979: cost = add_cost;
1980: synth_mult (alg_in, t + 1, cost_limit - cost);
1.1 root 1981:
1.1.1.6 root 1982: cost += alg_in->cost;
1983: if (cost < cost_limit)
1984: {
1985: struct algorithm *x;
1986: x = alg_in, alg_in = best_alg, best_alg = x;
1987: best_alg->log[best_alg->ops] = 0;
1988: best_alg->op[best_alg->ops] = alg_sub_t_m2;
1989: cost_limit = cost;
1990: }
1991: }
1992: else
1993: {
1994: /* T ends with ...01 or ...011. Multiply by (T - 1) and add 1. */
1.1 root 1995:
1.1.1.6 root 1996: cost = add_cost;
1997: synth_mult (alg_in, t - 1, cost_limit - cost);
1.1.1.5 root 1998:
1.1.1.6 root 1999: cost += alg_in->cost;
2000: if (cost < cost_limit)
2001: {
2002: struct algorithm *x;
2003: x = alg_in, alg_in = best_alg, best_alg = x;
2004: best_alg->log[best_alg->ops] = 0;
2005: best_alg->op[best_alg->ops] = alg_add_t_m2;
2006: cost_limit = cost;
2007: }
2008: }
2009: }
1.1 root 2010:
1.1.1.5 root 2011: /* Look for factors of t of the form
2012: t = q(2**m +- 1), 2 <= m <= floor(log2(t - 1)).
2013: If we find such a factor, we can multiply by t using an algorithm that
2014: multiplies by q, shift the result by m and add/subtract it to itself.
1.1 root 2015:
1.1.1.5 root 2016: We search for large factors first and loop down, even if large factors
2017: are less probable than small; if we find a large factor we will find a
2018: good sequence quickly, and therefore be able to prune (by decreasing
2019: COST_LIMIT) the search. */
1.1 root 2020:
1.1.1.5 root 2021: for (m = floor_log2 (t - 1); m >= 2; m--)
2022: {
2023: unsigned HOST_WIDE_INT d;
1.1 root 2024:
1.1.1.5 root 2025: d = ((unsigned HOST_WIDE_INT) 1 << m) + 1;
2026: if (t % d == 0 && t > d)
2027: {
2028: cost = MIN (shiftadd_cost[m], add_cost + shift_cost[m]);
1.1.1.6 root 2029: synth_mult (alg_in, t / d, cost_limit - cost);
1.1 root 2030:
1.1.1.5 root 2031: cost += alg_in->cost;
1.1.1.6 root 2032: if (cost < cost_limit)
1.1.1.5 root 2033: {
2034: struct algorithm *x;
2035: x = alg_in, alg_in = best_alg, best_alg = x;
2036: best_alg->log[best_alg->ops] = m;
1.1.1.6 root 2037: best_alg->op[best_alg->ops] = alg_add_factor;
2038: cost_limit = cost;
1.1.1.5 root 2039: }
1.1.1.6 root 2040: /* Other factors will have been taken care of in the recursion. */
2041: break;
1.1.1.5 root 2042: }
1.1 root 2043:
1.1.1.5 root 2044: d = ((unsigned HOST_WIDE_INT) 1 << m) - 1;
2045: if (t % d == 0 && t > d)
2046: {
2047: cost = MIN (shiftsub_cost[m], add_cost + shift_cost[m]);
1.1.1.6 root 2048: synth_mult (alg_in, t / d, cost_limit - cost);
1.1 root 2049:
1.1.1.5 root 2050: cost += alg_in->cost;
1.1.1.6 root 2051: if (cost < cost_limit)
1.1.1.5 root 2052: {
2053: struct algorithm *x;
2054: x = alg_in, alg_in = best_alg, best_alg = x;
2055: best_alg->log[best_alg->ops] = m;
1.1.1.6 root 2056: best_alg->op[best_alg->ops] = alg_sub_factor;
2057: cost_limit = cost;
1.1.1.5 root 2058: }
1.1.1.6 root 2059: break;
1.1.1.5 root 2060: }
2061: }
1.1 root 2062:
1.1.1.5 root 2063: /* Try shift-and-add (load effective address) instructions,
2064: i.e. do a*3, a*5, a*9. */
2065: if ((t & 1) != 0)
2066: {
2067: q = t - 1;
2068: q = q & -q;
2069: m = exact_log2 (q);
2070: if (m >= 0)
2071: {
2072: cost = shiftadd_cost[m];
1.1.1.6 root 2073: synth_mult (alg_in, (t - 1) >> m, cost_limit - cost);
1.1.1.5 root 2074:
2075: cost += alg_in->cost;
1.1.1.6 root 2076: if (cost < cost_limit)
1.1.1.5 root 2077: {
2078: struct algorithm *x;
2079: x = alg_in, alg_in = best_alg, best_alg = x;
2080: best_alg->log[best_alg->ops] = m;
1.1.1.6 root 2081: best_alg->op[best_alg->ops] = alg_add_t2_m;
2082: cost_limit = cost;
1.1.1.5 root 2083: }
2084: }
1.1 root 2085:
1.1.1.5 root 2086: q = t + 1;
2087: q = q & -q;
2088: m = exact_log2 (q);
2089: if (m >= 0)
2090: {
2091: cost = shiftsub_cost[m];
1.1.1.6 root 2092: synth_mult (alg_in, (t + 1) >> m, cost_limit - cost);
1.1 root 2093:
1.1.1.5 root 2094: cost += alg_in->cost;
1.1.1.6 root 2095: if (cost < cost_limit)
1.1.1.5 root 2096: {
2097: struct algorithm *x;
2098: x = alg_in, alg_in = best_alg, best_alg = x;
2099: best_alg->log[best_alg->ops] = m;
1.1.1.6 root 2100: best_alg->op[best_alg->ops] = alg_sub_t2_m;
2101: cost_limit = cost;
1.1.1.5 root 2102: }
2103: }
2104: }
1.1 root 2105:
1.1.1.6 root 2106: /* If cost_limit has not decreased since we stored it in alg_out->cost,
2107: we have not found any algorithm. */
2108: if (cost_limit == alg_out->cost)
2109: return;
2110:
1.1.1.7 root 2111: /* If we are getting a too long sequence for `struct algorithm'
2112: to record, make this search fail. */
2113: if (best_alg->ops == MAX_BITS_PER_WORD)
2114: return;
2115:
1.1.1.6 root 2116: /* Copy the algorithm from temporary space to the space at alg_out.
2117: We avoid using structure assignment because the majority of
2118: best_alg is normally undefined, and this is a critical function. */
2119: alg_out->ops = best_alg->ops + 1;
2120: alg_out->cost = cost_limit;
1.1.1.7 root 2121: bcopy ((char *) best_alg->op, (char *) alg_out->op,
2122: alg_out->ops * sizeof *alg_out->op);
2123: bcopy ((char *) best_alg->log, (char *) alg_out->log,
2124: alg_out->ops * sizeof *alg_out->log);
1.1 root 2125: }
2126:
2127: /* Perform a multiplication and return an rtx for the result.
2128: MODE is mode of value; OP0 and OP1 are what to multiply (rtx's);
2129: TARGET is a suggestion for where to store the result (an rtx).
2130:
2131: We check specially for a constant integer as OP1.
2132: If you want this check for OP0 as well, then before calling
2133: you should swap the two operands if OP0 would be constant. */
2134:
2135: rtx
2136: expand_mult (mode, op0, op1, target, unsignedp)
2137: enum machine_mode mode;
2138: register rtx op0, op1, target;
2139: int unsignedp;
2140: {
2141: rtx const_op1 = op1;
2142:
1.1.1.7 root 2143: /* synth_mult does an `unsigned int' multiply. As long as the mode is
2144: less than or equal in size to `unsigned int' this doesn't matter.
2145: If the mode is larger than `unsigned int', then synth_mult works only
2146: if the constant value exactly fits in an `unsigned int' without any
2147: truncation. This means that multiplying by negative values does
2148: not work; results are off by 2^32 on a 32 bit machine. */
2149:
1.1 root 2150: /* If we are multiplying in DImode, it may still be a win
2151: to try to work with shifts and adds. */
2152: if (GET_CODE (op1) == CONST_DOUBLE
2153: && GET_MODE_CLASS (GET_MODE (op1)) == MODE_INT
1.1.1.7 root 2154: && HOST_BITS_PER_INT >= BITS_PER_WORD
2155: && CONST_DOUBLE_HIGH (op1) == 0)
2156: const_op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
2157: else if (HOST_BITS_PER_INT < GET_MODE_BITSIZE (mode)
2158: && GET_CODE (op1) == CONST_INT
2159: && INTVAL (op1) < 0)
2160: const_op1 = 0;
1.1 root 2161:
1.1.1.3 root 2162: /* We used to test optimize here, on the grounds that it's better to
2163: produce a smaller program when -O is not used.
2164: But this causes such a terrible slowdown sometimes
2165: that it seems better to use synth_mult always. */
1.1.1.5 root 2166:
1.1.1.7 root 2167: if (const_op1 && GET_CODE (const_op1) == CONST_INT)
1.1 root 2168: {
2169: struct algorithm alg;
1.1.1.7 root 2170: struct algorithm alg2;
1.1.1.5 root 2171: HOST_WIDE_INT val = INTVAL (op1);
2172: HOST_WIDE_INT val_so_far;
2173: rtx insn;
1.1.1.6 root 2174: int mult_cost;
1.1.1.7 root 2175: enum {basic_variant, negate_variant, add_variant} variant = basic_variant;
1.1 root 2176:
1.1.1.7 root 2177: /* Try to do the computation three ways: multiply by the negative of OP1
2178: and then negate, do the multiplication directly, or do multiplication
2179: by OP1 - 1. */
1.1 root 2180:
1.1.1.6 root 2181: mult_cost = rtx_cost (gen_rtx (MULT, mode, op0, op1), SET);
2182: mult_cost = MIN (12 * add_cost, mult_cost);
2183:
2184: synth_mult (&alg, val, mult_cost);
1.1 root 2185:
1.1.1.7 root 2186: /* This works only if the inverted value actually fits in an
2187: `unsigned int' */
2188: if (HOST_BITS_PER_INT >= GET_MODE_BITSIZE (mode))
2189: {
2190: synth_mult (&alg2, - val,
2191: (alg.cost < mult_cost ? alg.cost : mult_cost) - negate_cost);
2192: if (alg2.cost + negate_cost < alg.cost)
2193: alg = alg2, variant = negate_variant;
2194: }
2195:
2196: /* This proves very useful for division-by-constant. */
2197: synth_mult (&alg2, val - 1,
2198: (alg.cost < mult_cost ? alg.cost : mult_cost) - add_cost);
2199: if (alg2.cost + add_cost < alg.cost)
2200: alg = alg2, variant = add_variant;
1.1 root 2201:
1.1.1.5 root 2202: if (alg.cost < mult_cost)
1.1 root 2203: {
1.1.1.5 root 2204: /* We found something cheaper than a multiply insn. */
2205: int opno;
1.1 root 2206: rtx accum, tem;
2207:
2208: op0 = protect_from_queue (op0, 0);
2209:
2210: /* Avoid referencing memory over and over.
2211: For speed, but also for correctness when mem is volatile. */
2212: if (GET_CODE (op0) == MEM)
2213: op0 = force_reg (mode, op0);
2214:
1.1.1.5 root 2215: /* ACCUM starts out either as OP0 or as a zero, depending on
2216: the first operation. */
2217:
2218: if (alg.op[0] == alg_zero)
2219: {
2220: accum = copy_to_mode_reg (mode, const0_rtx);
2221: val_so_far = 0;
2222: }
2223: else if (alg.op[0] == alg_m)
2224: {
1.1.1.6 root 2225: accum = copy_to_mode_reg (mode, op0);
1.1.1.5 root 2226: val_so_far = 1;
2227: }
1.1 root 2228: else
1.1.1.5 root 2229: abort ();
2230:
2231: for (opno = 1; opno < alg.ops; opno++)
1.1 root 2232: {
1.1.1.5 root 2233: int log = alg.log[opno];
1.1.1.7 root 2234: int preserve = preserve_subexpressions_p ();
2235: rtx shift_subtarget = preserve ? 0 : accum;
2236: rtx add_target
2237: = (opno == alg.ops - 1 && target != 0 && variant != add_variant
2238: ? target : 0);
2239: rtx accum_target = preserve ? 0 : accum;
2240:
1.1 root 2241: switch (alg.op[opno])
2242: {
1.1.1.5 root 2243: case alg_shift:
2244: accum = expand_shift (LSHIFT_EXPR, mode, accum,
2245: build_int_2 (log, 0), NULL_RTX, 0);
2246: val_so_far <<= log;
1.1 root 2247: break;
2248:
1.1.1.5 root 2249: case alg_add_t_m2:
2250: tem = expand_shift (LSHIFT_EXPR, mode, op0,
2251: build_int_2 (log, 0), NULL_RTX, 0);
2252: accum = force_operand (gen_rtx (PLUS, mode, accum, tem),
1.1.1.7 root 2253: add_target ? add_target : accum_target);
1.1.1.5 root 2254: val_so_far += (HOST_WIDE_INT) 1 << log;
2255: break;
2256:
2257: case alg_sub_t_m2:
2258: tem = expand_shift (LSHIFT_EXPR, mode, op0,
2259: build_int_2 (log, 0), NULL_RTX, 0);
2260: accum = force_operand (gen_rtx (MINUS, mode, accum, tem),
1.1.1.7 root 2261: add_target ? add_target : accum_target);
1.1.1.5 root 2262: val_so_far -= (HOST_WIDE_INT) 1 << log;
2263: break;
2264:
2265: case alg_add_t2_m:
2266: accum = expand_shift (LSHIFT_EXPR, mode, accum,
1.1.1.7 root 2267: build_int_2 (log, 0), shift_subtarget,
2268: 0);
1.1.1.5 root 2269: accum = force_operand (gen_rtx (PLUS, mode, accum, op0),
1.1.1.7 root 2270: add_target ? add_target : accum_target);
1.1.1.5 root 2271: val_so_far = (val_so_far << log) + 1;
2272: break;
2273:
2274: case alg_sub_t2_m:
2275: accum = expand_shift (LSHIFT_EXPR, mode, accum,
1.1.1.7 root 2276: build_int_2 (log, 0), shift_subtarget,
2277: 0);
1.1.1.5 root 2278: accum = force_operand (gen_rtx (MINUS, mode, accum, op0),
1.1.1.7 root 2279: add_target ? add_target : accum_target);
1.1.1.5 root 2280: val_so_far = (val_so_far << log) - 1;
2281: break;
1.1 root 2282:
1.1.1.5 root 2283: case alg_add_factor:
2284: tem = expand_shift (LSHIFT_EXPR, mode, accum,
2285: build_int_2 (log, 0), NULL_RTX, 0);
2286: accum = force_operand (gen_rtx (PLUS, mode, accum, tem),
1.1.1.7 root 2287: add_target ? add_target : accum_target);
1.1.1.5 root 2288: val_so_far += val_so_far << log;
1.1 root 2289: break;
2290:
1.1.1.5 root 2291: case alg_sub_factor:
1.1 root 2292: tem = expand_shift (LSHIFT_EXPR, mode, accum,
1.1.1.4 root 2293: build_int_2 (log, 0), NULL_RTX, 0);
1.1.1.5 root 2294: accum = force_operand (gen_rtx (MINUS, mode, tem, accum),
1.1.1.7 root 2295: (add_target ? add_target
2296: : preserve ? 0 : tem));
1.1.1.5 root 2297: val_so_far = (val_so_far << log) - val_so_far;
2298: break;
1.1 root 2299:
1.1.1.5 root 2300: default:
2301: abort ();;
1.1 root 2302: }
2303:
1.1.1.5 root 2304: /* Write a REG_EQUAL note on the last insn so that we can cse
2305: multiplication sequences. */
1.1 root 2306:
1.1.1.5 root 2307: insn = get_last_insn ();
2308: REG_NOTES (insn)
2309: = gen_rtx (EXPR_LIST, REG_EQUAL,
2310: gen_rtx (MULT, mode, op0, GEN_INT (val_so_far)),
2311: REG_NOTES (insn));
2312: }
1.1 root 2313:
1.1.1.7 root 2314: if (variant == negate_variant)
1.1 root 2315: {
1.1.1.5 root 2316: val_so_far = - val_so_far;
2317: accum = expand_unop (mode, neg_optab, accum, target, 0);
1.1 root 2318: }
1.1.1.7 root 2319: else if (variant == add_variant)
2320: {
2321: val_so_far = val_so_far + 1;
2322: accum = force_operand (gen_rtx (PLUS, mode, accum, op0), target);
2323: }
1.1 root 2324:
1.1.1.5 root 2325: if (val != val_so_far)
2326: abort ();
2327:
2328: return accum;
1.1 root 2329: }
2330: }
2331:
1.1.1.6 root 2332: /* This used to use umul_optab if unsigned, but for non-widening multiply
2333: there is no difference between signed and unsigned. */
1.1 root 2334: op0 = expand_binop (mode, smul_optab,
2335: op0, op1, target, unsignedp, OPTAB_LIB_WIDEN);
2336: if (op0 == 0)
2337: abort ();
2338: return op0;
2339: }
2340:
1.1.1.7 root 2341: /* Return the smallest n such that 2**n >= X. */
2342:
2343: int
2344: ceil_log2 (x)
2345: unsigned HOST_WIDE_INT x;
2346: {
2347: return floor_log2 (x - 1) + 1;
2348: }
2349:
2350: /* Choose a minimal N + 1 bit approximation to 1/D that can be used to
2351: replace division by D, and put the least significant N bits of the result
2352: in *MULTIPLIER_PTR and return the most significant bit.
2353:
2354: The width of operations is N (should be <= HOST_BITS_PER_WIDE_INT), the
2355: needed precision is in PRECISION (should be <= N).
2356:
2357: PRECISION should be as small as possible so this function can choose
2358: multiplier more freely.
2359:
2360: The rounded-up logarithm of D is placed in *lgup_ptr. A shift count that
2361: is to be used for a final right shift is placed in *POST_SHIFT_PTR.
2362:
2363: Using this function, x/D will be equal to (x * m) >> (*POST_SHIFT_PTR),
2364: where m is the full HOST_BITS_PER_WIDE_INT + 1 bit multiplier. */
2365:
2366: static
2367: unsigned HOST_WIDE_INT
2368: choose_multiplier (d, n, precision, multiplier_ptr, post_shift_ptr, lgup_ptr)
2369: unsigned HOST_WIDE_INT d;
2370: int n;
2371: int precision;
2372: unsigned HOST_WIDE_INT *multiplier_ptr;
2373: int *post_shift_ptr;
2374: int *lgup_ptr;
2375: {
2376: unsigned HOST_WIDE_INT mhigh_hi, mhigh_lo;
2377: unsigned HOST_WIDE_INT mlow_hi, mlow_lo;
2378: int lgup, post_shift;
2379: int pow, pow2;
2380: unsigned HOST_WIDE_INT nh, nl, dummy1, dummy2;
2381:
2382: /* lgup = ceil(log2(divisor)); */
2383: lgup = ceil_log2 (d);
2384:
2385: if (lgup > n)
2386: abort ();
2387:
2388: pow = n + lgup;
2389: pow2 = n + lgup - precision;
2390:
2391: if (pow == 2 * HOST_BITS_PER_WIDE_INT)
2392: {
2393: /* We could handle this with some effort, but this case is much better
2394: handled directly with a scc insn, so rely on caller using that. */
2395: abort ();
2396: }
2397:
2398: /* mlow = 2^(N + lgup)/d */
2399: if (pow >= HOST_BITS_PER_WIDE_INT)
2400: {
2401: nh = (unsigned HOST_WIDE_INT) 1 << (pow - HOST_BITS_PER_WIDE_INT);
2402: nl = 0;
2403: }
2404: else
2405: {
2406: nh = 0;
2407: nl = (unsigned HOST_WIDE_INT) 1 << pow;
2408: }
2409: div_and_round_double (TRUNC_DIV_EXPR, 1, nl, nh, d, (HOST_WIDE_INT) 0,
2410: &mlow_lo, &mlow_hi, &dummy1, &dummy2);
2411:
2412: /* mhigh = (2^(N + lgup) + 2^N + lgup - precision)/d */
2413: if (pow2 >= HOST_BITS_PER_WIDE_INT)
2414: nh |= (unsigned HOST_WIDE_INT) 1 << (pow2 - HOST_BITS_PER_WIDE_INT);
2415: else
2416: nl |= (unsigned HOST_WIDE_INT) 1 << pow2;
2417: div_and_round_double (TRUNC_DIV_EXPR, 1, nl, nh, d, (HOST_WIDE_INT) 0,
2418: &mhigh_lo, &mhigh_hi, &dummy1, &dummy2);
2419:
2420: if (mhigh_hi && nh - d >= d)
2421: abort ();
2422: if (mhigh_hi > 1 || mlow_hi > 1)
2423: abort ();
2424: /* assert that mlow < mhigh. */
2425: if (! (mlow_hi < mhigh_hi || (mlow_hi == mhigh_hi && mlow_lo < mhigh_lo)))
2426: abort();
2427:
2428: /* If precision == N, then mlow, mhigh exceed 2^N
2429: (but they do not exceed 2^(N+1)). */
2430:
2431: /* Reduce to lowest terms */
2432: for (post_shift = lgup; post_shift > 0; post_shift--)
2433: {
2434: unsigned HOST_WIDE_INT ml_lo = (mlow_hi << (HOST_BITS_PER_WIDE_INT - 1)) | (mlow_lo >> 1);
2435: unsigned HOST_WIDE_INT mh_lo = (mhigh_hi << (HOST_BITS_PER_WIDE_INT - 1)) | (mhigh_lo >> 1);
2436: if (ml_lo >= mh_lo)
2437: break;
2438:
2439: mlow_hi = 0;
2440: mlow_lo = ml_lo;
2441: mhigh_hi = 0;
2442: mhigh_lo = mh_lo;
2443: }
2444:
2445: *post_shift_ptr = post_shift;
2446: *lgup_ptr = lgup;
2447: if (n < HOST_BITS_PER_WIDE_INT)
2448: {
2449: unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT) 1 << n) - 1;
2450: *multiplier_ptr = mhigh_lo & mask;
2451: return mhigh_lo >= mask;
2452: }
2453: else
2454: {
2455: *multiplier_ptr = mhigh_lo;
2456: return mhigh_hi;
2457: }
2458: }
2459:
2460: /* Compute the inverse of X mod 2**n, i.e., find Y such that X * Y is
2461: congruent to 1 (mod 2**N). */
2462:
2463: static unsigned HOST_WIDE_INT
2464: invert_mod2n (x, n)
2465: unsigned HOST_WIDE_INT x;
2466: int n;
2467: {
2468: /* Solve x*y == 1 (mod 2^n), where x is odd. Return y. */
2469:
2470: /* The algorithm notes that the choice y = x satisfies
2471: x*y == 1 mod 2^3, since x is assumed odd.
2472: Each iteration doubles the number of bits of significance in y. */
2473:
2474: unsigned HOST_WIDE_INT mask;
2475: unsigned HOST_WIDE_INT y = x;
2476: int nbit = 3;
2477:
2478: mask = (n == HOST_BITS_PER_WIDE_INT
2479: ? ~(unsigned HOST_WIDE_INT) 0
2480: : ((unsigned HOST_WIDE_INT) 1 << n) - 1);
2481:
2482: while (nbit < n)
2483: {
2484: y = y * (2 - x*y) & mask; /* Modulo 2^N */
2485: nbit *= 2;
2486: }
2487: return y;
2488: }
2489:
2490: /* Emit code to adjust ADJ_OPERAND after multiplication of wrong signedness
2491: flavor of OP0 and OP1. ADJ_OPERAND is already the high half of the
2492: product OP0 x OP1. If UNSIGNEDP is nonzero, adjust the signed product
2493: to become unsigned, if UNSIGNEDP is zero, adjust the unsigned product to
2494: become signed.
2495:
2496: The result is put in TARGET if that is convenient.
2497:
2498: MODE is the mode of operation. */
2499:
2500: rtx
2501: expand_mult_highpart_adjust (mode, adj_operand, op0, op1, target, unsignedp)
2502: enum machine_mode mode;
2503: register rtx adj_operand, op0, op1, target;
2504: int unsignedp;
2505: {
2506: rtx tem;
2507: enum rtx_code adj_code = unsignedp ? PLUS : MINUS;
2508:
2509: tem = expand_shift (RSHIFT_EXPR, mode, op0,
2510: build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
2511: NULL_RTX, 0);
2512: tem = expand_and (tem, op1, NULL_RTX);
2513: adj_operand = force_operand (gen_rtx (adj_code, mode, adj_operand, tem),
2514: adj_operand);
2515:
2516: tem = expand_shift (RSHIFT_EXPR, mode, op1,
2517: build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
2518: NULL_RTX, 0);
2519: tem = expand_and (tem, op0, NULL_RTX);
2520: target = force_operand (gen_rtx (adj_code, mode, adj_operand, tem), target);
2521:
2522: return target;
2523: }
2524:
2525: /* Emit code to multiply OP0 and CNST1, putting the high half of the result
2526: in TARGET if that is convenient, and return where the result is. If the
2527: operation can not be performed, 0 is returned.
2528:
2529: MODE is the mode of operation and result.
2530:
1.1.1.8 ! root 2531: UNSIGNEDP nonzero means unsigned multiply.
! 2532:
! 2533: MAX_COST is the total allowed cost for the expanded RTL. */
1.1.1.7 root 2534:
2535: rtx
1.1.1.8 ! root 2536: expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
1.1.1.7 root 2537: enum machine_mode mode;
2538: register rtx op0, target;
2539: unsigned HOST_WIDE_INT cnst1;
2540: int unsignedp;
1.1.1.8 ! root 2541: int max_cost;
1.1.1.7 root 2542: {
2543: enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
2544: optab mul_highpart_optab;
2545: optab moptab;
2546: rtx tem;
2547: int size = GET_MODE_BITSIZE (mode);
2548: rtx op1, wide_op1;
2549:
2550: /* We can't support modes wider than HOST_BITS_PER_INT. */
2551: if (size > HOST_BITS_PER_WIDE_INT)
2552: abort ();
2553:
2554: op1 = GEN_INT (cnst1);
2555:
2556: if (GET_MODE_BITSIZE (wider_mode) <= HOST_BITS_PER_INT)
2557: wide_op1 = op1;
2558: else
2559: wide_op1
2560: = immed_double_const (cnst1,
2561: (unsignedp
2562: ? (HOST_WIDE_INT) 0
2563: : -(cnst1 >> (HOST_BITS_PER_WIDE_INT - 1))),
2564: wider_mode);
2565:
2566: /* expand_mult handles constant multiplication of word_mode
2567: or narrower. It does a poor job for large modes. */
1.1.1.8 ! root 2568: if (size < BITS_PER_WORD
! 2569: && mul_cost[(int) wider_mode] + shift_cost[size-1] < max_cost)
1.1.1.7 root 2570: {
2571: /* We have to do this, since expand_binop doesn't do conversion for
2572: multiply. Maybe change expand_binop to handle widening multiply? */
2573: op0 = convert_to_mode (wider_mode, op0, unsignedp);
2574:
2575: tem = expand_mult (wider_mode, op0, wide_op1, NULL_RTX, unsignedp);
2576: tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
2577: build_int_2 (size, 0), NULL_RTX, 1);
1.1.1.8 ! root 2578: return convert_modes (mode, wider_mode, tem, unsignedp);
1.1.1.7 root 2579: }
2580:
2581: if (target == 0)
2582: target = gen_reg_rtx (mode);
2583:
2584: /* Firstly, try using a multiplication insn that only generates the needed
2585: high part of the product, and in the sign flavor of unsignedp. */
1.1.1.8 ! root 2586: if (mul_highpart_cost[(int) mode] < max_cost)
! 2587: {
! 2588: mul_highpart_optab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
! 2589: target = expand_binop (mode, mul_highpart_optab,
! 2590: op0, wide_op1, target, unsignedp, OPTAB_DIRECT);
! 2591: if (target)
! 2592: return target;
! 2593: }
1.1.1.7 root 2594:
2595: /* Secondly, same as above, but use sign flavor opposite of unsignedp.
2596: Need to adjust the result after the multiplication. */
1.1.1.8 ! root 2597: if (mul_highpart_cost[(int) mode] + 2 * shift_cost[size-1] + 4 * add_cost < max_cost)
! 2598: {
! 2599: mul_highpart_optab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
! 2600: target = expand_binop (mode, mul_highpart_optab,
! 2601: op0, wide_op1, target, unsignedp, OPTAB_DIRECT);
! 2602: if (target)
! 2603: /* We used the wrong signedness. Adjust the result. */
! 2604: return expand_mult_highpart_adjust (mode, target, op0,
! 2605: op1, target, unsignedp);
! 2606: }
1.1.1.7 root 2607:
1.1.1.8 ! root 2608: /* Try widening multiplication. */
1.1.1.7 root 2609: moptab = unsignedp ? umul_widen_optab : smul_widen_optab;
1.1.1.8 ! root 2610: if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
! 2611: && mul_widen_cost[(int) wider_mode] < max_cost)
! 2612: goto try;
! 2613:
! 2614: /* Try widening the mode and perform a non-widening multiplication. */
! 2615: moptab = smul_optab;
! 2616: if (smul_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
! 2617: && mul_cost[(int) wider_mode] + shift_cost[size-1] < max_cost)
! 2618: goto try;
! 2619:
! 2620: /* Try widening multiplication of opposite signedness, and adjust. */
! 2621: moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
! 2622: if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
! 2623: && (mul_widen_cost[(int) wider_mode]
! 2624: + 2 * shift_cost[size-1] + 4 * add_cost < max_cost))
1.1.1.7 root 2625: {
1.1.1.8 ! root 2626: tem = expand_binop (wider_mode, moptab, op0, wide_op1,
! 2627: NULL_RTX, ! unsignedp, OPTAB_WIDEN);
! 2628: if (tem != 0)
1.1.1.7 root 2629: {
1.1.1.8 ! root 2630: /* Extract the high half of the just generated product. */
! 2631: tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
! 2632: build_int_2 (size, 0), NULL_RTX, 1);
! 2633: tem = convert_modes (mode, wider_mode, tem, unsignedp);
! 2634: /* We used the wrong signedness. Adjust the result. */
! 2635: return expand_mult_highpart_adjust (mode, tem, op0, op1,
! 2636: target, unsignedp);
1.1.1.7 root 2637: }
2638: }
2639:
1.1.1.8 ! root 2640: return 0;
! 2641:
! 2642: try:
1.1.1.7 root 2643: /* Pass NULL_RTX as target since TARGET has wrong mode. */
2644: tem = expand_binop (wider_mode, moptab, op0, wide_op1,
2645: NULL_RTX, unsignedp, OPTAB_WIDEN);
2646: if (tem == 0)
2647: return 0;
2648:
2649: /* Extract the high half of the just generated product. */
2650: tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
2651: build_int_2 (size, 0), NULL_RTX, 1);
1.1.1.8 ! root 2652: return convert_modes (mode, wider_mode, tem, unsignedp);
1.1.1.7 root 2653: }
2654:
1.1 root 2655: /* Emit the code to divide OP0 by OP1, putting the result in TARGET
2656: if that is convenient, and returning where the result is.
2657: You may request either the quotient or the remainder as the result;
2658: specify REM_FLAG nonzero to get the remainder.
2659:
2660: CODE is the expression code for which kind of division this is;
2661: it controls how rounding is done. MODE is the machine mode to use.
2662: UNSIGNEDP nonzero means do unsigned division. */
2663:
2664: /* ??? For CEIL_MOD_EXPR, can compute incorrect remainder with ANDI
2665: and then correct it by or'ing in missing high bits
2666: if result of ANDI is nonzero.
2667: For ROUND_MOD_EXPR, can use ANDI and then sign-extend the result.
2668: This could optimize to a bfexts instruction.
2669: But C doesn't use these operations, so their optimizations are
2670: left for later. */
2671:
1.1.1.7 root 2672: #define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0)
2673:
1.1 root 2674: rtx
2675: expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
2676: int rem_flag;
2677: enum tree_code code;
2678: enum machine_mode mode;
2679: register rtx op0, op1, target;
2680: int unsignedp;
2681: {
2682: enum machine_mode compute_mode;
1.1.1.7 root 2683: register rtx tquotient;
2684: rtx quotient = 0, remainder = 0;
2685: rtx last;
1.1.1.4 root 2686: int size;
1.1.1.7 root 2687: rtx insn, set;
1.1 root 2688: optab optab1, optab2;
1.1.1.7 root 2689: int op1_is_constant, op1_is_pow2;
1.1.1.8 ! root 2690: int max_cost, extra_cost;
1.1 root 2691:
1.1.1.7 root 2692: op1_is_constant = GET_CODE (op1) == CONST_INT;
2693: op1_is_pow2 = (op1_is_constant
2694: && ((EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
2695: || EXACT_POWER_OF_2_OR_ZERO_P (-INTVAL (op1)))));
2696:
2697: /*
2698: This is the structure of expand_divmod:
2699:
2700: First comes code to fix up the operands so we can perform the operations
2701: correctly and efficiently.
2702:
2703: Second comes a switch statement with code specific for each rounding mode.
2704: For some special operands this code emits all RTL for the desired
2705: operation, for other cases, it generates only a quotient and stores it in
2706: QUOTIENT. The case for trunc division/remainder might leave quotient = 0,
2707: to indicate that it has not done anything.
2708:
2709: Last comes code that finishes the operation. If QUOTIENT is set and
2710: REM_FLAG is set, the remainder is computed as OP0 - QUOTIENT * OP1. If
2711: QUOTIENT is not set, it is computed using trunc rounding.
2712:
2713: We try to generate special code for division and remainder when OP1 is a
2714: constant. If |OP1| = 2**n we can use shifts and some other fast
2715: operations. For other values of OP1, we compute a carefully selected
2716: fixed-point approximation m = 1/OP1, and generate code that multiplies OP0
2717: by m.
2718:
2719: In all cases but EXACT_DIV_EXPR, this multiplication requires the upper
2720: half of the product. Different strategies for generating the product are
2721: implemented in expand_mult_highpart.
2722:
2723: If what we actually want is the remainder, we generate that by another
2724: by-constant multiplication and a subtraction. */
2725:
2726: /* We shouldn't be called with OP1 == const1_rtx, but some of the
1.1.1.4 root 2727: code below will malfunction if we are, so check here and handle
2728: the special case if so. */
2729: if (op1 == const1_rtx)
2730: return rem_flag ? const0_rtx : op0;
2731:
1.1.1.6 root 2732: if (target
2733: /* Don't use the function value register as a target
2734: since we have to read it as well as write it,
2735: and function-inlining gets confused by this. */
2736: && ((REG_P (target) && REG_FUNCTION_VALUE_P (target))
2737: /* Don't clobber an operand while doing a multi-step calculation. */
1.1.1.7 root 2738: || ((rem_flag || op1_is_constant)
1.1.1.6 root 2739: && (reg_mentioned_p (target, op0)
2740: || (GET_CODE (op0) == MEM && GET_CODE (target) == MEM)))
2741: || reg_mentioned_p (target, op1)
2742: || (GET_CODE (op1) == MEM && GET_CODE (target) == MEM)))
1.1 root 2743: target = 0;
2744:
2745: /* Get the mode in which to perform this computation. Normally it will
2746: be MODE, but sometimes we can't do the desired operation in MODE.
2747: If so, pick a wider mode in which we can do the operation. Convert
2748: to that mode at the start to avoid repeated conversions.
2749:
2750: First see what operations we need. These depend on the expression
2751: we are evaluating. (We assume that divxx3 insns exist under the
2752: same conditions that modxx3 insns and that these insns don't normally
2753: fail. If these assumptions are not correct, we may generate less
2754: efficient code in some cases.)
2755:
2756: Then see if we find a mode in which we can open-code that operation
2757: (either a division, modulus, or shift). Finally, check for the smallest
2758: mode for which we can do the operation with a library call. */
2759:
1.1.1.7 root 2760: /* We might want to refine this now that we have division-by-constant
2761: optimization. Since expand_mult_highpart tries so many variants, it is
2762: not straightforward to generalize this. Maybe we should make an array
2763: of possible modes in init_expmed? Save this for GCC 2.7. */
2764:
2765: optab1 = (op1_is_pow2 ? (unsignedp ? lshr_optab : ashr_optab)
1.1 root 2766: : (unsignedp ? udiv_optab : sdiv_optab));
1.1.1.7 root 2767: optab2 = (op1_is_pow2 ? optab1 : (unsignedp ? udivmod_optab : sdivmod_optab));
1.1 root 2768:
2769: for (compute_mode = mode; compute_mode != VOIDmode;
2770: compute_mode = GET_MODE_WIDER_MODE (compute_mode))
2771: if (optab1->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing
2772: || optab2->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing)
2773: break;
2774:
2775: if (compute_mode == VOIDmode)
2776: for (compute_mode = mode; compute_mode != VOIDmode;
2777: compute_mode = GET_MODE_WIDER_MODE (compute_mode))
2778: if (optab1->handlers[(int) compute_mode].libfunc
2779: || optab2->handlers[(int) compute_mode].libfunc)
2780: break;
2781:
1.1.1.6 root 2782: /* If we still couldn't find a mode, use MODE, but we'll probably abort
2783: in expand_binop. */
1.1 root 2784: if (compute_mode == VOIDmode)
2785: compute_mode = mode;
2786:
1.1.1.7 root 2787: if (target && GET_MODE (target) == compute_mode)
2788: tquotient = target;
2789: else
2790: tquotient = gen_reg_rtx (compute_mode);
2791:
1.1.1.4 root 2792: size = GET_MODE_BITSIZE (compute_mode);
1.1.1.7 root 2793: #if 0
2794: /* It should be possible to restrict the precision to GET_MODE_BITSIZE
1.1.1.8 ! root 2795: (mode), and thereby get better code when OP1 is a constant. Do that
! 2796: later. It will require going over all usages of SIZE below. */
1.1.1.7 root 2797: size = GET_MODE_BITSIZE (mode);
2798: #endif
1.1.1.4 root 2799:
1.1.1.8 ! root 2800: max_cost = div_cost[(int) compute_mode]
! 2801: - (rem_flag ? mul_cost[(int) compute_mode] + add_cost : 0);
! 2802:
1.1.1.7 root 2803: /* Now convert to the best mode to use. */
1.1 root 2804: if (compute_mode != mode)
2805: {
1.1.1.7 root 2806: op0 = convert_modes (compute_mode, mode, op0, unsignedp);
1.1.1.6 root 2807: op1 = convert_modes (compute_mode, mode, op1, unsignedp);
1.1 root 2808: }
2809:
1.1.1.7 root 2810: /* If one of the operands is a volatile MEM, copy it into a register. */
1.1.1.3 root 2811:
1.1.1.7 root 2812: if (GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0))
2813: op0 = force_reg (compute_mode, op0);
2814: if (GET_CODE (op1) == MEM && MEM_VOLATILE_P (op1))
1.1.1.3 root 2815: op1 = force_reg (compute_mode, op1);
2816:
1.1.1.7 root 2817: /* If we need the remainder or if OP1 is constant, we need to
2818: put OP0 in a register in case it has any queued subexpressions. */
2819: if (rem_flag || op1_is_constant)
2820: op0 = force_reg (compute_mode, op0);
1.1.1.6 root 2821:
1.1.1.7 root 2822: last = get_last_insn ();
1.1.1.6 root 2823:
1.1.1.8 ! root 2824: /* Promote floor rounding to trunc rounding for unsigned operations. */
1.1.1.7 root 2825: if (unsignedp)
2826: {
2827: if (code == FLOOR_DIV_EXPR)
2828: code = TRUNC_DIV_EXPR;
2829: if (code == FLOOR_MOD_EXPR)
2830: code = TRUNC_MOD_EXPR;
1.1.1.6 root 2831: }
2832:
1.1.1.7 root 2833: if (op1 != const0_rtx)
2834: switch (code)
2835: {
2836: case TRUNC_MOD_EXPR:
2837: case TRUNC_DIV_EXPR:
2838: if (op1_is_constant && HOST_BITS_PER_WIDE_INT >= size)
2839: {
1.1.1.8 ! root 2840: if (unsignedp)
1.1.1.7 root 2841: {
2842: unsigned HOST_WIDE_INT mh, ml;
2843: int pre_shift, post_shift;
2844: int dummy;
2845: unsigned HOST_WIDE_INT d = INTVAL (op1);
2846:
2847: if (EXACT_POWER_OF_2_OR_ZERO_P (d))
2848: {
2849: pre_shift = floor_log2 (d);
2850: if (rem_flag)
2851: {
2852: remainder = expand_binop (compute_mode, and_optab, op0,
2853: GEN_INT (((HOST_WIDE_INT) 1 << pre_shift) - 1),
2854: remainder, 1,
2855: OPTAB_LIB_WIDEN);
2856: if (remainder)
2857: return gen_lowpart (mode, remainder);
2858: }
2859: quotient = expand_shift (RSHIFT_EXPR, compute_mode, op0,
2860: build_int_2 (pre_shift, 0),
2861: tquotient, 1);
2862: }
2863: else if (d >= ((unsigned HOST_WIDE_INT) 1 << (size - 1)))
2864: {
2865: /* Most significant bit of divisor is set, emit a scc insn.
2866: emit_store_flag needs to be passed a place for the
2867: result. */
2868: quotient = emit_store_flag (tquotient, GEU, op0, op1,
2869: compute_mode, 1, 1);
2870: if (quotient == 0)
2871: goto fail1;
2872: }
2873: else
2874: {
2875: /* Find a suitable multiplier and right shift count instead
2876: of multiplying with D. */
2877:
2878: mh = choose_multiplier (d, size, size,
2879: &ml, &post_shift, &dummy);
2880:
2881: /* If the suggested multiplier is more than SIZE bits, we
2882: can do better for even divisors, using an initial right
2883: shift. */
2884: if (mh != 0 && (d & 1) == 0)
2885: {
2886: pre_shift = floor_log2 (d & -d);
2887: mh = choose_multiplier (d >> pre_shift, size,
2888: size - pre_shift,
2889: &ml, &post_shift, &dummy);
2890: if (mh)
2891: abort ();
2892: }
2893: else
2894: pre_shift = 0;
2895:
2896: if (mh != 0)
2897: {
2898: rtx t1, t2, t3, t4;
2899:
1.1.1.8 ! root 2900: extra_cost = (shift_cost[post_shift - 1]
! 2901: + shift_cost[1] + 2 * add_cost);
1.1.1.7 root 2902: t1 = expand_mult_highpart (compute_mode, op0, ml,
1.1.1.8 ! root 2903: NULL_RTX, 1,
! 2904: max_cost - extra_cost);
1.1.1.7 root 2905: if (t1 == 0)
2906: goto fail1;
2907: t2 = force_operand (gen_rtx (MINUS, compute_mode,
2908: op0, t1),
2909: NULL_RTX);
2910: t3 = expand_shift (RSHIFT_EXPR, compute_mode, t2,
2911: build_int_2 (1, 0), NULL_RTX, 1);
2912: t4 = force_operand (gen_rtx (PLUS, compute_mode,
2913: t1, t3),
2914: NULL_RTX);
2915: quotient = expand_shift (RSHIFT_EXPR, compute_mode, t4,
2916: build_int_2 (post_shift - 1,
2917: 0),
2918: tquotient, 1);
2919: }
2920: else
2921: {
2922: rtx t1, t2;
2923:
2924: t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
2925: build_int_2 (pre_shift, 0),
2926: NULL_RTX, 1);
1.1.1.8 ! root 2927: extra_cost = (shift_cost[pre_shift]
! 2928: + shift_cost[post_shift]);
1.1.1.7 root 2929: t2 = expand_mult_highpart (compute_mode, t1, ml,
1.1.1.8 ! root 2930: NULL_RTX, 1,
! 2931: max_cost - extra_cost);
1.1.1.7 root 2932: if (t2 == 0)
2933: goto fail1;
2934: quotient = expand_shift (RSHIFT_EXPR, compute_mode, t2,
2935: build_int_2 (post_shift, 0),
2936: tquotient, 1);
2937: }
2938: }
2939:
2940: insn = get_last_insn ();
2941: if (insn != last
2942: && (set = single_set (insn)) != 0
2943: && SET_DEST (set) == quotient)
2944: REG_NOTES (insn)
2945: = gen_rtx (EXPR_LIST, REG_EQUAL,
2946: gen_rtx (UDIV, compute_mode, op0, op1),
2947: REG_NOTES (insn));
2948: }
2949: else /* TRUNC_DIV, signed */
2950: {
2951: unsigned HOST_WIDE_INT ml;
2952: int lgup, post_shift;
2953: HOST_WIDE_INT d = INTVAL (op1);
2954: unsigned HOST_WIDE_INT abs_d = d >= 0 ? d : -d;
2955:
2956: /* n rem d = n rem -d */
2957: if (rem_flag && d < 0)
2958: {
2959: d = abs_d;
2960: op1 = GEN_INT (abs_d);
2961: }
2962:
2963: if (d == 1)
2964: quotient = op0;
2965: else if (d == -1)
2966: quotient = expand_unop (compute_mode, neg_optab, op0,
2967: tquotient, 0);
1.1.1.8 ! root 2968: else if (abs_d == (unsigned HOST_WIDE_INT) 1 << (size - 1))
! 2969: {
! 2970: /* This case is not handled correctly below. */
! 2971: quotient = emit_store_flag (tquotient, EQ, op0, op1,
! 2972: compute_mode, 1, 1);
! 2973: if (quotient == 0)
! 2974: goto fail1;
! 2975: }
1.1.1.7 root 2976: else if (EXACT_POWER_OF_2_OR_ZERO_P (d)
2977: && (rem_flag ? smod_pow2_cheap : sdiv_pow2_cheap))
2978: ;
2979: else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d))
2980: {
2981: lgup = floor_log2 (abs_d);
2982: if (abs_d != 2 && BRANCH_COST < 3)
2983: {
2984: rtx label = gen_label_rtx ();
2985: rtx t1;
2986:
2987: t1 = copy_to_mode_reg (compute_mode, op0);
2988: emit_cmp_insn (t1, const0_rtx, GE,
2989: NULL_RTX, compute_mode, 0, 0);
2990: emit_jump_insn (gen_bge (label));
2991: expand_inc (t1, GEN_INT (abs_d - 1));
2992: emit_label (label);
2993: quotient = expand_shift (RSHIFT_EXPR, compute_mode, t1,
2994: build_int_2 (lgup, 0),
2995: tquotient, 0);
2996: }
2997: else
2998: {
2999: rtx t1, t2, t3;
3000: t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
3001: build_int_2 (size - 1, 0),
3002: NULL_RTX, 0);
3003: t2 = expand_shift (RSHIFT_EXPR, compute_mode, t1,
3004: build_int_2 (size - lgup, 0),
3005: NULL_RTX, 1);
3006: t3 = force_operand (gen_rtx (PLUS, compute_mode,
3007: op0, t2),
3008: NULL_RTX);
3009: quotient = expand_shift (RSHIFT_EXPR, compute_mode, t3,
3010: build_int_2 (lgup, 0),
3011: tquotient, 0);
3012: }
3013:
3014: /* We have computed OP0 / abs(OP1). If OP1 is negative, negate
3015: the quotient. */
3016: if (d < 0)
3017: {
3018: insn = get_last_insn ();
3019: if (insn != last
3020: && (set = single_set (insn)) != 0
3021: && SET_DEST (set) == quotient)
3022: REG_NOTES (insn)
3023: = gen_rtx (EXPR_LIST, REG_EQUAL,
3024: gen_rtx (DIV, compute_mode, op0,
3025: GEN_INT (abs_d)),
3026: REG_NOTES (insn));
3027:
3028: quotient = expand_unop (compute_mode, neg_optab,
3029: quotient, quotient, 0);
3030: }
3031: }
3032: else
3033: {
3034: choose_multiplier (abs_d, size, size - 1,
3035: &ml, &post_shift, &lgup);
3036: if (ml < (unsigned HOST_WIDE_INT) 1 << (size - 1))
3037: {
3038: rtx t1, t2, t3;
3039:
1.1.1.8 ! root 3040: extra_cost = (shift_cost[post_shift]
! 3041: + shift_cost[size - 1] + add_cost);
1.1.1.7 root 3042: t1 = expand_mult_highpart (compute_mode, op0, ml,
1.1.1.8 ! root 3043: NULL_RTX, 0,
! 3044: max_cost - extra_cost);
1.1.1.7 root 3045: if (t1 == 0)
3046: goto fail1;
3047: t2 = expand_shift (RSHIFT_EXPR, compute_mode, t1,
3048: build_int_2 (post_shift, 0), NULL_RTX, 0);
3049: t3 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
3050: build_int_2 (size - 1, 0), NULL_RTX, 0);
3051: if (d < 0)
3052: quotient = force_operand (gen_rtx (MINUS, compute_mode, t3, t2),
3053: tquotient);
3054: else
3055: quotient = force_operand (gen_rtx (MINUS, compute_mode, t2, t3),
3056: tquotient);
3057: }
3058: else
3059: {
3060: rtx t1, t2, t3, t4;
3061:
3062: ml |= (~(unsigned HOST_WIDE_INT) 0) << (size - 1);
1.1.1.8 ! root 3063: extra_cost = (shift_cost[post_shift]
! 3064: + shift_cost[size - 1] + 2 * add_cost);
1.1.1.7 root 3065: t1 = expand_mult_highpart (compute_mode, op0, ml,
1.1.1.8 ! root 3066: NULL_RTX, 0,
! 3067: max_cost - extra_cost);
1.1.1.7 root 3068: if (t1 == 0)
3069: goto fail1;
3070: t2 = force_operand (gen_rtx (PLUS, compute_mode, t1, op0),
3071: NULL_RTX);
3072: t3 = expand_shift (RSHIFT_EXPR, compute_mode, t2,
3073: build_int_2 (post_shift, 0), NULL_RTX, 0);
3074: t4 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
3075: build_int_2 (size - 1, 0), NULL_RTX, 0);
3076: if (d < 0)
3077: quotient = force_operand (gen_rtx (MINUS, compute_mode, t4, t3),
3078: tquotient);
3079: else
3080: quotient = force_operand (gen_rtx (MINUS, compute_mode, t3, t4),
3081: tquotient);
3082: }
3083: }
3084:
3085: insn = get_last_insn ();
3086: if (insn != last
3087: && (set = single_set (insn)) != 0
3088: && SET_DEST (set) == quotient)
3089: REG_NOTES (insn)
3090: = gen_rtx (EXPR_LIST, REG_EQUAL,
3091: gen_rtx (DIV, compute_mode, op0, op1),
3092: REG_NOTES (insn));
3093: }
3094: break;
3095: }
3096: fail1:
3097: delete_insns_since (last);
3098: break;
1.1 root 3099:
1.1.1.7 root 3100: case FLOOR_DIV_EXPR:
3101: case FLOOR_MOD_EXPR:
3102: /* We will come here only for signed operations. */
3103: if (op1_is_constant && HOST_BITS_PER_WIDE_INT >= size)
3104: {
3105: unsigned HOST_WIDE_INT mh, ml;
3106: int pre_shift, lgup, post_shift;
3107: HOST_WIDE_INT d = INTVAL (op1);
3108:
3109: if (d > 0)
3110: {
3111: /* We could just as easily deal with negative constants here,
3112: but it does not seem worth the trouble for GCC 2.6. */
3113: if (EXACT_POWER_OF_2_OR_ZERO_P (d))
3114: {
3115: pre_shift = floor_log2 (d);
3116: if (rem_flag)
3117: {
3118: remainder = expand_binop (compute_mode, and_optab, op0,
3119: GEN_INT (((HOST_WIDE_INT) 1 << pre_shift) - 1),
3120: remainder, 0, OPTAB_LIB_WIDEN);
3121: if (remainder)
3122: return gen_lowpart (mode, remainder);
3123: }
3124: quotient = expand_shift (RSHIFT_EXPR, compute_mode, op0,
3125: build_int_2 (pre_shift, 0),
3126: tquotient, 0);
3127: }
3128: else
3129: {
3130: rtx t1, t2, t3, t4;
3131:
3132: mh = choose_multiplier (d, size, size - 1,
3133: &ml, &post_shift, &lgup);
3134: if (mh)
3135: abort ();
3136:
3137: t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
3138: build_int_2 (size - 1, 0), NULL_RTX, 0);
3139: t2 = expand_binop (compute_mode, xor_optab, op0, t1,
3140: NULL_RTX, 0, OPTAB_WIDEN);
1.1.1.8 ! root 3141: extra_cost = (shift_cost[post_shift]
! 3142: + shift_cost[size - 1] + 2 * add_cost);
1.1.1.7 root 3143: t3 = expand_mult_highpart (compute_mode, t2, ml,
1.1.1.8 ! root 3144: NULL_RTX, 1,
! 3145: max_cost - extra_cost);
1.1.1.7 root 3146: if (t3 != 0)
3147: {
3148: t4 = expand_shift (RSHIFT_EXPR, compute_mode, t3,
3149: build_int_2 (post_shift, 0),
3150: NULL_RTX, 1);
3151: quotient = expand_binop (compute_mode, xor_optab,
3152: t4, t1, tquotient, 0,
3153: OPTAB_WIDEN);
3154: }
3155: }
3156: }
3157: else
3158: {
3159: rtx nsign, t1, t2, t3, t4;
3160: t1 = force_operand (gen_rtx (PLUS, compute_mode,
3161: op0, constm1_rtx), NULL_RTX);
3162: t2 = expand_binop (compute_mode, ior_optab, op0, t1, NULL_RTX,
3163: 0, OPTAB_WIDEN);
3164: nsign = expand_shift (RSHIFT_EXPR, compute_mode, t2,
3165: build_int_2 (size - 1, 0), NULL_RTX, 0);
3166: t3 = force_operand (gen_rtx (MINUS, compute_mode, t1, nsign),
3167: NULL_RTX);
3168: t4 = expand_divmod (0, TRUNC_DIV_EXPR, compute_mode, t3, op1,
3169: NULL_RTX, 0);
3170: if (t4)
3171: {
3172: rtx t5;
3173: t5 = expand_unop (compute_mode, one_cmpl_optab, nsign,
3174: NULL_RTX, 0);
3175: quotient = force_operand (gen_rtx (PLUS, compute_mode,
3176: t4, t5),
3177: tquotient);
3178: }
3179: }
3180: }
1.1.1.6 root 3181:
1.1.1.7 root 3182: if (quotient != 0)
3183: break;
3184: delete_insns_since (last);
1.1 root 3185:
1.1.1.7 root 3186: /* Try using an instruction that produces both the quotient and
3187: remainder, using truncation. We can easily compensate the quotient
3188: or remainder to get floor rounding, once we have the remainder.
3189: Notice that we compute also the final remainder value here,
3190: and return the result right away. */
3191: if (target == 0)
3192: target = gen_reg_rtx (compute_mode);
1.1.1.8 ! root 3193:
1.1.1.7 root 3194: if (rem_flag)
3195: {
1.1.1.8 ! root 3196: remainder
! 3197: = GET_CODE (target) == REG ? target : gen_reg_rtx (compute_mode);
1.1.1.7 root 3198: quotient = gen_reg_rtx (compute_mode);
3199: }
3200: else
3201: {
1.1.1.8 ! root 3202: quotient
! 3203: = GET_CODE (target) == REG ? target : gen_reg_rtx (compute_mode);
1.1.1.7 root 3204: remainder = gen_reg_rtx (compute_mode);
3205: }
3206:
3207: if (expand_twoval_binop (sdivmod_optab, op0, op1,
3208: quotient, remainder, 0))
3209: {
3210: /* This could be computed with a branch-less sequence.
3211: Save that for later. */
3212: rtx tem;
3213: rtx label = gen_label_rtx ();
3214: emit_cmp_insn (remainder, const0_rtx, EQ, NULL_RTX,
3215: compute_mode, 0, 0);
3216: emit_jump_insn (gen_beq (label));
3217: tem = expand_binop (compute_mode, xor_optab, op0, op1,
3218: NULL_RTX, 0, OPTAB_WIDEN);
3219: emit_cmp_insn (tem, const0_rtx, GE, NULL_RTX, compute_mode, 0, 0);
3220: emit_jump_insn (gen_bge (label));
3221: expand_dec (quotient, const1_rtx);
3222: expand_inc (remainder, op1);
3223: emit_label (label);
3224: return gen_lowpart (mode, rem_flag ? remainder : quotient);
3225: }
1.1 root 3226:
1.1.1.7 root 3227: /* No luck with division elimination or divmod. Have to do it
3228: by conditionally adjusting op0 *and* the result. */
3229: {
3230: rtx label1, label2, label3, label4, label5;
3231: rtx adjusted_op0;
3232: rtx tem;
3233:
3234: quotient = gen_reg_rtx (compute_mode);
3235: adjusted_op0 = copy_to_mode_reg (compute_mode, op0);
3236: label1 = gen_label_rtx ();
3237: label2 = gen_label_rtx ();
3238: label3 = gen_label_rtx ();
3239: label4 = gen_label_rtx ();
3240: label5 = gen_label_rtx ();
3241: emit_cmp_insn (op1, const0_rtx, LT, NULL_RTX, compute_mode, 0, 0);
3242: emit_jump_insn (gen_blt (label2));
3243: emit_cmp_insn (adjusted_op0, const0_rtx, LT, NULL_RTX,
3244: compute_mode, 0, 0);
3245: emit_jump_insn (gen_blt (label1));
3246: tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
3247: quotient, 0, OPTAB_LIB_WIDEN);
3248: if (tem != quotient)
3249: emit_move_insn (quotient, tem);
3250: emit_jump_insn (gen_jump (label5));
3251: emit_barrier ();
3252: emit_label (label1);
3253: expand_inc (adjusted_op0, const1_rtx);
3254: emit_jump_insn (gen_jump (label4));
3255: emit_barrier ();
3256: emit_label (label2);
3257: emit_cmp_insn (adjusted_op0, const0_rtx, GT, NULL_RTX,
3258: compute_mode, 0, 0);
3259: emit_jump_insn (gen_bgt (label3));
3260: tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
3261: quotient, 0, OPTAB_LIB_WIDEN);
3262: if (tem != quotient)
3263: emit_move_insn (quotient, tem);
3264: emit_jump_insn (gen_jump (label5));
3265: emit_barrier ();
3266: emit_label (label3);
1.1 root 3267: expand_dec (adjusted_op0, const1_rtx);
1.1.1.7 root 3268: emit_label (label4);
3269: tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
3270: quotient, 0, OPTAB_LIB_WIDEN);
3271: if (tem != quotient)
3272: emit_move_insn (quotient, tem);
3273: expand_dec (quotient, const1_rtx);
3274: emit_label (label5);
1.1 root 3275: }
1.1.1.7 root 3276: break;
1.1 root 3277:
1.1.1.7 root 3278: case CEIL_DIV_EXPR:
3279: case CEIL_MOD_EXPR:
3280: if (unsignedp)
3281: {
3282: if (op1_is_constant && EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1)))
3283: {
3284: rtx t1, t2, t3;
3285: unsigned HOST_WIDE_INT d = INTVAL (op1);
3286: t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
3287: build_int_2 (floor_log2 (d), 0),
3288: tquotient, 1);
3289: t2 = expand_binop (compute_mode, and_optab, op0,
3290: GEN_INT (d - 1),
3291: NULL_RTX, 1, OPTAB_LIB_WIDEN);
3292: t3 = gen_reg_rtx (compute_mode);
3293: t3 = emit_store_flag (t3, NE, t2, const0_rtx,
3294: compute_mode, 1, 1);
3295: if (t3 == 0)
3296: {
3297: rtx lab;
3298: lab = gen_label_rtx ();
3299: emit_cmp_insn (t2, const0_rtx, EQ, NULL_RTX,
3300: compute_mode, 0, 0);
3301: emit_jump_insn (gen_beq (lab));
3302: expand_inc (t1, const1_rtx);
3303: emit_label (lab);
3304: quotient = t1;
3305: }
3306: else
3307: quotient = force_operand (gen_rtx (PLUS, compute_mode,
3308: t1, t3),
3309: tquotient);
3310: break;
3311: }
3312:
3313: /* Try using an instruction that produces both the quotient and
3314: remainder, using truncation. We can easily compensate the
3315: quotient or remainder to get ceiling rounding, once we have the
3316: remainder. Notice that we compute also the final remainder
3317: value here, and return the result right away. */
3318: if (target == 0)
3319: target = gen_reg_rtx (compute_mode);
1.1.1.8 ! root 3320:
1.1.1.7 root 3321: if (rem_flag)
3322: {
1.1.1.8 ! root 3323: remainder = (GET_CODE (target) == REG
! 3324: ? target : gen_reg_rtx (compute_mode));
1.1.1.7 root 3325: quotient = gen_reg_rtx (compute_mode);
3326: }
3327: else
3328: {
1.1.1.8 ! root 3329: quotient = (GET_CODE (target) == REG
! 3330: ? target : gen_reg_rtx (compute_mode));
1.1.1.7 root 3331: remainder = gen_reg_rtx (compute_mode);
3332: }
3333:
3334: if (expand_twoval_binop (udivmod_optab, op0, op1, quotient,
3335: remainder, 1))
3336: {
3337: /* This could be computed with a branch-less sequence.
3338: Save that for later. */
3339: rtx label = gen_label_rtx ();
3340: emit_cmp_insn (remainder, const0_rtx, EQ, NULL_RTX,
3341: compute_mode, 0, 0);
3342: emit_jump_insn (gen_beq (label));
3343: expand_inc (quotient, const1_rtx);
3344: expand_dec (remainder, op1);
3345: emit_label (label);
3346: return gen_lowpart (mode, rem_flag ? remainder : quotient);
3347: }
3348:
3349: /* No luck with division elimination or divmod. Have to do it
3350: by conditionally adjusting op0 *and* the result. */
3351: {
3352: rtx label1, label2;
3353: rtx adjusted_op0, tem;
3354:
3355: quotient = gen_reg_rtx (compute_mode);
3356: adjusted_op0 = copy_to_mode_reg (compute_mode, op0);
3357: label1 = gen_label_rtx ();
3358: label2 = gen_label_rtx ();
3359: emit_cmp_insn (adjusted_op0, const0_rtx, NE, NULL_RTX,
3360: compute_mode, 0, 0);
3361: emit_jump_insn (gen_bne (label1));
3362: emit_move_insn (quotient, const0_rtx);
3363: emit_jump_insn (gen_jump (label2));
3364: emit_barrier ();
3365: emit_label (label1);
3366: expand_dec (adjusted_op0, const1_rtx);
3367: tem = expand_binop (compute_mode, udiv_optab, adjusted_op0, op1,
3368: quotient, 1, OPTAB_LIB_WIDEN);
3369: if (tem != quotient)
3370: emit_move_insn (quotient, tem);
3371: expand_inc (quotient, const1_rtx);
3372: emit_label (label2);
3373: }
3374: }
3375: else /* signed */
3376: {
3377: if (op1_is_constant && EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
3378: && INTVAL (op1) >= 0)
3379: {
3380: /* This is extremely similar to the code for the unsigned case
3381: above. For 2.7 we should merge these variants, but for
3382: 2.6.1 I don't want to touch the code for unsigned since that
3383: get used in C. The signed case will only be used by other
3384: languages (Ada). */
3385:
3386: rtx t1, t2, t3;
3387: unsigned HOST_WIDE_INT d = INTVAL (op1);
3388: t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
3389: build_int_2 (floor_log2 (d), 0),
3390: tquotient, 0);
3391: t2 = expand_binop (compute_mode, and_optab, op0,
3392: GEN_INT (d - 1),
3393: NULL_RTX, 1, OPTAB_LIB_WIDEN);
3394: t3 = gen_reg_rtx (compute_mode);
3395: t3 = emit_store_flag (t3, NE, t2, const0_rtx,
3396: compute_mode, 1, 1);
3397: if (t3 == 0)
3398: {
3399: rtx lab;
3400: lab = gen_label_rtx ();
3401: emit_cmp_insn (t2, const0_rtx, EQ, NULL_RTX,
3402: compute_mode, 0, 0);
3403: emit_jump_insn (gen_beq (lab));
3404: expand_inc (t1, const1_rtx);
3405: emit_label (lab);
3406: quotient = t1;
3407: }
3408: else
3409: quotient = force_operand (gen_rtx (PLUS, compute_mode,
3410: t1, t3),
3411: tquotient);
3412: break;
3413: }
3414:
3415: /* Try using an instruction that produces both the quotient and
3416: remainder, using truncation. We can easily compensate the
3417: quotient or remainder to get ceiling rounding, once we have the
3418: remainder. Notice that we compute also the final remainder
3419: value here, and return the result right away. */
3420: if (target == 0)
3421: target = gen_reg_rtx (compute_mode);
3422: if (rem_flag)
3423: {
1.1.1.8 ! root 3424: remainder= (GET_CODE (target) == REG
! 3425: ? target : gen_reg_rtx (compute_mode));
1.1.1.7 root 3426: quotient = gen_reg_rtx (compute_mode);
3427: }
3428: else
3429: {
1.1.1.8 ! root 3430: quotient = (GET_CODE (target) == REG
! 3431: ? target : gen_reg_rtx (compute_mode));
1.1.1.7 root 3432: remainder = gen_reg_rtx (compute_mode);
3433: }
3434:
3435: if (expand_twoval_binop (sdivmod_optab, op0, op1, quotient,
3436: remainder, 0))
3437: {
3438: /* This could be computed with a branch-less sequence.
3439: Save that for later. */
3440: rtx tem;
3441: rtx label = gen_label_rtx ();
3442: emit_cmp_insn (remainder, const0_rtx, EQ, NULL_RTX,
3443: compute_mode, 0, 0);
3444: emit_jump_insn (gen_beq (label));
3445: tem = expand_binop (compute_mode, xor_optab, op0, op1,
3446: NULL_RTX, 0, OPTAB_WIDEN);
3447: emit_cmp_insn (tem, const0_rtx, LT, NULL_RTX,
3448: compute_mode, 0, 0);
3449: emit_jump_insn (gen_blt (label));
3450: expand_inc (quotient, const1_rtx);
3451: expand_dec (remainder, op1);
3452: emit_label (label);
3453: return gen_lowpart (mode, rem_flag ? remainder : quotient);
3454: }
3455:
3456: /* No luck with division elimination or divmod. Have to do it
3457: by conditionally adjusting op0 *and* the result. */
3458: {
3459: rtx label1, label2, label3, label4, label5;
3460: rtx adjusted_op0;
3461: rtx tem;
3462:
3463: quotient = gen_reg_rtx (compute_mode);
3464: adjusted_op0 = copy_to_mode_reg (compute_mode, op0);
3465: label1 = gen_label_rtx ();
3466: label2 = gen_label_rtx ();
3467: label3 = gen_label_rtx ();
3468: label4 = gen_label_rtx ();
3469: label5 = gen_label_rtx ();
3470: emit_cmp_insn (op1, const0_rtx, LT, NULL_RTX,
3471: compute_mode, 0, 0);
3472: emit_jump_insn (gen_blt (label2));
3473: emit_cmp_insn (adjusted_op0, const0_rtx, GT, NULL_RTX,
3474: compute_mode, 0, 0);
3475: emit_jump_insn (gen_bgt (label1));
3476: tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
3477: quotient, 0, OPTAB_LIB_WIDEN);
3478: if (tem != quotient)
3479: emit_move_insn (quotient, tem);
3480: emit_jump_insn (gen_jump (label5));
3481: emit_barrier ();
3482: emit_label (label1);
3483: expand_dec (adjusted_op0, const1_rtx);
3484: emit_jump_insn (gen_jump (label4));
3485: emit_barrier ();
3486: emit_label (label2);
3487: emit_cmp_insn (adjusted_op0, const0_rtx, LT, NULL_RTX,
3488: compute_mode, 0, 0);
3489: emit_jump_insn (gen_blt (label3));
3490: tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
3491: quotient, 0, OPTAB_LIB_WIDEN);
3492: if (tem != quotient)
3493: emit_move_insn (quotient, tem);
3494: emit_jump_insn (gen_jump (label5));
3495: emit_barrier ();
3496: emit_label (label3);
3497: expand_inc (adjusted_op0, const1_rtx);
3498: emit_label (label4);
3499: tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
3500: quotient, 0, OPTAB_LIB_WIDEN);
3501: if (tem != quotient)
3502: emit_move_insn (quotient, tem);
3503: expand_inc (quotient, const1_rtx);
3504: emit_label (label5);
1.1 root 3505: }
1.1.1.7 root 3506: }
3507: break;
1.1.1.6 root 3508:
1.1.1.7 root 3509: case EXACT_DIV_EXPR:
3510: if (op1_is_constant && HOST_BITS_PER_WIDE_INT >= size)
3511: {
3512: HOST_WIDE_INT d = INTVAL (op1);
3513: unsigned HOST_WIDE_INT ml;
3514: int post_shift;
3515: rtx t1;
3516:
3517: post_shift = floor_log2 (d & -d);
3518: ml = invert_mod2n (d >> post_shift, size);
3519: t1 = expand_mult (compute_mode, op0, GEN_INT (ml), NULL_RTX,
3520: unsignedp);
3521: quotient = expand_shift (RSHIFT_EXPR, compute_mode, t1,
3522: build_int_2 (post_shift, 0),
3523: NULL_RTX, unsignedp);
3524:
3525: insn = get_last_insn ();
3526: REG_NOTES (insn)
3527: = gen_rtx (EXPR_LIST, REG_EQUAL,
3528: gen_rtx (unsignedp ? UDIV : DIV, compute_mode,
3529: op0, op1),
3530: REG_NOTES (insn));
3531: }
3532: break;
1.1 root 3533:
1.1.1.7 root 3534: case ROUND_DIV_EXPR:
3535: case ROUND_MOD_EXPR:
3536: if (unsignedp)
3537: {
3538: rtx tem;
3539: rtx label;
3540: label = gen_label_rtx ();
3541: quotient = gen_reg_rtx (compute_mode);
3542: remainder = gen_reg_rtx (compute_mode);
3543: if (expand_twoval_binop (udivmod_optab, op0, op1, quotient, remainder, 1) == 0)
3544: {
3545: rtx tem;
3546: quotient = expand_binop (compute_mode, udiv_optab, op0, op1,
3547: quotient, 1, OPTAB_LIB_WIDEN);
3548: tem = expand_mult (compute_mode, quotient, op1, NULL_RTX, 1);
3549: remainder = expand_binop (compute_mode, sub_optab, op0, tem,
3550: remainder, 1, OPTAB_LIB_WIDEN);
3551: }
3552: tem = plus_constant (op1, -1);
3553: tem = expand_shift (RSHIFT_EXPR, compute_mode, tem,
3554: build_int_2 (1, 0), NULL_RTX, 1);
3555: emit_cmp_insn (remainder, tem, LEU, NULL_RTX, compute_mode, 0, 0);
3556: emit_jump_insn (gen_bleu (label));
3557: expand_inc (quotient, const1_rtx);
3558: expand_dec (remainder, op1);
3559: emit_label (label);
3560: }
3561: else
3562: {
3563: rtx abs_rem, abs_op1, tem, mask;
3564: rtx label;
3565: label = gen_label_rtx ();
3566: quotient = gen_reg_rtx (compute_mode);
3567: remainder = gen_reg_rtx (compute_mode);
3568: if (expand_twoval_binop (sdivmod_optab, op0, op1, quotient, remainder, 0) == 0)
3569: {
3570: rtx tem;
3571: quotient = expand_binop (compute_mode, sdiv_optab, op0, op1,
3572: quotient, 0, OPTAB_LIB_WIDEN);
3573: tem = expand_mult (compute_mode, quotient, op1, NULL_RTX, 0);
3574: remainder = expand_binop (compute_mode, sub_optab, op0, tem,
3575: remainder, 0, OPTAB_LIB_WIDEN);
3576: }
3577: abs_rem = expand_abs (compute_mode, remainder, NULL_RTX, 0, 0);
3578: abs_op1 = expand_abs (compute_mode, op1, NULL_RTX, 0, 0);
3579: tem = expand_shift (LSHIFT_EXPR, compute_mode, abs_rem,
3580: build_int_2 (1, 0), NULL_RTX, 1);
3581: emit_cmp_insn (tem, abs_op1, LTU, NULL_RTX, compute_mode, 0, 0);
3582: emit_jump_insn (gen_bltu (label));
3583: tem = expand_binop (compute_mode, xor_optab, op0, op1,
3584: NULL_RTX, 0, OPTAB_WIDEN);
3585: mask = expand_shift (RSHIFT_EXPR, compute_mode, tem,
3586: build_int_2 (size - 1, 0), NULL_RTX, 0);
3587: tem = expand_binop (compute_mode, xor_optab, mask, const1_rtx,
3588: NULL_RTX, 0, OPTAB_WIDEN);
3589: tem = expand_binop (compute_mode, sub_optab, tem, mask,
3590: NULL_RTX, 0, OPTAB_WIDEN);
3591: expand_inc (quotient, tem);
3592: tem = expand_binop (compute_mode, xor_optab, mask, op1,
3593: NULL_RTX, 0, OPTAB_WIDEN);
3594: tem = expand_binop (compute_mode, sub_optab, tem, mask,
3595: NULL_RTX, 0, OPTAB_WIDEN);
3596: expand_dec (remainder, tem);
3597: emit_label (label);
3598: }
3599: return gen_lowpart (mode, rem_flag ? remainder : quotient);
3600: }
3601:
3602: if (quotient == 0)
1.1 root 3603: {
1.1.1.7 root 3604: if (rem_flag)
1.1 root 3605: {
1.1.1.7 root 3606: /* Try to produce the remainder directly without a library call. */
3607: remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab,
3608: op0, op1, target,
3609: unsignedp, OPTAB_WIDEN);
3610: if (remainder == 0)
1.1 root 3611: {
3612: /* No luck there. Can we do remainder and divide at once
3613: without a library call? */
1.1.1.7 root 3614: remainder = gen_reg_rtx (compute_mode);
3615: if (! expand_twoval_binop ((unsignedp
3616: ? udivmod_optab
3617: : sdivmod_optab),
3618: op0, op1,
3619: NULL_RTX, remainder, unsignedp))
3620: remainder = 0;
1.1 root 3621: }
1.1.1.7 root 3622:
3623: if (remainder)
3624: return gen_lowpart (mode, remainder);
1.1 root 3625: }
3626:
1.1.1.7 root 3627: /* Produce the quotient. */
1.1 root 3628: /* Try a quotient insn, but not a library call. */
1.1.1.7 root 3629: quotient = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab,
3630: op0, op1, rem_flag ? NULL_RTX : target,
3631: unsignedp, OPTAB_WIDEN);
3632: if (quotient == 0)
1.1 root 3633: {
3634: /* No luck there. Try a quotient-and-remainder insn,
3635: keeping the quotient alone. */
1.1.1.7 root 3636: quotient = gen_reg_rtx (compute_mode);
1.1 root 3637: if (! expand_twoval_binop (unsignedp ? udivmod_optab : sdivmod_optab,
1.1.1.7 root 3638: op0, op1,
3639: quotient, NULL_RTX, unsignedp))
3640: {
3641: quotient = 0;
3642: if (! rem_flag)
3643: /* Still no luck. If we are not computing the remainder,
3644: use a library call for the quotient. */
3645: quotient = sign_expand_binop (compute_mode,
3646: udiv_optab, sdiv_optab,
3647: op0, op1, target,
3648: unsignedp, OPTAB_LIB_WIDEN);
3649: }
1.1 root 3650: }
3651: }
3652:
3653: if (rem_flag)
3654: {
1.1.1.7 root 3655: if (quotient == 0)
1.1 root 3656: /* No divide instruction either. Use library for remainder. */
1.1.1.7 root 3657: remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab,
3658: op0, op1, target,
3659: unsignedp, OPTAB_LIB_WIDEN);
1.1 root 3660: else
3661: {
3662: /* We divided. Now finish doing X - Y * (X / Y). */
1.1.1.7 root 3663: remainder = expand_mult (compute_mode, quotient, op1,
3664: NULL_RTX, unsignedp);
3665: remainder = expand_binop (compute_mode, sub_optab, op0,
3666: remainder, target, unsignedp,
3667: OPTAB_LIB_WIDEN);
1.1 root 3668: }
3669: }
3670:
1.1.1.7 root 3671: return gen_lowpart (mode, rem_flag ? remainder : quotient);
1.1 root 3672: }
3673:
3674: /* Return a tree node with data type TYPE, describing the value of X.
3675: Usually this is an RTL_EXPR, if there is no obvious better choice.
3676: X may be an expression, however we only support those expressions
3677: generated by loop.c. */
3678:
3679: tree
3680: make_tree (type, x)
3681: tree type;
3682: rtx x;
3683: {
3684: tree t;
3685:
3686: switch (GET_CODE (x))
3687: {
3688: case CONST_INT:
3689: t = build_int_2 (INTVAL (x),
1.1.1.6 root 3690: TREE_UNSIGNED (type) || INTVAL (x) >= 0 ? 0 : -1);
1.1 root 3691: TREE_TYPE (t) = type;
3692: return t;
3693:
3694: case CONST_DOUBLE:
3695: if (GET_MODE (x) == VOIDmode)
3696: {
3697: t = build_int_2 (CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x));
3698: TREE_TYPE (t) = type;
3699: }
3700: else
3701: {
3702: REAL_VALUE_TYPE d;
3703:
3704: REAL_VALUE_FROM_CONST_DOUBLE (d, x);
3705: t = build_real (type, d);
3706: }
3707:
3708: return t;
3709:
3710: case PLUS:
3711: return fold (build (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)),
3712: make_tree (type, XEXP (x, 1))));
3713:
3714: case MINUS:
3715: return fold (build (MINUS_EXPR, type, make_tree (type, XEXP (x, 0)),
3716: make_tree (type, XEXP (x, 1))));
3717:
3718: case NEG:
3719: return fold (build1 (NEGATE_EXPR, type, make_tree (type, XEXP (x, 0))));
3720:
3721: case MULT:
3722: return fold (build (MULT_EXPR, type, make_tree (type, XEXP (x, 0)),
3723: make_tree (type, XEXP (x, 1))));
3724:
3725: case ASHIFT:
3726: return fold (build (LSHIFT_EXPR, type, make_tree (type, XEXP (x, 0)),
3727: make_tree (type, XEXP (x, 1))));
3728:
3729: case LSHIFTRT:
3730: return fold (convert (type,
3731: build (RSHIFT_EXPR, unsigned_type (type),
3732: make_tree (unsigned_type (type),
3733: XEXP (x, 0)),
3734: make_tree (type, XEXP (x, 1)))));
3735:
3736: case ASHIFTRT:
3737: return fold (convert (type,
3738: build (RSHIFT_EXPR, signed_type (type),
3739: make_tree (signed_type (type), XEXP (x, 0)),
3740: make_tree (type, XEXP (x, 1)))));
3741:
3742: case DIV:
3743: if (TREE_CODE (type) != REAL_TYPE)
3744: t = signed_type (type);
3745: else
3746: t = type;
3747:
3748: return fold (convert (type,
3749: build (TRUNC_DIV_EXPR, t,
3750: make_tree (t, XEXP (x, 0)),
3751: make_tree (t, XEXP (x, 1)))));
3752: case UDIV:
3753: t = unsigned_type (type);
3754: return fold (convert (type,
3755: build (TRUNC_DIV_EXPR, t,
3756: make_tree (t, XEXP (x, 0)),
3757: make_tree (t, XEXP (x, 1)))));
3758: default:
3759: t = make_node (RTL_EXPR);
3760: TREE_TYPE (t) = type;
3761: RTL_EXPR_RTL (t) = x;
3762: /* There are no insns to be output
3763: when this rtl_expr is used. */
3764: RTL_EXPR_SEQUENCE (t) = 0;
3765: return t;
3766: }
3767: }
3768:
3769: /* Return an rtx representing the value of X * MULT + ADD.
3770: TARGET is a suggestion for where to store the result (an rtx).
3771: MODE is the machine mode for the computation.
3772: X and MULT must have mode MODE. ADD may have a different mode.
3773: So can X (defaults to same as MODE).
3774: UNSIGNEDP is non-zero to do unsigned multiplication.
3775: This may emit insns. */
3776:
3777: rtx
3778: expand_mult_add (x, target, mult, add, mode, unsignedp)
3779: rtx x, target, mult, add;
3780: enum machine_mode mode;
3781: int unsignedp;
3782: {
3783: tree type = type_for_mode (mode, unsignedp);
3784: tree add_type = (GET_MODE (add) == VOIDmode
1.1.1.2 root 3785: ? type : type_for_mode (GET_MODE (add), unsignedp));
1.1 root 3786: tree result = fold (build (PLUS_EXPR, type,
3787: fold (build (MULT_EXPR, type,
3788: make_tree (type, x),
3789: make_tree (type, mult))),
3790: make_tree (add_type, add)));
3791:
3792: return expand_expr (result, target, VOIDmode, 0);
3793: }
3794:
3795: /* Compute the logical-and of OP0 and OP1, storing it in TARGET
3796: and returning TARGET.
3797:
3798: If TARGET is 0, a pseudo-register or constant is returned. */
3799:
3800: rtx
3801: expand_and (op0, op1, target)
3802: rtx op0, op1, target;
3803: {
3804: enum machine_mode mode = VOIDmode;
3805: rtx tem;
3806:
3807: if (GET_MODE (op0) != VOIDmode)
3808: mode = GET_MODE (op0);
3809: else if (GET_MODE (op1) != VOIDmode)
3810: mode = GET_MODE (op1);
3811:
3812: if (mode != VOIDmode)
3813: tem = expand_binop (mode, and_optab, op0, op1, target, 0, OPTAB_LIB_WIDEN);
3814: else if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT)
1.1.1.4 root 3815: tem = GEN_INT (INTVAL (op0) & INTVAL (op1));
1.1 root 3816: else
3817: abort ();
3818:
3819: if (target == 0)
3820: target = tem;
3821: else if (tem != target)
3822: emit_move_insn (target, tem);
3823: return target;
3824: }
3825:
3826: /* Emit a store-flags instruction for comparison CODE on OP0 and OP1
3827: and storing in TARGET. Normally return TARGET.
3828: Return 0 if that cannot be done.
3829:
3830: MODE is the mode to use for OP0 and OP1 should they be CONST_INTs. If
3831: it is VOIDmode, they cannot both be CONST_INT.
3832:
3833: UNSIGNEDP is for the case where we have to widen the operands
3834: to perform the operation. It says to use zero-extension.
3835:
3836: NORMALIZEP is 1 if we should convert the result to be either zero
3837: or one one. Normalize is -1 if we should convert the result to be
3838: either zero or -1. If NORMALIZEP is zero, the result will be left
3839: "raw" out of the scc insn. */
3840:
3841: rtx
3842: emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
3843: rtx target;
3844: enum rtx_code code;
3845: rtx op0, op1;
3846: enum machine_mode mode;
3847: int unsignedp;
3848: int normalizep;
3849: {
3850: rtx subtarget;
3851: enum insn_code icode;
3852: enum machine_mode compare_mode;
3853: enum machine_mode target_mode = GET_MODE (target);
3854: rtx tem;
1.1.1.8 ! root 3855: rtx last = get_last_insn ();
1.1 root 3856: rtx pattern, comparison;
3857:
1.1.1.5 root 3858: /* If one operand is constant, make it the second one. Only do this
3859: if the other operand is not constant as well. */
3860:
3861: if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3862: || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3863: {
3864: tem = op0;
3865: op0 = op1;
3866: op1 = tem;
3867: code = swap_condition (code);
3868: }
3869:
1.1.1.8 ! root 3870: if (mode == VOIDmode)
! 3871: mode = GET_MODE (op0);
! 3872:
1.1 root 3873: /* For some comparisons with 1 and -1, we can convert this to
3874: comparisons with zero. This will often produce more opportunities for
3875: store-flag insns. */
3876:
3877: switch (code)
3878: {
3879: case LT:
3880: if (op1 == const1_rtx)
3881: op1 = const0_rtx, code = LE;
3882: break;
3883: case LE:
3884: if (op1 == constm1_rtx)
3885: op1 = const0_rtx, code = LT;
3886: break;
3887: case GE:
3888: if (op1 == const1_rtx)
3889: op1 = const0_rtx, code = GT;
3890: break;
3891: case GT:
3892: if (op1 == constm1_rtx)
3893: op1 = const0_rtx, code = GE;
3894: break;
3895: case GEU:
3896: if (op1 == const1_rtx)
3897: op1 = const0_rtx, code = NE;
3898: break;
3899: case LTU:
3900: if (op1 == const1_rtx)
3901: op1 = const0_rtx, code = EQ;
3902: break;
3903: }
3904:
3905: /* From now on, we won't change CODE, so set ICODE now. */
3906: icode = setcc_gen_code[(int) code];
3907:
3908: /* If this is A < 0 or A >= 0, we can do this by taking the ones
3909: complement of A (for GE) and shifting the sign bit to the low bit. */
3910: if (op1 == const0_rtx && (code == LT || code == GE)
3911: && GET_MODE_CLASS (mode) == MODE_INT
3912: && (normalizep || STORE_FLAG_VALUE == 1
1.1.1.4 root 3913: || (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
3914: && (STORE_FLAG_VALUE
3915: == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))))
1.1 root 3916: {
1.1.1.5 root 3917: subtarget = target;
1.1 root 3918:
3919: /* If the result is to be wider than OP0, it is best to convert it
3920: first. If it is to be narrower, it is *incorrect* to convert it
3921: first. */
3922: if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (mode))
3923: {
1.1.1.4 root 3924: op0 = protect_from_queue (op0, 0);
1.1.1.6 root 3925: op0 = convert_modes (target_mode, mode, op0, 0);
1.1 root 3926: mode = target_mode;
3927: }
3928:
3929: if (target_mode != mode)
3930: subtarget = 0;
3931:
3932: if (code == GE)
3933: op0 = expand_unop (mode, one_cmpl_optab, op0, subtarget, 0);
3934:
3935: if (normalizep || STORE_FLAG_VALUE == 1)
3936: /* If we are supposed to produce a 0/1 value, we want to do
3937: a logical shift from the sign bit to the low-order bit; for
3938: a -1/0 value, we do an arithmetic shift. */
3939: op0 = expand_shift (RSHIFT_EXPR, mode, op0,
3940: size_int (GET_MODE_BITSIZE (mode) - 1),
3941: subtarget, normalizep != -1);
3942:
3943: if (mode != target_mode)
1.1.1.6 root 3944: op0 = convert_modes (target_mode, mode, op0, 0);
1.1 root 3945:
3946: return op0;
3947: }
3948:
3949: if (icode != CODE_FOR_nothing)
3950: {
3951: /* We think we may be able to do this with a scc insn. Emit the
3952: comparison and then the scc insn.
3953:
3954: compare_from_rtx may call emit_queue, which would be deleted below
3955: if the scc insn fails. So call it ourselves before setting LAST. */
3956:
3957: emit_queue ();
3958: last = get_last_insn ();
3959:
1.1.1.4 root 3960: comparison
3961: = compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX, 0);
1.1 root 3962: if (GET_CODE (comparison) == CONST_INT)
3963: return (comparison == const0_rtx ? const0_rtx
3964: : normalizep == 1 ? const1_rtx
3965: : normalizep == -1 ? constm1_rtx
3966: : const_true_rtx);
3967:
1.1.1.5 root 3968: /* If the code of COMPARISON doesn't match CODE, something is
3969: wrong; we can no longer be sure that we have the operation.
3970: We could handle this case, but it should not happen. */
3971:
3972: if (GET_CODE (comparison) != code)
3973: abort ();
3974:
1.1 root 3975: /* Get a reference to the target in the proper mode for this insn. */
3976: compare_mode = insn_operand_mode[(int) icode][0];
3977: subtarget = target;
3978: if (preserve_subexpressions_p ()
3979: || ! (*insn_operand_predicate[(int) icode][0]) (subtarget, compare_mode))
3980: subtarget = gen_reg_rtx (compare_mode);
3981:
3982: pattern = GEN_FCN (icode) (subtarget);
3983: if (pattern)
3984: {
3985: emit_insn (pattern);
3986:
3987: /* If we are converting to a wider mode, first convert to
3988: TARGET_MODE, then normalize. This produces better combining
3989: opportunities on machines that have a SIGN_EXTRACT when we are
3990: testing a single bit. This mostly benefits the 68k.
3991:
3992: If STORE_FLAG_VALUE does not have the sign bit set when
3993: interpreted in COMPARE_MODE, we can do this conversion as
3994: unsigned, which is usually more efficient. */
3995: if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (compare_mode))
3996: {
3997: convert_move (target, subtarget,
3998: (GET_MODE_BITSIZE (compare_mode)
1.1.1.4 root 3999: <= HOST_BITS_PER_WIDE_INT)
1.1 root 4000: && 0 == (STORE_FLAG_VALUE
1.1.1.4 root 4001: & ((HOST_WIDE_INT) 1
4002: << (GET_MODE_BITSIZE (compare_mode) -1))));
1.1 root 4003: op0 = target;
4004: compare_mode = target_mode;
4005: }
4006: else
4007: op0 = subtarget;
4008:
1.1.1.4 root 4009: /* If we want to keep subexpressions around, don't reuse our
4010: last target. */
4011:
4012: if (preserve_subexpressions_p ())
4013: subtarget = 0;
4014:
1.1 root 4015: /* Now normalize to the proper value in COMPARE_MODE. Sometimes
4016: we don't have to do anything. */
4017: if (normalizep == 0 || normalizep == STORE_FLAG_VALUE)
4018: ;
4019: else if (normalizep == - STORE_FLAG_VALUE)
4020: op0 = expand_unop (compare_mode, neg_optab, op0, subtarget, 0);
4021:
4022: /* We don't want to use STORE_FLAG_VALUE < 0 below since this
4023: makes it hard to use a value of just the sign bit due to
4024: ANSI integer constant typing rules. */
1.1.1.4 root 4025: else if (GET_MODE_BITSIZE (compare_mode) <= HOST_BITS_PER_WIDE_INT
1.1 root 4026: && (STORE_FLAG_VALUE
1.1.1.4 root 4027: & ((HOST_WIDE_INT) 1
4028: << (GET_MODE_BITSIZE (compare_mode) - 1))))
1.1 root 4029: op0 = expand_shift (RSHIFT_EXPR, compare_mode, op0,
4030: size_int (GET_MODE_BITSIZE (compare_mode) - 1),
4031: subtarget, normalizep == 1);
4032: else if (STORE_FLAG_VALUE & 1)
4033: {
4034: op0 = expand_and (op0, const1_rtx, subtarget);
4035: if (normalizep == -1)
4036: op0 = expand_unop (compare_mode, neg_optab, op0, op0, 0);
4037: }
4038: else
4039: abort ();
4040:
4041: /* If we were converting to a smaller mode, do the
4042: conversion now. */
4043: if (target_mode != compare_mode)
4044: {
1.1.1.5 root 4045: convert_move (target, op0, 0);
1.1 root 4046: return target;
4047: }
4048: else
4049: return op0;
4050: }
4051: }
4052:
1.1.1.8 ! root 4053: delete_insns_since (last);
1.1 root 4054:
1.1.1.8 ! root 4055: /* If expensive optimizations, use different pseudo registers for each
! 4056: insn, instead of reusing the same pseudo. This leads to better CSE,
! 4057: but slows down the compiler, since there are more pseudos */
! 4058: subtarget = (!flag_expensive_optimizations
! 4059: && (target_mode == mode)) ? target : NULL_RTX;
1.1 root 4060:
4061: /* If we reached here, we can't do this with a scc insn. However, there
4062: are some comparisons that can be done directly. For example, if
4063: this is an equality comparison of integers, we can try to exclusive-or
4064: (or subtract) the two operands and use a recursive call to try the
4065: comparison with zero. Don't do any of these cases if branches are
4066: very cheap. */
4067:
1.1.1.5 root 4068: if (BRANCH_COST > 0
1.1 root 4069: && GET_MODE_CLASS (mode) == MODE_INT && (code == EQ || code == NE)
4070: && op1 != const0_rtx)
4071: {
4072: tem = expand_binop (mode, xor_optab, op0, op1, subtarget, 1,
4073: OPTAB_WIDEN);
4074:
4075: if (tem == 0)
4076: tem = expand_binop (mode, sub_optab, op0, op1, subtarget, 1,
4077: OPTAB_WIDEN);
4078: if (tem != 0)
4079: tem = emit_store_flag (target, code, tem, const0_rtx,
4080: mode, unsignedp, normalizep);
4081: if (tem == 0)
4082: delete_insns_since (last);
4083: return tem;
4084: }
4085:
4086: /* Some other cases we can do are EQ, NE, LE, and GT comparisons with
4087: the constant zero. Reject all other comparisons at this point. Only
4088: do LE and GT if branches are expensive since they are expensive on
4089: 2-operand machines. */
4090:
4091: if (BRANCH_COST == 0
4092: || GET_MODE_CLASS (mode) != MODE_INT || op1 != const0_rtx
4093: || (code != EQ && code != NE
4094: && (BRANCH_COST <= 1 || (code != LE && code != GT))))
4095: return 0;
4096:
4097: /* See what we need to return. We can only return a 1, -1, or the
4098: sign bit. */
4099:
4100: if (normalizep == 0)
4101: {
4102: if (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
4103: normalizep = STORE_FLAG_VALUE;
4104:
1.1.1.4 root 4105: else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
4106: && (STORE_FLAG_VALUE
4107: == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
1.1 root 4108: ;
4109: else
4110: return 0;
4111: }
4112:
4113: /* Try to put the result of the comparison in the sign bit. Assume we can't
4114: do the necessary operation below. */
4115:
4116: tem = 0;
4117:
4118: /* To see if A <= 0, compute (A | (A - 1)). A <= 0 iff that result has
4119: the sign bit set. */
4120:
4121: if (code == LE)
4122: {
4123: /* This is destructive, so SUBTARGET can't be OP0. */
4124: if (rtx_equal_p (subtarget, op0))
4125: subtarget = 0;
4126:
4127: tem = expand_binop (mode, sub_optab, op0, const1_rtx, subtarget, 0,
4128: OPTAB_WIDEN);
4129: if (tem)
4130: tem = expand_binop (mode, ior_optab, op0, tem, subtarget, 0,
4131: OPTAB_WIDEN);
4132: }
4133:
4134: /* To see if A > 0, compute (((signed) A) << BITS) - A, where BITS is the
4135: number of bits in the mode of OP0, minus one. */
4136:
4137: if (code == GT)
4138: {
4139: if (rtx_equal_p (subtarget, op0))
4140: subtarget = 0;
4141:
4142: tem = expand_shift (RSHIFT_EXPR, mode, op0,
4143: size_int (GET_MODE_BITSIZE (mode) - 1),
4144: subtarget, 0);
4145: tem = expand_binop (mode, sub_optab, tem, op0, subtarget, 0,
4146: OPTAB_WIDEN);
4147: }
4148:
4149: if (code == EQ || code == NE)
4150: {
4151: /* For EQ or NE, one way to do the comparison is to apply an operation
4152: that converts the operand into a positive number if it is non-zero
4153: or zero if it was originally zero. Then, for EQ, we subtract 1 and
4154: for NE we negate. This puts the result in the sign bit. Then we
4155: normalize with a shift, if needed.
4156:
4157: Two operations that can do the above actions are ABS and FFS, so try
4158: them. If that doesn't work, and MODE is smaller than a full word,
1.1.1.2 root 4159: we can use zero-extension to the wider mode (an unsigned conversion)
1.1 root 4160: as the operation. */
4161:
4162: if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4163: tem = expand_unop (mode, abs_optab, op0, subtarget, 1);
4164: else if (ffs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4165: tem = expand_unop (mode, ffs_optab, op0, subtarget, 1);
4166: else if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
4167: {
1.1.1.4 root 4168: op0 = protect_from_queue (op0, 0);
1.1.1.6 root 4169: tem = convert_modes (word_mode, mode, op0, 1);
4170: mode = word_mode;
1.1 root 4171: }
4172:
4173: if (tem != 0)
4174: {
4175: if (code == EQ)
4176: tem = expand_binop (mode, sub_optab, tem, const1_rtx, subtarget,
4177: 0, OPTAB_WIDEN);
4178: else
4179: tem = expand_unop (mode, neg_optab, tem, subtarget, 0);
4180: }
4181:
4182: /* If we couldn't do it that way, for NE we can "or" the two's complement
4183: of the value with itself. For EQ, we take the one's complement of
4184: that "or", which is an extra insn, so we only handle EQ if branches
4185: are expensive. */
4186:
4187: if (tem == 0 && (code == NE || BRANCH_COST > 1))
4188: {
1.1.1.2 root 4189: if (rtx_equal_p (subtarget, op0))
4190: subtarget = 0;
4191:
1.1 root 4192: tem = expand_unop (mode, neg_optab, op0, subtarget, 0);
4193: tem = expand_binop (mode, ior_optab, tem, op0, subtarget, 0,
4194: OPTAB_WIDEN);
4195:
4196: if (tem && code == EQ)
4197: tem = expand_unop (mode, one_cmpl_optab, tem, subtarget, 0);
4198: }
4199: }
4200:
4201: if (tem && normalizep)
4202: tem = expand_shift (RSHIFT_EXPR, mode, tem,
4203: size_int (GET_MODE_BITSIZE (mode) - 1),
1.1.1.8 ! root 4204: subtarget, normalizep == 1);
1.1 root 4205:
1.1.1.8 ! root 4206: if (tem)
1.1 root 4207: {
1.1.1.8 ! root 4208: if (GET_MODE (tem) != target_mode)
! 4209: {
! 4210: convert_move (target, tem, 0);
! 4211: tem = target;
! 4212: }
! 4213: else if (!subtarget)
! 4214: {
! 4215: emit_move_insn (target, tem);
! 4216: tem = target;
! 4217: }
1.1 root 4218: }
1.1.1.8 ! root 4219: else
1.1 root 4220: delete_insns_since (last);
4221:
4222: return tem;
4223: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.