diff mbox

[ARM] Fix %N output modifier

Message ID 5405E360.4010506@arm.com
State New
Headers show

Commit Message

Kyrylo Tkachov Sept. 2, 2014, 3:33 p.m. UTC
Hi all,

Following the transition to UAL I noticed that the %N output modifier 
doesn't really work. It calls fp_const_from_val to get the VFP encoding 
from a real value, but fp_const_from_val only supports the floating 
point zero constant and ICEs for all other values, making it useless for 
pretty much all purposes.
For example, the testcase in this patch ICEs.

With the conversion to UAL we no longer output the VFP encoded form of 
floating point constants but rather their natural representation. This 
patch makes sure that %N negates its operand properly and outputs it as 
a normal floating point number. It also handles operand lossage (if, for 
example, the user passed in a register instead of a constant).


Ok for upstream?

2014-09-02  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * config/arm/arm.c (fp_const_from_val): Delete prototype and
     definition.
     (arm_print_operand): Don't use fp_const_from_val in the 'N' case.
     Report unsupported operand.

2014-09-02  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * gcc.target/arm/n_output_modifier_1.c: New test.
diff mbox

Patch

commit 592aa40e87285c53229ccf544691611e9c78b578
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Wed Aug 13 14:08:02 2014 +0100

    [ARM] Fix %N output modifier

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 5f7cbb1..a48ca4e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -100,7 +100,6 @@  static void arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update
 static void arm_print_operand (FILE *, rtx, int);
 static void arm_print_operand_address (FILE *, rtx);
 static bool arm_print_operand_punct_valid_p (unsigned char code);
-static const char *fp_const_from_val (REAL_VALUE_TYPE *);
 static arm_cc get_arm_condition_code (rtx);
 static HOST_WIDE_INT int_log2 (HOST_WIDE_INT);
 static const char *output_multi_immediate (rtx *, const char *, const char *,
@@ -17534,17 +17533,6 @@  arm_reorg (void)
 
 /* Routines to output assembly language.  */
 
-/* Return string representation of passed in real value.  */
-static const char *
-fp_const_from_val (REAL_VALUE_TYPE *r)
-{
-  if (!fp_consts_inited)
-    init_fp_table ();
-
-  gcc_assert (REAL_VALUES_EQUAL (*r, value_fp0));
-  return "0";
-}
-
 /* OPERANDS[0] is the entire list of insns that constitute pop,
    OPERANDS[1] is the base register, RETURN_PC is true iff return insn
    is in the list, UPDATE is true iff the list contains explicit
@@ -21533,13 +21521,21 @@  arm_print_operand (FILE *stream, rtx x, int code)
 
     case 'N':
       {
-	REAL_VALUE_TYPE r;
-	REAL_VALUE_FROM_CONST_DOUBLE (r, x);
-	r = real_value_negate (&r);
-	fprintf (stream, "%s", fp_const_from_val (&r));
-      }
-      return;
+        if (CONST_DOUBLE_P (x))
+          {
+            char fpstr[20];
+            REAL_VALUE_TYPE r;
+
+            REAL_VALUE_FROM_CONST_DOUBLE (r, x);
+            r = real_value_negate (&r);
+            real_to_decimal (fpstr, &r, sizeof (fpstr), 0, 1);
+            fprintf (stream, "%s", fpstr);
+          }
+        else
+          output_operand_lossage ("Unsupported operand for code '%c'", code);
 
+        return;
+      }
     /* An integer or symbol address without a preceding # sign.  */
     case 'c':
       switch (GET_CODE (x))
diff --git a/gcc/testsuite/gcc.target/arm/n_output_modifier_1.c b/gcc/testsuite/gcc.target/arm/n_output_modifier_1.c
new file mode 100644
index 0000000..e94914b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/n_output_modifier_1.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-final { scan-assembler-times "-5.0e-1" 1 } } */
+
+
+int
+foo (int a)
+{
+  int result = 0;
+   __asm__ ("%0, %N1"
+            : "=r"(result)
+            : "Dt"(0.5)
+            : );
+  return result;
+}
+