zixuan-wu updated this revision to Diff 419076.
zixuan-wu added a comment.
Herald added subscribers: StephenFan, dexonsmith, MaskRay.

Address comments.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D121445/new/

https://reviews.llvm.org/D121445

Files:
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/CSKY.cpp
  clang/lib/Basic/Targets/CSKY.h
  clang/lib/Driver/CMakeLists.txt
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChains/Arch/CSKY.cpp
  clang/lib/Driver/ToolChains/Arch/CSKY.h
  clang/lib/Driver/ToolChains/CSKYToolChain.cpp
  clang/lib/Driver/ToolChains/CSKYToolChain.h
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/lib/Driver/ToolChains/Linux.cpp
  clang/test/Driver/Inputs/multilib_csky_linux_sdk/csky-linux-gnuabiv2/bin/ld
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/csky-linux-gnuabiv2/libc/ck860v/lib/.keep
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/csky-linux-gnuabiv2/libc/ck860v/usr/lib/crt1.o
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/csky-linux-gnuabiv2/libc/lib/.keep
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/csky-linux-gnuabiv2/libc/usr/lib/crt1.o
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v/crtbegin.o
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v/crtend.o
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v/crti.o
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v/crtn.o
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/crtbegin.o
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/crtend.o
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/crti.o
  
clang/test/Driver/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/crtn.o
  clang/test/Driver/csky-arch-error.c
  clang/test/Driver/csky-arch.c
  clang/test/Driver/csky-cpus-error.c
  clang/test/Driver/csky-cpus.c
  clang/test/Driver/csky-toolchain.c
  clang/test/Preprocessor/csky-target-features.c
  clang/test/Preprocessor/init-csky.c
  llvm/lib/Support/CSKYTargetParser.cpp
  llvm/unittests/Support/CSKYTargetParserTest.cpp

Index: llvm/unittests/Support/CSKYTargetParserTest.cpp
===================================================================
--- llvm/unittests/Support/CSKYTargetParserTest.cpp
+++ llvm/unittests/Support/CSKYTargetParserTest.cpp
@@ -1061,18 +1061,11 @@
   EXPECT_FALSE(CSKY::getExtensionFeatures(CSKY::AEK_INVALID, Features));
 
   for (auto &E : Extensions) {
-    // test +extension
-    Features.clear();
     CSKY::getExtensionFeatures(E.first, Features);
     EXPECT_TRUE(llvm::is_contained(Features, E.second.at(0)));
-    EXPECT_EQ(Extensions.size(), Features.size());
-
-    // test -extension
-    Features.clear();
-    CSKY::getExtensionFeatures(~E.first, Features);
-    EXPECT_TRUE(llvm::is_contained(Features, E.second.at(1)));
-    EXPECT_EQ(Extensions.size(), Features.size());
   }
