petecoup updated this revision to Diff 133674.
petecoup added a comment.

Hello Eugene,

Thanks for taking a look.
Changed // End anonymous namespace. -> // namespace


https://reviews.llvm.org/D43089

Files:
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/ARC.cpp
  clang/lib/Basic/Targets/ARC.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/arc-arguments.c
  clang/test/CodeGen/arc-struct-align.c
  clang/test/CodeGen/target-data.c

Index: clang/test/CodeGen/target-data.c
===================================================================
--- clang/test/CodeGen/target-data.c
+++ clang/test/CodeGen/target-data.c
@@ -159,6 +159,10 @@
 // RUN: %s | FileCheck %s -check-prefix=ARM-GNU
 // ARM-GNU: target datalayout = "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
 
+// RUN: %clang_cc1 -triple arc-unknown-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=ARC
+// ARC: target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32"
+
 // RUN: %clang_cc1 -triple hexagon-unknown -o - -emit-llvm %s | \
 // RUN: FileCheck %s -check-prefix=HEXAGON
 // HEXAGON: target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
Index: clang/test/CodeGen/arc-struct-align.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/arc-struct-align.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+// 64-bit fields need only be 32-bit aligned for arc.
+
+typedef struct {
+  int aa;
+  double bb;
+} s1;
+
+// CHECK: define i32 @f1
+// CHECK: ret i32 12
+int f1() {
+  return sizeof(s1);
+}
+
+typedef struct {
+  int aa;
+  long long bb;
+} s2;
+// CHECK: define i32 @f2
+// CHECK: ret i32 12
+int f2() {
+  return sizeof(s2);
+}
+
Index: clang/test/CodeGen/arc-arguments.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/arc-arguments.c
@@ -0,0 +1,135 @@
+// RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \
+// RUN:   | FileCheck %s
+
+// Basic argument tests for ARC.
+
+// CHECK: define void @f0(i32 %i, i32 %j, i64 %k)
+void f0(int i, long j, long long k) {}
+
+typedef struct {
+  int aa;
+  int bb;
+} s1;
+// CHECK: define void @f1(i32 %i.coerce0, i32 %i.coerce1)
+void f1(s1 i) {}
+
+typedef struct {
+  char aa; char bb; char cc; char dd;
+} cs1;
+// CHECK: define void @cf1(i32 %i.coerce)
+void cf1(cs1 i) {}
+
+typedef struct {
+  int cc;
+} s2;
+// CHECK: define void @f2(%struct.s2* noalias sret %agg.result)
+s2 f2() {
+  s2 foo;
+  return foo;
+}
+
+typedef struct {
+  int cc;
+  int dd;
+} s3;
+// CHECK: define void @f3(%struct.s3* noalias sret %agg.result)
+s3 f3() {
+  s3 foo;
+  return foo;
+}
+
+// CHECK: define void @f4(i64 %i)
+void f4(long long i) {}
+
+// CHECK: define void @f5(i8 signext %a, i16 signext %b)
+void f5(signed char a, short b) {}
+
+// CHECK: define void @f6(i8 zeroext %a, i16 zeroext %b)
+void f6(unsigned char a, unsigned short b) {}
+
+enum my_enum {
+  ENUM1,
+  ENUM2,
+  ENUM3,
+};
+// Enums should be treated as the underlying i32.
+// CHECK: define void @f7(i32 %a)
+void f7(enum my_enum a) {}
+
+enum my_big_enum {
+  ENUM4 = 0xFFFFFFFFFFFFFFFF,
+};
+// Big enums should be treated as the underlying i64.
+// CHECK: define void @f8(i64 %a)
+void f8(enum my_big_enum a) {}
+
+union simple_union {
+  int a;
+  char b;
+};
+// Unions should be passed inreg.
+// CHECK: define void @f9(i32 %s.coerce)
+void f9(union simple_union s) {}
+
+typedef struct {
+  int b4 : 4;
+  int b3 : 3;
+  int b8 : 8;
+} bitfield1;
+// Bitfields should be passed inreg.
+// CHECK: define void @f10(i32 %bf1.coerce)
+void f10(bitfield1 bf1) {}
+
+// CHECK: define { float, float } @cplx1(float %r)
+_Complex float cplx1(float r) {
+  return r + 2.0fi;
+}
+
+// CHECK: define { double, double } @cplx2(double %r)
+_Complex double cplx2(double r) {
+  return r + 2.0i;
+}
+
+// CHECK: define { i32, i32 } @cplx3(i32 %r)
+_Complex int cplx3(int r) {
+  return r + 2i;
+}
+
+// CHECK: define { i64, i64 } @cplx4(i64 %r)
+_Complex long long cplx4(long long r) {
+  return r + 2i;
+}
+
+// CHECK: define { i8, i8 } @cplx6(i8 signext %r)
+_Complex signed char cplx6(signed char r) {
+  return r + 2i;
+}
+
+// CHECK: define { i16, i16 } @cplx7(i16 signext %r)
+_Complex short cplx7(short r) {
+  return r + 2i;
+}
+
+typedef struct {
+  int aa; int bb;
+} s8;
+
+typedef struct {
+  int aa; int bb; int cc; int dd;
+} s16;
+
+// Use 16-byte struct 2 times, gets 8 registers.
+void st2(s16 a, s16 b) {}
+// CHECK: define void @st2(i32 %a.coerce0, i32 %a.coerce1, i32 %a.coerce2, i32 %a.coerce3, i32 %b.coerce0, i32 %b.coerce1, i32 %b.coerce2, i32 %b.coerce3)
+
+// Use 8-byte struct 3 times, gets 8 registers, 1 byval struct argument.
+void st3(s16 a, s16 b, s16 c) {}
+// CHECK: define void @st3(i32 %a.coerce0, i32 %a.coerce1, i32 %a.coerce2, i32 %a.coerce3, i32 %b.coerce0, i32 %b.coerce1, i32 %b.coerce2, i32 %b.coerce3, %struct.s16* byval align 4 %c)
+
+// 1 sret + 1 i32 + 2*(i32 coerce) + 4*(i32 coerce) + 1 byval
+s16 st4(int x, s8 a, s16 b, s16 c) { return b; }
+// CHECK: define void @st4(%struct.s16* noalias sret %agg.result, i32 %x, i32 %a.coerce0, i32 %a.coerce1, i32 %b.coerce0, i32 %b.coerce1, i32 %b.coerce2, i32 %b.coerce3, %struct.s16* byval align 4 %c)
+
+// 1 sret + + 2*(i32 coerce) + 4*(i32 coerce) + 4*(i32 coerce)
+s16 st5(s8 a, s16 b, s16 c) { return b; }
+// CHECK: define void @st5(%struct.s16* noalias sret %agg.result, i32 %a.coerce0, i32 %a.coerce1, i32 %b.coerce0, i32 %b.coerce1, i32 %b.coerce2, i32 %b.coerce3, i32 %c.coerce0, i32 %c.coerce1, i32 %c.coerce2, i32 %c.coerce3)
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -8115,6 +8115,109 @@
   return false;
 }
 
