I checked in this patch to always allow the offsetted memory references for TARGET_X32.
H.J. ---- commit 8dba2cfc28716e09853233e19500e44ba2619cb6 Author: H.J. Lu <hjl.to...@gmail.com> Date: Fri Mar 11 13:34:17 2011 -0800 Always allow the offsetted memory references for TARGET_X32. diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32 index 3f1f953..ac312af 100644 --- a/gcc/ChangeLog.x32 +++ b/gcc/ChangeLog.x32 @@ -1,3 +1,13 @@ +2011-03-11 H.J. Lu <hongjiu...@intel.com> + + PR target/47446 + * config/i386/i386.md (*movdi_internal_rex64): Only allow moving + integer constants into 64bit registers for TARGET_X32. + + * config/i386/predicates.md (x86_64_immediate_operand): Always + allow the offsetted memory references for TARGET_X32. + (x86_64_zext_immediate_operand): Likewise. + 2011-03-07 H.J. Lu <hongjiu...@intel.com> PR middle-end/48016 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 509ee82..d092a84 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2023,10 +2023,8 @@ return "mov{l}\t{%k1, %k0|%k0, %k1}"; else if (which_alternative == 2) { - if (TARGET_X32) - return "movabs{q}\t{%1, %0|%0, %1}"; - else - return "mov{q}\t{%1, %0|%0, %1}"; + gcc_assert (!TARGET_X32 || CONST_INT_P (operands[1])); + return "movabs{q}\t{%1, %0|%0, %1}"; } else return "mov{q}\t{%1, %0|%0, %1}"; diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 4bd5688..7c40958 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -188,8 +188,10 @@ if ((ix86_cmodel == CM_SMALL || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op1))) - && offset < 16*1024*1024 - && trunc_int_for_mode (offset, SImode) == offset) + && (TARGET_X32 + || (offset < 16*1024*1024 + && (trunc_int_for_mode (offset, SImode) + == offset)))) return true; /* For CM_KERNEL we know that all object resist in the negative half of 32bits address space. We may not @@ -293,8 +295,11 @@ || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op1))) && CONST_INT_P (op2) - && trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000 - && trunc_int_for_mode (INTVAL (op2), SImode) == INTVAL (op2)) + && (TARGET_X32 + || ((trunc_int_for_mode (INTVAL (op2), DImode) + > -0x10000) + && (trunc_int_for_mode (INTVAL (op2), SImode) + == INTVAL (op2))))) return true; /* ??? For the kernel, we may accept adjustment of -0x10000000, since we know that it will just convert diff --git a/gcc/testsuite/ChangeLog.x32 b/gcc/testsuite/ChangeLog.x32 index e5c6bfd..39ed391 100644 --- a/gcc/testsuite/ChangeLog.x32 +++ b/gcc/testsuite/ChangeLog.x32 @@ -1,3 +1,8 @@ +2011-03-11 H.J. Lu <hongjiu...@intel.com> + + PR target/47446 + * gcc.target/i386/pr47446-3.c: New. + 2011-03-06 H.J. Lu <hongjiu...@intel.com> * go.test/go-test.exp (go-set-goarch): Check x32. diff --git a/gcc/testsuite/gcc.target/i386/pr47446-3.c b/gcc/testsuite/gcc.target/i386/pr47446-3.c new file mode 100644 index 0000000..faa5f1f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr47446-3.c @@ -0,0 +1,21 @@ +/* { dg-do assemble } */ +/* { dg-options "-O3 -funroll-all-loops" } */ + +extern char inbuf[]; +extern char outbuf[]; +extern unsigned insize; +extern unsigned inptr; +static int max_len; +static int peek_bits; +void build_tree() { + int len; + char *prefixp; + max_len = inbuf[inptr++]; + peek_bits = ((max_len) <= (12) ? (max_len) : (12)); + prefixp = &outbuf[1<<peek_bits]; + for (len = 1; + len <= peek_bits; + len++) { + } + while (prefixp > outbuf) *--prefixp = 0; +}