Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for building libcxx/libcxxabi on MOS. #310

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 31 additions & 0 deletions clang/cmake/caches/MOSLibCXX.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# MOSLibCXX.cmake
# Configure llvm-mos for building libcxx based on llvm-mos-sdk.
# Usage for configuring:
# cmake -C [path-to-this-file] ...

set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "CMake build type")

# We need any hosted llvm-mos-sdk compiler capable of building binaries.
set(CMAKE_C_COMPILER mos-sim-clang CACHE STRING "")
set(CMAKE_CXX_COMPILER mos-sim-clang++ CACHE STRING "")

set(LLVM_ENABLE_RUNTIMES libcxx;libcxxabi CACHE STRING "")
set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
set(LIBCXXABI_ENABLE_PIC OFF CACHE BOOL "")
set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
set(LIBCXXABI_ENABLE_THREADS OFF CACHE BOOL "")
set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
set(LIBCXX_ENABLE_FSTREAM OFF CACHE BOOL "")
set(LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")
set(LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
set(LIBCXX_ENABLE_RTTI ON CACHE BOOL "")
set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
set(LIBCXX_ENABLE_UNICODE OFF CACHE BOOL "")
set(LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "")
set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
set(LIBCXX_TARGETING_MOS ON CACHE BOOL "")
7 changes: 7 additions & 0 deletions clang/lib/Basic/Targets/MOS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "MOS.h"
#include "clang/Basic/MacroBuilder.h"

using namespace clang::targets;

Expand Down Expand Up @@ -166,3 +167,9 @@ bool MOSTargetInfo::isValidCPUName(StringRef Name) const {
void MOSTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
}

void MOSTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__mos__");
Builder.defineMacro("__ELF__");
}
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/MOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class MOSTargetInfo : public TargetInfo {
MOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &);

void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {}
MacroBuilder &Builder) const override;

ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }

Expand Down
2 changes: 2 additions & 0 deletions libcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ else()
set(LIBCXX_TARGETING_MSVC OFF)
endif()

set(LIBCXX_TARGETING_MOS OFF CACHE BOOL "")

#===============================================================================
# Setup CMake Options
#===============================================================================
Expand Down
6 changes: 3 additions & 3 deletions libcxx/include/__bit/endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD

enum class endian {
little = 0xDEAD,
big = 0xFACE,
little = (int) 0xDEAD,
big = (int) 0xFACE,
# if defined(_LIBCPP_LITTLE_ENDIAN)
native = little
# elif defined(_LIBCPP_BIG_ENDIAN)
native = big
# else
native = 0xCAFE
native = (int) 0xCAFE
# endif
};

Expand Down
7 changes: 7 additions & 0 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,13 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# define _LIBCPP_HAS_NO_FGETPOS_FSETPOS
# endif

# if defined(__mos__)
# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
// error: target of using declaration conflicts with declaration already in scope
# define _LIBCPP_HAS_NO_REMOVE
# endif