+// ARC ABI implementation.
+namespace {
+
+class ARCABIInfo : public DefaultABIInfo {
+public:
+  ARCABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
+
+private:
+  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                    QualType Ty) const override;
+
+  void updateState(const ABIArgInfo &Info, QualType Ty, CCState &State) const {
+    if (!State.FreeRegs)
+      return;
+    if (Info.isIndirect())
+      State.FreeRegs--;
+    else {
+      unsigned sz = (getContext().getTypeSize(Ty) + 31) / 32;
+      if (sz < State.FreeRegs)
+        State.FreeRegs -= sz;
+      else
+        State.FreeRegs = 0;
+    }
+  }
+
+  void computeInfo(CGFunctionInfo &FI) const override {
+    CCState State(FI.getCallingConvention());
+    // ARC uses 8 registers to pass arguments.
+    State.FreeRegs = 8;
+
+    if (!getCXXABI().classifyReturnType(FI))
+      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+    updateState(FI.getReturnInfo(), FI.getReturnType(), State);
+    for (auto &I : FI.arguments()) {
+      I.info = classifyArgumentType(I.type, State.FreeRegs);
+      updateState(I.info, I.type, State);
+    }
+  }
+
+  ABIArgInfo getIndirect(QualType Ty) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy, unsigned) const;
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+};
+
+class ARCTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  ARCTargetCodeGenInfo(CodeGenTypes &CGT)
+      : TargetCodeGenInfo(new ARCABIInfo(CGT)) {}
+};
+
+ABIArgInfo ARCABIInfo::getIndirect(QualType Ty) const {
+  // Compute the byval alignment.
+  const unsigned MinABIStackAlignInBytes = 4;
+  unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8;
+  return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), /*ByVal=*/true,
+                                 TypeAlign > MinABIStackAlignInBytes);
+}
+
+Address ARCABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                              QualType Ty) const {
+  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false,
+                          getContext().getTypeInfoInChars(Ty),
+                          CharUnits::fromQuantity(4), true);
+}
+
+ABIArgInfo ARCABIInfo::classifyArgumentType(QualType Ty,
+                                            unsigned FreeRegs) const {
+  // TODO: C++ ABI?
+  unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
+  if (isAggregateTypeForABI(Ty)) {
+    const RecordType *RT = Ty->getAs<RecordType>();
+    // Structures with flexible arrays are always indirect.
+    if (RT && RT->getDecl()->hasFlexibleArrayMember())
+      return getIndirect(Ty);
+
+    // Ignore empty structs/unions.
+    if (isEmptyRecord(getContext(), Ty, true))
+      return ABIArgInfo::getIgnore();
+
+    llvm::LLVMContext &LLVMContext = getVMContext();
+    if (FreeRegs > 0) {
+      llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);
+      SmallVector<llvm::Type *, 3> Elements(SizeInRegs, Int32);
+      llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
+      return ABIArgInfo::getDirect(Result);
+    }
+    return getIndirect(Ty);
+  }
+
+  return DefaultABIInfo::classifyArgumentType(Ty);
+}
+
+ABIArgInfo ARCABIInfo::classifyReturnType(QualType RetTy) const {
+  if (RetTy->isAnyComplexType())
+    return ABIArgInfo::getDirect();
+  // Arguments of size > 4 registers are indirect.
+  unsigned RetSize = (getContext().getTypeSize(RetTy) + 31) / 32;
+  if (RetSize > 4)
+    return getIndirect(RetTy);
+  return DefaultABIInfo::classifyReturnType(RetTy);
+}
+
+} // namespace
 
 //===----------------------------------------------------------------------===//
 // XCore ABI Implementation