+
+  EXPECT_EQ(Extensions.size(), Features.size());
 }
 
 TEST(TargetParserTest, CSKYFPUFeatures) {
Index: llvm/lib/Support/CSKYTargetParser.cpp
===================================================================
--- llvm/lib/Support/CSKYTargetParser.cpp
+++ llvm/lib/Support/CSKYTargetParser.cpp
@@ -172,8 +172,6 @@
   for (const auto &AE : CSKYARCHExtNames) {
     if ((Extensions & AE.ID) == AE.ID && AE.Feature)
       Features.push_back(AE.Feature);
-    else if (AE.NegFeature)
-      Features.push_back(AE.NegFeature);
   }
 
   return true;
Index: clang/test/Preprocessor/init-csky.c
===================================================================
--- /dev/null
+++ clang/test/Preprocessor/init-csky.c
@@ -0,0 +1,211 @@
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=csky < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefix=CSKY %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=csky-unknown-linux < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefixes=CSKY,CSKY-LINUX %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=csky \
+// RUN: -fforce-enable-int128 < /dev/null | FileCheck -match-full-lines \
+// RUN: -check-prefixes=CSKY,CSKY-INT128 %s
+// CSKY: #define _ILP32 1
+// CSKY: #define __ATOMIC_ACQUIRE 2
+// CSKY: #define __ATOMIC_ACQ_REL 4
+// CSKY: #define __ATOMIC_CONSUME 1
+// CSKY: #define __ATOMIC_RELAXED 0
+// CSKY: #define __ATOMIC_RELEASE 3
+// CSKY: #define __ATOMIC_SEQ_CST 5
+// CSKY: #define __BIGGEST_ALIGNMENT__ 4
+// CSKY: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// CSKY: #define __CHAR16_TYPE__ unsigned short
+// CSKY: #define __CHAR32_TYPE__ unsigned int
+// CSKY: #define __CHAR_BIT__ 8
+// CSKY: #define __DBL_DECIMAL_DIG__ 17
+// CSKY: #define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// CSKY: #define __DBL_DIG__ 15
+// CSKY: #define __DBL_EPSILON__ 2.2204460492503131e-16
+// CSKY: #define __DBL_HAS_DENORM__ 1
+// CSKY: #define __DBL_HAS_INFINITY__ 1
+// CSKY: #define __DBL_HAS_QUIET_NAN__ 1
+// CSKY: #define __DBL_MANT_DIG__ 53
+// CSKY: #define __DBL_MAX_10_EXP__ 308
+// CSKY: #define __DBL_MAX_EXP__ 1024
+// CSKY: #define __DBL_MAX__ 1.7976931348623157e+308
+// CSKY: #define __DBL_MIN_10_EXP__ (-307)
+// CSKY: #define __DBL_MIN_EXP__ (-1021)
+// CSKY: #define __DBL_MIN__ 2.2250738585072014e-308
+// CSKY: #define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+// CSKY: #define __ELF__ 1
+// CSKY: #define __FINITE_MATH_ONLY__ 0
+// CSKY: #define __FLT_DECIMAL_DIG__ 9
+// CSKY: #define __FLT_DENORM_MIN__ 1.40129846e-45F
+// CSKY: #define __FLT_DIG__ 6
+// CSKY: #define __FLT_EPSILON__ 1.19209290e-7F
+// CSKY: #define __FLT_HAS_DENORM__ 1
+// CSKY: #define __FLT_HAS_INFINITY__ 1
+// CSKY: #define __FLT_HAS_QUIET_NAN__ 1
+// CSKY: #define __FLT_MANT_DIG__ 24
+// CSKY: #define __FLT_MAX_10_EXP__ 38
+// CSKY: #define __FLT_MAX_EXP__ 128
+// CSKY: #define __FLT_MAX__ 3.40282347e+38F
+// CSKY: #define __FLT_MIN_10_EXP__ (-37)
+// CSKY: #define __FLT_MIN_EXP__ (-125)
+// CSKY: #define __FLT_MIN__ 1.17549435e-38F
+// CSKY: #define __FLT_RADIX__ 2
+// CSKY: #define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// CSKY: #define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// CSKY: #define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// CSKY: #define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// CSKY: #define __GCC_ATOMIC_INT_LOCK_FREE 2
+// CSKY: #define __GCC_ATOMIC_LLONG_LOCK_FREE 1
+// CSKY: #define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// CSKY: #define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// CSKY: #define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// CSKY: #define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// CSKY: #define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+// CSKY: #define __GNUC_MINOR__ {{.*}}
+// CSKY: #define __GNUC_PATCHLEVEL__ {{.*}}
+// CSKY: #define __GNUC_STDC_INLINE__ 1
+// CSKY: #define __GNUC__ {{.*}}
+// CSKY: #define __GXX_ABI_VERSION {{.*}}
+// CSKY: #define __ILP32__ 1
+// CSKY: #define __INT16_C_SUFFIX__
+// CSKY: #define __INT16_MAX__ 32767
+// CSKY: #define __INT16_TYPE__ short
+// CSKY: #define __INT32_C_SUFFIX__
+// CSKY: #define __INT32_MAX__ 2147483647
+// CSKY: #define __INT32_TYPE__ int
+// CSKY: #define __INT64_C_SUFFIX__ LL
+// CSKY: #define __INT64_MAX__ 9223372036854775807LL
+// CSKY: #define __INT64_TYPE__ long long int
+// CSKY: #define __INT8_C_SUFFIX__
+// CSKY: #define __INT8_MAX__ 127
+// CSKY: #define __INT8_TYPE__ signed char
+// CSKY: #define __INTMAX_C_SUFFIX__ LL
+// CSKY: #define __INTMAX_MAX__ 9223372036854775807LL
+// CSKY: #define __INTMAX_TYPE__ long long int
+// CSKY: #define __INTMAX_WIDTH__ 64
+// CSKY: #define __INTPTR_MAX__ 2147483647
+// CSKY: #define __INTPTR_TYPE__ int
+// CSKY: #define __INTPTR_WIDTH__ 32
+// TODO: C-SKY GCC defines INT_FAST16 as int
+// CSKY: #define __INT_FAST16_MAX__ 32767
+// CSKY: #define __INT_FAST16_TYPE__ short
+// CSKY: #define __INT_FAST32_MAX__ 2147483647
+// CSKY: #define __INT_FAST32_TYPE__ int
+// CSKY: #define __INT_FAST64_MAX__ 9223372036854775807LL
+// CSKY: #define __INT_FAST64_TYPE__ long long int
+// TODO: C-SKY GCC defines INT_FAST8 as int
+// CSKY: #define __INT_FAST8_MAX__ 127
+// CSKY: #define __INT_FAST8_TYPE__ signed char
+// CSKY: #define __INT_LEAST16_MAX__ 32767
+// CSKY: #define __INT_LEAST16_TYPE__ short
+// CSKY: #define __INT_LEAST32_MAX__ 2147483647
+// CSKY: #define __INT_LEAST32_TYPE__ int
+// CSKY: #define __INT_LEAST64_MAX__ 9223372036854775807LL
+// CSKY: #define __INT_LEAST64_TYPE__ long long int
+// CSKY: #define __INT_LEAST8_MAX__ 127
+// CSKY: #define __INT_LEAST8_TYPE__ signed char
+// CSKY: #define __INT_MAX__ 2147483647
+// CSKY: #define __LDBL_DECIMAL_DIG__ 17
+// CSKY: #define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+// CSKY: #define __LDBL_DIG__ 15
+// CSKY: #define __LDBL_EPSILON__ 2.2204460492503131e-16L
+// CSKY: #define __LDBL_HAS_DENORM__ 1
+// CSKY: #define __LDBL_HAS_INFINITY__ 1
+// CSKY: #define __LDBL_HAS_QUIET_NAN__ 1
+// CSKY: #define __LDBL_MANT_DIG__ 53
+// CSKY: #define __LDBL_MAX_10_EXP__ 308
+// CSKY: #define __LDBL_MAX_EXP__ 1024
+// CSKY: #define __LDBL_MAX__ 1.7976931348623157e+308L
+// CSKY: #define __LDBL_MIN_10_EXP__ (-307)
+// CSKY: #define __LDBL_MIN_EXP__ (-1021)
+// CSKY: #define __LDBL_MIN__ 2.2250738585072014e-308L
+// CSKY: #define __LITTLE_ENDIAN__ 1
+// CSKY: #define __LONG_LONG_MAX__ 9223372036854775807LL
+// CSKY: #define __LONG_MAX__ 2147483647L
+// CSKY: #define __NO_INLINE__ 1
+// CSKY: #define __POINTER_WIDTH__ 32
+// CSKY: #define __PRAGMA_REDEFINE_EXTNAME 1
+// CSKY: #define __PTRDIFF_MAX__ 2147483647
+// CSKY: #define __PTRDIFF_TYPE__ int
+// CSKY: #define __PTRDIFF_WIDTH__ 32
+// CSKY: #define __SCHAR_MAX__ 127
+// CSKY: #define __SHRT_MAX__ 32767
+// CSKY: #define __SIG_ATOMIC_MAX__ 2147483647
+// CSKY: #define __SIG_ATOMIC_WIDTH__ 32
+// CSKY: #define __SIZEOF_DOUBLE__ 8
+// CSKY: #define __SIZEOF_FLOAT__ 4
+// CSKY-INT128: #define __SIZEOF_INT128__ 16
+// CSKY: #define __SIZEOF_INT__ 4
+// CSKY: #define __SIZEOF_LONG_DOUBLE__ 8
+// CSKY: #define __SIZEOF_LONG_LONG__ 8
+// CSKY: #define __SIZEOF_LONG__ 4
+// CSKY: #define __SIZEOF_POINTER__ 4
+// CSKY: #define __SIZEOF_PTRDIFF_T__ 4
+// CSKY: #define __SIZEOF_SHORT__ 2
+// CSKY: #define __SIZEOF_SIZE_T__ 4
+// CSKY: #define __SIZEOF_WCHAR_T__ 4
+// CSKY: #define __SIZEOF_WINT_T__ 4
+// CSKY: #define __SIZE_MAX__ 4294967295U
+// CSKY: #define __SIZE_TYPE__ unsigned int
+// CSKY: #define __SIZE_WIDTH__ 32
+// CSKY: #define __STDC_HOSTED__ 0
+// CSKY: #define __STDC_UTF_16__ 1
+// CSKY: #define __STDC_UTF_32__ 1
+// CSKY: #define __STDC_VERSION__ 201710L
+// CSKY: #define __STDC__ 1
+// CSKY: #define __UINT16_C_SUFFIX__
+// CSKY: #define __UINT16_MAX__ 65535
+// CSKY: #define __UINT16_TYPE__ unsigned short
+// CSKY: #define __UINT32_C_SUFFIX__ U
+// CSKY: #define __UINT32_MAX__ 4294967295U
+// CSKY: #define __UINT32_TYPE__ unsigned int
+// CSKY: #define __UINT64_C_SUFFIX__ ULL
+// CSKY: #define __UINT64_MAX__ 18446744073709551615ULL
+// CSKY: #define __UINT64_TYPE__ long long unsigned int
+// CSKY: #define __UINT8_C_SUFFIX__
+// CSKY: #define __UINT8_MAX__ 255
+// CSKY: #define __UINT8_TYPE__ unsigned char
+// CSKY: #define __UINTMAX_C_SUFFIX__ ULL
+// CSKY: #define __UINTMAX_MAX__ 18446744073709551615ULL
+// CSKY: #define __UINTMAX_TYPE__ long long unsigned int
+// CSKY: #define __UINTMAX_WIDTH__ 64
+// CSKY: #define __UINTPTR_MAX__ 4294967295U
+// CSKY: #define __UINTPTR_TYPE__ unsigned int
+// CSKY: #define __UINTPTR_WIDTH__ 32
+// TODO: C-SKY GCC defines UINT_FAST16 to be unsigned int
+// CSKY: #define __UINT_FAST16_MAX__ 65535
+// CSKY: #define __UINT_FAST16_TYPE__ unsigned short
+// CSKY: #define __UINT_FAST32_MAX__ 4294967295U
+// CSKY: #define __UINT_FAST32_TYPE__ unsigned int
+// CSKY: #define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// CSKY: #define __UINT_FAST64_TYPE__ long long unsigned int
+// TODO: C-SKY GCC defines UINT_FAST8 to be unsigned int
+// CSKY: #define __UINT_FAST8_MAX__ 255
+// CSKY: #define __UINT_FAST8_TYPE__ unsigned char
+// CSKY: #define __UINT_LEAST16_MAX__ 65535
+// CSKY: #define __UINT_LEAST16_TYPE__ unsigned short
+// CSKY: #define __UINT_LEAST32_MAX__ 4294967295U
+// CSKY: #define __UINT_LEAST32_TYPE__ unsigned int
+// CSKY: #define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// CSKY: #define __UINT_LEAST64_TYPE__ long long unsigned int
+// CSKY: #define __UINT_LEAST8_MAX__ 255
+// CSKY: #define __UINT_LEAST8_TYPE__ unsigned char
+// CSKY: #define __USER_LABEL_PREFIX__
+// CSKY: #define __WCHAR_MAX__ 2147483647
+// CSKY: #define __WCHAR_TYPE__ int
+// CSKY: #define __WCHAR_WIDTH__ 32
+// CSKY: #define __WINT_TYPE__ unsigned int
+// CSKY: #define __WINT_UNSIGNED__ 1
+// CSKY: #define __WINT_WIDTH__ 32
+// CSKY: #define __ck810__ 1
+// CSKY: #define __ckcore__ 2
+// CSKY: #define __cskyLE__ 1
+// CSKY: #define __csky__ 2
+// CSKY: #define __cskyabi__ 2
+// CSKY: #define __cskyle__ 1
+// CSKY-LINUX: #define __gnu_linux__ 1
+// CSKY-LINUX: #define __linux 1
+// CSKY-LINUX: #define __linux__ 1
+// CSKY-LINUX: #define __unix 1
+// CSKY-LINUX: #define __unix__ 1
+// CSKY-LINUX: #define linux 1
+// CSKY-LINUX: #define unix 1
Index: clang/test/Preprocessor/csky-target-features.c
===================================================================
--- /dev/null
+++ clang/test/Preprocessor/csky-target-features.c
@@ -0,0 +1,15 @@
+// RUN: %clang -target csky-unknown-linux-gnu  -x c -E -dM %s \
+// RUN: -o - | FileCheck %s
+
+// CHECK: __CK810__ 1
+// CHECK: __CKCORE__ 2
+// CHECK: __CSKYABI__ 2
+// CHECK: __CSKYLE__ 1
+// CHECK: __CSKY__ 2
+
+// CHECK: __ck810__ 1
+// CHECK: __ckcore__ 2
+// CHECK: __cskyLE__ 1
+// CHECK: __csky__ 2
+// CHECK: __cskyabi__ 2
+// CHECK: __cskyle__ 1
Index: clang/test/Driver/csky-toolchain.c
===================================================================
--- /dev/null
+++ clang/test/Driver/csky-toolchain.c
@@ -0,0 +1,43 @@
+// A basic clang -cc1 command-line, and simple environment check.
+
+// RUN: %clang %s -### -no-canonical-prefixes -target csky 2>&1 | FileCheck -check-prefix=CC1 %s
+// CC1: clang{{.*}} "-cc1" "-triple" "csky"
+
+// Test interaction with -fuse-ld=lld, if lld is available.
+// RUN: %clang %s -### -no-canonical-prefixes -target csky -fuse-ld=lld 2>&1 | FileCheck -check-prefix=LLD %s
+// LLD: {{(error: invalid linker name in argument '-fuse-ld=lld')|(ld.lld)}}
+
+// In the below tests, --rtlib=platform is used so that the driver ignores
+// the configure-time CLANG_DEFAULT_RTLIB option when choosing the runtime lib
+
+// RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld -target csky-unknown-linux-gnu --rtlib=platform  \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_csky_linux_sdk  2>&1 | FileCheck -check-prefix=C-CSKY-LINUX-MULTI %s
+
+// C-CSKY-LINUX-MULTI: "{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/bin{{/|\\\\}}ld"
+// C-CSKY-LINUX-MULTI: "--sysroot={{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc"
+// C-CSKY-LINUX-MULTI: "-m" "cskyelf_linux"
+// C-CSKY-LINUX-MULTI: "-dynamic-linker" "/lib/ld.so.1"
+// C-CSKY-LINUX-MULTI: "{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/usr/lib/../lib/crt1.o"
+// C-CSKY-LINUX-MULTI: "{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/crti.o"
+// C-CSKY-LINUX-MULTI: "{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/crtbegin.o"
+// C-CSKY-LINUX-MULTI: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0"
+// C-CSKY-LINUX-MULTI: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/lib/../lib"
+// C-CSKY-LINUX-MULTI: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/usr/lib/../lib"
+// C-CSKY-LINUX-MULTI: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/lib"
+// C-CSKY-LINUX-MULTI: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/usr/lib"
+
+// RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld -target csky-unknown-linux-gnu --rtlib=platform -march=ck860v \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_csky_linux_sdk 2>&1 | FileCheck -check-prefix=C-CSKY-LINUX-CK860V %s
+
+// C-CSKY-LINUX-CK860V: "{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/bin{{/|\\\\}}ld"
+// C-CSKY-LINUX-CK860V: "--sysroot={{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/ck860v"
+// C-CSKY-LINUX-CK860V: "-m" "cskyelf_linux"
+// C-CSKY-LINUX-CK860V: "-dynamic-linker" "/lib/ld.so.1"
+// C-CSKY-LINUX-CK860V: "{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/ck860v/usr/lib/../lib/crt1.o"
+// C-CSKY-LINUX-CK860V: "{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v/crti.o"
+// C-CSKY-LINUX-CK860V: "{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v/crtbegin.o"
+// C-CSKY-LINUX-CK860V: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v"
+// C-CSKY-LINUX-CK860V: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/ck860v/lib/../lib"
+// C-CSKY-LINUX-CK860V: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/ck860v/usr/lib/../lib"
+// C-CSKY-LINUX-CK860V: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/ck860v/lib"
+// C-CSKY-LINUX-CK860V: "-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|\\\\}}..{{/|\\\\}}csky-linux-gnuabiv2/libc/ck860v/usr/lib"
Index: clang/test/Driver/csky-cpus.c
===================================================================
--- /dev/null
+++ clang/test/Driver/csky-cpus.c
@@ -0,0 +1,25 @@
+// Check target CPUs are correctly passed.
+
+// RUN: %clang -target csky -### -c %s -fsyntax-only 2>&1 -mcpu=ck801 | FileCheck -check-prefix=MCPU-CK801 %s
+// MCPU-CK801: "-target-cpu" "ck801"
+// MCPU-CK801: "-target-feature" "+elrw" "-target-feature" "+trust" "-target-feature" "+e1"
+
+// RUN: %clang -target csky -### -c %s -fsyntax-only 2>&1 -mcpu=ck801t | FileCheck -check-prefix=MCPU-CK801T %s
+// MCPU-CK801T: "-target-cpu" "ck801t"
+// MCPU-CK801T: "-target-feature" "+elrw" "-target-feature" "+trust" "-target-feature" "+e1"
+
+// RUN: %clang -target csky -### -c %s -fsyntax-only 2>&1 -mcpu=e801 | FileCheck -check-prefix=MCPU-E801 %s
+// MCPU-E801: "-target-cpu" "e801"
+// MCPU-E801: "-target-feature" "+elrw" "-target-feature" "+trust" "-target-feature" "+e1"
+
+// RUN: %clang -target csky -### -c %s -fsyntax-only 2>&1 -mcpu=ck802 | FileCheck -check-prefix=MCPU-CK802 %s
+// MCPU-CK802: "-target-cpu" "ck802"
+// MCPU-CK802: "-target-feature" "+elrw" "-target-feature" "+trust" "-target-feature" "+nvic"
+// MCPU-CK802: "-target-feature" "+e1" "-target-feature" "+e2"
+
+// RUN: %clang -target csky -### -c %s -fsyntax-only 2>&1 -mcpu=ck802t | FileCheck -check-prefix=MCPU-CK802T %s
+// MCPU-CK802T: "-target-cpu" "ck802t"
+// MCPU-CK802T: "-target-feature" "+elrw" "-target-feature" "+trust" "-target-feature" "+nvic"
+// MCPU-CK802T: "-target-feature" "+e1" "-target-feature" "+e2"
+
+// TODO: Add more cpu test.
Index: clang/test/Driver/csky-cpus-error.c
===================================================================
--- /dev/null
+++ clang/test/Driver/csky-cpus-error.c
@@ -0,0 +1,7 @@
+// Check failed cases
+
+// RUN: not %clang -target csky -c %s 2>&1 -mcpu=generic1 | FileCheck -check-prefix=FAIL-MCPU-NAME %s
+// FAIL-MCPU-NAME: error: the clang compiler does not support '-mcpu=generic1'
+
+// RUN: not %clang -target csky -c %s 2>&1 -mcpu=generic -march=ck860 | FileCheck -check-prefix=MISMATCH-ARCH %s
+// MISMATCH-ARCH: error: the clang compiler does not support '-mcpu=generic'
Index: clang/test/Driver/csky-arch.c
===================================================================
--- /dev/null
+++ clang/test/Driver/csky-arch.c
@@ -0,0 +1,108 @@
+// RUN: %clang -target csky-unknown-elf -march=ck801 -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK801
+
+// CHECK-CK801: "-target-cpu" "ck801"
+// CHECK-CK801: "-target-feature" "+elrw" "-target-feature" "+trust"
+// CHECK-CK801: "-target-feature" "+e1"
+
+// RUN: %clang -target csky-unknown-elf -march=ck802 -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK802
+
+// CHECK-CK802: "-target-cpu" "ck802"
+// CHECK-CK802: "-target-feature" "+elrw" "-target-feature" "+trust"
+// CHECK-CK802: "-target-feature" "+nvic" "-target-feature" "+e1"
+// CHECK-CK802: "-target-feature" "+e2"
+
+// RUN: %clang -target csky-unknown-elf -march=ck803 -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK803
+
+// CHECK-CK803: "-target-cpu" "ck803"
+// CHECK-CK803: "-target-feature" "+hwdiv" "-target-feature" "+elrw"
+// CHECK-CK803: "-target-feature" "+trust" "-target-feature" "+nvic"
+// CHECK-CK803: "-target-feature" "+e1" "-target-feature" "+e2" "-target-feature" "+2e3"
+// CHECK-CK803: "-target-feature" "+mp"
+
+// RUN: %clang -target csky-unknown-elf -march=ck803s -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK803S
+
+// CHECK-CK803S: "-target-cpu" "ck803s"
+// CHECK-CK803S: "-target-feature" "+hwdiv" "-target-feature" "+elrw"
+// CHECK-CK803S: "-target-feature" "+trust" "-target-feature" "+nvic"
+// CHECK-CK803S: "-target-feature" "+e1" "-target-feature" "+e2"
+// CHECK-CK803S: "-target-feature" "+2e3" "-target-feature" "+mp"
+
+// RUN: %clang -target csky-unknown-elf -march=ck804 -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK804
+
+// CHECK-CK804: "-target-cpu" "ck804"
+// CHECK-CK804: "-target-feature" "+hwdiv" "-target-feature" "+elrw"
+// CHECK-CK804: "-target-feature" "+trust" "-target-feature" "+nvic"
+// CHECK-CK804: "-target-feature" "+doloop" "-target-feature" "+e1"
+// CHECK-CK804: "-target-feature" "+e2" "-target-feature" "+2e3"
+// CHECK-CK804: "-target-feature" "+mp" "-target-feature" "+3e3r1"
+// CHECK-CK804: "-target-feature" "+3e3r2" "-target-feature" "+3e3r3"
+
+// RUN: %clang -target csky-unknown-elf -march=ck805 -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK805
+
+// CHECK-CK805: "-target-cpu" "ck805"
+// CHECK-CK805: "-target-feature" "+hwdiv" "-target-feature" "+elrw"
+// CHECK-CK805: "-target-feature" "+trust" "-target-feature" "+nvic"
+// CHECK-CK805: "-target-feature" "+doloop" "-target-feature" "+high-registers"
+// CHECK-CK805: "-target-feature" "+vdsp2e3" "-target-feature" "+vdspv2" "-target-feature" "+e1"
+// CHECK-CK805: "-target-feature" "+e2" "-target-feature" "+2e3" "-target-feature" "+mp"
+// CHECK-CK805: "-target-feature" "+3e3r1" "-target-feature" "+3e3r2" "-target-feature" "+3e3r3"
+
+// RUN: %clang -target csky-unknown-elf -march=ck807 -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK807
+
+// CHECK-CK807: "-target-cpu" "ck807"
+// CHECK-CK807: "-target-feature" "+hwdiv" "-target-feature" "+edsp"
+// CHECK-CK807: "-target-feature" "+dsp1e2" "-target-feature" "+dspe60" "-target-feature" "+elrw"
+// CHECK-CK807: "-target-feature" "+trust" "-target-feature" "+cache" "-target-feature" "+nvic"
+// CHECK-CK807: "-target-feature" "+high-registers" "-target-feature" "+hard-tp" "-target-feature" "+e1"
+// CHECK-CK807: "-target-feature" "+e2" "-target-feature" "+2e3" "-target-feature" "+mp"
+// CHECK-CK807: "-target-feature" "+3e7" "-target-feature" "+mp1e2"
+
+// RUN: %clang -target csky-unknown-elf -march=ck810 -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK810
+
+// CHECK-CK810: "-target-cpu" "ck810"
+// CHECK-CK810: "-target-feature" "+hwdiv" "-target-feature" "+edsp" "-target-feature" "+dsp1e2"
+// CHECK-CK810: "-target-feature" "+dspe60" "-target-feature" "+elrw" "-target-feature" "+trust"
+// CHECK-CK810: "-target-feature" "+cache" "-target-feature" "+nvic" "-target-feature" "+high-registers"
+// CHECK-CK810: "-target-feature" "+hard-tp" "-target-feature" "+e1" "-target-feature" "+e2" "-target-feature" "+2e3"
+// CHECK-CK810: "-target-feature" "+mp" "-target-feature" "+3e7" "-target-feature" "+mp1e2" "-target-feature" "+7e10"
+
+// RUN: %clang -target csky-unknown-elf -march=ck810v -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK810V
+
+// CHECK-CK810V: "-target-cpu" "ck810v"
+// CHECK-CK810V: "-target-feature" "+hwdiv" "-target-feature" "+edsp" "-target-feature" "+dsp1e2"
+// CHECK-CK810V: "-target-feature" "+dspe60" "-target-feature" "+elrw" "-target-feature" "+trust"
+// CHECK-CK810V: "-target-feature" "+cache" "-target-feature" "+nvic" "-target-feature" "+high-registers"
+// CHECK-CK810V: "-target-feature" "+hard-tp" "-target-feature" "+vdspv1" "-target-feature" "+e1"
+// CHECK-CK810V: "-target-feature" "+e2" "-target-feature" "+2e3" "-target-feature" "+mp"
+// CHECK-CK810V: "-target-feature" "+3e7" "-target-feature" "+mp1e2" "-target-feature" "+7e10"
+
+// RUN: %clang -target csky-unknown-elf -march=ck860 -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK860
+
+// CHECK-CK860: "-target-cpu" "ck860"
+// CHECK-CK860: "-target-feature" "+hwdiv" "-target-feature" "+dspe60" "-target-feature" "+elrw"
+// CHECK-CK860: "-target-feature" "+trust" "-target-feature" "+cache" "-target-feature" "+nvic"
+// CHECK-CK860: "-target-feature" "+doloop" "-target-feature" "+high-registers" "-target-feature" "+hard-tp"
+// CHECK-CK860: "-target-feature" "+e1" "-target-feature" "+e2" "-target-feature" "+2e3" "-target-feature" "+mp"
+// CHECK-CK860: "-target-feature" "+3e3r1" "-target-feature" "+3e3r2" "-target-feature" "+3e3r3"
+// CHECK-CK860: "-target-feature" "+3e7" "-target-feature" "+mp1e2" "-target-feature" "+7e10" "-target-feature" "+10e60"
+
+// RUN: %clang -target csky-unknown-elf -march=ck860v -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck %s -check-prefixes=CHECK-CK860V
+
+// CHECK-CK860V: "-target-cpu" "ck860v"
+// CHECK-CK860V: "-target-feature" "+hwdiv" "-target-feature" "+dspe60" "-target-feature" "+elrw" "-target-feature" "+trust"
+// CHECK-CK860V: "-target-feature" "+cache" "-target-feature" "+nvic" "-target-feature" "+doloop"
+// CHECK-CK860V: "-target-feature" "+high-registers" "-target-feature" "+vdsp2e60f" "-target-feature" "+vdspv2"
+// CHECK-CK860V: "-target-feature" "+hard-tp" "-target-feature" "+e1" "-target-feature" "+e2" "-target-feature" "+2e3"
+// CHECK-CK860V: "-target-feature" "+mp" "-target-feature" "+3e3r1" "-target-feature" "+3e3r2" "-target-feature" "+3e3r3"
+// CHECK-CK860V: "-target-feature" "+3e7" "-target-feature" "+mp1e2" "-target-feature" "+7e10" "-target-feature" "+10e60"
\ No newline at end of file
Index: clang/test/Driver/csky-arch-error.c
===================================================================
--- /dev/null
+++ clang/test/Driver/csky-arch-error.c
@@ -0,0 +1,7 @@
+// RUN: not %clang -target csky-unknown-elf -march=csky %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=CSKY %s
+// CSKY: error: invalid arch name '-march=csky'
+
+// RUN: not %clang -target csky-unknown-elf -march=CK810 %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=CSKY-UPPER %s
+// CSKY-UPPER: error: invalid arch name '-march=CK810'
Index: clang/lib/Driver/ToolChains/Linux.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Linux.cpp
+++ clang/lib/Driver/ToolChains/Linux.cpp
@@ -221,8 +221,12 @@
   const bool IsMips = Triple.isMIPS();
   const bool IsHexagon = Arch == llvm::Triple::hexagon;
   const bool IsRISCV = Triple.isRISCV();
+  const bool IsCSKY = Triple.isCSKY();
 
-  if (IsMips && !SysRoot.empty())
+  if (IsCSKY)
+    SysRoot = SysRoot + SelectedMultilib.osSuffix();
+
+  if ((IsMips || IsCSKY) && !SysRoot.empty())
     ExtraOpts.push_back("--sysroot=" + SysRoot);
 
   // Do not use 'gnu' hash style for Mips targets because .gnu.hash
@@ -368,6 +372,21 @@
       return AndroidSysRootPath;
   }
 
