I added some Initial ARM target support to clang. I'm pretty sure it's
not all correct (validateAsmConstraint for example)
The defines were taken from a FreeBSD machine with: arm-elf-gcc -dM -E
- < /dev/null

Can anyone take a look and give me some hints on how it needs to be
changed before it can be committed?

Marcoen
diff --git a/Basic/Targets.cpp b/Basic/Targets.cpp
index fcd105a..67e856e 100644
--- a/Basic/Targets.cpp
+++ b/Basic/Targets.cpp
@@ -269,6 +269,88 @@ static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
   Define(Defs, "__LDBL_MIN__", "3.36210314311209350626e-4932L");
 }
 
+/// getARMDefines - Return a set of the ARM-specific #defines that are
+/// not tied to a specific subtarget.
+static void getARMDefines(std::vector<char> &Defs, bool is64Bit) {
+  // Target identification.
+  Define(Defs, "__arm__");
+  Define(Defs, "__APCS_32__");
+  Define(Defs, "__ARMEL__");
+  Define(Defs, "__ARM_ARCH_4T__");
+
+  Define(Defs, "__CHAR_BIT__", "8");
+  Define(Defs, "__CHAR_UNSIGNED__");
+
+  Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
+  Define(Defs, "__INTMAX_TYPE__", "long long int");
+  Define(Defs, "__INT_MAX__", "2147483647");
+  Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
+
+  Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
+  Define(Defs, "__LONG_MAX__", "2147483647L");
+  Define(Defs, "__PTRDIFF_TYPE__", "long int");
+  Define(Defs, "__SCHAR_MAX__", "127");
+  Define(Defs, "__SHRT_MAX__", "32767");
+  Define(Defs, "__SIZE_TYPE__", "long unsigned int");
+
+  Define(Defs, "__NO_INLINE__");
+  Define(Defs, "__REGISTER_PREFIX__", "");
+  Define(Defs, "__SOFTFP__");
+  Define(Defs, "__STDC_HOSTED__");
+  Define(Defs, "__USER_LABEL_PREFIX__", "");
+  Define(Defs, "__USES_INITFINI__");
+  Define(Defs, "__USING_SJLJ_EXCEPTIONS__");
+
+  Define(Defs, "__WCHAR_MAX__", "2147483647");
+  Define(Defs, "__WCHAR_TYPE__", "int");
+  Define(Defs, "__WINT_TYPE__", "unsigned int");
+
+  // Float macros.
+  Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
+  Define(Defs, "__FLT_DIG__", "6");
+  Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
+  Define(Defs, "__FLT_EVAL_METHOD__", "0");
+  Define(Defs, "__FLT_HAS_INFINITY__");
+  Define(Defs, "__FLT_HAS_QUIET_NAN__");
+  Define(Defs, "__FLT_MANT_DIG__", "24");
+  Define(Defs, "__FLT_MAX_10_EXP__", "38");
+  Define(Defs, "__FLT_MAX_EXP__", "128");
+  Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
+  Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
+  Define(Defs, "__FLT_MIN_EXP__", "(-125)");
+  Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
+  Define(Defs, "__FLT_RADIX__", "2");
+
+  // Double macros.
+  Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
+  Define(Defs, "__DBL_DIG__", "15");
+  Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
+  Define(Defs, "__DBL_HAS_INFINITY__");
+  Define(Defs, "__DBL_HAS_QUIET_NAN__");
+  Define(Defs, "__DBL_MANT_DIG__", "53");
+  Define(Defs, "__DBL_MAX_10_EXP__", "308");
+  Define(Defs, "__DBL_MAX_EXP__", "1024");
+  Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
+  Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
+  Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
+  Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
+  Define(Defs, "__DECIMAL_DIG__", "17");
+
+  // 80-bit Long double macros.
+  Define(Defs, "__LDBL_DENORM_MIN__", "4.9406564584124654e-324L");
+  Define(Defs, "__LDBL_DIG__", "15");
+  Define(Defs, "__LDBL_EPSILON__", "2.2204460492503131e-16L");
+  Define(Defs, "__LDBL_HAS_INFINITY__");
+  Define(Defs, "__LDBL_HAS_QUIET_NAN__");
+  Define(Defs, "__LDBL_MANT_DIG__", "53");
+  Define(Defs, "__LDBL_MAX_10_EXP__", "308");
+  Define(Defs, "__LDBL_MAX_EXP__", "1024");
+  Define(Defs, "__LDBL_MAX__", "1.7976931348623157e+308L");
+  Define(Defs, "__LDBL_MIN_10_EXP__", "(-307)");
+  Define(Defs, "__LDBL_MIN_EXP__", "(-1021)");
+  Define(Defs, "__LDBL_MIN__", "2.2250738585072014e-308L");
+}
+
 static const char* getI386VAListDeclaration() {
   return "typedef char* __builtin_va_list;";
 }
@@ -294,6 +376,10 @@ static const char* getPPCVAListDeclaration() {
     "} __builtin_va_list[1];";
 }
 