@@ -9115,6 +9218,8 @@
     return SetCGInfo(new SparcV9TargetCodeGenInfo(Types));
   case llvm::Triple::xcore:
     return SetCGInfo(new XCoreTargetCodeGenInfo(Types));
+  case llvm::Triple::arc:
+    return SetCGInfo(new ARCTargetCodeGenInfo(Types));
   case llvm::Triple::spir:
   case llvm::Triple::spir64:
     return SetCGInfo(new SPIRTargetCodeGenInfo(Types));
Index: clang/lib/Basic/Targets/ARC.h
===================================================================
--- /dev/null
+++ clang/lib/Basic/Targets/ARC.h
@@ -0,0 +1,76 @@
+//===--- ARC.h - Declare ARC target feature support -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares ARC TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_ARC_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_ARC_H
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+namespace targets {
+
+class LLVM_LIBRARY_VISIBILITY ARCTargetInfo : public TargetInfo {
+  static const Builtin::Info BuiltinInfo[];
+
+public:
+  ARCTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+      : TargetInfo(Triple) {
+    NoAsmVariants = true;
+    LongLongAlign = 32;
+    SuitableAlign = 32;
+    DoubleAlign = LongDoubleAlign = 32;
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+    IntPtrType = SignedInt;
+    UseZeroLengthBitfieldAlignment = true;
+    resetDataLayout("e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-"
+                    "i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32");
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override;
+
+  ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::VoidPtrBuiltinVaList;
+  }
+
+  const char *getClobbers() const override { return ""; }
+
+  ArrayRef<const char *> getGCCRegNames() const override {
+    static const char *const GCCRegNames[] = {
+        "r0",  "r1",  "r2",  "r3",  "r4",  "r5",     "r6",  "r7",
+        "r8",  "r9",  "r10", "r11", "r12", "r13",    "r14", "r15",
+        "r16", "r17", "r18", "r19", "r20", "r21",    "r22", "r23",
+        "r24", "r25", "gp",  "sp",  "fp",  "ilink1", "r30", "blink"};
+    return llvm::makeArrayRef(GCCRegNames);
+  }
+
+  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
+    return None;
+  }
+
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
+    return false;
+  }
+};
+
+} // namespace targets
+} // namespace clang
+
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_ARC_H
Index: clang/lib/Basic/Targets/ARC.cpp
===================================================================
--- /dev/null
+++ clang/lib/Basic/Targets/ARC.cpp
@@ -0,0 +1,25 @@
+//===--- ARC.cpp - Implement ARC target feature support -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements ARC TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARC.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+void ARCTargetInfo::getTargetDefines(const LangOptions &Opts,
+                                     MacroBuilder &Builder) const {
+  Builder.defineMacro("__arc__");
+}
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -16,6 +16,7 @@
 
 #include "Targets/AArch64.h"
 #include "Targets/AMDGPU.h"
+#include "Targets/ARC.h"
 #include "Targets/ARM.h"
 #include "Targets/AVR.h"
 #include "Targets/BPF.h"
@@ -123,6 +124,9 @@
   default:
     return nullptr;
 
+  case llvm::Triple::arc:
+    return new ARCTargetInfo(Triple, Opts);
+
   case llvm::Triple::xcore:
     return new XCoreTargetInfo(Triple, Opts);
 
Index: clang/lib/Basic/CMakeLists.txt
===================================================================
--- clang/lib/Basic/CMakeLists.txt
+++ clang/lib/Basic/CMakeLists.txt
@@ -70,6 +70,7 @@
   Targets.cpp
   Targets/AArch64.cpp
   Targets/AMDGPU.cpp
+  Targets/ARC.cpp
   Targets/ARM.cpp
   Targets/AVR.cpp
   Targets/BPF.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to