brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.0 KiB · 2d213d9 Raw
357 lines · plain
1Compiler-RT2================================3 4This directory and its subdirectories contain source code for the compiler5support routines.6 7Compiler-RT is open source software. You may freely distribute it under the8terms of the license agreement found in LICENSE.txt.9 10================================11 12This is a replacement library for libgcc.  Each function is contained13in its own file.  Each function has a corresponding unit test under14test/Unit.15 16A rudimentary script to test each file is in the file called17test/Unit/test.18 19Here is the specification for this library:20 21http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc22 23Please note that the libgcc specification explicitly mentions actual types of24arguments and returned values being expressed with machine modes.25In some cases particular types such as "int", "unsigned", "long long", etc.26may be specified just as examples there.27 28Here is a synopsis of the contents of this library:29 30typedef  int32_t si_int;31typedef uint32_t su_int;32 33typedef  int64_t di_int;34typedef uint64_t du_int;35 36// Integral bit manipulation37 38di_int __ashldi3(di_int a, int b);         // a << b39ti_int __ashlti3(ti_int a, int b);         // a << b40 41di_int __ashrdi3(di_int a, int b);         // a >> b  arithmetic (sign fill)42ti_int __ashrti3(ti_int a, int b);         // a >> b  arithmetic (sign fill)43di_int __lshrdi3(di_int a, int b);         // a >> b  logical    (zero fill)44ti_int __lshrti3(ti_int a, int b);         // a >> b  logical    (zero fill)45 46int __clzsi2(si_int a);  // count leading zeros47int __clzdi2(di_int a);  // count leading zeros48int __clzti2(ti_int a);  // count leading zeros49int __ctzsi2(si_int a);  // count trailing zeros50int __ctzdi2(di_int a);  // count trailing zeros51int __ctzti2(ti_int a);  // count trailing zeros52 53int __ffssi2(si_int a);  // find least significant 1 bit54int __ffsdi2(di_int a);  // find least significant 1 bit55int __ffsti2(ti_int a);  // find least significant 1 bit56 57int __paritysi2(si_int a);  // bit parity58int __paritydi2(di_int a);  // bit parity59int __parityti2(ti_int a);  // bit parity60 61int __popcountsi2(si_int a);  // bit population62int __popcountdi2(di_int a);  // bit population63int __popcountti2(ti_int a);  // bit population64 65uint32_t __bswapsi2(uint32_t a);   // a byteswapped66uint64_t __bswapdi2(uint64_t a);   // a byteswapped67 68// Integral arithmetic69 70di_int __negdi2    (di_int a);                         // -a71ti_int __negti2    (ti_int a);                         // -a72di_int __muldi3    (di_int a, di_int b);               // a * b73ti_int __multi3    (ti_int a, ti_int b);               // a * b74si_int __divsi3    (si_int a, si_int b);               // a / b   signed75di_int __divdi3    (di_int a, di_int b);               // a / b   signed76ti_int __divti3    (ti_int a, ti_int b);               // a / b   signed77su_int __udivsi3   (su_int n, su_int d);               // a / b   unsigned78du_int __udivdi3   (du_int a, du_int b);               // a / b   unsigned79tu_int __udivti3   (tu_int a, tu_int b);               // a / b   unsigned80si_int __modsi3    (si_int a, si_int b);               // a % b   signed81di_int __moddi3    (di_int a, di_int b);               // a % b   signed82ti_int __modti3    (ti_int a, ti_int b);               // a % b   signed83su_int __umodsi3   (su_int a, su_int b);               // a % b   unsigned84du_int __umoddi3   (du_int a, du_int b);               // a % b   unsigned85tu_int __umodti3   (tu_int a, tu_int b);               // a % b   unsigned86du_int __udivmoddi4(du_int a, du_int b, du_int* rem);  // a / b, *rem = a % b  unsigned87tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);  // a / b, *rem = a % b  unsigned88su_int __udivmodsi4(su_int a, su_int b, su_int* rem);  // a / b, *rem = a % b  unsigned89si_int __divmodsi4(si_int a, si_int b, si_int* rem);   // a / b, *rem = a % b  signed90di_int __divmoddi4(di_int a, di_int b, di_int* rem);   // a / b, *rem = a % b  signed91ti_int __divmodti4(ti_int a, ti_int b, ti_int* rem);   // a / b, *rem = a % b  signed92 93 94 95//  Integral arithmetic with trapping overflow96 97si_int __absvsi2(si_int a);           // abs(a)98di_int __absvdi2(di_int a);           // abs(a)99ti_int __absvti2(ti_int a);           // abs(a)100 101si_int __negvsi2(si_int a);           // -a102di_int __negvdi2(di_int a);           // -a103ti_int __negvti2(ti_int a);           // -a104 105si_int __addvsi3(si_int a, si_int b);  // a + b106di_int __addvdi3(di_int a, di_int b);  // a + b107ti_int __addvti3(ti_int a, ti_int b);  // a + b108 109si_int __subvsi3(si_int a, si_int b);  // a - b110di_int __subvdi3(di_int a, di_int b);  // a - b111ti_int __subvti3(ti_int a, ti_int b);  // a - b112 113si_int __mulvsi3(si_int a, si_int b);  // a * b114di_int __mulvdi3(di_int a, di_int b);  // a * b115ti_int __mulvti3(ti_int a, ti_int b);  // a * b116 117 118// Integral arithmetic which returns if overflow119 120si_int __mulosi4(si_int a, si_int b, int* overflow);  // a * b, overflow set to one if result not in signed range121di_int __mulodi4(di_int a, di_int b, int* overflow);  // a * b, overflow set to one if result not in signed range122ti_int __muloti4(ti_int a, ti_int b, int* overflow);  // a * b, overflow set to123 one if result not in signed range124 125 126//  Integral comparison: a  < b -> 0127//                       a == b -> 1128//                       a  > b -> 2129 130si_int __cmpdi2 (di_int a, di_int b);131si_int __cmpti2 (ti_int a, ti_int b);132si_int __ucmpdi2(du_int a, du_int b);133si_int __ucmpti2(tu_int a, tu_int b);134 135//  Integral / floating point conversion136 137di_int __fixsfdi(      float a);138di_int __fixdfdi(     double a);139di_int __fixxfdi(long double a);140di_int __fixtfdi(   tf_float a);141 142ti_int __fixsfti(      float a);143ti_int __fixdfti(     double a);144ti_int __fixxfti(long double a);145ti_int __fixtfti(   tf_float a);146 147su_int __fixunssfsi(      float a);148su_int __fixunsdfsi(     double a);149su_int __fixunsxfsi(long double a);150su_int __fixunstfsi(   tf_float a);151 152du_int __fixunssfdi(      float a);153du_int __fixunsdfdi(     double a);154du_int __fixunsxfdi(long double a);155du_int __fixunstfdi(   tf_float a);156 157tu_int __fixunssfti(      float a);158tu_int __fixunsdfti(     double a);159tu_int __fixunsxfti(long double a);160tu_int __fixunstfti(   tf_float a);161 162float       __floatdisf(di_int a);163double      __floatdidf(di_int a);164long double __floatdixf(di_int a);165tf_float    __floatditf(int64_t a);166 167float       __floattisf(ti_int a);168double      __floattidf(ti_int a);169long double __floattixf(ti_int a);170tf_float    __floattitf(ti_int a);171 172float       __floatundisf(du_int a);173double      __floatundidf(du_int a);174long double __floatundixf(du_int a);175tf_float    __floatunditf(du_int a);176 177float       __floatuntisf(tu_int a);178double      __floatuntidf(tu_int a);179long double __floatuntixf(tu_int a);180tf_float    __floatuntixf(tu_int a);181 182//  Floating point raised to integer power183 184float       __powisf2(      float a, int b);  // a ^ b185double      __powidf2(     double a, int b);  // a ^ b186long double __powixf2(long double a, int b);  // a ^ b187tf_float    __powitf2(   tf_float a, int b);  // a ^ b188 189//  Complex arithmetic190 191//  (a + ib) * (c + id)192 193      float _Complex __mulsc3( float a,  float b,  float c,  float d);194     double _Complex __muldc3(double a, double b, double c, double d);195long double _Complex __mulxc3(long double a, long double b,196                              long double c, long double d);197   tf_float _Complex __multc3(tf_float a, tf_float b, tf_float c, tf_float d);198 199//  (a + ib) / (c + id)200 201      float _Complex __divsc3( float a,  float b,  float c,  float d);202     double _Complex __divdc3(double a, double b, double c, double d);203long double _Complex __divxc3(long double a, long double b,204                              long double c, long double d);205   tf_float _Complex __divtc3(tf_float a, tf_float b, tf_float c, tf_float d);206 207 208//         Runtime support209 210// __clear_cache() is used to tell process that new instructions have been211// written to an address range.  Necessary on processors that do not have212// a unified instruction and data cache.213void __clear_cache(void* start, void* end);214 215// __enable_execute_stack() is used with nested functions when a trampoline216// function is written onto the stack and that page range needs to be made217// executable.218void __enable_execute_stack(void* addr);219 220// __gcc_personality_v0() is normally only called by the system unwinder.221// C code (as opposed to C++) normally does not need a personality function222// because there are no catch clauses or destructors to be run.  But there223// is a C language extension __attribute__((cleanup(func))) which marks local224// variables as needing the cleanup function "func" to be run when the225// variable goes out of scope.  That includes when an exception is thrown,226// so a personality handler is needed.  227_Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,228         uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,229         _Unwind_Context_t context);230 231// for use with some implementations of assert() in <assert.h>232void __eprintf(const char* format, const char* assertion_expression,233				const char* line, const char* file);234 235// for systems with emulated thread local storage236void* __emutls_get_address(struct __emutls_control*);237 238 239//   Power PC specific functions240 241// There is no C interface to the saveFP/restFP functions.  They are helper242// functions called by the prolog and epilog of functions that need to save243// a number of non-volatile float point registers.  244saveFP245restFP246 247// PowerPC has a standard template for trampoline functions.  This function248// generates a custom trampoline function with the specific realFunc249// and localsPtr values.250void __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated, 251                                const void* realFunc, void* localsPtr);252 253// adds two 128-bit double-double precision values ( x + y )254long double __gcc_qadd(long double x, long double y);  255 256// subtracts two 128-bit double-double precision values ( x - y )257long double __gcc_qsub(long double x, long double y); 258 259// multiples two 128-bit double-double precision values ( x * y )260long double __gcc_qmul(long double x, long double y);  261 262// divides two 128-bit double-double precision values ( x / y )263long double __gcc_qdiv(long double a, long double b);  264 265 266//    ARM specific functions267 268// There is no C interface to the switch* functions.  These helper functions269// are only needed by Thumb1 code for efficient switch table generation.270switch16271switch32272switch8273switchu8274 275// There is no C interface to the *_vfp_d8_d15_regs functions.  There are276// called in the prolog and epilog of Thumb1 functions.  When the C++ ABI use277// SJLJ for exceptions, each function with a catch clause or destructors needs278// to save and restore all registers in it prolog and epilog.  But there is279// no way to access vector and high float registers from thumb1 code, so the 280// compiler must add call outs to these helper functions in the prolog and 281// epilog.282restore_vfp_d8_d15_regs283save_vfp_d8_d15_regs284 285 286// Note: long ago ARM processors did not have floating point hardware support.287// Floating point was done in software and floating point parameters were 288// passed in integer registers.  When hardware support was added for floating289// point, new *vfp functions were added to do the same operations but with 290// floating point parameters in floating point registers.291 292// Undocumented functions293 294float  __addsf3vfp(float a, float b);   // Appears to return a + b295double __adddf3vfp(double a, double b); // Appears to return a + b296float  __divsf3vfp(float a, float b);   // Appears to return a / b297double __divdf3vfp(double a, double b); // Appears to return a / b298int    __eqsf2vfp(float a, float b);    // Appears to return  one299                                        //     iff a == b and neither is NaN.300int    __eqdf2vfp(double a, double b);  // Appears to return  one301                                        //     iff a == b and neither is NaN.302double __extendsfdf2vfp(float a);       // Appears to convert from303                                        //     float to double.304int    __fixdfsivfp(double a);          // Appears to convert from305                                        //     double to int.306int    __fixsfsivfp(float a);           // Appears to convert from307                                        //     float to int.308unsigned int __fixunssfsivfp(float a);  // Appears to convert from309                                        //     float to unsigned int.310unsigned int __fixunsdfsivfp(double a); // Appears to convert from311                                        //     double to unsigned int.312double __floatsidfvfp(int a);           // Appears to convert from313                                        //     int to double.314float __floatsisfvfp(int a);            // Appears to convert from315                                        //     int to float.316double __floatunssidfvfp(unsigned int a); // Appears to convert from317                                        //     unsigned int to double.318float __floatunssisfvfp(unsigned int a); // Appears to convert from319                                        //     unsigned int to float.320int __gedf2vfp(double a, double b);     // Appears to return __gedf2321                                        //     (a >= b)322int __gesf2vfp(float a, float b);       // Appears to return __gesf2323                                        //     (a >= b)324int __gtdf2vfp(double a, double b);     // Appears to return __gtdf2325                                        //     (a > b)326int __gtsf2vfp(float a, float b);       // Appears to return __gtsf2327                                        //     (a > b)328int __ledf2vfp(double a, double b);     // Appears to return __ledf2329                                        //     (a <= b)330int __lesf2vfp(float a, float b);       // Appears to return __lesf2331                                        //     (a <= b)332int __ltdf2vfp(double a, double b);     // Appears to return __ltdf2333                                        //     (a < b)334int __ltsf2vfp(float a, float b);       // Appears to return __ltsf2335                                        //     (a < b)336double __muldf3vfp(double a, double b); // Appears to return a * b337float __mulsf3vfp(float a, float b);    // Appears to return a * b338int __nedf2vfp(double a, double b);     // Appears to return __nedf2339                                        //     (a != b)340double __negdf2vfp(double a);           // Appears to return -a341float __negsf2vfp(float a);             // Appears to return -a342float __negsf2vfp(float a);             // Appears to return -a343double __subdf3vfp(double a, double b); // Appears to return a - b344float __subsf3vfp(float a, float b);    // Appears to return a - b345float __truncdfsf2vfp(double a);        // Appears to convert from346                                        //     double to float.347int __unorddf2vfp(double a, double b);  // Appears to return __unorddf2348int __unordsf2vfp(float a, float b);    // Appears to return __unordsf2349 350 351Preconditions are listed for each function at the definition when there are any.352Any preconditions reflect the specification at353http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc.354 355Assumptions are listed in "int_lib.h", and in individual files.  Where possible356assumptions are checked at compile time.357