+  if (getTriple().isCSKY()) {
+    // CSKY toolchains use different names for sysroot folder.
+    if (!GCCInstallation.isValid())
+      return std::string();
+    // GCCInstallation.getInstallPath() =
+    //   $GCCToolchainPath/lib/gcc/csky-linux-gnuabiv2/6.3.0
+    // Path = $GCCToolchainPath/csky-linux-gnuabiv2/libc
+    std::string Path = (GCCInstallation.getInstallPath() + "/../../../../" +
+                        GCCInstallation.getTriple().str() + "/libc")
+                           .str();
+    if (getVFS().exists(Path))
+      return Path;
+    return std::string();
+  }
+
   if (!GCCInstallation.isValid() || !getTriple().isMIPS())
     return std::string();
 
@@ -544,6 +563,11 @@
   }
   case llvm::Triple::ve:
     return "/opt/nec/ve/lib/ld-linux-ve.so.1";
+  case llvm::Triple::csky: {
+    LibDir = "lib";
+    Loader = "ld.so.1";
+    break;
+  }
   }
 
   if (Distro == Distro::Exherbo &&
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -8,6 +8,7 @@
 
 #include "Gnu.h"
 #include "Arch/ARM.h"
+#include "Arch/CSKY.h"
 #include "Arch/Mips.h"
 #include "Arch/PPC.h"
 #include "Arch/RISCV.h"
@@ -299,6 +300,8 @@
     return "elf_x86_64";
   case llvm::Triple::ve:
     return "elf64ve";
+  case llvm::Triple::csky:
+    return "cskyelf_linux";
   default:
     return nullptr;
   }