# if __has_attribute(__init_priority__)
# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((__init_priority__(100)))
# else
Expand Down
4 changes: 4 additions & 0 deletions libcxx/include/__format/parser_std_format_spec.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,10 @@ struct __parsed_specifications {

// Validate the struct is small and cheap to copy since the struct is passed by
// value in formatting functions.
# if !defined(__mos__)
static_assert(sizeof(__parsed_specifications<char>) == 16);
static_assert(is_trivially_copyable_v<__parsed_specifications<char>>);
# endif
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
static_assert(sizeof(__parsed_specifications<wchar_t>) == 16);
static_assert(is_trivially_copyable_v<__parsed_specifications<wchar_t>>);
Expand Down Expand Up @@ -624,7 +626,9 @@ class _LIBCPP_TEMPLATE_VIS __parser {
};

// Validates whether the reserved bitfields don't change the size.
# if !defined(__mos__)
static_assert(sizeof(__parser<char>) == 16);
# endif
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
static_assert(sizeof(__parser<wchar_t>) == 16);
# endif
Expand Down
14 changes: 14 additions & 0 deletions libcxx/include/__functional/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ __loadword(const void* __p)
template <class _Size, size_t = sizeof(_Size)*__CHAR_BIT__>
struct __murmur2_or_cityhash;

template <class _Size>
struct __murmur2_or_cityhash<_Size, 16>
{
_LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
_Size operator()(const void* __key, _Size __len) const {
// TODO: This is a stub implementation. Implement something better.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call these TODO(llvm-mos); otherwise it will be more difficult to find them again. Consider filing issues for these too; that will make them easier to track.

_Size hash = __len;
const unsigned char* __data = static_cast<const unsigned char*>(__key);
for (; __len; __data++, __len--)
hash = (hash << 1) + *__data;
return hash;
}
};

template <class _Size>
struct __murmur2_or_cityhash<_Size, 32>
{
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/__mbstate_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
# include_next <wchar.h> // fall back to the C standard provider of mbstate_t
#elif __has_include_next(<uchar.h>)
# include_next <uchar.h> // <uchar.h> is also required to make mbstate_t visible
#elif defined(__mos__) && __has_include_next(<wchar.h>)
# include_next <wchar.h> // on MOS, we do provide a stub <wchar.h>
#else
# error "We don't know how to get the definition of mbstate_t without <wchar.h> on your platform."
#endif
Expand Down
12 changes: 12 additions & 0 deletions libcxx/include/__memory_resource/unsynchronized_pool_resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ class _LIBCPP_TYPE_VIS unsynchronized_pool_resource : public memory_resource {
void __do_deallocate(memory_resource* __upstream, void* __p, size_t __bytes, size_t __align);
};

#if defined(__mos__)
static const size_t __min_blocks_per_chunk = 16;
static const size_t __min_bytes_per_chunk = 256;
static const size_t __max_blocks_per_chunk = (size_t(1) << 10);
static const size_t __max_bytes_per_chunk = (size_t(1) << 15);

static const int __log2_smallest_block_size = 3;
static const size_t __smallest_block_size = 8;
static const size_t __default_largest_block_size = (size_t(1) << 10);
static const size_t __max_largest_block_size = (size_t(1) << 15);
#else
static const size_t __min_blocks_per_chunk = 16;
static const size_t __min_bytes_per_chunk = 1024;
static const size_t __max_blocks_per_chunk = (size_t(1) << 20);
Expand All @@ -51,6 +62,7 @@ class _LIBCPP_TYPE_VIS unsynchronized_pool_resource : public memory_resource {
static const size_t __smallest_block_size = 8;
static const size_t __default_largest_block_size = (size_t(1) << 20);
static const size_t __max_largest_block_size = (size_t(1) << 30);
#endif

size_t __pool_block_size(int __i) const;
int __log2_pool_block_size(int __i) const;
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__random/seed_seq.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ seed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last)
: (__n - 1) / 2;
const size_t __p = (__n - __t) / 2;
const size_t __q = __p + __t;
const size_t __m = _VSTD::max(__s + 1, __n);
const size_t __m = _VSTD::max(static_cast<size_t>(__s + 1), __n);
// __k = 0;
{
result_type __r = 1664525 * _Tp(__first[0] ^ __first[__p]
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/cstdio
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ using ::perror _LIBCPP_USING_IF_EXISTS;

using ::fopen _LIBCPP_USING_IF_EXISTS;
using ::freopen _LIBCPP_USING_IF_EXISTS;
#ifndef _LIBCPP_HAS_NO_REMOVE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something specific that makes remove different than all the other functions here? It seems odd to introduce a _LIBCPP_HAS_NO_REMOVE if not... maybe just #ifndef mos otherwise?

using ::remove _LIBCPP_USING_IF_EXISTS;
#endif
using ::rename _LIBCPP_USING_IF_EXISTS;
using ::tmpfile _LIBCPP_USING_IF_EXISTS;
using ::tmpnam _LIBCPP_USING_IF_EXISTS;
Expand Down
28 changes: 14 additions & 14 deletions libcxx/include/string
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ public:
size_type __str_sz = __str.size();
if (__pos > __str_sz)
__throw_out_of_range();
__init(__str.data() + __pos, std::min(__n, __str_sz - __pos));
__init(__str.data() + __pos, std::min(__n, static_cast<size_t>(__str_sz - __pos)));
mysterymath marked this conversation as resolved.
Show resolved Hide resolved
std::__debug_db_insert_c(this);
}

Expand Down Expand Up @@ -2492,7 +2492,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz
size_type __sz = __str.size();
if (__pos > __sz)
__throw_out_of_range();
return assign(__str.data() + __pos, std::min(__n, __sz - __pos));
return assign(__str.data() + __pos, std::min(__n, static_cast<size_t>(__sz - __pos)));
}

template <class _CharT, class _Traits, class _Allocator>
Expand All @@ -2506,7 +2506,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __po
size_type __sz = __sv.size();
if (__pos > __sz)
__throw_out_of_range();
return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
return assign(__sv.data() + __pos, std::min(__n, static_cast<size_t>(__sz - __pos)));
}

template <class _CharT, class _Traits, class _Allocator>
Expand Down Expand Up @@ -2668,7 +2668,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz
size_type __sz = __str.size();
if (__pos > __sz)
__throw_out_of_range();
return append(__str.data() + __pos, std::min(__n, __sz - __pos));
return append(__str.data() + __pos, std::min(__n, static_cast<size_t>(__sz - __pos)));
}

template <class _CharT, class _Traits, class _Allocator>
Expand All @@ -2682,7 +2682,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __po
size_type __sz = __sv.size();
if (__pos > __sz)
__throw_out_of_range();
return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
return append(__sv.data() + __pos, std::min(__n, static_cast<size_t>(__sz - __pos)));
}

template <class _CharT, class _Traits, class _Allocator>
Expand Down Expand Up @@ -2813,7 +2813,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_
size_type __str_sz = __str.size();
if (__pos2 > __str_sz)
__throw_out_of_range();
return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2));
return insert(__pos1, __str.data() + __pos2, std::min(__n, static_cast<size_t>(__str_sz - __pos2)));
}

