diff options
author | Uros Bizjak <uros@gcc.gnu.org> | 2009-04-28 08:54:02 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2009-04-28 08:54:02 +0200 |
commit | b91322f2ba88548f5137cea907c85cd74b0b90a8 (patch) | |
tree | e907955ebd25213e01b632ca3ab28601b9dcb477 /gcc | |
parent | 297c37173212c85e2e0c61cb9a1fd89fa9d44f25 (diff) | |
download | gcc-b91322f2ba88548f5137cea907c85cd74b0b90a8.zip gcc-b91322f2ba88548f5137cea907c85cd74b0b90a8.tar.gz gcc-b91322f2ba88548f5137cea907c85cd74b0b90a8.tar.bz2 |
re PR target/39911 (The 'z' suffix doesn't work with 16bit integer insn)
PR target/39911
* config/i386/i386.c (print_operand) ['Z']: Handle floating point
and integer modes for x87 operands. Do not ICE for unsupported size,
generate error instead. Generate error for unsupported operand types.
['z']: Do not handle HImode memory operands specially. Warning
for floating-point operands. Fallthru to 'Z' for unsupported operand
types. Do not ICE for unsupported size, generate error instead.
(output_387_binary_op): Use %Z to output operands.
(output_fp_compare): Ditto.
(output_387_reg_move): Ditto.
testsuite/ChangeLog:
PR target/39911
* gcc.target/i386/pr39911.c: New test.
From-SVN: r146874
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 168 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr39911.c | 57 |
5 files changed, 173 insertions, 76 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 153e71b..601b0b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2009-04-28 Uros Bizjak <ubizjak@gmail.com> + + PR target/39911 + * config/i386/i386.c (print_operand) ['Z']: Handle floating point + and integer modes for x87 operands. Do not ICE for unsupported size, + generate error instead. Generate error for unsupported operand types. + ['z']: Do not handle HImode memory operands specially. Warning + for floating-point operands. Fallthru to 'Z' for unsupported operand + types. Do not ICE for unsupported size, generate error instead. + (output_387_binary_op): Use %Z to output operands. + (output_fp_compare): Ditto. + (output_387_reg_move): Ditto. + 2009-04-28 Ben Elliston <bje@au.ibm.com> PR c++/35652 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 704b0f2..650325a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -10851,7 +10851,7 @@ get_some_local_dynamic_name (void) otherwise nothing R -- print the prefix for register names. z -- print the opcode suffix for the size of the current operand. - Z -- likewise, with special suffixes for fild/fist instructions. + Z -- likewise, with special suffixes for x87 instructions. * -- print a star (in certain assembler syntax) A -- print an absolute memory reference. w -- print the operand as if it's a "word" (HImode) even if it isn't. @@ -10950,91 +10950,111 @@ print_operand (FILE *file, rtx x, int code) putc ('t', file); return; - case 'Z': - gcc_assert (MEM_P (x)); + case 'z': + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT) + { + /* Opcodes don't get size suffixes if using Intel opcodes. */ + if (ASSEMBLER_DIALECT == ASM_INTEL) + return; + + switch (GET_MODE_SIZE (GET_MODE (x))) + { + case 1: + putc ('b', file); + return; + + case 2: + putc ('w', file); + return; + + case 4: + putc ('l', file); + return; + + case 8: + putc ('q', file); + return; + + default: + output_operand_lossage + ("invalid operand size for operand code '%c'", code); + return; + } + } - /* fild/fist don't get size suffixes if using Intel opcodes. */ + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) + warning + (0, "non-integer operand used with operand code '%c'", code); + /* FALLTHRU */ + + case 'Z': + /* 387 opcodes don't get size suffixes if using Intel opcodes. */ if (ASSEMBLER_DIALECT == ASM_INTEL) return; - switch (GET_MODE_SIZE (GET_MODE (x))) + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT) { - case 2: + switch (GET_MODE_SIZE (GET_MODE (x))) + { + case 2: #ifdef HAVE_AS_IX86_FILDS - putc ('s', file); + putc ('s', file); #endif - return; + return; - case 4: - putc ('l', file); - return; + case 4: + putc ('l', file); + return; - case 8: + case 8: #ifdef HAVE_AS_IX86_FILDQ - putc ('q', file); + putc ('q', file); #else - fputs ("ll", file); + fputs ("ll", file); #endif - return; + return; - default: - gcc_unreachable (); + default: + break; + } } - - case 'z': - /* 387 opcodes don't get size suffixes if the operands are - registers. */ - if (STACK_REG_P (x)) - return; - - /* Likewise if using Intel opcodes. */ - if (ASSEMBLER_DIALECT == ASM_INTEL) - return; - - /* This is the size of op from size of operand. */ - switch (GET_MODE_SIZE (GET_MODE (x))) + else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) { - case 1: - putc ('b', file); - return; + /* 387 opcodes don't get size suffixes + if the operands are registers. */ + if (STACK_REG_P (x)) + return; - case 2: - /* ??? This fails for HImode integer - operator with memory operand. */ - if (MEM_P (x)) + switch (GET_MODE_SIZE (GET_MODE (x))) { -#ifdef HAVE_AS_IX86_FILDS + case 4: putc ('s', file); -#endif return; - } - else - putc ('w', file); - return; - case 4: - if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT) - putc ('l', file); - else - putc ('s', file); - return; + case 8: + putc ('l', file); + return; - case 8: - if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT) - putc ('q', file); - else - putc ('l', file); - return; + case 12: + case 16: + putc ('t', file); + return; - case 12: - case 16: - putc ('t', file); + default: + break; + } + } + else + { + output_operand_lossage + ("invalid operand type used with operand code '%c'", code); return; - - default: - gcc_unreachable (); } + output_operand_lossage + ("invalid operand size for operand code '%c'", code); + return; + case 'd': case 'b': case 'w': @@ -11833,7 +11853,7 @@ output_387_binary_op (rtx insn, rtx *operands) if (MEM_P (operands[2])) { - p = "%z2\t%2"; + p = "%Z2\t%2"; break; } @@ -11863,13 +11883,13 @@ output_387_binary_op (rtx insn, rtx *operands) case DIV: if (MEM_P (operands[1])) { - p = "r%z1\t%1"; + p = "r%Z1\t%1"; break; } if (MEM_P (operands[2])) { - p = "%z2\t%2"; + p = "%Z2\t%2"; break; } @@ -12241,13 +12261,13 @@ output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p) static const char * const alt[16] = { - "fcom%z2\t%y2\n\tfnstsw\t%0", - "fcomp%z2\t%y2\n\tfnstsw\t%0", - "fucom%z2\t%y2\n\tfnstsw\t%0", - "fucomp%z2\t%y2\n\tfnstsw\t%0", + "fcom%Z2\t%y2\n\tfnstsw\t%0", + "fcomp%Z2\t%y2\n\tfnstsw\t%0", + "fucom%Z2\t%y2\n\tfnstsw\t%0", + "fucomp%Z2\t%y2\n\tfnstsw\t%0", - "ficom%z2\t%y2\n\tfnstsw\t%0", - "ficomp%z2\t%y2\n\tfnstsw\t%0", + "ficom%Z2\t%y2\n\tfnstsw\t%0", + "ficomp%Z2\t%y2\n\tfnstsw\t%0", NULL, NULL, @@ -28782,22 +28802,22 @@ output_387_reg_move (rtx insn, rtx *operands) return "fstp\t%y0"; } if (STACK_TOP_P (operands[0])) - return "fld%z1\t%y1"; + return "fld%Z1\t%y1"; return "fst\t%y0"; } else if (MEM_P (operands[0])) { gcc_assert (REG_P (operands[1])); if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) - return "fstp%z0\t%y0"; + return "fstp%Z0\t%y0"; else { /* There is no non-popping store to memory for XFmode. So if we need one, follow the store with a load. */ if (GET_MODE (operands[0]) == XFmode) - return "fstp%z0\t%y0\n\tfld%z0\t%y0"; + return "fstp%Z0\t%y0\n\tfld%Z0\t%y0"; else - return "fst%z0\t%y0"; + return "fst%Z0\t%y0"; } } else diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d315580..2979431 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -36,7 +36,7 @@ ;; otherwise nothing ;; R -- print the prefix for register names. ;; z -- print the opcode suffix for the size of the current operand. -;; Z -- likewise, with special suffixes for fild/fist instructions. +;; Z -- likewise, with special suffixes for x87 instructions. ;; * -- print a star (in certain assembler syntax) ;; A -- print an absolute memory reference. ;; w -- print the operand as if it's a "word" (HImode) even if it isn't. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 53a8125..91e2337 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-04-28 Uros Bizjak <ubizjak@gmail.com> + H.J. Lu <hongjiu.lu@intel.com> + + PR target/39911 + * gcc.target/i386/pr39911.c: New test. + 2009-04-28 Paul Thomas <pault@gcc.gnu.org> PR fortran/39879 @@ -24,7 +30,8 @@ * gcc.dg/Wconversion-real.c: Require large_double. * gcc.dg/cdce1.c: Require large_double instead of checking targets. - * gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c: Skip if doubles are too small. + * gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c: Skip if doubles + are too small. * gcc.c-torture/execute/ieee/20010226-1.c: Mark all floating point constants as long. diff --git a/gcc/testsuite/gcc.target/i386/pr39911.c b/gcc/testsuite/gcc.target/i386/pr39911.c new file mode 100644 index 0000000..fe63ff0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr39911.c @@ -0,0 +1,57 @@ +/* { dg-do assemble } */ +/* { dg-options "-O2" } */ + +void +bar1 () +{ + char foo; + asm volatile ("mov%z0 %1, %0": "=m" (foo): "iq" (-23)); + asm volatile ("add%z0 %1, %0": "+m" (foo): "iq" (23)); + asm volatile ("mov%z0 %1, %0": "=q" (foo): "iq" (-23)); + asm volatile ("add%z0 %1, %0": "+q" (foo): "iq" (23)); +} + +void +bar2 () +{ + short foo; + asm volatile ("mov%z0 %1, %0": "=m" (foo): "ir" (-23)); + asm volatile ("add%z0 %1, %0": "+m" (foo): "ir" (23)); + asm volatile ("mov%z0 %1, %0": "=r" (foo): "ir" (-23)); + asm volatile ("add%z0 %1, %0": "+r" (foo): "ir" (23)); + + asm volatile ("pop%z0 %0": "=m" (foo)); + asm volatile ("pop%z0 %0": "=r" (foo)); +} + +void +bar3 () +{ + int foo; + asm volatile ("mov%z0 %1, %0": "=m" (foo): "ir" (-23)); + asm volatile ("add%z0 %1, %0": "+m" (foo): "ir" (23)); + asm volatile ("mov%z0 %1, %0": "=r" (foo): "ir" (-23)); + asm volatile ("add%z0 %1, %0": "+r" (foo): "ir" (23)); + + if (sizeof (void *) == sizeof (int)) + { + asm volatile ("pop%z0 %0": "=m" (foo)); + asm volatile ("pop%z0 %0": "=r" (foo)); + } +} + +void +bar4 () +{ + if (sizeof (void *) == sizeof (long long)) + { + long long foo; + asm volatile ("mov%z0 %1, %0": "=m" (foo): "er" (-23)); + asm volatile ("add%z0 %1, %0": "+m" (foo): "er" (23)); + asm volatile ("mov%z0 %1, %0": "=r" (foo): "er" (-23)); + asm volatile ("add%z0 %1, %0": "+r" (foo): "er" (23)); + + asm volatile ("pop%z0 %0": "=m" (foo)); + asm volatile ("pop%z0 %0": "=r" (foo)); + } +} |