diff options
Diffstat (limited to 'gcc/d/d-target.cc')
-rw-r--r-- | gcc/d/d-target.cc | 112 |
1 files changed, 68 insertions, 44 deletions
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index 1488bcebb2c..21417dddf78 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tm_p.h" #include "target.h" +#include "calls.h" #include "d-tree.h" #include "d-target.h" @@ -42,8 +43,6 @@ along with GCC; see the file COPYING3. If not see /* Implements the Target interface defined by the front end. Used for retrieving target-specific information. */ -Target target; - /* Internal key handlers for `__traits(getTargetInfo)'. */ static tree d_handle_target_cpp_std (void); static tree d_handle_target_cpp_runtime_library (void); @@ -89,9 +88,6 @@ define_float_constants (T &f, tree type) /* Floating-point NaN. */ real_nan (&f.nan.rv (), "", 1, mode); - /* Signalling floating-point NaN. */ - real_nan (&f.snan.rv (), "", 0, mode); - /* Floating-point +Infinity if the target supports infinities. */ real_inf (&f.infinity.rv ()); @@ -142,19 +138,19 @@ Target::_init (const Param &) /* Define what type to use for size_t, ptrdiff_t. */ if (this->ptrsize == 8) { - global.params.isLP64 = true; - Type::tsize_t = Type::basic[Tuns64]; - Type::tptrdiff_t = Type::basic[Tint64]; + this->isLP64 = true; + Type::tsize_t = Type::basic[(int)TY::Tuns64]; + Type::tptrdiff_t = Type::basic[(int)TY::Tint64]; } else if (this->ptrsize == 4) { - Type::tsize_t = Type::basic[Tuns32]; - Type::tptrdiff_t = Type::basic[Tint32]; + Type::tsize_t = Type::basic[(int)TY::Tuns32]; + Type::tptrdiff_t = Type::basic[(int)TY::Tint32]; } else if (this->ptrsize == 2) { - Type::tsize_t = Type::basic[Tuns16]; - Type::tptrdiff_t = Type::basic[Tint16]; + Type::tsize_t = Type::basic[(int)TY::Tuns16]; + Type::tptrdiff_t = Type::basic[(int)TY::Tint16]; } else sorry ("D does not support pointers on this target."); @@ -164,15 +160,7 @@ Target::_init (const Param &) /* Set-up target C ABI. */ this->c.longsize = int_size_in_bytes (long_integer_type_node); this->c.long_doublesize = int_size_in_bytes (long_double_type_node); - - /* Define what type to use for wchar_t. We don't want to support wide - characters less than "short" in D. */ - if (WCHAR_TYPE_SIZE == 32) - this->c.twchar_t = Type::basic[Tdchar]; - else if (WCHAR_TYPE_SIZE == 16) - this->c.twchar_t = Type::basic[Twchar]; - else - sorry ("D does not support wide characters on this target."); + this->c.wchar_tsize = (WCHAR_TYPE_SIZE / BITS_PER_UNIT); /* Set-up target C++ ABI. */ this->cpp.reverseOverloads = false; @@ -182,6 +170,12 @@ Target::_init (const Param &) /* Set-up target Objective-C ABI. */ this->objc.supported = false; + /* Set-up environmental settings. */ + this->obj_ext = "o"; + this->lib_ext = "a"; + this->dll_ext = "so"; + this->run_noext = true; + /* Initialize all compile-time properties for floating-point types. Should ensure that our real_t type is able to represent real_value. */ gcc_assert (sizeof (real_t) >= sizeof (real_value)); @@ -273,7 +267,7 @@ Target::isVectorTypeSupported (int sz, Type *type) type = Type::tuns8; /* No support for non-trivial types, complex types, or booleans. */ - if (!type->isTypeBasic () || type->iscomplex () || type->ty == Tbool) + if (!type->isTypeBasic () || type->iscomplex () || type->ty == TY::Tbool) return 2; /* In [simd/vector extensions], which vector types are supported depends on @@ -293,9 +287,9 @@ Target::isVectorTypeSupported (int sz, Type *type) Returns true if the operation is supported or type is not a vector. */ bool -Target::isVectorOpSupported (Type *type, TOK op, Type *) +Target::isVectorOpSupported (Type *type, unsigned op, Type *) { - if (type->ty != Tvector) + if (type->ty != TY::Tvector) return true; /* Don't support if type is non-scalar, such as __vector(void[]). */ @@ -322,18 +316,10 @@ Target::isVectorOpSupported (Type *type, TOK op, Type *) /* Logical operators must have a result type of bool. */ return false; - case TOKue: - case TOKlg: - case TOKule: - case TOKul: - case TOKuge: - case TOKug: case TOKle: case TOKlt: case TOKge: case TOKgt: - case TOKleg: - case TOKunord: case TOKequal: case TOKnotequal: case TOKidentity: @@ -379,7 +365,8 @@ TargetCPP::thunkMangle (FuncDeclaration *fd, int offset) const char * TargetCPP::typeMangle (Type *type) { - if (type->isTypeBasic () || type->ty == Tvector || type->ty == Tstruct) + if (type->isTypeBasic () || type->ty == TY::Tvector + || type->ty == TY::Tstruct) { tree ctype = build_ctype (type); return targetm.mangle_type (ctype); @@ -400,14 +387,14 @@ TargetCPP::parameterType (Parameter *arg) else if (arg->storageClass & STClazy) { /* Mangle as delegate. */ - Type *td = TypeFunction::create (NULL, t, VARARGnone, LINKd); - td = TypeDelegate::create (td); - t = t->merge2 (); + TypeFunction *tf = TypeFunction::create (NULL, t, VARARGnone, LINK::d); + TypeDelegate *td = TypeDelegate::create (tf); + t = td->merge2 (); } /* Could be a va_list, which we mangle as a pointer. */ Type *tvalist = target.va_listType (Loc (), NULL); - if (t->ty == Tsarray && tvalist->ty == Tsarray) + if (t->ty == TY::Tsarray && tvalist->ty == TY::Tsarray) { Type *tb = t->toBasetype ()->mutableOf (); if (tb == tvalist) @@ -450,10 +437,10 @@ Target::systemLinkage (void) /* In [attribute/linkage], `System' is the same as `Windows' on Windows platforms, and `C' on other platforms. */ if (link_system) - return LINKwindows; + return LINK::windows; } - return LINKc; + return LINK::c; } /* Generate a TypeTuple of the equivalent types used to determine if a @@ -477,12 +464,12 @@ Target::isReturnOnStack (TypeFunction *tf, bool) /* Need the back-end type to determine this, but this is called from the frontend before semantic processing is finished. An accurate value is not currently needed anyway. */ - if (tf->isref) + if (tf->isref ()) return false; Type *tn = tf->next->toBasetype (); - return (tn->ty == Tstruct || tn->ty == Tsarray); + return (tn->ty == TY::Tstruct || tn->ty == TY::Tsarray); } /* Add all target info in HANDLERS to D_TARGET_INFO_TABLE for use by @@ -575,12 +562,49 @@ Target::getTargetInfo (const char *key, const Loc &loc) return NULL; } -/** - * Returns true if the implementation for object monitors is always defined - * in the D runtime library (rt/monitor_.d). */ +/* Returns true if the callee invokes destructors for arguments. */ + +bool +Target::isCalleeDestroyingArgs (TypeFunction *tf) +{ + return tf->linkage == LINK::d; +} + +/* Returns true if the implementation for object monitors is always defined + in the D runtime library (rt/monitor_.d). */ bool Target::libraryObjectMonitors (FuncDeclaration *, Statement *) { return true; } + +/* Decides whether an `in' parameter of the specified POD type PARAM_TYPE is to + be passed by reference or by valie. This is used only when compiling with + `-fpreview=in' enabled. */ + +bool +Target::preferPassByRef (Type *param_type) +{ + if (param_type->size () == SIZE_INVALID) + return false; + + tree type = build_ctype (param_type); + + /* Prefer a `ref' if the type is an aggregate, and its size is greater than + its alignment. */ + if (AGGREGATE_TYPE_P (type) + && (!valid_constant_size_p (TYPE_SIZE_UNIT (type)) + || compare_tree_int (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type)) > 0)) + return true; + + /* If the back-end is always going to pass this by invisible reference. */ + if (pass_by_reference (NULL, function_arg_info (type, true))) + return true; + + /* If returning the parameter means the caller will do RVO. */ + if (targetm.calls.return_in_memory (type, NULL_TREE)) + return true; + + return false; +} |