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/config | |
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/config')
-rw-r--r-- | gcc/config/i386/i386.c | 168 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 2 |
2 files changed, 95 insertions, 75 deletions
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. |