diff --git a/gcc/ChangeLog b/gcc/ChangeLog index da6dede393c..783ee345d3e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-05-04 Eric Botcazou + + PR target/48496 + * recog.c (constrain_operands): If extra constraints are present, also + accept pseudo-registers with equivalent memory locations during reload. + 2012-05-04 Olivier Hainque * collect2.c (may_unlink_output_file): New global. diff --git a/gcc/recog.c b/gcc/recog.c index cb2bfd31701..3f6bc545fb4 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2680,6 +2680,16 @@ constrain_operands (int strict) /* Every address operand can be reloaded to fit. */ && strict < 0) win = 1; + /* Cater to architectures like IA-64 that define extra memory + constraints without using define_memory_constraint. */ + else if (reload_in_progress + && REG_P (op) + && REGNO (op) >= FIRST_PSEUDO_REGISTER + && reg_renumber[REGNO (op)] < 0 + && reg_equiv_mem (REGNO (op)) != 0 + && EXTRA_CONSTRAINT_STR + (reg_equiv_mem (REGNO (op)), c, p)) + win = 1; #endif break; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4600d5cb883..7036381b0ac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-05-04 Eric Botcazou + + * gcc.target/ia64/pr48496.c: New test. + * gcc.target/ia64/pr52657.c: Likewise. + 2012-05-04 Manuel López-Ibáñez PR c/51712 diff --git a/gcc/testsuite/gcc.target/ia64/pr48496.c b/gcc/testsuite/gcc.target/ia64/pr48496.c new file mode 100644 index 00000000000..6e604336adb --- /dev/null +++ b/gcc/testsuite/gcc.target/ia64/pr48496.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); + +typedef struct +{ + UINT64 x[2] __attribute__((aligned(16))); +} fpreg; + +struct ia64_args +{ + fpreg fp_regs[8]; + UINT64 gp_regs[8]; +}; + +ffi_call(long i, long gpcount, long fpcount, void **avalue) +{ + struct ia64_args *stack; + stack = __builtin_alloca (64); + asm ("stf.spill %0 = %1%P0" : "=m" (*&stack->fp_regs[fpcount++]) + : "f"(*(double *)avalue[i])); + stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i]; +} diff --git a/gcc/testsuite/gcc.target/ia64/pr52657.c b/gcc/testsuite/gcc.target/ia64/pr52657.c new file mode 100644 index 00000000000..8db5881985e --- /dev/null +++ b/gcc/testsuite/gcc.target/ia64/pr52657.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +typedef unsigned long int mp_limb_t; + +typedef struct +{ + int _mp_alloc; + int _mp_size; + mp_limb_t *_mp_d; +} __mpz_struct; + +typedef __mpz_struct mpz_t[1]; +typedef mp_limb_t * mp_ptr; +typedef const mp_limb_t * mp_srcptr; +typedef long int mp_size_t; + +extern mp_limb_t __gmpn_addmul_2 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr); + +void +__gmpn_redc_2 (mp_ptr rp, mp_ptr up, mp_srcptr mp, mp_size_t n, mp_srcptr mip) +{ + mp_limb_t q[2]; + mp_size_t j; + mp_limb_t upn; + + for (j = n - 2; j >= 0; j -= 2) + { + mp_limb_t _ph, _pl; + __asm__ ("xma.hu %0 = %3, %5, f0\n\t" + "xma.l %1 = %3, %5, f0\n\t" + ";;\n\t" + "xma.l %0 = %3, %4, %0\n\t" + ";;\n\t" + "xma.l %0 = %2, %5, %0" + : "=&f" (q[1]), "=&f" (q[0]) + : "f" (mip[1]), "f" (mip[0]), "f" (up[1]), "f" (up[0])); + upn = up[n]; + up[1] = __gmpn_addmul_2 (up, mp, n, q); + up[0] = up[n]; + up[n] = upn; + up += 2; + } +}