Commit 41632b58eff46d351fffa529a5f860eb63155818

Chongyu Zhu 2013-10-15T11:40:34

[arm] Fix thumb2 inline assembly under LLVM. When using `ADD' with an immediate operand, the instruction is actually `ADD Rd, Rn, #<imm12>', that is, the maximum of the immediate operand cannot exceed 4095. It will fail to compile with LLVM. However, in GCC, due to some legacy compatibility considerations, `ADD.W' will be automatically emitted when the immediate operand is larger than 4095. * builds/unix/ftconfig.in, include/freetype/config/ftconfig.h (FT_MulFix_arm) [__GNUC__]: Support clang compiler. * src/truetype/ttinterp.c (TT_MulFix14_arm) [__GNUC__]: Ditto.

diff --git a/ChangeLog b/ChangeLog
index d880f3c..2d3f65e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2013-10-15  Chongyu Zhu  <lembacon@gmail.com>
+
+	[arm] Fix thumb2 inline assembly under LLVM.
+
+	When using `ADD' with an immediate operand, the instruction is
+	actually `ADD Rd, Rn, #<imm12>', that is, the maximum of the
+	immediate operand cannot exceed 4095.  It will fail to compile with
+	LLVM.
+
+	However, in GCC, due to some legacy compatibility considerations,
+	`ADD.W' will be automatically emitted when the immediate operand is
+	larger than 4095.
+
+	* builds/unix/ftconfig.in, include/freetype/config/ftconfig.h
+	(FT_MulFix_arm) [__GNUC__]: Support clang compiler.
+
+	* src/truetype/ttinterp.c (TT_MulFix14_arm) [__GNUC__]: Ditto.
+
 2013-10-12  Werner Lemberg  <wl@gnu.org>
 
 	[autofit] Improve tracing of `latin' hinter.
diff --git a/builds/unix/ftconfig.in b/builds/unix/ftconfig.in
index d2f3cd5..1753a6e 100644
--- a/builds/unix/ftconfig.in
+++ b/builds/unix/ftconfig.in
@@ -419,7 +419,11 @@ FT_BEGIN_HEADER
     __asm__ __volatile__ (
       "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
       "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
+#ifdef __clang__
+      "add.w  %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
+#else
       "add    %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
+#endif
       "adds   %1, %1, %0\n\t"           /* %1 += %0 */
       "adc    %2, %2, #0\n\t"           /* %2 += carry */
       "mov    %0, %1, lsr #16\n\t"      /* %0  = %1 >> 16 */
diff --git a/include/freetype/config/ftconfig.h b/include/freetype/config/ftconfig.h
index 9c32256..1180b12 100644
--- a/include/freetype/config/ftconfig.h
+++ b/include/freetype/config/ftconfig.h
@@ -386,7 +386,11 @@ FT_BEGIN_HEADER
     __asm__ __volatile__ (
       "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
       "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
+#ifdef __clang__
+      "add.w  %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
+#else
       "add    %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
+#endif
       "adds   %1, %1, %0\n\t"           /* %1 += %0 */
       "adc    %2, %2, #0\n\t"           /* %2 += carry */
       "mov    %0, %1, lsr #16\n\t"      /* %0  = %1 >> 16 */
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 14854d9..fedad9d 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -1470,7 +1470,11 @@
     __asm__ __volatile__ (
       "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
       "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
+#ifdef __clang__
+      "add.w  %0, %0, #0x2000\n\t"      /* %0 += 0x2000 */
+#else
       "add    %0, %0, #0x2000\n\t"      /* %0 += 0x2000 */
+#endif
       "adds   %1, %1, %0\n\t"           /* %1 += %0 */
       "adc    %2, %2, #0\n\t"           /* %2 += carry */
       "mov    %0, %1, lsr #14\n\t"      /* %0  = %1 >> 16 */