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