// // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // builtins.c -- // // Author : Peter A. Buhr // Created On : Fri Jul 21 16:21:03 2017 // Last Modified By : Peter A. Buhr // Last Modified On : Sun Dec 8 09:01:23 2024 // Update Count : 149 // #define __cforall_builtins__ // Type that wraps a pointer and a destructor-like function - used in generating implicit destructor calls for struct // members in user-defined functions. Note: needs to occur early, because it is used to generate destructor calls during // code generation forall( T &) struct __Destructor { T * object; void (*dtor)( T * ); }; // Defined destructor in the case that non-generated code wants to use __Destructor. forall( T &) static inline void ^?{}( __Destructor(T) & x ) { if ( x.object && x.dtor ) { x.dtor( x.object ); } } // Easy interface into __Destructor's destructor for easy codegen purposes. extern "C" { forall( T &) static inline void __destroy_Destructor( __Destructor(T) * dtor ) { ^(*dtor){}; } } // exception implementation typedef unsigned long long __cfaabi_abi_exception_type_t; #include "../src/virtual.h" #include "../src/exception.h" void exit( int status, const char fmt[], ... ) __attribute__ (( format( printf, 2, 3 ), __nothrow__, __leaf__, __noreturn__ )); void abort( const char fmt[], ... ) __attribute__ (( format( printf, 1, 2 ), __nothrow__, __leaf__, __noreturn__ )); forall( T &) static inline T & identity( T & i ) { return i; } // generator support struct generator$ { inline int; }; static inline void ?{}( generator$ & this ) { ((int&)this) = 0; } static inline void ^?{}( generator$ &) {} forall( T & ) trait is_generator { void main( T & this ); generator$ * get_generator( T & this ); }; forall( T & | is_generator( T ) ) static inline T & resume( T & gen ) { main( gen ); return gen; } // implicit increment, decrement if += defined, and implicit not if != defined // C11 reference manual Section 6.5.16 (page 101): "An assignment expression has the value of the left operand after the // assignment, but is not an lvalue." Hence, return a value not a reference. static inline { forall( T | { T ?+=?( T &, one_t ); } ) T ++?( T & x ) { return x += 1; } forall( T | { T ?+=?( T &, one_t ); } ) T ?++( T & x ) { T tmp = x; x += 1; return tmp; } forall( T | { T ?-=?( T &, one_t ); } ) T --?( T & x ) { return x -= 1; } forall( T | { T ?-=?( T &, one_t ); } ) T ?--( T & x ) { T tmp = x; x -= 1; return tmp; } forall( T | { int ?!=?( T, zero_t ); } ) int !?( T & x ) { return !( x != 0 ); } } // distribution // universal typed pointer constant static inline forall( DT & ) DT * intptr( uintptr_t addr ) { return (DT *)addr; } static inline forall( ftype FT ) FT * intptr( uintptr_t addr ) { return (FT *)addr; } #if defined(__SIZEOF_INT128__) // constructor for 128-bit numbers (all constants are unsigned as +/- are operators) static inline void ?{}( unsigned int128 & this, unsigned long int h, unsigned long int l ) { this = (unsigned int128)h << 64 | (unsigned int128)l; } // ?{} #endif // __SIZEOF_INT128__ // for-control index constraints // forall( T | { void ?{}( T &, zero_t ); void ?{}( T &, one_t ); T ?+=?( T &, T ); T ?-=?( T &, T ); int ? fromInstance( upper ) ) abort( "call to fromInt has index %d outside of enumeration range %d-%d.", i, fromInstance( lower ), fromInstance( upper ) ); return fromInt_unsafe( i ); } E succ( E e ) { E upper = upperBound(); if ( fromInstance( e ) >= fromInstance( upper ) ) abort( "call to succ() exceeds enumeration upper bound of %d.", fromInstance( upper ) ); return succ_unsafe( e ); } E pred( E e ) { E lower = lowerBound(); if ( fromInstance( e ) <= fromInstance( lower ) ) abort( "call to pred() exceeds enumeration lower bound of %d.", fromInstance( lower ) ); return pred_unsafe( e ); } int Countof( E ) { E upper = upperBound(); E lower = lowerBound(); return fromInstance( upper ) + fromInstance( lower ) + 1; } } } static inline forall( E | CfaEnum( E ) | Serial( E ) ) { int ?==?( E l, E r ) { return posn( l ) == posn( r ); } // relational operators int ?!=?( E l, E r ) { return posn( l ) != posn( r ); } int ??( E l, E r ) { return posn( l ) > posn( r ); } int ?>=?( E l, E r ) { return posn( l ) >= posn( r ); } E ++?( E & l ) { // increment operators int pos = posn( l ); l = fromInt_unsafe( pos + 1 ); return l; } E --?( E & l ) { int pos = posn( l ); l = fromInt_unsafe( pos - 1 ); return l; } E ?+=? ( E & l, one_t ) { int pos = posn( l ); l = fromInt_unsafe( pos + 1 ); return l; } E ?-=? ( E & l, one_t ) { int pos = posn( l ); l = fromInt_unsafe( pos - 1 ); return l; } E ?+=? ( E & l, int i ) { int pos = posn( l ); l = fromInt_unsafe( pos + i ); return l; } E ?-=? ( E & l, int i ) { int pos = posn( l ); l = fromInt_unsafe( pos - i ); return l; } E ?++( E & l ) { int pos = posn( l ); l = fromInt_unsafe( pos + 1 ); return fromInt_unsafe( pos ); } E ?--( E & l ) { int pos = posn( l ); l = fromInt_unsafe( pos - 1 ); return fromInt_unsafe( pos ); } } // Local Variables: // // mode: c // // tab-width: 4 // // End: //