@@ -1577,6 +1580,72 @@
   return false;
 }
 
+static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
+                              StringRef Path, const ArgList &Args,
+                              DetectedMultilibs &Result) {
+  FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
+
+  tools::csky::FloatABI TheFloatABI = tools::csky::getCSKYFloatABI(D, Args);
+  llvm::Optional<llvm::StringRef> Res = tools::csky::getCSKYArchName(D, Args, TargetTriple);
+
+  if (!Res)
+    return;
+  auto ARCHName = *Res;
+
+  if (ARCHName.empty())
+    ARCHName = "ck810";
+
+  bool isBigEndian = false;
+
+  Multilib::flags_list Flags;
+  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Hard, "hard-fp", Flags);
+  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::SoftFP, "soft-fp",
+                  Flags);
+  addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Soft, "soft", Flags);
+  addMultilibFlag(ARCHName == "ck801", "march=ck801", Flags);
+  addMultilibFlag(ARCHName == "ck802", "march=ck802", Flags);
+  addMultilibFlag(ARCHName == "ck803", "march=ck803", Flags);
+  addMultilibFlag(ARCHName == "ck804", "march=ck804", Flags);
+  addMultilibFlag(ARCHName == "ck805", "march=ck805", Flags);
+  addMultilibFlag(ARCHName == "ck807", "march=ck807", Flags);
+  addMultilibFlag(ARCHName == "ck810", "march=ck810", Flags);
+  addMultilibFlag(ARCHName == "ck810v", "march=ck810v", Flags);
+  addMultilibFlag(ARCHName == "ck860", "march=ck860", Flags);
+  addMultilibFlag(ARCHName == "ck860v", "march=ck860v", Flags);
+
+  if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+                               options::OPT_mbig_endian))
+    isBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
+  addMultilibFlag(isBigEndian, "EB", Flags);
+
+  auto HardFloat = makeMultilib("/hard-fp").flag("+hard-fp");
+  auto SoftFpFloat = makeMultilib("/soft-fp").flag("+soft-fp");
+  auto SoftFloat = makeMultilib("").flag("+soft");
+  auto Arch801 = makeMultilib("/ck801").flag("+march=ck801");
+  auto Arch802 = makeMultilib("/ck802").flag("+march=ck802");
+  auto Arch803 = makeMultilib("/ck803").flag("+march=ck803");
+  // CK804 use the same library as CK803
+  auto Arch804 = makeMultilib("/ck803").flag("+march=ck804");
+  auto Arch805 = makeMultilib("/ck805").flag("+march=ck805");
+  auto Arch807 = makeMultilib("/ck807").flag("+march=ck807");
+  auto Arch810 = makeMultilib("").flag("+march=ck810");
+  auto Arch810v = makeMultilib("/ck810v").flag("+march=ck810v");
+  auto Arch860 = makeMultilib("/ck860").flag("+march=ck860");
+  auto Arch860v = makeMultilib("/ck860v").flag("+march=ck860v");
+  auto BigEndian = makeMultilib("/big").flag("+EB");
+
+  MultilibSet CSKYMultilibs =
+      MultilibSet()
+          .Maybe(BigEndian)
+          .Either({Arch801, Arch802, Arch803, Arch804, Arch805, Arch807,
+                   Arch810, Arch810v, Arch860, Arch860v})
+          .Either(HardFloat, SoftFpFloat, SoftFloat)
+          .FilterOut(NonExistent);
+
+  if (CSKYMultilibs.select(Flags, Result.SelectedMultilib))
+    Result.Multilibs = CSKYMultilibs;
+}
+
 static void findRISCVBareMetalMultilibs(const Driver &D,
                                         const llvm::Triple &TargetTriple,
                                         StringRef Path, const ArgList &Args,
@@ -2099,6 +2168,10 @@
   static const char *const AVRLibDirs[] = {"/lib"};
   static const char *const AVRTriples[] = {"avr"};
 
+  static const char *const CSKYLibDirs[] = {"/lib"};
+  static const char *const CSKYTriples[] = {
+      "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2"};
+
   static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};
   static const char *const X86_64Triples[] = {
       "x86_64-linux-gnu",       "x86_64-unknown-linux-gnu",
@@ -2333,6 +2406,10 @@
     LibDirs.append(begin(AVRLibDirs), end(AVRLibDirs));
     TripleAliases.append(begin(AVRTriples), end(AVRTriples));
     break;
+  case llvm::Triple::csky:
+    LibDirs.append(begin(CSKYLibDirs), end(CSKYLibDirs));
+    TripleAliases.append(begin(CSKYTriples), end(CSKYTriples));
+    break;
   case llvm::Triple::x86_64:
     if (TargetTriple.isX32()) {
       LibDirs.append(begin(X32LibDirs), end(X32LibDirs));
@@ -2482,6 +2559,8 @@
   if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {
     // It should also work without multilibs in a simplified toolchain.
     findAndroidArmMultilibs(D, TargetTriple, Path, Args, Detected);
+  } else if (TargetTriple.isCSKY()) {
+    findCSKYMultilibs(D, TargetTriple, Path, Args, Detected);
   } else if (TargetTriple.isMIPS()) {
     if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected))
       return false;
@@ -2742,6 +2821,7 @@
   case llvm::Triple::avr:
   case llvm::Triple::bpfel:
   case llvm::Triple::bpfeb:
+  case llvm::Triple::csky:
   case llvm::Triple::thumb:
   case llvm::Triple::thumbeb:
   case llvm::Triple::ppc:
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -424,6 +424,13 @@
 
     return TargetCPUName;
   }
