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