162306a36Sopenharmony_ci 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci=============================================================================== 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciThis C source fragment is part of the SoftFloat IEC/IEEE Floating-point 662306a36Sopenharmony_ciArithmetic Package, Release 2. 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciWritten by John R. Hauser. This work was made possible in part by the 962306a36Sopenharmony_ciInternational Computer Science Institute, located at Suite 600, 1947 Center 1062306a36Sopenharmony_ciStreet, Berkeley, California 94704. Funding was partially provided by the 1162306a36Sopenharmony_ciNational Science Foundation under grant MIP-9311980. The original version 1262306a36Sopenharmony_ciof this code was written as part of a project to build a fixed-point vector 1362306a36Sopenharmony_ciprocessor in collaboration with the University of California at Berkeley, 1462306a36Sopenharmony_cioverseen by Profs. Nelson Morgan and John Wawrzynek. More information 1562306a36Sopenharmony_ciis available through the Web page 1662306a36Sopenharmony_cihttp://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ciTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 1962306a36Sopenharmony_cihas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 2062306a36Sopenharmony_ciTIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 2162306a36Sopenharmony_ciPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY 2262306a36Sopenharmony_ciAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ciDerivative works are acceptable, even for commercial purposes, so long as 2562306a36Sopenharmony_ci(1) they include prominent notice that the work is derivative, and (2) they 2662306a36Sopenharmony_ciinclude prominent notice akin to these three paragraphs for those parts of 2762306a36Sopenharmony_cithis code that are retained. 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci=============================================================================== 3062306a36Sopenharmony_ci*/ 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* 3362306a36Sopenharmony_ci------------------------------------------------------------------------------- 3462306a36Sopenharmony_ciUnderflow tininess-detection mode, statically initialized to default value. 3562306a36Sopenharmony_ci(The declaration in `softfloat.h' must match the `int8' type here.) 3662306a36Sopenharmony_ci------------------------------------------------------------------------------- 3762306a36Sopenharmony_ci*/ 3862306a36Sopenharmony_ciint8 float_detect_tininess = float_tininess_after_rounding; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* 4162306a36Sopenharmony_ci------------------------------------------------------------------------------- 4262306a36Sopenharmony_ciRaises the exceptions specified by `flags'. Floating-point traps can be 4362306a36Sopenharmony_cidefined here if desired. It is currently not possible for such a trap to 4462306a36Sopenharmony_cisubstitute a result value. If traps are not implemented, this routine 4562306a36Sopenharmony_cishould be simply `float_exception_flags |= flags;'. 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ciScottB: November 4, 1998 4862306a36Sopenharmony_ciMoved this function out of softfloat-specialize into fpmodule.c. 4962306a36Sopenharmony_ciThis effectively isolates all the changes required for integrating with the 5062306a36Sopenharmony_ciLinux kernel into fpmodule.c. Porting to NetBSD should only require modifying 5162306a36Sopenharmony_cifpmodule.c to integrate with the NetBSD kernel (I hope!). 5262306a36Sopenharmony_ci------------------------------------------------------------------------------- 5362306a36Sopenharmony_civoid float_raise( int8 flags ) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci float_exception_flags |= flags; 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci*/ 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* 6062306a36Sopenharmony_ci------------------------------------------------------------------------------- 6162306a36Sopenharmony_ciInternal canonical NaN format. 6262306a36Sopenharmony_ci------------------------------------------------------------------------------- 6362306a36Sopenharmony_ci*/ 6462306a36Sopenharmony_citypedef struct { 6562306a36Sopenharmony_ci flag sign; 6662306a36Sopenharmony_ci bits64 high, low; 6762306a36Sopenharmony_ci} commonNaNT; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* 7062306a36Sopenharmony_ci------------------------------------------------------------------------------- 7162306a36Sopenharmony_ciThe pattern for a default generated single-precision NaN. 7262306a36Sopenharmony_ci------------------------------------------------------------------------------- 7362306a36Sopenharmony_ci*/ 7462306a36Sopenharmony_ci#define float32_default_nan 0xFFFFFFFF 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* 7762306a36Sopenharmony_ci------------------------------------------------------------------------------- 7862306a36Sopenharmony_ciReturns 1 if the single-precision floating-point value `a' is a NaN; 7962306a36Sopenharmony_ciotherwise returns 0. 8062306a36Sopenharmony_ci------------------------------------------------------------------------------- 8162306a36Sopenharmony_ci*/ 8262306a36Sopenharmony_ciflag float32_is_nan( float32 a ) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci return ( 0xFF000000 < (bits32) ( a<<1 ) ); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/* 9062306a36Sopenharmony_ci------------------------------------------------------------------------------- 9162306a36Sopenharmony_ciReturns 1 if the single-precision floating-point value `a' is a signaling 9262306a36Sopenharmony_ciNaN; otherwise returns 0. 9362306a36Sopenharmony_ci------------------------------------------------------------------------------- 9462306a36Sopenharmony_ci*/ 9562306a36Sopenharmony_ciflag float32_is_signaling_nan( float32 a ) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci} 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/* 10362306a36Sopenharmony_ci------------------------------------------------------------------------------- 10462306a36Sopenharmony_ciReturns the result of converting the single-precision floating-point NaN 10562306a36Sopenharmony_ci`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 10662306a36Sopenharmony_ciexception is raised. 10762306a36Sopenharmony_ci------------------------------------------------------------------------------- 10862306a36Sopenharmony_ci*/ 10962306a36Sopenharmony_cistatic commonNaNT float32ToCommonNaN( float32 a ) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci commonNaNT z; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 11462306a36Sopenharmony_ci z.sign = a>>31; 11562306a36Sopenharmony_ci z.low = 0; 11662306a36Sopenharmony_ci z.high = ( (bits64) a )<<41; 11762306a36Sopenharmony_ci return z; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/* 12262306a36Sopenharmony_ci------------------------------------------------------------------------------- 12362306a36Sopenharmony_ciReturns the result of converting the canonical NaN `a' to the single- 12462306a36Sopenharmony_ciprecision floating-point format. 12562306a36Sopenharmony_ci------------------------------------------------------------------------------- 12662306a36Sopenharmony_ci*/ 12762306a36Sopenharmony_cistatic float32 commonNaNToFloat32( commonNaNT a ) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/* 13562306a36Sopenharmony_ci------------------------------------------------------------------------------- 13662306a36Sopenharmony_ciTakes two single-precision floating-point values `a' and `b', one of which 13762306a36Sopenharmony_ciis a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 13862306a36Sopenharmony_cisignaling NaN, the invalid exception is raised. 13962306a36Sopenharmony_ci------------------------------------------------------------------------------- 14062306a36Sopenharmony_ci*/ 14162306a36Sopenharmony_cistatic float32 propagateFloat32NaN( float32 a, float32 b ) 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci aIsNaN = float32_is_nan( a ); 14662306a36Sopenharmony_ci aIsSignalingNaN = float32_is_signaling_nan( a ); 14762306a36Sopenharmony_ci bIsNaN = float32_is_nan( b ); 14862306a36Sopenharmony_ci bIsSignalingNaN = float32_is_signaling_nan( b ); 14962306a36Sopenharmony_ci a |= 0x00400000; 15062306a36Sopenharmony_ci b |= 0x00400000; 15162306a36Sopenharmony_ci if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 15262306a36Sopenharmony_ci if ( aIsNaN ) { 15362306a36Sopenharmony_ci return ( aIsSignalingNaN & bIsNaN ) ? b : a; 15462306a36Sopenharmony_ci } 15562306a36Sopenharmony_ci else { 15662306a36Sopenharmony_ci return b; 15762306a36Sopenharmony_ci } 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* 16262306a36Sopenharmony_ci------------------------------------------------------------------------------- 16362306a36Sopenharmony_ciThe pattern for a default generated double-precision NaN. 16462306a36Sopenharmony_ci------------------------------------------------------------------------------- 16562306a36Sopenharmony_ci*/ 16662306a36Sopenharmony_ci#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci/* 16962306a36Sopenharmony_ci------------------------------------------------------------------------------- 17062306a36Sopenharmony_ciReturns 1 if the double-precision floating-point value `a' is a NaN; 17162306a36Sopenharmony_ciotherwise returns 0. 17262306a36Sopenharmony_ci------------------------------------------------------------------------------- 17362306a36Sopenharmony_ci*/ 17462306a36Sopenharmony_ciflag float64_is_nan( float64 a ) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci/* 18262306a36Sopenharmony_ci------------------------------------------------------------------------------- 18362306a36Sopenharmony_ciReturns 1 if the double-precision floating-point value `a' is a signaling 18462306a36Sopenharmony_ciNaN; otherwise returns 0. 18562306a36Sopenharmony_ci------------------------------------------------------------------------------- 18662306a36Sopenharmony_ci*/ 18762306a36Sopenharmony_ciflag float64_is_signaling_nan( float64 a ) 18862306a36Sopenharmony_ci{ 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci return 19162306a36Sopenharmony_ci ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 19262306a36Sopenharmony_ci && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci} 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci/* 19762306a36Sopenharmony_ci------------------------------------------------------------------------------- 19862306a36Sopenharmony_ciReturns the result of converting the double-precision floating-point NaN 19962306a36Sopenharmony_ci`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 20062306a36Sopenharmony_ciexception is raised. 20162306a36Sopenharmony_ci------------------------------------------------------------------------------- 20262306a36Sopenharmony_ci*/ 20362306a36Sopenharmony_cistatic commonNaNT float64ToCommonNaN( float64 a ) 20462306a36Sopenharmony_ci{ 20562306a36Sopenharmony_ci commonNaNT z; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 20862306a36Sopenharmony_ci z.sign = a>>63; 20962306a36Sopenharmony_ci z.low = 0; 21062306a36Sopenharmony_ci z.high = a<<12; 21162306a36Sopenharmony_ci return z; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci/* 21662306a36Sopenharmony_ci------------------------------------------------------------------------------- 21762306a36Sopenharmony_ciReturns the result of converting the canonical NaN `a' to the double- 21862306a36Sopenharmony_ciprecision floating-point format. 21962306a36Sopenharmony_ci------------------------------------------------------------------------------- 22062306a36Sopenharmony_ci*/ 22162306a36Sopenharmony_cistatic float64 commonNaNToFloat64( commonNaNT a ) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci return 22562306a36Sopenharmony_ci ( ( (bits64) a.sign )<<63 ) 22662306a36Sopenharmony_ci | LIT64( 0x7FF8000000000000 ) 22762306a36Sopenharmony_ci | ( a.high>>12 ); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci/* 23262306a36Sopenharmony_ci------------------------------------------------------------------------------- 23362306a36Sopenharmony_ciTakes two double-precision floating-point values `a' and `b', one of which 23462306a36Sopenharmony_ciis a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 23562306a36Sopenharmony_cisignaling NaN, the invalid exception is raised. 23662306a36Sopenharmony_ci------------------------------------------------------------------------------- 23762306a36Sopenharmony_ci*/ 23862306a36Sopenharmony_cistatic float64 propagateFloat64NaN( float64 a, float64 b ) 23962306a36Sopenharmony_ci{ 24062306a36Sopenharmony_ci flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci aIsNaN = float64_is_nan( a ); 24362306a36Sopenharmony_ci aIsSignalingNaN = float64_is_signaling_nan( a ); 24462306a36Sopenharmony_ci bIsNaN = float64_is_nan( b ); 24562306a36Sopenharmony_ci bIsSignalingNaN = float64_is_signaling_nan( b ); 24662306a36Sopenharmony_ci a |= LIT64( 0x0008000000000000 ); 24762306a36Sopenharmony_ci b |= LIT64( 0x0008000000000000 ); 24862306a36Sopenharmony_ci if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 24962306a36Sopenharmony_ci if ( aIsNaN ) { 25062306a36Sopenharmony_ci return ( aIsSignalingNaN & bIsNaN ) ? b : a; 25162306a36Sopenharmony_ci } 25262306a36Sopenharmony_ci else { 25362306a36Sopenharmony_ci return b; 25462306a36Sopenharmony_ci } 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci} 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci#ifdef FLOATX80 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci/* 26162306a36Sopenharmony_ci------------------------------------------------------------------------------- 26262306a36Sopenharmony_ciThe pattern for a default generated extended double-precision NaN. The 26362306a36Sopenharmony_ci`high' and `low' values hold the most- and least-significant bits, 26462306a36Sopenharmony_cirespectively. 26562306a36Sopenharmony_ci------------------------------------------------------------------------------- 26662306a36Sopenharmony_ci*/ 26762306a36Sopenharmony_ci#define floatx80_default_nan_high 0xFFFF 26862306a36Sopenharmony_ci#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci/* 27162306a36Sopenharmony_ci------------------------------------------------------------------------------- 27262306a36Sopenharmony_ciReturns 1 if the extended double-precision floating-point value `a' is a 27362306a36Sopenharmony_ciNaN; otherwise returns 0. 27462306a36Sopenharmony_ci------------------------------------------------------------------------------- 27562306a36Sopenharmony_ci*/ 27662306a36Sopenharmony_ciflag floatx80_is_nan( floatx80 a ) 27762306a36Sopenharmony_ci{ 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci/* 28462306a36Sopenharmony_ci------------------------------------------------------------------------------- 28562306a36Sopenharmony_ciReturns 1 if the extended double-precision floating-point value `a' is a 28662306a36Sopenharmony_cisignaling NaN; otherwise returns 0. 28762306a36Sopenharmony_ci------------------------------------------------------------------------------- 28862306a36Sopenharmony_ci*/ 28962306a36Sopenharmony_ciflag floatx80_is_signaling_nan( floatx80 a ) 29062306a36Sopenharmony_ci{ 29162306a36Sopenharmony_ci //register int lr; 29262306a36Sopenharmony_ci bits64 aLow; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci //__asm__("mov %0, lr" : : "g" (lr)); 29562306a36Sopenharmony_ci //fp_printk("floatx80_is_signalling_nan() called from 0x%08x\n",lr); 29662306a36Sopenharmony_ci aLow = a.low & ~ LIT64( 0x4000000000000000 ); 29762306a36Sopenharmony_ci return 29862306a36Sopenharmony_ci ( ( a.high & 0x7FFF ) == 0x7FFF ) 29962306a36Sopenharmony_ci && (bits64) ( aLow<<1 ) 30062306a36Sopenharmony_ci && ( a.low == aLow ); 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci/* 30562306a36Sopenharmony_ci------------------------------------------------------------------------------- 30662306a36Sopenharmony_ciReturns the result of converting the extended double-precision floating- 30762306a36Sopenharmony_cipoint NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 30862306a36Sopenharmony_ciinvalid exception is raised. 30962306a36Sopenharmony_ci------------------------------------------------------------------------------- 31062306a36Sopenharmony_ci*/ 31162306a36Sopenharmony_cistatic commonNaNT floatx80ToCommonNaN( floatx80 a ) 31262306a36Sopenharmony_ci{ 31362306a36Sopenharmony_ci commonNaNT z; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 31662306a36Sopenharmony_ci z.sign = a.high>>15; 31762306a36Sopenharmony_ci z.low = 0; 31862306a36Sopenharmony_ci z.high = a.low<<1; 31962306a36Sopenharmony_ci return z; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci/* 32462306a36Sopenharmony_ci------------------------------------------------------------------------------- 32562306a36Sopenharmony_ciReturns the result of converting the canonical NaN `a' to the extended 32662306a36Sopenharmony_cidouble-precision floating-point format. 32762306a36Sopenharmony_ci------------------------------------------------------------------------------- 32862306a36Sopenharmony_ci*/ 32962306a36Sopenharmony_cistatic floatx80 commonNaNToFloatx80( commonNaNT a ) 33062306a36Sopenharmony_ci{ 33162306a36Sopenharmony_ci floatx80 z; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); 33462306a36Sopenharmony_ci z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 33562306a36Sopenharmony_ci z.__padding = 0; 33662306a36Sopenharmony_ci return z; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci} 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci/* 34162306a36Sopenharmony_ci------------------------------------------------------------------------------- 34262306a36Sopenharmony_ciTakes two extended double-precision floating-point values `a' and `b', one 34362306a36Sopenharmony_ciof which is a NaN, and returns the appropriate NaN result. If either `a' or 34462306a36Sopenharmony_ci`b' is a signaling NaN, the invalid exception is raised. 34562306a36Sopenharmony_ci------------------------------------------------------------------------------- 34662306a36Sopenharmony_ci*/ 34762306a36Sopenharmony_cistatic floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) 34862306a36Sopenharmony_ci{ 34962306a36Sopenharmony_ci flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci aIsNaN = floatx80_is_nan( a ); 35262306a36Sopenharmony_ci aIsSignalingNaN = floatx80_is_signaling_nan( a ); 35362306a36Sopenharmony_ci bIsNaN = floatx80_is_nan( b ); 35462306a36Sopenharmony_ci bIsSignalingNaN = floatx80_is_signaling_nan( b ); 35562306a36Sopenharmony_ci a.low |= LIT64( 0xC000000000000000 ); 35662306a36Sopenharmony_ci b.low |= LIT64( 0xC000000000000000 ); 35762306a36Sopenharmony_ci if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 35862306a36Sopenharmony_ci if ( aIsNaN ) { 35962306a36Sopenharmony_ci return ( aIsSignalingNaN & bIsNaN ) ? b : a; 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci else { 36262306a36Sopenharmony_ci return b; 36362306a36Sopenharmony_ci } 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci} 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci#endif 368