+  case llvm::Triple::csky:
+    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+      return A->getValue();
+    else if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+      return A->getValue();
+    else
+      return "ck810";
   case llvm::Triple::riscv32:
   case llvm::Triple::riscv64:
     if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -10,6 +10,7 @@
 #include "AMDGPU.h"
 #include "Arch/AArch64.h"
 #include "Arch/ARM.h"
+#include "Arch/CSKY.h"
 #include "Arch/M68k.h"
 #include "Arch/Mips.h"
 #include "Arch/PPC.h"
@@ -383,6 +384,9 @@
   case llvm::Triple::ve:
     ve::getVETargetFeatures(D, Args, Features);
     break;
+  case llvm::Triple::csky:
+    csky::getCSKYTargetFeatures(D, Triple, Args, CmdArgs, Features);
+    break;
   }
 
   for (auto Feature : unifyTargetFeatures(Features)) {
@@ -547,6 +551,7 @@
   case llvm::Triple::riscv64:
   case llvm::Triple::amdgcn:
   case llvm::Triple::r600:
+  case llvm::Triple::csky:
     return !areOptimizationsEnabled(Args);
   default:
     break;
Index: clang/lib/Driver/ToolChains/CSKYToolChain.h
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/CSKYToolChain.h
@@ -0,0 +1,64 @@
+//===--- CSKYToolchain.h - CSKY ToolChain Implementations -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CSKYTOOLCHAIN_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CSKYTOOLCHAIN_H
+
+#include "Gnu.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY CSKYToolChain : public Generic_ELF {
+public:
+  CSKYToolChain(const Driver &D, const llvm::Triple &Triple,
+                const llvm::opt::ArgList &Args);
+
+  bool IsIntegratedAssemblerDefault() const override { return true; }
+  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                             llvm::opt::ArgStringList &CC1Args,
+                             Action::OffloadKind) const override;
+  RuntimeLibType GetDefaultRuntimeLibType() const override;
+  UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const override;
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void
+  addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+                           llvm::opt::ArgStringList &CC1Args) const override;
+
+protected:
+  Tool *buildLinker() const override;
+
+private:
+  std::string computeSysRoot() const override;
+};
+
+} // end namespace toolchains
+
+namespace tools {
+namespace CSKY {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+public:
+  Linker(const ToolChain &TC) : Tool("CSKY::Linker", "ld", TC) {}
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace CSKY
+} // end namespace tools
+
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CSKYTOOLCHAIN_H
Index: clang/lib/Driver/ToolChains/CSKYToolChain.cpp
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/CSKYToolChain.cpp
@@ -0,0 +1,204 @@
+//===--- CSKYToolchain.cpp - CSKY ToolChain Implementations ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CSKYToolChain.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/InputInfo.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
+                                  const Multilib &Multilib,
+                                  StringRef InstallPath,
+                                  ToolChain::path_list &Paths) {
+  if (const auto &PathsCallback = Multilibs.filePathsCallback())
+    for (const auto &Path : PathsCallback(Multilib))
+      addPathIfExists(D, InstallPath + Path, Paths);
+}
+
+/// CSKY Toolchain
+CSKYToolChain::CSKYToolChain(const Driver &D, const llvm::Triple &Triple,
+                             const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  GCCInstallation.init(Triple, Args);
+  if (GCCInstallation.isValid()) {
+    Multilibs = GCCInstallation.getMultilibs();
+    SelectedMultilib = GCCInstallation.getMultilib();
+    path_list &Paths = getFilePaths();
+    // Add toolchain/multilib specific file paths.
+    addMultilibsFilePaths(D, Multilibs, SelectedMultilib,
+                          GCCInstallation.getInstallPath(), Paths);
+    getFilePaths().push_back(GCCInstallation.getInstallPath().str() +
+                             SelectedMultilib.osSuffix());
+    ToolChain::path_list &PPaths = getProgramPaths();
+    // Multilib cross-compiler GCC installations put ld in a triple-prefixed
+    // directory off of the parent of the GCC installation.
+    PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
+                           GCCInstallation.getTriple().str() + "/bin")
+                         .str());
+    PPaths.push_back((GCCInstallation.getParentLibPath() + "/../bin").str());
+  } else {
+    getProgramPaths().push_back(D.Dir);
+  }
+  getFilePaths().push_back(computeSysRoot() + "/lib" +
+                           SelectedMultilib.osSuffix());
+}
+
+Tool *CSKYToolChain::buildLinker() const {
+  return new tools::CSKY::Linker(*this);
+}
+
+ToolChain::RuntimeLibType CSKYToolChain::GetDefaultRuntimeLibType() const {
+  return GCCInstallation.isValid() ? ToolChain::RLT_Libgcc
+                                   : ToolChain::RLT_CompilerRT;
+}
+
+ToolChain::UnwindLibType
+CSKYToolChain::GetUnwindLibType(const llvm::opt::ArgList &Args) const {
+  return ToolChain::UNW_None;
+}
+
+void CSKYToolChain::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                                          llvm::opt::ArgStringList &CC1Args,
+                                          Action::OffloadKind) const {
+  CC1Args.push_back("-nostdsysteminc");
+}
+
+void CSKYToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                              ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nostdinc))
+    return;
+
+  if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
+    SmallString<128> Dir(computeSysRoot());
+    llvm::sys::path::append(Dir, "include");
+    addSystemInclude(DriverArgs, CC1Args, Dir.str());
+    SmallString<128> Dir2(computeSysRoot());
+    llvm::sys::path::append(Dir2, "sys-include");
+    addSystemInclude(DriverArgs, CC1Args, Dir2.str());
+  }
+}
+
+void CSKYToolChain::addLibStdCxxIncludePaths(
+    const llvm::opt::ArgList &DriverArgs,
+    llvm::opt::ArgStringList &CC1Args) const {
+  const GCCVersion &Version = GCCInstallation.getVersion();
+  StringRef TripleStr = GCCInstallation.getTriple().str();
+  const Multilib &Multilib = GCCInstallation.getMultilib();
+  addLibStdCXXIncludePaths(computeSysRoot() + "/include/c++/" + Version.Text,
+                           TripleStr, Multilib.includeSuffix(), DriverArgs,
+                           CC1Args);
+}
+
+std::string CSKYToolChain::computeSysRoot() const {
+  if (!getDriver().SysRoot.empty())
+    return getDriver().SysRoot;
+
+  SmallString<128> SysRootDir;
+  if (GCCInstallation.isValid()) {
+    StringRef LibDir = GCCInstallation.getParentLibPath();
+    StringRef TripleStr = GCCInstallation.getTriple().str();
+    llvm::sys::path::append(SysRootDir, LibDir, "..", TripleStr);
+  } else {
+    // Use the triple as provided to the driver. Unlike the parsed triple
+    // this has not been normalized to always contain every field.
+    llvm::sys::path::append(SysRootDir, getDriver().Dir, "..",
+                            getDriver().getTargetTriple());
+  }
+
+  if (!llvm::sys::fs::exists(SysRootDir))
+    return std::string();
+
+  return std::string(SysRootDir.str());
+}
+
+void CSKY::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                const InputInfo &Output,
+                                const InputInfoList &Inputs,
+                                const ArgList &Args,
+                                const char *LinkingOutput) const {
+  const ToolChain &ToolChain = getToolChain();
+  const Driver &D = ToolChain.getDriver();
+  ArgStringList CmdArgs;
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  CmdArgs.push_back("-m");
+  CmdArgs.push_back("cskyelf");
+
+  std::string Linker = getToolChain().GetLinkerPath();
+
+  bool WantCRTs =
+      !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
+
+  const char *crtbegin, *crtend;
+  auto RuntimeLib = ToolChain.GetRuntimeLibType(Args);
+  if (RuntimeLib == ToolChain::RLT_Libgcc) {
+    crtbegin = "crtbegin.o";
+    crtend = "crtend.o";
+  } else {
+    assert(RuntimeLib == ToolChain::RLT_CompilerRT);
+    crtbegin = ToolChain.getCompilerRTArgString(Args, "crtbegin",
+                                                ToolChain::FT_Object);
+    crtend =
+        ToolChain.getCompilerRTArgString(Args, "crtend", ToolChain::FT_Object);
+  }
+
+  if (WantCRTs) {
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+  Args.AddAllArgs(CmdArgs,
+                  {options::OPT_T_Group, options::OPT_e, options::OPT_s,
+                   options::OPT_t, options::OPT_Z_Flag, options::OPT_r});
+
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
+
+  // TODO: add C++ includes and libs if compiling C++.
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    if (ToolChain.ShouldLinkCXXStdlib(Args))
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+    CmdArgs.push_back("--start-group");
+    CmdArgs.push_back("-lc");
+    if (Args.hasArg(options::OPT_msim))
+      CmdArgs.push_back("-lsemi");
+    else
+      CmdArgs.push_back("-lnosys");
+    CmdArgs.push_back("--end-group");
+    AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args);
+  }
+
+  if (WantCRTs) {
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+  }
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+  C.addCommand(std::make_unique<Command>(
+      JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),
+      CmdArgs, Inputs, Output));
+}
+// CSKY tools end.
Index: clang/lib/Driver/ToolChains/Arch/CSKY.h
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/Arch/CSKY.h
@@ -0,0 +1,47 @@
+//===--- CSKY.h - CSKY-specific Tool Helpers ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_CSKY_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_CSKY_H
+
+#include "clang/Driver/Driver.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace csky {
+
+enum class FloatABI {
+  Invalid,
+  Soft,
+  SoftFP,
+  Hard,
+};
+
+FloatABI getCSKYFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
+
+void getCSKYTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                           const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs,
+                           std::vector<llvm::StringRef> &Features);
+
+llvm::Optional<llvm::StringRef> getCSKYArchName(const Driver &D,
+                                                const llvm::opt::ArgList &Args,
+                                                const llvm::Triple &Triple);
+
+} // end namespace csky
+} // namespace tools
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_CSKY_H
Index: clang/lib/Driver/ToolChains/Arch/CSKY.cpp
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/Arch/CSKY.cpp
@@ -0,0 +1,154 @@
+//===--- CSKY.cpp - CSKY Helpers for Tools --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CSKY.h"
+#include "ToolChains/CommonArgs.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/CSKYTargetParser.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/TargetParser.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+llvm::Optional<llvm::StringRef>
+csky::getCSKYArchName(const Driver &D, const ArgList &Args,
+                      const llvm::Triple &Triple) {
+  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+    llvm::CSKY::ArchKind ArchKind = llvm::CSKY::parseArch(A->getValue());
+
+    if (ArchKind == llvm::CSKY::ArchKind::INVALID) {
+      D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
+      return llvm::Optional<llvm::StringRef>();
+    }
+    return llvm::Optional<llvm::StringRef>(A->getValue());
+  }
+
+  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
+    llvm::CSKY::ArchKind ArchKind = llvm::CSKY::parseCPUArch(A->getValue());
+    if (ArchKind == llvm::CSKY::ArchKind::INVALID) {
+      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+      return llvm::Optional<llvm::StringRef>();
+    }
+    return llvm::Optional<llvm::StringRef>(llvm::CSKY::getArchName(ArchKind));
+  }
+
+  return llvm::Optional<llvm::StringRef>("");
+}
+
+csky::FloatABI csky::getCSKYFloatABI(const Driver &D, const ArgList &Args) {
+  csky::FloatABI ABI = FloatABI::Soft;
+  if (Arg *A =
+          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
+                          options::OPT_mfloat_abi_EQ)) {
+    if (A->getOption().matches(options::OPT_msoft_float)) {
+      ABI = FloatABI::Soft;
+    } else if (A->getOption().matches(options::OPT_mhard_float)) {
+      ABI = FloatABI::Hard;
+    } else {
+      ABI = llvm::StringSwitch<csky::FloatABI>(A->getValue())
+                .Case("soft", FloatABI::Soft)
+                .Case("softfp", FloatABI::SoftFP)
+                .Case("hard", FloatABI::Hard)
+                .Default(FloatABI::Invalid);
+      if (ABI == FloatABI::Invalid) {
+        D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
+        ABI = FloatABI::Soft;
+      }
+    }
+  }
+
+  return ABI;
+}
+
+// Handle -mfpu=.
+static llvm::CSKY::CSKYFPUKind
+getCSKYFPUFeatures(const Driver &D, const Arg *A, const ArgList &Args,
+                   StringRef FPU, std::vector<StringRef> &Features) {
+
+  llvm::CSKY::CSKYFPUKind FPUID =
+      llvm::StringSwitch<llvm::CSKY::CSKYFPUKind>(FPU)
+          .Case("auto", llvm::CSKY::FK_AUTO)
+          .Case("fpv2", llvm::CSKY::FK_FPV2)
+          .Case("fpv2_divd", llvm::CSKY::FK_FPV2_DIVD)
+          .Case("fpv2_sf", llvm::CSKY::FK_FPV2_SF)
+          .Case("fpv3", llvm::CSKY::FK_FPV3)
+          .Case("fpv3_hf", llvm::CSKY::FK_FPV3_HF)
+          .Case("fpv3_hsf", llvm::CSKY::FK_FPV3_HSF)
+          .Case("fpv3_sdf", llvm::CSKY::FK_FPV3_SDF)
+          .Default(llvm::CSKY::FK_INVALID);
+
+  if (!llvm::CSKY::getFPUFeatures(FPUID, Features)) {
+    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+    return llvm::CSKY::FK_INVALID;
+  }
+
+  return FPUID;
+}
+
+void csky::getCSKYTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                                 const ArgList &Args, ArgStringList &CmdArgs,
+                                 std::vector<llvm::StringRef> &Features) {
+  llvm::StringRef archName;
+  llvm::StringRef cpuName;
+  llvm::CSKY::ArchKind ArchKind = llvm::CSKY::ArchKind::INVALID;
+  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+    ArchKind = llvm::CSKY::parseArch(A->getValue());
+    if (ArchKind == llvm::CSKY::ArchKind::INVALID) {
+      D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
+      return;
+    }
+    archName = A->getValue();
+  }
+
+  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
+    llvm::CSKY::ArchKind Kind = llvm::CSKY::parseCPUArch(A->getValue());
+    if (Kind == llvm::CSKY::ArchKind::INVALID) {
+      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+      return;
+    }
+    if (!archName.empty() && Kind != ArchKind) {
+      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+      return;
+    }
+    cpuName = A->getValue();
+  }
+
+  if (archName.empty() && cpuName.empty()) {
+    archName = "ck810";
+    cpuName = "ck810";
+  } else if (!archName.empty() && cpuName.empty()) {
+    cpuName = archName;
+  }
+
+  csky::FloatABI FloatABI = csky::getCSKYFloatABI(D, Args);
+
+  if (FloatABI == csky::FloatABI::Hard) {
+    Features.push_back("+hard-float-abi");
+    Features.push_back("+hard-float");
+  } else if (FloatABI == csky::FloatABI::SoftFP) {
+    Features.push_back("+hard-float");
+  }
+
+  if (const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ))
+    getCSKYFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
+  else if (FloatABI != csky::FloatABI::Soft && archName.empty())
+    llvm::CSKY::getFPUFeatures(llvm::CSKY::FK_AUTO, Features);
+
+  uint64_t Extension = llvm::CSKY::getDefaultExtensions(cpuName);
+  llvm::CSKY::getExtensionFeatures(Extension, Features);
+}
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -13,6 +13,7 @@
 #include "ToolChains/AVR.h"
 #include "ToolChains/Ananas.h"
 #include "ToolChains/BareMetal.h"