+static const char* getARMVAListDeclaration() {
+  return "typedef char* __builtin_va_list;";
+}
+
 
 /// PPC builtin info.
 namespace clang {
@@ -474,6 +560,63 @@ namespace X86 {
   }
   
 } // End namespace X86
+
+/// ARM builtin info.
+namespace ARM {
+  static const Builtin::Info BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
+#include "clang/AST/ARMBuiltins.def"
+  };
+
+  static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
+    Records = BuiltinInfo;
+    NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
+  }
+
+  static const char *GCCRegNames[] = {
+    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+    "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc",
+  };
+
+  static void getGCCRegNames(const char * const *&Names, 
+                                  unsigned &NumNames) {
+    Names = GCCRegNames;
+    NumNames = llvm::array_lengthof(GCCRegNames);
+  }
+
+  static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
+    { { "r10" }, "sl" },
+    { { "r11" }, "fp" },
+    { { "r12" }, "ip" },
+    { { "r13" }, "sp" },
+    { { "r14" }, "lr" },
+    { { "r15" }, "pc" },
+  };
+
+  static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases, 
+                               unsigned &NumAliases) {
+    Aliases = GCCRegAliases;
+    NumAliases = llvm::array_lengthof(GCCRegAliases);
+  }  
+  
+  static bool validateAsmConstraint(char c, 
+                                    TargetInfo::ConstraintInfo &info) {
+    switch (c) {
+    default: return false;
+    case ',':
+      return true;
+    }
+  }
+
+  const char *getClobbers() {
+    return 0;
+  }
+  
+  const char *getTargetPrefix() {
+    return "arm";
+  }
+  
+} // End namespace ARM
 } // end namespace clang.
 
 //===----------------------------------------------------------------------===//
@@ -670,6 +813,43 @@ public:
 };
 } // end anonymous namespace.
 
+namespace {
+class DarwinARMTargetInfo : public DarwinTargetInfo {
+public:
+  DarwinARMTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
+  
+  virtual void getTargetDefines(std::vector<char> &Defines) const {
+    DarwinTargetInfo::getTargetDefines(Defines);
+    getARMDefines(Defines, false);
+  }
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const {
+    ARM::getBuiltins(Records, NumRecords);
+  }
+  virtual const char *getVAListDeclaration() const {
+    return getARMVAListDeclaration();
+  }
+  virtual const char *getTargetPrefix() const {
+    return ARM::getTargetPrefix();
+  }
+  virtual void getGCCRegNames(const char * const *&Names, 
+                              unsigned &NumNames) const {
+    ARM::getGCCRegNames(Names, NumNames);
+  }
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 
+                                unsigned &NumAliases) const {
+    ARM::getGCCRegAliases(Aliases, NumAliases);
+  }
+  virtual bool validateAsmConstraint(char c,
+                                     TargetInfo::ConstraintInfo &info) const {
+    return ARM::validateAsmConstraint(c, info);
+  }
+  virtual const char *getClobbers() const {
+    return ARM::getClobbers();
+  }
+};
+} // end anonymous namespace.
+
 
 //===----------------------------------------------------------------------===//
 // Driver code
@@ -693,6 +873,8 @@ static TargetInfoImpl *CreateTarget(const std::string& T) {
     return new DarwinI386TargetInfo(T);
   else if (T.find("bogusW16W16-") == 0) // For testing portability.
     return new LinuxTargetInfo(T);
+  else if (T.find("arm-") == 0)
+    return new DarwinARMTargetInfo(T);
   else
     return NULL;
 }
diff --git a/include/clang/AST/ARMBuiltins.def b/include/clang/AST/ARMBuiltins.def
new file mode 100644
index 0000000..3a8478e
--- /dev/null
+++ b/include/clang/AST/ARMBuiltins.def
@@ -0,0 +1,24 @@
+//===--- ARMBuiltins.def - ARM Builtin function database ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ARM-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: this needs to be the full list supported by GCC.  Right now, I'm just
+// adding stuff on demand.
+
+// The format of this database matches clang/AST/Builtins.def.
+
+// This is just a placeholder, the types and attributes are wrong.
+BUILTIN(__builtin_altivec_abs_v4sf  , "ii"   , "nc")
+// FIXME: Obviously incomplete.
+
+#undef BUILTIN
diff --git a/include/clang/AST/TargetBuiltins.h b/include/clang/AST/TargetBuiltins.h
index d0f7844..fdfa217 100644
--- a/include/clang/AST/TargetBuiltins.h
+++ b/include/clang/AST/TargetBuiltins.h
@@ -32,6 +32,16 @@ namespace clang {
         LastTSBuiltin
     };
   }
+
+  /// ARM builtins
+  namespace ARM {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "ARMBuiltins.def"
+        LastTSBuiltin
+    };
+  }
 } // end namespace clang.
 
 #endif
_______________________________________________
cfe-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

Reply via email to