Deleted Added
full compact
246a247
> static void dup_replacements PARAMS ((rtx *, rtx *));
259a261
> static int maybe_memory_address_p PARAMS ((enum machine_mode, rtx, rtx *));
278c280
< non-zero) or storing (if IN_P is zero) X to or from a reload register of
---
> nonzero) or storing (if IN_P is zero) X to or from a reload register of
370c372
< /* If IN_P is non-zero, the reload register will be the output in
---
> /* If IN_P is nonzero, the reload register will be the output in
647c649
< find_reloads_address (mode, (rtx*) 0, XEXP (loc, 0), &XEXP (loc, 0),
---
> find_reloads_address (mode, &loc, XEXP (loc, 0), &XEXP (loc, 0),
819a822,828
> if (!subreg_offset_representable_p
> (REGNO (SUBREG_REG (x)),
> GET_MODE (SUBREG_REG (x)),
> SUBREG_BYTE (x),
> GET_MODE (x)))
> return 1;
>
831c840
< != HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner))));
---
> != (int) HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner))));
840c849
< If IN and OUT are both non-zero, it means the same register must be used
---
> If IN and OUT are both nonzero, it means the same register must be used
969,971c978,979
< #ifdef CLASS_CANNOT_CHANGE_MODE
< && (class != CLASS_CANNOT_CHANGE_MODE
< || ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)), inmode))
---
> #ifdef CANNOT_CHANGE_MODE_CLASS
> && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, class)
1008,1009c1016,1017
< != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
< GET_MODE (SUBREG_REG (in)))))
---
> != (int) HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
> GET_MODE (SUBREG_REG (in)))))
1018c1026
< #ifdef CLASS_CANNOT_CHANGE_MODE
---
> #ifdef CANNOT_CHANGE_MODE_CLASS
1021,1025c1029,1030
< && (TEST_HARD_REG_BIT
< (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
< REGNO (SUBREG_REG (in))))
< && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)),
< inmode))
---
> && REG_CANNOT_CHANGE_MODE_P
> (REGNO (SUBREG_REG (in)), GET_MODE (SUBREG_REG (in)), inmode))
1083,1086c1088,1089
< #ifdef CLASS_CANNOT_CHANGE_MODE
< && (class != CLASS_CANNOT_CHANGE_MODE
< || ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
< outmode))
---
> #ifdef CANNOT_CHANGE_MODE_CLASS
> && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, class)
1110,1111c1113,1114
< != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
< GET_MODE (SUBREG_REG (out)))))
---
> != (int) HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
> GET_MODE (SUBREG_REG (out)))))
1120c1123
< #ifdef CLASS_CANNOT_CHANGE_MODE
---
> #ifdef CANNOT_CHANGE_MODE_CLASS
1123,1127c1126,1128
< && (TEST_HARD_REG_BIT
< (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
< REGNO (SUBREG_REG (out))))
< && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
< outmode))
---
> && REG_CANNOT_CHANGE_MODE_P (REGNO (SUBREG_REG (out)),
> GET_MODE (SUBREG_REG (out)),
> outmode))
1288,1298c1289,1294
< {
< int regnum;
<
< /* If a memory location is needed for the copy, make one. */
< if (in != 0
< && ((regnum = true_regnum (in)) >= 0)
< && regnum < FIRST_PSEUDO_REGISTER
< && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (regnum),
< class, inmode))
< get_secondary_mem (in, inmode, opnum, type);
< }
---
> /* If a memory location is needed for the copy, make one. */
> if (in != 0 && (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
> && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
> && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
> class, inmode))
> get_secondary_mem (in, inmode, opnum, type);
1324,1333c1320,1325
< {
< int regnum;
<
< if (out != 0
< && ((regnum = true_regnum (out)) >= 0)
< && regnum < FIRST_PSEUDO_REGISTER
< && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (regnum),
< outmode))
< get_secondary_mem (out, outmode, opnum, type);
< }
---
> if (out != 0 && (GET_CODE (out) == REG || GET_CODE (out) == SUBREG)
> && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
> && SECONDARY_MEMORY_NEEDED (class,
> REGNO_REG_CLASS (reg_or_subregno (out)),
> outmode))
> get_secondary_mem (out, outmode, opnum, type);
1577a1570,1588
>
> /* Duplicate any replacement we have recorded to apply at
> location ORIG_LOC to also be performed at DUP_LOC.
> This is used in insn patterns that use match_dup. */
>
> static void
> dup_replacements (dup_loc, orig_loc)
> rtx *dup_loc;
> rtx *orig_loc;
> {
> int i, n = n_replacements;
>
> for (i = 0; i < n; i++)
> {
> struct replacement *r = &replacements[i];
> if (r->where == orig_loc)
> push_replacement (dup_loc, r->what, r->mode);
> }
> }
1596c1607
< Return non-zero if we canceled any reloads. */
---
> Return nonzero if we canceled any reloads. */
1836c1847
< EARLYCLOBBER is non-zero if OUT is an earlyclobber operand. This
---
> EARLYCLOBBER is nonzero if OUT is an earlyclobber operand. This
2139c2150
< On the other hand, an postincrement matches ordinary indexing
---
> On the other hand, a postincrement matches ordinary indexing
2145c2156
< On the other hand, an preincrement matches ordinary indexing
---
> On the other hand, a preincrement matches ordinary indexing
2467a2479,2480
> /* Nonzero for an address operand that needs to be completely reloaded. */
> int address_operand_reloaded[MAX_RECOG_OPERANDS];
2645a2659
> address_operand_reloaded[i] = 0;
2657c2671,2672
< else if (constraints[i][0] == 'p')
---
> else if (constraints[i][0] == 'p'
> || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
2659,2662c2674,2678
< find_reloads_address (recog_data.operand_mode[i], (rtx*) 0,
< recog_data.operand[i],
< recog_data.operand_loc[i],
< i, operand_type[i], ind_levels, insn);
---
> address_operand_reloaded[i]
> = find_reloads_address (recog_data.operand_mode[i], (rtx*) 0,
> recog_data.operand[i],
> recog_data.operand_loc[i],
> i, operand_type[i], ind_levels, insn);
2678a2695,2698
>
> /* Address operands are reloaded in their existing mode,
> no matter what is specified in the machine description. */
> operand_mode[i] = GET_MODE (recog_data.operand[i]);
2858a2879,2884
> if (!subreg_offset_representable_p
> (REGNO (SUBREG_REG (operand)),
> GET_MODE (SUBREG_REG (operand)),
> SUBREG_BYTE (operand),
> GET_MODE (operand)))
> force_reload = 1;
2914,2933d2939
< /* This following hunk of code should no longer be
< needed at all with SUBREG_BYTE. If you need this
< code back, please explain to me why so I can
< fix the real problem. -DaveM */
< #if 0
< /* Subreg of a hard reg which can't handle the subreg's mode
< or which would handle that mode in the wrong number of
< registers for subregging to work. */
< || (GET_CODE (operand) == REG
< && REGNO (operand) < FIRST_PSEUDO_REGISTER
< && ((GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
< && (GET_MODE_SIZE (GET_MODE (operand))
< > UNITS_PER_WORD)
< && ((GET_MODE_SIZE (GET_MODE (operand))
< / UNITS_PER_WORD)
< != HARD_REGNO_NREGS (REGNO (operand),
< GET_MODE (operand))))
< || ! HARD_REGNO_MODE_OK (REGNO (operand) + offset,
< operand_mode[i])))
< #endif
3157,3168d3162
< #ifndef REAL_ARITHMETIC
< /* Match any floating double constant, but only if
< we can examine the bits of it reliably. */
< if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
< || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
< && GET_MODE (operand) != VOIDmode && ! flag_pretend_float)
< break;
< #endif
< if (GET_CODE (operand) == CONST_DOUBLE)
< win = 1;
< break;
<
3170c3164,3167
< if (GET_CODE (operand) == CONST_DOUBLE)
---
> if (GET_CODE (operand) == CONST_DOUBLE
> || (GET_CODE (operand) == CONST_VECTOR
> && (GET_MODE_CLASS (GET_MODE (operand))
> == MODE_VECTOR_FLOAT)))
3246a3244,3286
> if (EXTRA_MEMORY_CONSTRAINT (c))
> {
> if (force_reload)
> break;
> if (EXTRA_CONSTRAINT (operand, c))
> win = 1;
> /* If the address was already reloaded,
> we win as well. */
> if (GET_CODE (operand) == MEM && address_reloaded[i])
> win = 1;
> /* Likewise if the address will be reloaded because
> reg_equiv_address is nonzero. For reg_equiv_mem
> we have to check. */
> if (GET_CODE (operand) == REG
> && REGNO (operand) >= FIRST_PSEUDO_REGISTER
> && reg_renumber[REGNO (operand)] < 0
> && ((reg_equiv_mem[REGNO (operand)] != 0
> && EXTRA_CONSTRAINT (reg_equiv_mem[REGNO (operand)], c))
> || (reg_equiv_address[REGNO (operand)] != 0)))
> win = 1;
>
> /* If we didn't already win, we can reload
> constants via force_const_mem, and other
> MEMs by reloading the address like for 'o'. */
> if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
> || GET_CODE (operand) == MEM)
> badop = 0;
> constmemok = 1;
> offmemok = 1;
> break;
> }
> if (EXTRA_ADDRESS_CONSTRAINT (c))
> {
> if (EXTRA_CONSTRAINT (operand, c))
> win = 1;
>
> /* If we didn't already win, we can reload
> the address into a base register. */
> this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
> badop = 0;
> break;
> }
>
3609c3649
<
---
>
3812a3853
> && !address_operand_reloaded[i]
3960,3962c4001
< if (operand_reloadnum[opno] >= 0)
< push_replacement (recog_data.dup_loc[i], operand_reloadnum[opno],
< insn_data[insn_code_number].operand[opno].mode);
---
> dup_replacements (recog_data.dup_loc[i], recog_data.operand_loc[opno]);
4316c4355
< if (c == 'm' || c == 'o')
---
> if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c))
4441,4468d4479
< /* If the SUBREG is wider than a word, the above test will fail.
< For example, we might have a SImode SUBREG of a DImode SUBREG_REG
< for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
< a 32 bit target. We still can - and have to - handle this
< for non-paradoxical subregs of CONST_INTs. */
< if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
< && reg_equiv_constant[regno] != 0
< && GET_CODE (reg_equiv_constant[regno]) == CONST_INT
< && (GET_MODE_SIZE (GET_MODE (x))
< < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
< {
< int shift = SUBREG_BYTE (x) * BITS_PER_UNIT;
< if (WORDS_BIG_ENDIAN)
< shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
< - GET_MODE_BITSIZE (GET_MODE (x))
< - shift);
< /* Here we use the knowledge that CONST_INTs have a
< HOST_WIDE_INT field. */
< if (shift >= HOST_BITS_PER_WIDE_INT)
< shift = HOST_BITS_PER_WIDE_INT - 1;
< return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
< }
<
< if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
< && reg_equiv_constant[regno] != 0
< && GET_MODE (reg_equiv_constant[regno]) == VOIDmode)
< abort ();
<
4547a4559,4579
> /* Returns true if AD could be turned into a valid memory reference
> to mode MODE by reloading the part pointed to by PART into a
> register. */
>
> static int
> maybe_memory_address_p (mode, ad, part)
> enum machine_mode mode;
> rtx ad;
> rtx *part;
> {
> int retv;
> rtx tem = *part;
> rtx reg = gen_rtx_REG (GET_MODE (tem), max_reg_num ());
>
> *part = reg;
> retv = memory_address_p (mode, ad);
> *part = tem;
>
> return retv;
> }
>
4614,4616c4646,4648
< find_reloads_address (GET_MODE (tem), (rtx*) 0, XEXP (tem, 0),
< &XEXP (tem, 0), opnum, ADDR_TYPE (type),
< ind_levels, insn);
---
> find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
> &XEXP (tem, 0), opnum,
> ADDR_TYPE (type), ind_levels, insn);
4828,4830c4860,4865
< If we decide to do something here, it must be that
< `double_reg_address_ok' is true and that this address rtl was made by
< eliminate_regs. We generate a reload of the fp/sp/ap + constant and
---
> Handle all base registers here, not just fp/ap/sp, because on some
> targets (namely Sparc) we can also get invalid addresses from preventive
> subreg big-endian corrections made by find_reloads_toplev.
>
> If we decide to do something, it must be that `double_reg_address_ok'
> is true. We generate a reload of the base register + constant and
4834,4835c4869,4870
< We check for fp/ap/sp as both the first and second operand of the
< innermost PLUS. */
---
> We check for the base register as both the first and second operand of
> the innermost PLUS. */
4839,4847c4874,4877
< && (XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx
< #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
< || XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx
< #endif
< #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
< || XEXP (XEXP (ad, 0), 0) == arg_pointer_rtx
< #endif
< || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
< && ! memory_address_p (mode, ad))
---
> && GET_CODE (XEXP (XEXP (ad, 0), 0)) == REG
> && REGNO (XEXP (XEXP (ad, 0), 0)) < FIRST_PSEUDO_REGISTER
> && REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 0), mode)
> && ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 1)))
4864,4872c4894,4897
< && (XEXP (XEXP (ad, 0), 1) == frame_pointer_rtx
< #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
< || XEXP (XEXP (ad, 0), 1) == hard_frame_pointer_rtx
< #endif
< #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
< || XEXP (XEXP (ad, 0), 1) == arg_pointer_rtx
< #endif
< || XEXP (XEXP (ad, 0), 1) == stack_pointer_rtx)
< && ! memory_address_p (mode, ad))
---
> && GET_CODE (XEXP (XEXP (ad, 0), 1)) == REG
> && REGNO (XEXP (XEXP (ad, 0), 1)) < FIRST_PSEUDO_REGISTER
> && REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 1), mode)
> && ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 0)))
5216a5242,5254
> /* Plus in the index register may be created only as a result of
> register remateralization for expresion like &localvar*4. Reload it.
> It may be possible to combine the displacement on the outer level,
> but it is probably not worthwhile to do so. */
> if (context)
> {
> find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
> opnum, ADDR_TYPE (type), ind_levels, insn);
> push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
> (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
> GET_MODE (x), VOIDmode, 0, 0, opnum, type);
> return 1;
> }
5344c5382
< find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0),
---
> find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
5647c5685
< if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
---
> if ((unsigned) CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
5991c6029
< /* Change any replacements being done to *X to be done to *Y */
---
> /* Change any replacements being done to *X to be done to *Y. */
6862c6900
<
---
>