1  
       2  /* Compiler implementation of the D programming language
       3   * Copyright (C) 2013-2023 by The D Language Foundation, All Rights Reserved
       4   * written by Iain Buclaw
       5   * https://www.digitalmars.com
       6   * Distributed under the Boost Software License, Version 1.0.
       7   * https://www.boost.org/LICENSE_1_0.txt
       8   * https://github.com/dlang/dmd/blob/master/src/dmd/target.h
       9   */
      10  
      11  #pragma once
      12  
      13  // This file contains a data structure that describes a back-end target.
      14  // At present it is incomplete, but in future it should grow to contain
      15  // most or all target machine and target O/S specific information.
      16  #include "globals.h"
      17  #include "tokens.h"
      18  
      19  class ClassDeclaration;
      20  class Dsymbol;
      21  class Expression;
      22  class FuncDeclaration;
      23  class Statement;
      24  class Type;
      25  class TypeTuple;
      26  class TypeFunction;
      27  
      28  enum class CPU : unsigned char
      29  {
      30      x87,
      31      mmx,
      32      sse,
      33      sse2,
      34      sse3,
      35      ssse3,
      36      sse4_1,
      37      sse4_2,
      38      avx,                // AVX1 instruction set
      39      avx2,               // AVX2 instruction set
      40      avx512,             // AVX-512 instruction set
      41  
      42      // Special values that don't survive past the command line processing
      43      baseline,           // (default) the minimum capability CPU
      44      native              // the machine the compiler is being run on
      45  };
      46  
      47  struct TargetC
      48  {
      49      enum class Runtime : unsigned char
      50      {
      51          Unspecified,
      52          Bionic,
      53          DigitalMars,
      54          Glibc,
      55          Microsoft,
      56          Musl,
      57          Newlib,
      58          UClibc,
      59          WASI,
      60      };
      61  
      62      enum class BitFieldStyle : unsigned char
      63      {
      64          Unspecified,
      65          DM,                   // Digital Mars 32 bit C compiler
      66          MS,                   // Microsoft 32 and 64 bit C compilers
      67                                // https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160
      68                                // https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160
      69          Gcc_Clang,            // gcc and clang
      70      };
      71  
      72      uint8_t crtDestructorsSupported; // Not all platforms support crt_destructor
      73      uint8_t boolsize;            // size of a C '_Bool' type
      74      uint8_t shortsize;           // size of a C 'short' or 'unsigned short' type
      75      uint8_t intsize;             // size of a C 'int' or 'unsigned int' type
      76      uint8_t longsize;            // size of a C 'long' or 'unsigned long' type
      77      uint8_t long_longsize;       // size of a C 'long long' or 'unsigned long long' type
      78      uint8_t long_doublesize;     // size of a C 'long double'
      79      uint8_t wchar_tsize;         // size of a C 'wchar_t' type
      80      Runtime runtime;
      81      BitFieldStyle bitFieldStyle; // different C compilers do it differently
      82  };
      83  
      84  struct TargetCPP
      85  {
      86      enum class Runtime : unsigned char
      87      {
      88          Unspecified,
      89          Clang,
      90          DigitalMars,
      91          Gcc,
      92          Microsoft,
      93          Sun
      94      };
      95      d_bool reverseOverloads;    // with dmc and cl, overloaded functions are grouped and in reverse order
      96      d_bool exceptions;          // set if catching C++ exceptions is supported
      97      d_bool twoDtorInVtable;     // target C++ ABI puts deleting and non-deleting destructor into vtable
      98      d_bool splitVBasetable;     // set if C++ ABI uses separate tables for virtual functions and virtual bases
      99      d_bool wrapDtorInExternD;   // set if C++ dtors require a D wrapper to be callable from runtime
     100      Runtime runtime;
     101  
     102      const char *toMangle(Dsymbol *s);
     103      const char *typeInfoMangle(ClassDeclaration *cd);
     104      const char *thunkMangle(FuncDeclaration *fd, int offset);
     105      const char *typeMangle(Type *t);
     106      Type *parameterType(Type *p);
     107      bool fundamentalType(const Type *t, bool& isFundamental);
     108      unsigned derivedClassOffset(ClassDeclaration *baseClass);
     109  };
     110  
     111  struct TargetObjC
     112  {
     113      d_bool supported;     // set if compiler can interface with Objective-C
     114  };
     115  
     116  struct Target
     117  {
     118      typedef unsigned char OS;
     119      enum
     120      {
     121          /* These are mutually exclusive; one and only one is set.
     122           * Match spelling and casing of corresponding version identifiers
     123           */
     124          OS_Freestanding = 0,
     125          OS_linux        = 1,
     126          OS_Windows      = 2,
     127          OS_OSX          = 4,
     128          OS_OpenBSD      = 8,
     129          OS_FreeBSD      = 0x10,
     130          OS_Solaris      = 0x20,
     131          OS_DragonFlyBSD = 0x40,
     132  
     133          // Combination masks
     134          all = OS_linux | OS_Windows | OS_OSX | OS_OpenBSD | OS_FreeBSD | OS_Solaris | OS_DragonFlyBSD,
     135          Posix = OS_linux | OS_OSX | OS_OpenBSD | OS_FreeBSD | OS_Solaris | OS_DragonFlyBSD,
     136      };
     137  
     138      OS os;
     139      uint8_t osMajor;
     140      // D ABI
     141      uint8_t ptrsize;
     142      uint8_t realsize;           // size a real consumes in memory
     143      uint8_t realpad;            // 'padding' added to the CPU real size to bring it up to realsize
     144      uint8_t realalignsize;      // alignment for reals
     145      uint8_t classinfosize;      // size of 'ClassInfo'
     146      uint64_t maxStaticDataSize; // maximum size of static data
     147  
     148      // C ABI
     149      TargetC c;
     150  
     151      // C++ ABI
     152      TargetCPP cpp;
     153  
     154      // Objective-C ABI
     155      TargetObjC objc;
     156  
     157      DString architectureName;    // name of the platform architecture (e.g. X86_64)
     158      CPU cpu;                // CPU instruction set to target
     159      d_bool is64bit;           // generate 64 bit code for x86_64; true by default for 64 bit dmd
     160      d_bool isLP64;            // pointers are 64 bits
     161  
     162      // Environmental
     163      DString obj_ext;    /// extension for object files
     164      DString lib_ext;    /// extension for static library files
     165      DString dll_ext;    /// extension for dynamic library files
     166      d_bool run_noext;     /// allow -run sources without extensions
     167      d_bool omfobj;        /// for Win32: write OMF object files instead of COFF
     168  
     169      template <typename T>
     170      struct FPTypeProperties
     171      {
     172          real_t max;
     173          real_t min_normal;
     174          real_t nan;
     175          real_t infinity;
     176          real_t epsilon;
     177  
     178          int64_t dig;
     179          int64_t mant_dig;
     180          int64_t max_exp;
     181          int64_t min_exp;
     182          int64_t max_10_exp;
     183          int64_t min_10_exp;
     184      };
     185  
     186      FPTypeProperties<float> FloatProperties;
     187      FPTypeProperties<double> DoubleProperties;
     188      FPTypeProperties<real_t> RealProperties;
     189  
     190  private:
     191      Type *tvalist;
     192      const Param *params;
     193  
     194  public:
     195      void _init(const Param& params);
     196      // Type sizes and support.
     197      unsigned alignsize(Type *type);
     198      unsigned fieldalign(Type *type);
     199      Type *va_listType(const Loc &loc, Scope *sc);  // get type of va_list
     200      int isVectorTypeSupported(int sz, Type *type);
     201      bool isVectorOpSupported(Type *type, EXP op, Type *t2 = NULL);
     202      // ABI and backend.
     203      LINK systemLinkage();
     204      TypeTuple *toArgTypes(Type *t);
     205      bool isReturnOnStack(TypeFunction *tf, bool needsThis);
     206      bool preferPassByRef(Type *t);
     207      Expression *getTargetInfo(const char* name, const Loc& loc);
     208      bool isCalleeDestroyingArgs(TypeFunction* tf);
     209      bool libraryObjectMonitors(FuncDeclaration *fd, Statement *fbody);
     210      bool supportsLinkerDirective() const;
     211      void addPredefinedGlobalIdentifiers() const;
     212  };
     213  
     214  extern Target target;