Hi, with the attached testcase I run into:
if (this_insn_is_asm) { enum machine_mode mode; if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode)) mode = inmode; else mode = outmode; if (mode == VOIDmode) { error_for_asm (this_insn, "cannot reload integer constant " "operand in %<asm%>"); ... in reload.c push_reload. The problem occurs with CONST_INT only addresses. Overriding operand_mode with Pmode in that case fixes the problem for me. Bootstrapped and regtested on s390x, ppc64 and x86_64. Ok for mainline? Bye, -Andreas- 2011-09-21 Andreas Krebbel <andreas.kreb...@de.ibm.com> * reload.c (find_reloads): Set operand_mode to Pmode for address operands consisting of just a CONST_INT. 2011-09-21 Andreas Krebbel <andreas.kreb...@de.ibm.com> * gcc.target/s390/addr-constraints-1.c: New testcase. Index: gcc/reload.c =================================================================== *** gcc/reload.c.orig --- gcc/reload.c *************** find_reloads (rtx insn, int replace, int *** 2825,2830 **** --- 2825,2837 ---- /* 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]); + + /* If the address is a single CONST_INT pick address mode + instead otherwise we will later not know in which mode + the reload should be performed. */ + if (operand_mode[i] == VOIDmode) + operand_mode[i] = Pmode; + } else if (code == MEM) { Index: gcc/testsuite/gcc.target/s390/addr-constraints-1.c =================================================================== *** /dev/null --- gcc/testsuite/gcc.target/s390/addr-constraints-1.c *************** *** 0 **** --- 1,70 ---- + /* { dg-compile } */ + /* { dg-options "-O2" } */ + + static inline unsigned long + lay_uw(unsigned long addr) + { + unsigned long result; + + __asm__ ("lay %[result],%a[addr]" + : [result] "=d" (result) + : [addr] "UW" (addr)); + return result; + } + + static inline unsigned long + la_u(unsigned long addr) + { + unsigned long result; + + __asm__ ("la %[result],%a[addr]" + : [result] "=d" (result) + : [addr] "U" (addr)); + return result; + } + + static inline unsigned long + lay_zqzrzszt(unsigned long addr) + { + unsigned long result; + + __asm__ ("lay %[result],%a[addr]" + : [result] "=d" (result) + : [addr] "ZQZRZSZT" (addr)); + return result; + } + + static inline unsigned long + la_zqzr(unsigned long addr) + { + unsigned long result; + + __asm__ ("la %[result],%a[addr]" + : [result] "=d" (result) + : [addr] "ZQZR" (addr)); + return result; + } + + + extern unsigned long a[15]; + + int main(void) + { + a[1] = lay_uw(3333); + a[2] = lay_uw(4444); + a[3] = lay_uw(1000000); + a[4] = lay_uw(a[0]); + + a[5] = la_u(2222); + a[6] = la_u(5555); + a[7] = la_u(a[0]); + + a[8] = lay_zqzrzszt(3333); + a[9] = lay_zqzrzszt(4444); + a[10] = lay_zqzrzszt(1000000); + a[11] = lay_zqzrzszt(a[0]); + + a[12] = la_zqzr(2222); + a[13] = la_zqzr(5555); + a[14] = la_zqzr(a[0]); + }