148fb7bfaSmrg<section xmlns="http://docbook.org/ns/docbook" version="5.0" 248fb7bfaSmrg xml:id="appendix.porting.internals" xreflabel="Portin Internals"> 34fee23f9Smrg<?dbhtml filename="internals.html"?> 44fee23f9Smrg 548fb7bfaSmrg<info><title>Porting to New Hardware or Operating Systems</title> 64fee23f9Smrg <keywordset> 748fb7bfaSmrg <keyword>ISO C++</keyword> 848fb7bfaSmrg <keyword>internals</keyword> 94fee23f9Smrg </keywordset> 1048fb7bfaSmrg</info> 114fee23f9Smrg 1248fb7bfaSmrg 134fee23f9Smrg 144fee23f9Smrg<para> 154fee23f9Smrg</para> 164fee23f9Smrg 174fee23f9Smrg 184fee23f9Smrg<para>This document explains how to port libstdc++ (the GNU C++ library) to 194fee23f9Smrga new target. 204fee23f9Smrg</para> 214fee23f9Smrg 224fee23f9Smrg <para>In order to make the GNU C++ library (libstdc++) work with a new 234fee23f9Smrgtarget, you must edit some configuration files and provide some new 244fee23f9Smrgheader files. Unless this is done, libstdc++ will use generic 254fee23f9Smrgsettings which may not be correct for your target; even if they are 264fee23f9Smrgcorrect, they will likely be inefficient. 274fee23f9Smrg </para> 284fee23f9Smrg 294fee23f9Smrg <para>Before you get started, make sure that you have a working C library on 304fee23f9Smrgyour target. The C library need not precisely comply with any 314fee23f9Smrgparticular standard, but should generally conform to the requirements 324fee23f9Smrgimposed by the ANSI/ISO standard. 334fee23f9Smrg </para> 344fee23f9Smrg 354fee23f9Smrg <para>In addition, you should try to verify that the C++ compiler generally 364fee23f9Smrgworks. It is difficult to test the C++ compiler without a working 374fee23f9Smrglibrary, but you should at least try some minimal test cases. 384fee23f9Smrg </para> 394fee23f9Smrg 404fee23f9Smrg <para>(Note that what we think of as a "target," the library refers to as 414fee23f9Smrga "host." The comment at the top of <code>configure.ac</code> explains why.) 424fee23f9Smrg </para> 434fee23f9Smrg 444fee23f9Smrg 4548fb7bfaSmrg<section xml:id="internals.os"><info><title>Operating System</title></info> 4648fb7bfaSmrg 474fee23f9Smrg 484fee23f9Smrg<para>If you are porting to a new operating system (as opposed to a new chip 494fee23f9Smrgusing an existing operating system), you will need to create a new 504fee23f9Smrgdirectory in the <code>config/os</code> hierarchy. For example, the IRIX 514fee23f9Smrgconfiguration files are all in <code>config/os/irix</code>. There is no set 524fee23f9Smrgway to organize the OS configuration directory. For example, 534fee23f9Smrg<code>config/os/solaris/solaris-2.6</code> and 544fee23f9Smrg<code>config/os/solaris/solaris-2.7</code> are used as configuration 554fee23f9Smrgdirectories for these two versions of Solaris. On the other hand, both 564fee23f9SmrgSolaris 2.7 and Solaris 2.8 use the <code>config/os/solaris/solaris-2.7</code> 574fee23f9Smrgdirectory. The important information is that there needs to be a 584fee23f9Smrgdirectory under <code>config/os</code> to store the files for your operating 594fee23f9Smrgsystem. 604fee23f9Smrg</para> 614fee23f9Smrg 624fee23f9Smrg <para>You might have to change the <code>configure.host</code> file to ensure that 634fee23f9Smrgyour new directory is activated. Look for the switch statement that sets 644fee23f9Smrg<code>os_include_dir</code>, and add a pattern to handle your operating system 654fee23f9Smrgif the default will not suffice. The switch statement switches on only 664fee23f9Smrgthe OS portion of the standard target triplet; e.g., the <code>solaris2.8</code> 674fee23f9Smrgin <code>sparc-sun-solaris2.8</code>. If the new directory is named after the 684fee23f9SmrgOS portion of the triplet (the default), then nothing needs to be changed. 694fee23f9Smrg </para> 704fee23f9Smrg 714fee23f9Smrg <para>The first file to create in this directory, should be called 724fee23f9Smrg<code>os_defines.h</code>. This file contains basic macro definitions 734fee23f9Smrgthat are required to allow the C++ library to work with your C library. 744fee23f9Smrg </para> 754fee23f9Smrg 764fee23f9Smrg <para>Several libstdc++ source files unconditionally define the macro 774fee23f9Smrg<code>_POSIX_SOURCE</code>. On many systems, defining this macro causes 784fee23f9Smrglarge portions of the C library header files to be eliminated 794fee23f9Smrgat preprocessing time. Therefore, you may have to <code>#undef</code> this 804fee23f9Smrgmacro, or define other macros (like <code>_LARGEFILE_SOURCE</code> or 814fee23f9Smrg<code>__EXTENSIONS__</code>). You won't know what macros to define or 824fee23f9Smrgundefine at this point; you'll have to try compiling the library and 834fee23f9Smrgseeing what goes wrong. If you see errors about calling functions 844fee23f9Smrgthat have not been declared, look in your C library headers to see if 854fee23f9Smrgthe functions are declared there, and then figure out what macros you 864fee23f9Smrgneed to define. You will need to add them to the 874fee23f9Smrg<code>CPLUSPLUS_CPP_SPEC</code> macro in the GCC configuration file for your 884fee23f9Smrgtarget. It will not work to simply define these macros in 894fee23f9Smrg<code>os_defines.h</code>. 904fee23f9Smrg </para> 914fee23f9Smrg 924fee23f9Smrg <para>At this time, there are a few libstdc++-specific macros which may be 934fee23f9Smrgdefined: 944fee23f9Smrg </para> 954fee23f9Smrg 964fee23f9Smrg <para><code>_GLIBCXX_USE_C99_CHECK</code> may be defined to 1 to check C99 974fee23f9Smrgfunction declarations (which are not covered by specialization below) 984fee23f9Smrgfound in system headers against versions found in the library headers 994fee23f9Smrgderived from the standard. 1004fee23f9Smrg </para> 1014fee23f9Smrg 1024fee23f9Smrg <para><code>_GLIBCXX_USE_C99_DYNAMIC</code> may be defined to an expression that 1034fee23f9Smrgyields 0 if and only if the system headers are exposing proper support 1044fee23f9Smrgfor C99 functions (which are not covered by specialization below). If 1054fee23f9Smrgdefined, it must be 0 while bootstrapping the compiler/rebuilding the 1064fee23f9Smrglibrary. 1074fee23f9Smrg </para> 1084fee23f9Smrg 1094fee23f9Smrg <para><code>_GLIBCXX_USE_C99_LONG_LONG_CHECK</code> may be defined to 1 to check 1104fee23f9Smrgthe set of C99 long long function declarations found in system headers 1114fee23f9Smrgagainst versions found in the library headers derived from the 1124fee23f9Smrgstandard. 1134fee23f9Smrg 1144fee23f9Smrg </para> 1154fee23f9Smrg <para><code>_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC</code> may be defined to an 1164fee23f9Smrgexpression that yields 0 if and only if the system headers are 1174fee23f9Smrgexposing proper support for the set of C99 long long functions. If 1184fee23f9Smrgdefined, it must be 0 while bootstrapping the compiler/rebuilding the 1194fee23f9Smrglibrary. 1204fee23f9Smrg </para> 1214fee23f9Smrg <para><code>_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC</code> may be defined to an 1224fee23f9Smrgexpression that yields 0 if and only if the system headers 1234fee23f9Smrgare exposing proper support for the related set of macros. If defined, 1244fee23f9Smrgit must be 0 while bootstrapping the compiler/rebuilding the library. 1254fee23f9Smrg </para> 1264fee23f9Smrg <para><code>_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_CHECK</code> may be defined 1274fee23f9Smrgto 1 to check the related set of function declarations found in system 1284fee23f9Smrgheaders against versions found in the library headers derived from 1294fee23f9Smrgthe standard. 1304fee23f9Smrg </para> 1314fee23f9Smrg <para><code>_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC</code> may be defined 1324fee23f9Smrgto an expression that yields 0 if and only if the system headers 1334fee23f9Smrgare exposing proper support for the related set of functions. If defined, 1344fee23f9Smrgit must be 0 while bootstrapping the compiler/rebuilding the library. 1354fee23f9Smrg </para> 136*f9a78e0eSmrg <para><code>_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC</code> may be defined 137*f9a78e0eSmrgto an expression that yields 0 if and only if the system headers 138*f9a78e0eSmrgare exposing non-standard <code>isinf(double)</code> and 139*f9a78e0eSmrg<code>isnan(double)</code> functions in the global namespace. Those functions 140*f9a78e0eSmrgshould be detected automatically by the <code>configure</code> script when 141*f9a78e0eSmrglibstdc++ is built but if their presence depends on compilation flags or 142*f9a78e0eSmrgother macros the static configuration can be overridden. 143*f9a78e0eSmrg </para> 1444fee23f9Smrg <para>Finally, you should bracket the entire file in an include-guard, like 1454fee23f9Smrgthis: 1464fee23f9Smrg </para> 1474fee23f9Smrg 1484fee23f9Smrg<programlisting> 1494fee23f9Smrg 1504fee23f9Smrg#ifndef _GLIBCXX_OS_DEFINES 1514fee23f9Smrg#define _GLIBCXX_OS_DEFINES 1524fee23f9Smrg... 1534fee23f9Smrg#endif 1544fee23f9Smrg</programlisting> 1554fee23f9Smrg 1564fee23f9Smrg <para>We recommend copying an existing <code>os_defines.h</code> to use as a 1574fee23f9Smrgstarting point. 1584fee23f9Smrg </para> 15948fb7bfaSmrg</section> 1604fee23f9Smrg 1614fee23f9Smrg 16248fb7bfaSmrg<section xml:id="internals.cpu"><info><title>CPU</title></info> 16348fb7bfaSmrg 1644fee23f9Smrg 1654fee23f9Smrg<para>If you are porting to a new chip (as opposed to a new operating system 1664fee23f9Smrgrunning on an existing chip), you will need to create a new directory in the 1674fee23f9Smrg<code>config/cpu</code> hierarchy. Much like the <link linkend="internals.os">Operating system</link> setup, 1684fee23f9Smrgthere are no strict rules on how to organize the CPU configuration 1694fee23f9Smrgdirectory, but careful naming choices will allow the configury to find your 1704fee23f9Smrgsetup files without explicit help. 1714fee23f9Smrg</para> 1724fee23f9Smrg 1734fee23f9Smrg <para>We recommend that for a target triplet <code><CPU>-<vendor>-<OS></code>, you 1744fee23f9Smrgname your configuration directory <code>config/cpu/<CPU></code>. If you do this, 1754fee23f9Smrgthe configury will find the directory by itself. Otherwise you will need to 1764fee23f9Smrgedit the <code>configure.host</code> file and, in the switch statement that sets 1774fee23f9Smrg<code>cpu_include_dir</code>, add a pattern to handle your chip. 1784fee23f9Smrg </para> 1794fee23f9Smrg 1804fee23f9Smrg <para>Note that some chip families share a single configuration directory, for 1814fee23f9Smrgexample, <code>alpha</code>, <code>alphaev5</code>, and <code>alphaev6</code> all use the 1824fee23f9Smrg<code>config/cpu/alpha</code> directory, and there is an entry in the 1834fee23f9Smrg<code>configure.host</code> switch statement to handle this. 1844fee23f9Smrg </para> 1854fee23f9Smrg 1864fee23f9Smrg <para>The <code>cpu_include_dir</code> sets default locations for the files controlling 1874fee23f9Smrg<link linkend="internals.thread_safety">Thread safety</link> and <link linkend="internals.numeric_limits">Numeric limits</link>, if the defaults are not 1884fee23f9Smrgappropriate for your chip. 1894fee23f9Smrg </para> 1904fee23f9Smrg 19148fb7bfaSmrg</section> 1924fee23f9Smrg 1934fee23f9Smrg 19448fb7bfaSmrg<section xml:id="internals.char_types"><info><title>Character Types</title></info> 19548fb7bfaSmrg 1964fee23f9Smrg 1974fee23f9Smrg<para>The library requires that you provide three header files to implement 1984fee23f9Smrgcharacter classification, analogous to that provided by the C libraries 1994fee23f9Smrg<code><ctype.h></code> header. You can model these on the files provided in 2004fee23f9Smrg<code>config/os/generic</code>. However, these files will almost 2014fee23f9Smrgcertainly need some modification. 2024fee23f9Smrg</para> 2034fee23f9Smrg 2044fee23f9Smrg <para>The first file to write is <code>ctype_base.h</code>. This file provides 2054fee23f9Smrgsome very basic information about character classification. The libstdc++ 2064fee23f9Smrglibrary assumes that your C library implements <code><ctype.h></code> by using 2074fee23f9Smrga table (indexed by character code) containing integers, where each of 2084fee23f9Smrgthese integers is a bit-mask indicating whether the character is 2094fee23f9Smrgupper-case, lower-case, alphabetic, etc. The <code>ctype_base.h</code> 2104fee23f9Smrgfile gives the type of the integer, and the values of the various bit 2114fee23f9Smrgmasks. You will have to peer at your own <code><ctype.h></code> to figure out 2124fee23f9Smrghow to define the values required by this file. 2134fee23f9Smrg </para> 2144fee23f9Smrg 2154fee23f9Smrg <para>The <code>ctype_base.h</code> header file does not need include guards. 2164fee23f9SmrgIt should contain a single <code>struct</code> definition called 2174fee23f9Smrg<code>ctype_base</code>. This <code>struct</code> should contain two type 2184fee23f9Smrgdeclarations, and one enumeration declaration, like this example, taken 2194fee23f9Smrgfrom the IRIX configuration: 2204fee23f9Smrg </para> 2214fee23f9Smrg 2224fee23f9Smrg<programlisting> 2234fee23f9Smrg struct ctype_base 2244fee23f9Smrg { 2254fee23f9Smrg typedef unsigned int mask; 2264fee23f9Smrg typedef int* __to_type; 2274fee23f9Smrg 2284fee23f9Smrg enum 2294fee23f9Smrg { 2304fee23f9Smrg space = _ISspace, 2314fee23f9Smrg print = _ISprint, 2324fee23f9Smrg cntrl = _IScntrl, 2334fee23f9Smrg upper = _ISupper, 2344fee23f9Smrg lower = _ISlower, 2354fee23f9Smrg alpha = _ISalpha, 2364fee23f9Smrg digit = _ISdigit, 2374fee23f9Smrg punct = _ISpunct, 2384fee23f9Smrg xdigit = _ISxdigit, 2394fee23f9Smrg alnum = _ISalnum, 2404fee23f9Smrg graph = _ISgraph 2414fee23f9Smrg }; 2424fee23f9Smrg }; 2434fee23f9Smrg</programlisting> 2444fee23f9Smrg 2454fee23f9Smrg<para>The <code>mask</code> type is the type of the elements in the table. If your 2464fee23f9SmrgC library uses a table to map lower-case numbers to upper-case numbers, 2474fee23f9Smrgand vice versa, you should define <code>__to_type</code> to be the type of the 2484fee23f9Smrgelements in that table. If you don't mind taking a minor performance 2494fee23f9Smrgpenalty, or if your library doesn't implement <code>toupper</code> and 2504fee23f9Smrg<code>tolower</code> in this way, you can pick any pointer-to-integer type, 2514fee23f9Smrgbut you must still define the type. 2524fee23f9Smrg</para> 2534fee23f9Smrg 2544fee23f9Smrg <para>The enumeration should give definitions for all the values in the above 2554fee23f9Smrgexample, using the values from your native <code><ctype.h></code>. They can 2564fee23f9Smrgbe given symbolically (as above), or numerically, if you prefer. You do 2574fee23f9Smrgnot have to include <code><ctype.h></code> in this header; it will always be 2584fee23f9Smrgincluded before <code>ctype_base.h</code> is included. 2594fee23f9Smrg </para> 2604fee23f9Smrg 26148fb7bfaSmrg <para>The next file to write is <code>ctype_configure_char.cc</code>. 26248fb7bfaSmrgThe first function that must be written is the <code>ctype<char>::ctype</code> constructor. Here is the IRIX example: 2634fee23f9Smrg </para> 2644fee23f9Smrg 2654fee23f9Smrg<programlisting> 2664fee23f9Smrgctype<char>::ctype(const mask* __table = 0, bool __del = false, 2674fee23f9Smrg size_t __refs = 0) 2684fee23f9Smrg : _Ctype_nois<char>(__refs), _M_del(__table != 0 && __del), 2694fee23f9Smrg _M_toupper(NULL), 2704fee23f9Smrg _M_tolower(NULL), 2714fee23f9Smrg _M_ctable(NULL), 2724fee23f9Smrg _M_table(!__table 2734fee23f9Smrg ? (const mask*) (__libc_attr._ctype_tbl->_class + 1) 2744fee23f9Smrg : __table) 2754fee23f9Smrg { } 2764fee23f9Smrg</programlisting> 2774fee23f9Smrg 2784fee23f9Smrg<para>There are two parts of this that you might choose to alter. The first, 2794fee23f9Smrgand most important, is the line involving <code>__libc_attr</code>. That is 2804fee23f9SmrgIRIX system-dependent code that gets the base of the table mapping 2814fee23f9Smrgcharacter codes to attributes. You need to substitute code that obtains 2824fee23f9Smrgthe address of this table on your system. If you want to use your 2834fee23f9Smrgoperating system's tables to map upper-case letters to lower-case, and 2844fee23f9Smrgvice versa, you should initialize <code>_M_toupper</code> and 2854fee23f9Smrg<code>_M_tolower</code> with those tables, in similar fashion. 2864fee23f9Smrg</para> 2874fee23f9Smrg 2884fee23f9Smrg <para>Now, you have to write two functions to convert from upper-case to 2894fee23f9Smrglower-case, and vice versa. Here are the IRIX versions: 2904fee23f9Smrg </para> 2914fee23f9Smrg 2924fee23f9Smrg<programlisting> 2934fee23f9Smrg char 2944fee23f9Smrg ctype<char>::do_toupper(char __c) const 2954fee23f9Smrg { return _toupper(__c); } 2964fee23f9Smrg 2974fee23f9Smrg char 2984fee23f9Smrg ctype<char>::do_tolower(char __c) const 2994fee23f9Smrg { return _tolower(__c); } 3004fee23f9Smrg</programlisting> 3014fee23f9Smrg 3024fee23f9Smrg<para>Your C library provides equivalents to IRIX's <code>_toupper</code> and 3034fee23f9Smrg<code>_tolower</code>. If you initialized <code>_M_toupper</code> and 3044fee23f9Smrg<code>_M_tolower</code> above, then you could use those tables instead. 3054fee23f9Smrg</para> 3064fee23f9Smrg 3074fee23f9Smrg <para>Finally, you have to provide two utility functions that convert strings 3084fee23f9Smrgof characters. The versions provided here will always work - but you 3094fee23f9Smrgcould use specialized routines for greater performance if you have 3104fee23f9Smrgmachinery to do that on your system: 3114fee23f9Smrg </para> 3124fee23f9Smrg 3134fee23f9Smrg<programlisting> 3144fee23f9Smrg const char* 3154fee23f9Smrg ctype<char>::do_toupper(char* __low, const char* __high) const 3164fee23f9Smrg { 3174fee23f9Smrg while (__low < __high) 3184fee23f9Smrg { 3194fee23f9Smrg *__low = do_toupper(*__low); 3204fee23f9Smrg ++__low; 3214fee23f9Smrg } 3224fee23f9Smrg return __high; 3234fee23f9Smrg } 3244fee23f9Smrg 3254fee23f9Smrg const char* 3264fee23f9Smrg ctype<char>::do_tolower(char* __low, const char* __high) const 3274fee23f9Smrg { 3284fee23f9Smrg while (__low < __high) 3294fee23f9Smrg { 3304fee23f9Smrg *__low = do_tolower(*__low); 3314fee23f9Smrg ++__low; 3324fee23f9Smrg } 3334fee23f9Smrg return __high; 3344fee23f9Smrg } 3354fee23f9Smrg</programlisting> 3364fee23f9Smrg 3374fee23f9Smrg <para>You must also provide the <code>ctype_inline.h</code> file, which 3384fee23f9Smrgcontains a few more functions. On most systems, you can just copy 3394fee23f9Smrg<code>config/os/generic/ctype_inline.h</code> and use it on your system. 3404fee23f9Smrg </para> 3414fee23f9Smrg 3424fee23f9Smrg <para>In detail, the functions provided test characters for particular 3434fee23f9Smrgproperties; they are analogous to the functions like <code>isalpha</code> and 3444fee23f9Smrg<code>islower</code> provided by the C library. 3454fee23f9Smrg </para> 3464fee23f9Smrg 3474fee23f9Smrg <para>The first function is implemented like this on IRIX: 3484fee23f9Smrg </para> 3494fee23f9Smrg 3504fee23f9Smrg<programlisting> 3514fee23f9Smrg bool 3524fee23f9Smrg ctype<char>:: 3534fee23f9Smrg is(mask __m, char __c) const throw() 3544fee23f9Smrg { return (_M_table)[(unsigned char)(__c)] & __m; } 3554fee23f9Smrg</programlisting> 3564fee23f9Smrg 3574fee23f9Smrg<para>The <code>_M_table</code> is the table passed in above, in the constructor. 3584fee23f9SmrgThis is the table that contains the bitmasks for each character. The 3594fee23f9Smrgimplementation here should work on all systems. 3604fee23f9Smrg</para> 3614fee23f9Smrg 3624fee23f9Smrg <para>The next function is: 3634fee23f9Smrg </para> 3644fee23f9Smrg 3654fee23f9Smrg<programlisting> 3664fee23f9Smrg const char* 3674fee23f9Smrg ctype<char>:: 3684fee23f9Smrg is(const char* __low, const char* __high, mask* __vec) const throw() 3694fee23f9Smrg { 3704fee23f9Smrg while (__low < __high) 3714fee23f9Smrg *__vec++ = (_M_table)[(unsigned char)(*__low++)]; 3724fee23f9Smrg return __high; 3734fee23f9Smrg } 3744fee23f9Smrg</programlisting> 3754fee23f9Smrg 3764fee23f9Smrg<para>This function is similar; it copies the masks for all the characters 3774fee23f9Smrgfrom <code>__low</code> up until <code>__high</code> into the vector given by 3784fee23f9Smrg<code>__vec</code>. 3794fee23f9Smrg</para> 3804fee23f9Smrg 3814fee23f9Smrg <para>The last two functions again are entirely generic: 3824fee23f9Smrg </para> 3834fee23f9Smrg 3844fee23f9Smrg<programlisting> 3854fee23f9Smrg const char* 3864fee23f9Smrg ctype<char>:: 3874fee23f9Smrg scan_is(mask __m, const char* __low, const char* __high) const throw() 3884fee23f9Smrg { 3894fee23f9Smrg while (__low < __high && !this->is(__m, *__low)) 3904fee23f9Smrg ++__low; 3914fee23f9Smrg return __low; 3924fee23f9Smrg } 3934fee23f9Smrg 3944fee23f9Smrg const char* 3954fee23f9Smrg ctype<char>:: 3964fee23f9Smrg scan_not(mask __m, const char* __low, const char* __high) const throw() 3974fee23f9Smrg { 3984fee23f9Smrg while (__low < __high && this->is(__m, *__low)) 3994fee23f9Smrg ++__low; 4004fee23f9Smrg return __low; 4014fee23f9Smrg } 4024fee23f9Smrg</programlisting> 4034fee23f9Smrg 40448fb7bfaSmrg</section> 4054fee23f9Smrg 4064fee23f9Smrg 40748fb7bfaSmrg<section xml:id="internals.thread_safety"><info><title>Thread Safety</title></info> 40848fb7bfaSmrg 4094fee23f9Smrg 4104fee23f9Smrg<para>The C++ library string functionality requires a couple of atomic 4114fee23f9Smrgoperations to provide thread-safety. If you don't take any special 4124fee23f9Smrgaction, the library will use stub versions of these functions that are 4134fee23f9Smrgnot thread-safe. They will work fine, unless your applications are 4144fee23f9Smrgmulti-threaded. 4154fee23f9Smrg</para> 4164fee23f9Smrg 4174fee23f9Smrg <para>If you want to provide custom, safe, versions of these functions, there 4184fee23f9Smrgare two distinct approaches. One is to provide a version for your CPU, 4194fee23f9Smrgusing assembly language constructs. The other is to use the 4204fee23f9Smrgthread-safety primitives in your operating system. In either case, you 4214fee23f9Smrgmake a file called <code>atomicity.h</code>, and the variable 4224fee23f9Smrg<code>ATOMICITYH</code> must point to this file. 4234fee23f9Smrg </para> 4244fee23f9Smrg 4254fee23f9Smrg <para>If you are using the assembly-language approach, put this code in 4264fee23f9Smrg<code>config/cpu/<chip>/atomicity.h</code>, where chip is the name of 4274fee23f9Smrgyour processor (see <link linkend="internals.cpu">CPU</link>). No additional changes are necessary to 4284fee23f9Smrglocate the file in this case; <code>ATOMICITYH</code> will be set by default. 4294fee23f9Smrg </para> 4304fee23f9Smrg 4314fee23f9Smrg <para>If you are using the operating system thread-safety primitives approach, 4324fee23f9Smrgyou can also put this code in the same CPU directory, in which case no more 4334fee23f9Smrgwork is needed to locate the file. For examples of this approach, 4344fee23f9Smrgsee the <code>atomicity.h</code> file for IRIX or IA64. 4354fee23f9Smrg </para> 4364fee23f9Smrg 4374fee23f9Smrg <para>Alternatively, if the primitives are more closely related to the OS 4384fee23f9Smrgthan they are to the CPU, you can put the <code>atomicity.h</code> file in 4394fee23f9Smrgthe <link linkend="internals.os">Operating system</link> directory instead. In this case, you must 4404fee23f9Smrgedit <code>configure.host</code>, and in the switch statement that handles 4414fee23f9Smrgoperating systems, override the <code>ATOMICITYH</code> variable to point to 4424fee23f9Smrgthe appropriate <code>os_include_dir</code>. For examples of this approach, 4434fee23f9Smrgsee the <code>atomicity.h</code> file for AIX. 4444fee23f9Smrg </para> 4454fee23f9Smrg 4464fee23f9Smrg <para>With those bits out of the way, you have to actually write 4474fee23f9Smrg<code>atomicity.h</code> itself. This file should be wrapped in an 4484fee23f9Smrginclude guard named <code>_GLIBCXX_ATOMICITY_H</code>. It should define one 4494fee23f9Smrgtype, and two functions. 4504fee23f9Smrg </para> 4514fee23f9Smrg 4524fee23f9Smrg <para>The type is <code>_Atomic_word</code>. Here is the version used on IRIX: 4534fee23f9Smrg </para> 4544fee23f9Smrg 4554fee23f9Smrg<programlisting> 4564fee23f9Smrgtypedef long _Atomic_word; 4574fee23f9Smrg</programlisting> 4584fee23f9Smrg 4594fee23f9Smrg<para>This type must be a signed integral type supporting atomic operations. 4604fee23f9SmrgIf you're using the OS approach, use the same type used by your system's 4614fee23f9Smrgprimitives. Otherwise, use the type for which your CPU provides atomic 4624fee23f9Smrgprimitives. 4634fee23f9Smrg</para> 4644fee23f9Smrg 4654fee23f9Smrg <para>Then, you must provide two functions. The bodies of these functions 4664fee23f9Smrgmust be equivalent to those provided here, but using atomic operations: 4674fee23f9Smrg </para> 4684fee23f9Smrg 4694fee23f9Smrg<programlisting> 4704fee23f9Smrg static inline _Atomic_word 4714fee23f9Smrg __attribute__ ((__unused__)) 4724fee23f9Smrg __exchange_and_add (_Atomic_word* __mem, int __val) 4734fee23f9Smrg { 4744fee23f9Smrg _Atomic_word __result = *__mem; 4754fee23f9Smrg *__mem += __val; 4764fee23f9Smrg return __result; 4774fee23f9Smrg } 4784fee23f9Smrg 4794fee23f9Smrg static inline void 4804fee23f9Smrg __attribute__ ((__unused__)) 4814fee23f9Smrg __atomic_add (_Atomic_word* __mem, int __val) 4824fee23f9Smrg { 4834fee23f9Smrg *__mem += __val; 4844fee23f9Smrg } 4854fee23f9Smrg</programlisting> 4864fee23f9Smrg 48748fb7bfaSmrg</section> 4884fee23f9Smrg 4894fee23f9Smrg 49048fb7bfaSmrg<section xml:id="internals.numeric_limits"><info><title>Numeric Limits</title></info> 49148fb7bfaSmrg 4924fee23f9Smrg 4934fee23f9Smrg<para>The C++ library requires information about the fundamental data types, 4944fee23f9Smrgsuch as the minimum and maximum representable values of each type. 4954fee23f9SmrgYou can define each of these values individually, but it is usually 4964fee23f9Smrgeasiest just to indicate how many bits are used in each of the data 4974fee23f9Smrgtypes and let the library do the rest. For information about the 4984fee23f9Smrgmacros to define, see the top of <code>include/bits/std_limits.h</code>. 4994fee23f9Smrg</para> 5004fee23f9Smrg 5014fee23f9Smrg <para>If you need to define any macros, you can do so in <code>os_defines.h</code>. 5024fee23f9SmrgHowever, if all operating systems for your CPU are likely to use the 5034fee23f9Smrgsame values, you can provide a CPU-specific file instead so that you 5044fee23f9Smrgdo not have to provide the same definitions for each operating system. 5054fee23f9SmrgTo take that approach, create a new file called <code>cpu_limits.h</code> in 5064fee23f9Smrgyour CPU configuration directory (see <link linkend="internals.cpu">CPU</link>). 5074fee23f9Smrg </para> 5084fee23f9Smrg 50948fb7bfaSmrg</section> 5104fee23f9Smrg 5114fee23f9Smrg 51248fb7bfaSmrg<section xml:id="internals.libtool"><info><title>Libtool</title></info> 51348fb7bfaSmrg 5144fee23f9Smrg 5154fee23f9Smrg<para>The C++ library is compiled, archived and linked with libtool. 5164fee23f9SmrgExplaining the full workings of libtool is beyond the scope of this 5174fee23f9Smrgdocument, but there are a few, particular bits that are necessary for 5184fee23f9Smrgporting. 5194fee23f9Smrg</para> 5204fee23f9Smrg 5214fee23f9Smrg <para>Some parts of the libstdc++ library are compiled with the libtool 5224fee23f9Smrg<code>--tags CXX</code> option (the C++ definitions for libtool). Therefore, 5234fee23f9Smrg<code>ltcf-cxx.sh</code> in the top-level directory needs to have the correct 5244fee23f9Smrglogic to compile and archive objects equivalent to the C version of libtool, 5254fee23f9Smrg<code>ltcf-c.sh</code>. Some libtool targets have definitions for C but not 5264fee23f9Smrgfor C++, or C++ definitions which have not been kept up to date. 5274fee23f9Smrg </para> 5284fee23f9Smrg 5294fee23f9Smrg <para>The C++ run-time library contains initialization code that needs to be 5304fee23f9Smrgrun as the library is loaded. Often, that requires linking in special 5314fee23f9Smrgobject files when the C++ library is built as a shared library, or 5324fee23f9Smrgtaking other system-specific actions. 5334fee23f9Smrg </para> 5344fee23f9Smrg 5354fee23f9Smrg <para>The libstdc++ library is linked with the C version of libtool, even 5364fee23f9Smrgthough it is a C++ library. Therefore, the C version of libtool needs to 5374fee23f9Smrgensure that the run-time library initializers are run. The usual way to 5384fee23f9Smrgdo this is to build the library using <code>gcc -shared</code>. 5394fee23f9Smrg </para> 5404fee23f9Smrg 5414fee23f9Smrg <para>If you need to change how the library is linked, look at 5424fee23f9Smrg<code>ltcf-c.sh</code> in the top-level directory. Find the switch statement 5434fee23f9Smrgthat sets <code>archive_cmds</code>. Here, adjust the setting for your 5444fee23f9Smrgoperating system. 5454fee23f9Smrg </para> 5464fee23f9Smrg 5474fee23f9Smrg 54848fb7bfaSmrg</section> 5494fee23f9Smrg 55048fb7bfaSmrg</section> 551