aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2009-04-28 08:54:02 +0200
committerUros Bizjak <uros@gcc.gnu.org>2009-04-28 08:54:02 +0200
commitb91322f2ba88548f5137cea907c85cd74b0b90a8 (patch)
treee907955ebd25213e01b632ca3ab28601b9dcb477 /gcc/config
parent297c37173212c85e2e0c61cb9a1fd89fa9d44f25 (diff)
downloadgcc-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.c168
-rw-r--r--gcc/config/i386/i386.md2
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.