template <class _CharT, class _Traits, class _Allocator>
Expand All @@ -2827,7 +2827,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& _
size_type __str_sz = __sv.size();
if (__pos2 > __str_sz)
__throw_out_of_range();
return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));
return insert(__pos1, __sv.data() + __pos2, std::min(__n, static_cast<size_t>(__str_sz - __pos2)));
}

template <class _CharT, class _Traits, class _Allocator>
Expand Down Expand Up @@ -2882,7 +2882,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
size_type __sz = size();
if (__pos > __sz)
__throw_out_of_range();
__n1 = std::min(__n1, __sz - __pos);
__n1 = std::min(__n1, static_cast<size_t>(__sz - __pos));
size_type __cap = capacity();
if (__cap - __sz + __n1 >= __n2)
{
Expand Down Expand Up @@ -2934,7 +2934,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
size_type __sz = size();
if (__pos > __sz)
__throw_out_of_range();
__n1 = std::min(__n1, __sz - __pos);
__n1 = std::min(__n1, static_cast<size_t>(__sz - __pos));
size_type __cap = capacity();
value_type* __p;
if (__cap - __sz + __n1 >= __n2)
Expand Down Expand Up @@ -2975,7 +2975,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _
size_type __str_sz = __str.size();
if (__pos2 > __str_sz)
__throw_out_of_range();
return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2));
return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, static_cast<size_t>(__str_sz - __pos2)));
}

template <class _CharT, class _Traits, class _Allocator>
Expand All @@ -2990,7 +2990,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(
size_type __str_sz = __sv.size();
if (__pos2 > __str_sz)
__throw_out_of_range();
return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));
return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, static_cast<size_t>(__str_sz - __pos2)));
}

template <class _CharT, class _Traits, class _Allocator>
Expand All @@ -3016,7 +3016,7 @@ basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
{
size_type __sz = size();
value_type* __p = std::__to_address(__get_pointer());
__n = std::min(__n, __sz - __pos);
__n = std::min(__n, static_cast<size_t>(__sz - __pos));
size_type __n_move = __sz - __pos - __n;
if (__n_move != 0)
traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
Expand Down Expand Up @@ -3245,7 +3245,7 @@ basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n,
size_type __sz = size();
if (__pos > __sz)
__throw_out_of_range();
size_type __rlen = std::min(__n, __sz - __pos);
size_type __rlen = std::min(__n, static_cast<size_t>(__sz - __pos));
traits_type::copy(__s, data() + __pos, __rlen);
return __rlen;
}
Expand Down Expand Up @@ -3659,7 +3659,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
size_type __sz = size();
if (__pos1 > __sz || __n2 == npos)
__throw_out_of_range();
size_type __rlen = std::min(__n1, __sz - __pos1);
size_type __rlen = std::min(__n1, static_cast<size_t>(__sz - __pos1));
int __r = traits_type::compare(data() + __pos1, __s, std::min(__rlen, __n2));
if (__r == 0)
{
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/string_view
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ public:
{
if (__pos > size())
__throw_out_of_range("string_view::copy");
size_type __rlen = _VSTD::min(__n, size() - __pos);
size_type __rlen = _VSTD::min(__n, static_cast<size_t>(size() - __pos));
_Traits::copy(__s, data() + __pos, __rlen);
return __rlen;
}
Expand All @@ -467,7 +467,7 @@ public:
{
return __pos > size()
? (__throw_out_of_range("string_view::substr"), basic_string_view())
: basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
: basic_string_view(data() + __pos, _VSTD::min(__n, static_cast<size_t>(size() - __pos)));
}

_LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT
Expand Down
5 changes: 5 additions & 0 deletions libcxx/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ set(LIBCXX_SOURCES
verbose_abort.cpp
)

if (LIBCXX_TARGETING_MOS)
# ryu tables are over 64 KB
list(FILTER LIBCXX_SOURCES EXCLUDE REGEX "^(include/)?ryu/")
endif()

if (LIBCXX_ENABLE_DEBUG_MODE OR LIBCXX_ENABLE_BACKWARDS_COMPATIBILITY_DEBUG_MODE_SYMBOLS)
list(APPEND LIBCXX_SOURCES
debug.cpp
Expand Down
5 changes: 5 additions & 0 deletions libcxx/src/chrono.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
//
//===----------------------------------------------------------------------===//

// FIXME: This file does not compile correctly under LLVM-MOS.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO(llvm-mos):

#if !defined(__mos__)

#if defined(__MVS__)
// As part of monotonic clock support on z/OS we need macro _LARGE_TIME_API
// to be defined before any system header to include definition of struct timespec64.
Expand Down Expand Up @@ -252,3 +255,5 @@ steady_clock::now() noexcept
}

_LIBCPP_END_NAMESPACE_STD

#endif
9 changes: 9 additions & 0 deletions libcxx/src/hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ const unsigned indices[] =
// are fewer potential primes to search, and fewer potential primes to divide
// against.

template <size_t _Sz = sizeof(size_t)>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if<_Sz == 2, void>::type
__check_for_overflow(size_t N)
{
if (N > 0xFFF1)
__throw_overflow_error("__next_prime overflow");
}

template <size_t _Sz = sizeof(size_t)>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if<_Sz == 4, void>::type
Expand Down