+#include "ToolChains/CSKYToolChain.h"
 #include "ToolChains/Clang.h"
 #include "ToolChains/CloudABI.h"
 #include "ToolChains/Contiki.h"
@@ -5731,6 +5732,9 @@
       case llvm::Triple::spirv64:
         TC = std::make_unique<toolchains::SPIRVToolChain>(*this, Target, Args);
         break;
+      case llvm::Triple::csky:
+        TC = std::make_unique<toolchains::CSKYToolChain>(*this, Target, Args);
+        break;
       default:
         if (Target.getVendor() == llvm::Triple::Myriad)
           TC = std::make_unique<toolchains::MyriadToolChain>(*this, Target,
Index: clang/lib/Driver/CMakeLists.txt
===================================================================
--- clang/lib/Driver/CMakeLists.txt
+++ clang/lib/Driver/CMakeLists.txt
@@ -27,6 +27,7 @@
   ToolChain.cpp
   ToolChains/Arch/AArch64.cpp
   ToolChains/Arch/ARM.cpp
+  ToolChains/Arch/CSKY.cpp
   ToolChains/Arch/M68k.cpp
   ToolChains/Arch/Mips.cpp
   ToolChains/Arch/PPC.cpp
@@ -46,6 +47,7 @@
   ToolChains/CommonArgs.cpp
   ToolChains/Contiki.cpp
   ToolChains/CrossWindows.cpp
+  ToolChains/CSKYToolChain.cpp
   ToolChains/Cuda.cpp
   ToolChains/Darwin.cpp
   ToolChains/DragonFly.cpp
Index: clang/lib/Basic/Targets/CSKY.h
===================================================================
--- /dev/null
+++ clang/lib/Basic/Targets/CSKY.h
@@ -0,0 +1,101 @@
+//===--- CSKY.h - Declare CSKY target feature support -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares CSKY TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_CSKY_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_CSKY_H
+
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/Support/CSKYTargetParser.h"
+
+namespace clang {
+namespace targets {
+
+class LLVM_LIBRARY_VISIBILITY CSKYTargetInfo : public TargetInfo {
+protected:
+  std::string ABI;
+  llvm::CSKY::ArchKind Arch = llvm::CSKY::ArchKind::INVALID;
+  std::string CPU;
+
+  bool HardFloat;
+  bool VDSPV2;
+  bool VDSPV1;
+  bool DSPV2;
+  bool is3E3R1;
+
+public:
+  CSKYTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+      : TargetInfo(Triple) {
+    NoAsmVariants = true;
+    LongLongAlign = 32;
+    SuitableAlign = 32;
+    DoubleAlign = LongDoubleAlign = 32;
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+    IntPtrType = SignedInt;
+    WCharType = SignedInt;
+    WIntType = UnsignedInt;
+
+    UseZeroLengthBitfieldAlignment = true;
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
+    resetDataLayout("e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-"
+                    "v64:32:32-v128:32:32-a:0:32-Fi32-n32");
+
+    setABI("abiv2");
+  }
+
+  StringRef getABI() const override { return ABI; }
+  bool setABI(const std::string &Name) override {
+    if (Name == "abiv2" || Name == "abiv1") {
+      ABI = Name;
+      return true;
+    }
+    return false;
+  }
+
+  bool setCPU(const std::string &Name) override;
+
+  bool isValidCPUName(StringRef Name) const override;
+
+  virtual unsigned getMinGlobalAlign(uint64_t) const override;
+
+  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return VoidPtrBuiltinVaList;
+  }
+
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &info) const override;
+
+  const char *getClobbers() const override { return ""; }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override;
+  bool handleTargetFeatures(std::vector<std::string> &Features,
+                            DiagnosticsEngine &Diags) override;
+
+  /// Whether target allows to overalign ABI-specified preferred alignment
+  bool allowsLargerPreferedTypeAlignment() const override { return false; }
+
+  bool hasBitIntType() const override { return true; }
+
+protected:
+  ArrayRef<const char *> getGCCRegNames() const override;
+
+  ArrayRef<GCCRegAlias> getGCCRegAliases() const override;
+};
+
+} // namespace targets
+} // namespace clang
+
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_CSKY_H
Index: clang/lib/Basic/Targets/CSKY.cpp
===================================================================
--- /dev/null
+++ clang/lib/Basic/Targets/CSKY.cpp
@@ -0,0 +1,295 @@
+//===--- CSKY.cpp - Implement CSKY target feature support -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements CSKY TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CSKY.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+bool CSKYTargetInfo::isValidCPUName(StringRef Name) const {
+  return llvm::CSKY::parseCPUArch(Name) != llvm::CSKY::ArchKind::INVALID;
+}
+
+bool CSKYTargetInfo::setCPU(const std::string &Name) {
+  llvm::CSKY::ArchKind archKind = llvm::CSKY::parseCPUArch(Name);
+  bool isValid = (archKind != llvm::CSKY::ArchKind::INVALID);
+
+  if (isValid) {
+    CPU = Name;
+    Arch = archKind;
+  }
+
+  return isValid;
+}
+
+void CSKYTargetInfo::getTargetDefines(const LangOptions &Opts,
+                                      MacroBuilder &Builder) const {
+  Builder.defineMacro("__ELF__");
+  Builder.defineMacro("__csky__", "2");
+  Builder.defineMacro("__CSKY__", "2");
+  Builder.defineMacro("__ckcore__", "2");
+  Builder.defineMacro("__CKCORE__", "2");
+
+  Builder.defineMacro("__CSKYABI__", ABI == "abiv2" ? "2" : "1");
+  Builder.defineMacro("__cskyabi__", ABI == "abiv2" ? "2" : "1");
+
+  StringRef ArchName = "ck810";
+  StringRef CPUName = "ck810";
+
+  if (Arch != llvm::CSKY::ArchKind::INVALID) {
+    ArchName = llvm::CSKY::getArchName(Arch);
+    CPUName = CPU;
+  }
+
+  Builder.defineMacro("__" + ArchName.upper() + "__");
+  Builder.defineMacro("__" + ArchName.lower() + "__");
+  Builder.defineMacro("__" + CPUName.upper() + "__");
+  Builder.defineMacro("__" + CPUName.lower() + "__");
+
+  // TODO: Add support for BE if BE was supported later
+  StringRef endian = "__cskyLE__";
+
+  Builder.defineMacro(endian);
+  Builder.defineMacro(endian.upper());
+  Builder.defineMacro(endian.lower());
+
+  if (DSPV2) {
+    StringRef dspv2 = "__CSKY_DSPV2__";
+    Builder.defineMacro(dspv2);
+    Builder.defineMacro(dspv2.lower());
+  }
+
+  if (VDSPV2) {
+    StringRef vdspv2 = "__CSKY_VDSPV2__";
+    Builder.defineMacro(vdspv2);
+    Builder.defineMacro(vdspv2.lower());
+
+    if (HardFloat) {
+      StringRef vdspv2_f = "__CSKY_VDSPV2_F__";
+      Builder.defineMacro(vdspv2_f);
+      Builder.defineMacro(vdspv2_f.lower());
+    }
+  }
+  if (VDSPV1) {
+    StringRef vdspv1_64 = "__CSKY_VDSP64__";
+    StringRef vdspv1_128 = "__CSKY_VDSP128__";
+
+    Builder.defineMacro(vdspv1_64);
+    Builder.defineMacro(vdspv1_64.lower());
+    Builder.defineMacro(vdspv1_128);
+    Builder.defineMacro(vdspv1_128.lower());
+  }
+  if (is3E3R1) {
+    StringRef is3e3r1 = "__CSKY_3E3R1__";
+    Builder.defineMacro(is3e3r1);
+    Builder.defineMacro(is3e3r1.lower());
+  }
+}
+
+bool CSKYTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
+                                          DiagnosticsEngine &Diags) {
+  HardFloat = false;
+  VDSPV2 = false;
+  VDSPV1 = false;
+  DSPV2 = false;
+  is3E3R1 = false;
+
+  for (const auto &Feature : Features) {
+    if (Feature == "+hard-float")
+      HardFloat = true;
+    if (Feature == "+vdspv2")
+      VDSPV2 = true;
+    if (Feature == "+dspv2")
+      DSPV2 = true;
+    if (Feature == "+vdspv1")
+      VDSPV1 = true;
+    if (Feature == "+3e3r1")
+      is3E3R1 = true;
+  }
+
+  return true;
+}
+
+ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const {
+  return ArrayRef<Builtin::Info>();
+}
+
+ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const {
+  static const char *const GCCRegNames[] = {
+      // Integer registers
+      "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",
+      "r26",
+      "r27",
+      "r28",
+      "r29",
+      "r30",
+      "r31",
+
+      // Floating point registers
+      "fr0",
+      "fr1",
+      "fr2",
+      "fr3",
+      "fr4",
+      "fr5",
+      "fr6",
+      "fr7",
+      "fr8",
+      "fr9",
+      "fr10",
+      "fr11",
+      "fr12",
+      "fr13",
+      "fr14",
+      "fr15",
+      "fr16",
+      "fr17",
+      "fr18",
+      "fr19",
+      "fr20",
+      "fr21",
+      "fr22",
+      "fr23",
+      "fr24",
+      "fr25",
+      "fr26",
+      "fr27",
+      "fr28",
+      "fr29",
+      "fr30",
+      "fr31",
+
+  };
+  return llvm::makeArrayRef(GCCRegNames);
+}
+
+ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const {
+  static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+      {{"a0"}, "r0"},
+      {{"a1"}, "r1"},
+      {{"a2"}, "r2"},
+      {{"a3"}, "r3"},
+      {{"l0"}, "r4"},
+      {{"l1"}, "r5"},
+      {{"l2"}, "r6"},
+      {{"l3"}, "r7"},
+      {{"l4"}, "r8"},
+      {{"l5"}, "r9"},
+      {{"l6"}, "r10"},
+      {{"l7"}, "r11"},
+      {{"t0"}, "r12"},
+      {{"t1"}, "r13"},
+      {{"sp"}, "r14"},
+      {{"lr"}, "r15"},
+      {{"l8"}, "r16"},
+      {{"l9"}, "r17"},
+      {{"t2"}, "r18"},
+      {{"t3"}, "r19"},
+      {{"t4"}, "r20"},
+      {{"t5"}, "r21"},
+      {{"t6"}, "r22"},
+      {{"t7", "fp"}, "r23"},
+      {{"t8", "top"}, "r24"},
+      {{"t9", "bsp"}, "r25"},
+      {{"r26"}, "r26"},
+      {{"r27"}, "r27"},
+      {{"gb", "rgb", "rdb"}, "r28"},
+      {{"tb", "rtb"}, "r29"},
+      {{"svbr"}, "r30"},
+      {{"tls"}, "r31"},
+
+      {{"vr0"}, "fr0"},
+      {{"vr1"}, "fr1"},
+      {{"vr2"}, "fr2"},
+      {{"vr3"}, "fr3"},
+      {{"vr4"}, "fr4"},
+      {{"vr5"}, "fr5"},
+      {{"vr6"}, "fr6"},
+      {{"vr7"}, "fr7"},
+      {{"vr8"}, "fr8"},
+      {{"vr9"}, "fr9"},
+      {{"vr10"}, "fr10"},
+      {{"vr11"}, "fr11"},
+      {{"vr12"}, "fr12"},
+      {{"vr13"}, "fr13"},
+      {{"vr14"}, "fr14"},
+      {{"vr15"}, "fr15"},
+      {{"vr16"}, "fr16"},
+      {{"vr17"}, "fr17"},
+      {{"vr18"}, "fr18"},
+      {{"vr19"}, "fr19"},
+      {{"vr20"}, "fr20"},
+      {{"vr21"}, "fr21"},
+      {{"vr22"}, "fr22"},
+      {{"vr23"}, "fr23"},
+      {{"vr24"}, "fr24"},
+      {{"vr25"}, "fr25"},
+      {{"vr26"}, "fr26"},
+      {{"vr27"}, "fr27"},
+      {{"vr28"}, "fr28"},
+      {{"vr29"}, "fr29"},
+      {{"vr30"}, "fr30"},
+      {{"vr31"}, "fr31"},
+
+  };
+  return llvm::makeArrayRef(GCCRegAliases);
+}
+
+bool CSKYTargetInfo::validateAsmConstraint(
+    const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+  switch (*Name) {
+  default:
+    return false;
+  case 'a':
+  case 'b':
+  case 'c':
+  case 'y':
+  case 'l':
+  case 'h':
+  case 'w':
+  case 'v': // A floating-point and vector register.
+  case 'z':
+    Info.setAllowsRegister();
+    return true;
+  }
+}
+
+unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const {
+  if (Size >= 32)
+    return 32;
+  return 0;
+}
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -19,6 +19,7 @@
 #include "Targets/ARM.h"
 #include "Targets/AVR.h"
 #include "Targets/BPF.h"
+#include "Targets/CSKY.h"
 #include "Targets/Hexagon.h"
 #include "Targets/Lanai.h"
 #include "Targets/Le64.h"
@@ -656,6 +657,14 @@
 
   case llvm::Triple::ve:
     return new LinuxTargetInfo<VETargetInfo>(Triple, Opts);
+
+  case llvm::Triple::csky:
+    switch (os) {
+    case llvm::Triple::Linux:
+      return new LinuxTargetInfo<CSKYTargetInfo>(Triple, Opts);
+    default:
+      return new CSKYTargetInfo(Triple, Opts);
+    }
   }
 }
 } // namespace targets
Index: clang/lib/Basic/CMakeLists.txt
===================================================================
--- clang/lib/Basic/CMakeLists.txt
+++ clang/lib/Basic/CMakeLists.txt
@@ -75,6 +75,7 @@
   Targets/ARM.cpp
   Targets/AVR.cpp
   Targets/BPF.cpp
+  Targets/CSKY.cpp
   Targets/Hexagon.cpp
   Targets/Lanai.cpp
   Targets/Le64.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to