applies clang-format changes

This commit is contained in:
Eyck Jentzsch 2023-10-29 17:06:56 +01:00
parent 2115e9ceae
commit 759061b569
51 changed files with 11493 additions and 12673 deletions

View File

@ -1,4 +1,3 @@
---
Language: Cpp Language: Cpp
# BasedOnStyle: LLVM # BasedOnStyle: LLVM
# should be in line with IndentWidth # should be in line with IndentWidth
@ -13,8 +12,8 @@ AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: true AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false AlwaysBreakBeforeMultilineStrings: false
@ -39,8 +38,8 @@ BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true BreakConstructorInitializersBeforeComma: true
BreakAfterJavaFieldAnnotations: false BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true BreakStringLiterals: true
ColumnLimit: 120 ColumnLimit: 140
CommentPragmas: '^ IWYU pragma:' CommentPragmas: '^( IWYU pragma:| @suppress)'
ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 0 ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 4 ContinuationIndentWidth: 4
@ -76,13 +75,13 @@ PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000 PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000 PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60 PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right PointerAlignment: Left
ReflowComments: true ReflowComments: true
SortIncludes: true SortIncludes: true
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements SpaceBeforeParens: Never
SpaceInEmptyParentheses: false SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1 SpacesBeforeTrailingComments: 1
SpacesInAngles: false SpacesInAngles: false

View File

@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/ =============================================================================*/
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define LITTLEENDIAN 1 #define LITTLEENDIAN 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef __GNUC_STDC_INLINE__ #ifdef __GNUC_STDC_INLINE__
#define INLINE inline #define INLINE inline
#else #else
@ -47,7 +47,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define SOFTFLOAT_BUILTIN_CLZ 1 #define SOFTFLOAT_BUILTIN_CLZ 1
#include "opts-GCC.h" #include "opts-GCC.h"

View File

@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/ =============================================================================*/
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define LITTLEENDIAN 1 #define LITTLEENDIAN 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef __GNUC_STDC_INLINE__ #ifdef __GNUC_STDC_INLINE__
#define INLINE inline #define INLINE inline
#else #else
@ -47,7 +47,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define SOFTFLOAT_BUILTIN_CLZ 1 #define SOFTFLOAT_BUILTIN_CLZ 1
#include "opts-GCC.h" #include "opts-GCC.h"

View File

@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/ =============================================================================*/
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define LITTLEENDIAN 1 #define LITTLEENDIAN 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef __GNUC_STDC_INLINE__ #ifdef __GNUC_STDC_INLINE__
#define INLINE inline #define INLINE inline
#else #else
@ -47,7 +47,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define SOFTFLOAT_BUILTIN_CLZ 1 #define SOFTFLOAT_BUILTIN_CLZ 1
#include "opts-GCC.h" #include "opts-GCC.h"

View File

@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/ =============================================================================*/
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define LITTLEENDIAN 1 #define LITTLEENDIAN 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef __GNUC_STDC_INLINE__ #ifdef __GNUC_STDC_INLINE__
//#define INLINE inline //#define INLINE inline
#define INLINE static #define INLINE static
@ -48,10 +48,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef __GNUC__ #ifdef __GNUC__
#define SOFTFLOAT_BUILTIN_CLZ 1 #define SOFTFLOAT_BUILTIN_CLZ 1
#define SOFTFLOAT_INTRINSIC_INT128 1 #define SOFTFLOAT_INTRINSIC_INT128 1
#endif #endif
#include "opts-GCC.h" #include "opts-GCC.h"

View File

@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/ =============================================================================*/
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define LITTLEENDIAN 1 #define LITTLEENDIAN 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef __GNUC_STDC_INLINE__ #ifdef __GNUC_STDC_INLINE__
#define INLINE inline #define INLINE inline
#else #else
@ -47,7 +47,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define SOFTFLOAT_BUILTIN_CLZ 1 #define SOFTFLOAT_BUILTIN_CLZ 1
#include "opts-GCC.h" #include "opts-GCC.h"

View File

@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/ =============================================================================*/
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define LITTLEENDIAN 1 #define LITTLEENDIAN 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef __GNUC_STDC_INLINE__ #ifdef __GNUC_STDC_INLINE__
#define INLINE inline #define INLINE inline
#else #else
@ -47,7 +47,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define SOFTFLOAT_BUILTIN_CLZ 1 #define SOFTFLOAT_BUILTIN_CLZ 1
#include "opts-GCC.h" #include "opts-GCC.h"

View File

@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/ =============================================================================*/
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define LITTLEENDIAN 1 #define LITTLEENDIAN 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef __GNUC_STDC_INLINE__ #ifdef __GNUC_STDC_INLINE__
#define INLINE inline #define INLINE inline
#else #else
@ -47,8 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define SOFTFLOAT_BUILTIN_CLZ 1 #define SOFTFLOAT_BUILTIN_CLZ 1
#define SOFTFLOAT_INTRINSIC_INT128 1 #define SOFTFLOAT_INTRINSIC_INT128 1
#include "opts-GCC.h" #include "opts-GCC.h"

View File

@ -37,14 +37,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Edit lines marked with `==>'. See "SoftFloat-source.html". // Edit lines marked with `==>'. See "SoftFloat-source.html".
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
==> #define LITTLEENDIAN 1 == > #define LITTLEENDIAN 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
==> #define INLINE inline == > #define INLINE inline
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
==> #define THREAD_LOCAL _Thread_local
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
== > #define THREAD_LOCAL _Thread_local

View File

@ -37,14 +37,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Edit lines marked with `==>'. See "SoftFloat-source.html". // Edit lines marked with `==>'. See "SoftFloat-source.html".
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
==> #define LITTLEENDIAN 1 == > #define LITTLEENDIAN 1
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
==> #define INLINE inline == > #define INLINE inline
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
==> #define THREAD_LOCAL _Thread_local
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
== > #define THREAD_LOCAL _Thread_local

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h #ifndef specialize_h
#define specialize_h 1 #define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h" #include "primitiveTypes.h"
#include "softfloat.h" #include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Default value for 'softfloat_detectTininess'. | Default value for 'softfloat_detectTininess'.
@ -53,21 +53,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui32_fromPosOverflow 0xFFFFFFFF #define ui32_fromPosOverflow 0xFFFFFFFF
#define ui32_fromNegOverflow 0xFFFFFFFF #define ui32_fromNegOverflow 0xFFFFFFFF
#define ui32_fromNaN 0xFFFFFFFF #define ui32_fromNaN 0xFFFFFFFF
#define i32_fromPosOverflow (-0x7FFFFFFF - 1) #define i32_fromPosOverflow (-0x7FFFFFFF - 1)
#define i32_fromNegOverflow (-0x7FFFFFFF - 1) #define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN (-0x7FFFFFFF - 1) #define i32_fromNaN (-0x7FFFFFFF - 1)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an | The values to return on conversions to 64-bit integer formats that raise an
| invalid exception. | invalid exception.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) #define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) #define ui64_fromNegOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF ) #define ui64_fromNaN UINT64_C(0xFFFFFFFFFFFFFFFF)
#define i64_fromPosOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) #define i64_fromPosOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) #define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) #define i64_fromNaN (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format | "Common NaN" structure, used to transfer NaN representations from one format
@ -92,7 +92,7 @@ struct commonNaN {
| 16-bit floating-point signaling NaN. | 16-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) #define softfloat_isSigNaNF16UI(uiA) ((((uiA)&0x7E00) == 0x7C00) && ((uiA)&0x01FF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts
@ -100,13 +100,13 @@ struct commonNaN {
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ); void softfloat_f16UIToCommonNaN(uint_fast16_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ); uint_fast16_t softfloat_commonNaNToF16UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating-
@ -114,8 +114,7 @@ uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast16_t uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 32-bit floating-point NaN. | The bit pattern for a default generated 32-bit floating-point NaN.
@ -127,7 +126,7 @@ uint_fast16_t
| 32-bit floating-point signaling NaN. | 32-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) #define softfloat_isSigNaNF32UI(uiA) ((((uiA)&0x7FC00000) == 0x7F800000) && ((uiA)&0x003FFFFF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts
@ -135,13 +134,13 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ); void softfloat_f32UIToCommonNaN(uint_fast32_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ); uint_fast32_t softfloat_commonNaNToF32UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating-
@ -149,20 +148,20 @@ uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 64-bit floating-point NaN. | The bit pattern for a default generated 64-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF64UI UINT64_C( 0xFFF8000000000000 ) #define defaultNaNF64UI UINT64_C(0xFFF8000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a | Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a
| 64-bit floating-point signaling NaN. | 64-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) #define softfloat_isSigNaNF64UI(uiA) \
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
@ -170,13 +169,13 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ); void softfloat_f64UIToCommonNaN(uint_fast64_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ); uint_fast64_t softfloat_commonNaNToF64UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating-
@ -184,14 +183,13 @@ uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast64_t uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN. | The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0xFFFF #define defaultNaNExtF80UI64 0xFFFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) #define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating | Returns true when the 80-bit unsigned integer formed from concatenating
@ -199,7 +197,8 @@ uint_fast64_t
| floating-point signaling NaN. | floating-point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) #define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
@ -215,16 +214,14 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_extF80UIToCommonNaN(uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
softfloat_extF80UIToCommonNaN(
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and returns the bit pattern of this value as an unsigned | floating-point NaN, and returns the bit pattern of this value as an unsigned
| integer. | integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting the unsigned integer formed from concatenating 'uiA64' and | Interpreting the unsigned integer formed from concatenating 'uiA64' and
@ -235,19 +232,13 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
| result. If either original floating-point value is a signaling NaN, the | result. If either original floating-point value is a signaling NaN, the
| invalid exception is raised. | invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0xFFFF800000000000 ) #define defaultNaNF128UI64 UINT64_C(0xFFFF800000000000)
#define defaultNaNF128UI0 UINT64_C( 0 ) #define defaultNaNF128UI0 UINT64_C(0)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating | Returns true when the 128-bit unsigned integer formed from concatenating
@ -255,7 +246,8 @@ struct uint128
| point signaling NaN. | point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) #define softfloat_isSigNaNF128UI(uiA64, uiA0) \
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' | Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
@ -264,15 +256,13 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception | pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| is raised. | is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_f128UIToCommonNaN(uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
softfloat_f128UIToCommonNaN(
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN*);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting the unsigned integer formed from concatenating 'uiA64' and | Interpreting the unsigned integer formed from concatenating 'uiA64' and
@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid | If either original floating-point value is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
#else #else
@ -304,18 +288,14 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling | common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| NaN, the invalid exception is raised. | NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
softfloat_extF80MToCommonNaN(
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and stores this NaN at the location pointed to by | floating-point NaN, and stores this NaN at the location pointed to by
| 'zSPtr'. | 'zSPtr'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming at least one of the two 80-bit extended floating-point values | Assuming at least one of the two 80-bit extended floating-point values
@ -323,12 +303,7 @@ void
| at the location pointed to by 'zSPtr'. If either original floating-point | at the location pointed to by 'zSPtr'. If either original floating-point
| value is a signaling NaN, the invalid exception is raised. | value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
@ -336,7 +311,7 @@ void
#define defaultNaNF128UI96 0xFFFF8000 #define defaultNaNF128UI96 0xFFFF8000
#define defaultNaNF128UI64 0 #define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0 #define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0 #define defaultNaNF128UI0 0
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, | Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN,
@ -346,8 +321,7 @@ void
| four 32-bit elements that concatenate in the platform's normal endian order | four 32-bit elements that concatenate in the platform's normal endian order
| to form a 128-bit floating-point value. | to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
@ -355,8 +329,7 @@ void
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the | 'zWPtr' points to an array of four 32-bit elements that concatenate in the
| platform's normal endian order to form a 128-bit floating-point value. | platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming at least one of the two 128-bit floating-point values pointed to by | Assuming at least one of the two 128-bit floating-point values pointed to by
@ -366,11 +339,8 @@ void
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in | and 'zWPtr' points to an array of four 32-bit elements that concatenate in
| the platform's normal endian order to form a 128-bit floating-point value. | the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
#endif #endif
#endif #endif

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h #ifndef specialize_h
#define specialize_h 1 #define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h" #include "primitiveTypes.h"
#include "softfloat.h" #include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Default value for 'softfloat_detectTininess'. | Default value for 'softfloat_detectTininess'.
@ -53,21 +53,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui32_fromPosOverflow 0xFFFFFFFF #define ui32_fromPosOverflow 0xFFFFFFFF
#define ui32_fromNegOverflow 0xFFFFFFFF #define ui32_fromNegOverflow 0xFFFFFFFF
#define ui32_fromNaN 0xFFFFFFFF #define ui32_fromNaN 0xFFFFFFFF
#define i32_fromPosOverflow (-0x7FFFFFFF - 1) #define i32_fromPosOverflow (-0x7FFFFFFF - 1)
#define i32_fromNegOverflow (-0x7FFFFFFF - 1) #define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN (-0x7FFFFFFF - 1) #define i32_fromNaN (-0x7FFFFFFF - 1)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an | The values to return on conversions to 64-bit integer formats that raise an
| invalid exception. | invalid exception.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) #define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) #define ui64_fromNegOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF ) #define ui64_fromNaN UINT64_C(0xFFFFFFFFFFFFFFFF)
#define i64_fromPosOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) #define i64_fromPosOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) #define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) #define i64_fromNaN (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format | "Common NaN" structure, used to transfer NaN representations from one format
@ -92,7 +92,7 @@ struct commonNaN {
| 16-bit floating-point signaling NaN. | 16-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) #define softfloat_isSigNaNF16UI(uiA) ((((uiA)&0x7E00) == 0x7C00) && ((uiA)&0x01FF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts
@ -100,13 +100,13 @@ struct commonNaN {
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ); void softfloat_f16UIToCommonNaN(uint_fast16_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ); uint_fast16_t softfloat_commonNaNToF16UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating-
@ -114,8 +114,7 @@ uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast16_t uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 32-bit floating-point NaN. | The bit pattern for a default generated 32-bit floating-point NaN.
@ -127,7 +126,7 @@ uint_fast16_t
| 32-bit floating-point signaling NaN. | 32-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) #define softfloat_isSigNaNF32UI(uiA) ((((uiA)&0x7FC00000) == 0x7F800000) && ((uiA)&0x003FFFFF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts
@ -135,13 +134,13 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ); void softfloat_f32UIToCommonNaN(uint_fast32_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ); uint_fast32_t softfloat_commonNaNToF32UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating-
@ -149,20 +148,20 @@ uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 64-bit floating-point NaN. | The bit pattern for a default generated 64-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF64UI UINT64_C( 0xFFF8000000000000 ) #define defaultNaNF64UI UINT64_C(0xFFF8000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a | Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a
| 64-bit floating-point signaling NaN. | 64-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) #define softfloat_isSigNaNF64UI(uiA) \
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
@ -170,13 +169,13 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ); void softfloat_f64UIToCommonNaN(uint_fast64_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ); uint_fast64_t softfloat_commonNaNToF64UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating-
@ -184,14 +183,13 @@ uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast64_t uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN. | The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0xFFFF #define defaultNaNExtF80UI64 0xFFFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) #define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating | Returns true when the 80-bit unsigned integer formed from concatenating
@ -199,7 +197,8 @@ uint_fast64_t
| floating-point signaling NaN. | floating-point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) #define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
@ -215,16 +214,14 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_extF80UIToCommonNaN(uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
softfloat_extF80UIToCommonNaN(
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and returns the bit pattern of this value as an unsigned | floating-point NaN, and returns the bit pattern of this value as an unsigned
| integer. | integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting the unsigned integer formed from concatenating 'uiA64' and | Interpreting the unsigned integer formed from concatenating 'uiA64' and
@ -235,19 +232,13 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
| result. If either original floating-point value is a signaling NaN, the | result. If either original floating-point value is a signaling NaN, the
| invalid exception is raised. | invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0xFFFF800000000000 ) #define defaultNaNF128UI64 UINT64_C(0xFFFF800000000000)
#define defaultNaNF128UI0 UINT64_C( 0 ) #define defaultNaNF128UI0 UINT64_C(0)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating | Returns true when the 128-bit unsigned integer formed from concatenating
@ -255,7 +246,8 @@ struct uint128
| point signaling NaN. | point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) #define softfloat_isSigNaNF128UI(uiA64, uiA0) \
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' | Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
@ -264,15 +256,13 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception | pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| is raised. | is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_f128UIToCommonNaN(uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
softfloat_f128UIToCommonNaN(
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN*);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting the unsigned integer formed from concatenating 'uiA64' and | Interpreting the unsigned integer formed from concatenating 'uiA64' and
@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid | If either original floating-point value is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
#else #else
@ -304,18 +288,14 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling | common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| NaN, the invalid exception is raised. | NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
softfloat_extF80MToCommonNaN(
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and stores this NaN at the location pointed to by | floating-point NaN, and stores this NaN at the location pointed to by
| 'zSPtr'. | 'zSPtr'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming at least one of the two 80-bit extended floating-point values | Assuming at least one of the two 80-bit extended floating-point values
@ -323,12 +303,7 @@ void
| at the location pointed to by 'zSPtr'. If either original floating-point | at the location pointed to by 'zSPtr'. If either original floating-point
| value is a signaling NaN, the invalid exception is raised. | value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
@ -336,7 +311,7 @@ void
#define defaultNaNF128UI96 0xFFFF8000 #define defaultNaNF128UI96 0xFFFF8000
#define defaultNaNF128UI64 0 #define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0 #define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0 #define defaultNaNF128UI0 0
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, | Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN,
@ -346,8 +321,7 @@ void
| four 32-bit elements that concatenate in the platform's normal endian order | four 32-bit elements that concatenate in the platform's normal endian order
| to form a 128-bit floating-point value. | to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
@ -355,8 +329,7 @@ void
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the | 'zWPtr' points to an array of four 32-bit elements that concatenate in the
| platform's normal endian order to form a 128-bit floating-point value. | platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming at least one of the two 128-bit floating-point values pointed to by | Assuming at least one of the two 128-bit floating-point values pointed to by
@ -366,11 +339,8 @@ void
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in | and 'zWPtr' points to an array of four 32-bit elements that concatenate in
| the platform's normal endian order to form a 128-bit floating-point value. | the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
#endif #endif
#endif #endif

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h #ifndef specialize_h
#define specialize_h 1 #define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h" #include "primitiveTypes.h"
#include "softfloat.h" #include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Default value for 'softfloat_detectTininess'. | Default value for 'softfloat_detectTininess'.
@ -53,27 +53,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui32_fromPosOverflow 0xFFFFFFFF #define ui32_fromPosOverflow 0xFFFFFFFF
#define ui32_fromNegOverflow 0 #define ui32_fromNegOverflow 0
#define ui32_fromNaN 0 #define ui32_fromNaN 0
#define i32_fromPosOverflow 0x7FFFFFFF #define i32_fromPosOverflow 0x7FFFFFFF
#define i32_fromNegOverflow (-0x7FFFFFFF - 1) #define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN 0 #define i32_fromNaN 0
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an | The values to return on conversions to 64-bit integer formats that raise an
| invalid exception. | invalid exception.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) #define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow 0 #define ui64_fromNegOverflow 0
#define ui64_fromNaN 0 #define ui64_fromNaN 0
#define i64_fromPosOverflow INT64_C( 0x7FFFFFFFFFFFFFFF ) #define i64_fromPosOverflow INT64_C(0x7FFFFFFFFFFFFFFF)
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) #define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN 0 #define i64_fromNaN 0
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format | "Common NaN" structure, used to transfer NaN representations from one format
| to another. | to another.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct commonNaN { char _unused; }; struct commonNaN {
char _unused;
};
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 16-bit floating-point NaN. | The bit pattern for a default generated 16-bit floating-point NaN.
@ -85,7 +87,7 @@ struct commonNaN { char _unused; };
| 16-bit floating-point signaling NaN. | 16-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) #define softfloat_isSigNaNF16UI(uiA) ((((uiA)&0x7E00) == 0x7C00) && ((uiA)&0x01FF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts
@ -93,13 +95,15 @@ struct commonNaN { char _unused; };
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_f16UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x0200) ) softfloat_raiseFlags( softfloat_flag_invalid ) #define softfloat_f16UIToCommonNaN(uiA, zPtr) \
if(!((uiA)&0x0200)) \
softfloat_raiseFlags(softfloat_flag_invalid)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_commonNaNToF16UI( aPtr ) ((uint_fast16_t) defaultNaNF16UI) #define softfloat_commonNaNToF16UI(aPtr) ((uint_fast16_t)defaultNaNF16UI)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating-
@ -107,8 +111,7 @@ struct commonNaN { char _unused; };
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast16_t uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 32-bit floating-point NaN. | The bit pattern for a default generated 32-bit floating-point NaN.
@ -120,7 +123,7 @@ uint_fast16_t
| 32-bit floating-point signaling NaN. | 32-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) #define softfloat_isSigNaNF32UI(uiA) ((((uiA)&0x7FC00000) == 0x7F800000) && ((uiA)&0x003FFFFF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts
@ -128,13 +131,15 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_f32UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x00400000) ) softfloat_raiseFlags( softfloat_flag_invalid ) #define softfloat_f32UIToCommonNaN(uiA, zPtr) \
if(!((uiA)&0x00400000)) \
softfloat_raiseFlags(softfloat_flag_invalid)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_commonNaNToF32UI( aPtr ) ((uint_fast32_t) defaultNaNF32UI) #define softfloat_commonNaNToF32UI(aPtr) ((uint_fast32_t)defaultNaNF32UI)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating-
@ -142,20 +147,20 @@ uint_fast16_t
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 64-bit floating-point NaN. | The bit pattern for a default generated 64-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 ) #define defaultNaNF64UI UINT64_C(0x7FF8000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a | Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a
| 64-bit floating-point signaling NaN. | 64-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) #define softfloat_isSigNaNF64UI(uiA) \
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
@ -163,13 +168,15 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_f64UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & UINT64_C( 0x0008000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) #define softfloat_f64UIToCommonNaN(uiA, zPtr) \
if(!((uiA)&UINT64_C(0x0008000000000000))) \
softfloat_raiseFlags(softfloat_flag_invalid)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_commonNaNToF64UI( aPtr ) ((uint_fast64_t) defaultNaNF64UI) #define softfloat_commonNaNToF64UI(aPtr) ((uint_fast64_t)defaultNaNF64UI)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating-
@ -177,14 +184,13 @@ uint_fast32_t
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast64_t uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN. | The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0x7FFF #define defaultNaNExtF80UI64 0x7FFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) #define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating | Returns true when the 80-bit unsigned integer formed from concatenating
@ -192,7 +198,8 @@ uint_fast64_t
| floating-point signaling NaN. | floating-point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) #define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
@ -208,24 +215,25 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_extF80UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA0) & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) #define softfloat_extF80UIToCommonNaN(uiA64, uiA0, zPtr) \
if(!((uiA0)&UINT64_C(0x4000000000000000))) \
softfloat_raiseFlags(softfloat_flag_invalid)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and returns the bit pattern of this value as an unsigned | floating-point NaN, and returns the bit pattern of this value as an unsigned
| integer. | integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE && ! defined softfloat_commonNaNToExtF80UI #if defined INLINE && !defined softfloat_commonNaNToExtF80UI
INLINE INLINE
struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr) {
{
struct uint128 uiZ; struct uint128 uiZ;
uiZ.v64 = defaultNaNExtF80UI64; uiZ.v64 = defaultNaNExtF80UI64;
uiZ.v0 = defaultNaNExtF80UI0; uiZ.v0 = defaultNaNExtF80UI0;
return uiZ; return uiZ;
} }
#else #else
struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr);
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -237,19 +245,13 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
| result. If either original floating-point value is a signaling NaN, the | result. If either original floating-point value is a signaling NaN, the
| invalid exception is raised. | invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0x7FFF800000000000 ) #define defaultNaNF128UI64 UINT64_C(0x7FFF800000000000)
#define defaultNaNF128UI0 UINT64_C( 0 ) #define defaultNaNF128UI0 UINT64_C(0)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating | Returns true when the 128-bit unsigned integer formed from concatenating
@ -257,7 +259,8 @@ struct uint128
| point signaling NaN. | point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) #define softfloat_isSigNaNF128UI(uiA64, uiA0) \
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' | Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
@ -266,23 +269,24 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception | pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| is raised. | is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_f128UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA64) & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) #define softfloat_f128UIToCommonNaN(uiA64, uiA0, zPtr) \
if(!((uiA64)&UINT64_C(0x0000800000000000))) \
softfloat_raiseFlags(softfloat_flag_invalid)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE && ! defined softfloat_commonNaNToF128UI #if defined INLINE && !defined softfloat_commonNaNToF128UI
INLINE INLINE
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN* aPtr) {
{
struct uint128 uiZ; struct uint128 uiZ;
uiZ.v64 = defaultNaNF128UI64; uiZ.v64 = defaultNaNF128UI64;
uiZ.v0 = defaultNaNF128UI0; uiZ.v0 = defaultNaNF128UI0;
return uiZ; return uiZ;
} }
#else #else
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN*);
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -294,13 +298,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid | If either original floating-point value is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
#else #else
@ -315,26 +313,23 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling | common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| NaN, the invalid exception is raised. | NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_extF80MToCommonNaN( aSPtr, zPtr ) if ( ! ((aSPtr)->signif & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) #define softfloat_extF80MToCommonNaN(aSPtr, zPtr) \
if(!((aSPtr)->signif & UINT64_C(0x4000000000000000))) \
softfloat_raiseFlags(softfloat_flag_invalid)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and stores this NaN at the location pointed to by | floating-point NaN, and stores this NaN at the location pointed to by
| 'zSPtr'. | 'zSPtr'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE && ! defined softfloat_commonNaNToExtF80M #if defined INLINE && !defined softfloat_commonNaNToExtF80M
INLINE INLINE
void void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr) {
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr )
{
zSPtr->signExp = defaultNaNExtF80UI64; zSPtr->signExp = defaultNaNExtF80UI64;
zSPtr->signif = defaultNaNExtF80UI0; zSPtr->signif = defaultNaNExtF80UI0;
} }
#else #else
void void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -343,12 +338,7 @@ void
| at the location pointed to by 'zSPtr'. If either original floating-point | at the location pointed to by 'zSPtr'. If either original floating-point
| value is a signaling NaN, the invalid exception is raised. | value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
@ -356,7 +346,7 @@ void
#define defaultNaNF128UI96 0x7FFF8000 #define defaultNaNF128UI96 0x7FFF8000
#define defaultNaNF128UI64 0 #define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0 #define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0 #define defaultNaNF128UI0 0
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, | Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN,
@ -366,7 +356,9 @@ void
| four 32-bit elements that concatenate in the platform's normal endian order | four 32-bit elements that concatenate in the platform's normal endian order
| to form a 128-bit floating-point value. | to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_f128MToCommonNaN( aWPtr, zPtr ) if ( ! ((aWPtr)[indexWordHi( 4 )] & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) #define softfloat_f128MToCommonNaN(aWPtr, zPtr) \
if(!((aWPtr)[indexWordHi(4)] & UINT64_C(0x0000800000000000))) \
softfloat_raiseFlags(softfloat_flag_invalid)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
@ -374,19 +366,16 @@ void
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the | 'zWPtr' points to an array of four 32-bit elements that concatenate in the
| platform's normal endian order to form a 128-bit floating-point value. | platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE && ! defined softfloat_commonNaNToF128M #if defined INLINE && !defined softfloat_commonNaNToF128M
INLINE INLINE
void void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr) {
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ) zWPtr[indexWord(4, 3)] = defaultNaNF128UI96;
{ zWPtr[indexWord(4, 2)] = defaultNaNF128UI64;
zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96; zWPtr[indexWord(4, 1)] = defaultNaNF128UI32;
zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64; zWPtr[indexWord(4, 0)] = defaultNaNF128UI0;
zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32;
zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0;
} }
#else #else
void void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -397,11 +386,8 @@ void
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in | and 'zWPtr' points to an array of four 32-bit elements that concatenate in
| the platform's normal endian order to form a 128-bit floating-point value. | the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
#endif #endif
#endif #endif

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h #ifndef specialize_h
#define specialize_h 1 #define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h" #include "primitiveTypes.h"
#include "softfloat.h" #include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Default value for 'softfloat_detectTininess'. | Default value for 'softfloat_detectTininess'.
@ -53,21 +53,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui32_fromPosOverflow 0xFFFFFFFF #define ui32_fromPosOverflow 0xFFFFFFFF
#define ui32_fromNegOverflow 0 #define ui32_fromNegOverflow 0
#define ui32_fromNaN 0 #define ui32_fromNaN 0
#define i32_fromPosOverflow 0x7FFFFFFF #define i32_fromPosOverflow 0x7FFFFFFF
#define i32_fromNegOverflow (-0x7FFFFFFF - 1) #define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN 0 #define i32_fromNaN 0
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an | The values to return on conversions to 64-bit integer formats that raise an
| invalid exception. | invalid exception.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) #define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow 0 #define ui64_fromNegOverflow 0
#define ui64_fromNaN 0 #define ui64_fromNaN 0
#define i64_fromPosOverflow INT64_C( 0x7FFFFFFFFFFFFFFF ) #define i64_fromPosOverflow INT64_C(0x7FFFFFFFFFFFFFFF)
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) #define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN 0 #define i64_fromNaN 0
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format | "Common NaN" structure, used to transfer NaN representations from one format
@ -92,7 +92,7 @@ struct commonNaN {
| 16-bit floating-point signaling NaN. | 16-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) #define softfloat_isSigNaNF16UI(uiA) ((((uiA)&0x7E00) == 0x7C00) && ((uiA)&0x01FF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts
@ -100,13 +100,13 @@ struct commonNaN {
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ); void softfloat_f16UIToCommonNaN(uint_fast16_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ); uint_fast16_t softfloat_commonNaNToF16UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating-
@ -114,8 +114,7 @@ uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast16_t uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 32-bit floating-point NaN. | The bit pattern for a default generated 32-bit floating-point NaN.
@ -127,7 +126,7 @@ uint_fast16_t
| 32-bit floating-point signaling NaN. | 32-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) #define softfloat_isSigNaNF32UI(uiA) ((((uiA)&0x7FC00000) == 0x7F800000) && ((uiA)&0x003FFFFF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts
@ -135,13 +134,13 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ); void softfloat_f32UIToCommonNaN(uint_fast32_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ); uint_fast32_t softfloat_commonNaNToF32UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating-
@ -149,20 +148,20 @@ uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 64-bit floating-point NaN. | The bit pattern for a default generated 64-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 ) #define defaultNaNF64UI UINT64_C(0x7FF8000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a | Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a
| 64-bit floating-point signaling NaN. | 64-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) #define softfloat_isSigNaNF64UI(uiA) \
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
@ -170,13 +169,13 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ); void softfloat_f64UIToCommonNaN(uint_fast64_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ); uint_fast64_t softfloat_commonNaNToF64UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating-
@ -184,14 +183,13 @@ uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast64_t uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN. | The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0x7FFF #define defaultNaNExtF80UI64 0x7FFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) #define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating | Returns true when the 80-bit unsigned integer formed from concatenating
@ -199,7 +197,8 @@ uint_fast64_t
| floating-point signaling NaN. | floating-point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) #define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
@ -215,16 +214,14 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_extF80UIToCommonNaN(uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
softfloat_extF80UIToCommonNaN(
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and returns the bit pattern of this value as an unsigned | floating-point NaN, and returns the bit pattern of this value as an unsigned
| integer. | integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting the unsigned integer formed from concatenating 'uiA64' and | Interpreting the unsigned integer formed from concatenating 'uiA64' and
@ -235,19 +232,13 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
| result. If either original floating-point value is a signaling NaN, the | result. If either original floating-point value is a signaling NaN, the
| invalid exception is raised. | invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0x7FFF800000000000 ) #define defaultNaNF128UI64 UINT64_C(0x7FFF800000000000)
#define defaultNaNF128UI0 UINT64_C( 0 ) #define defaultNaNF128UI0 UINT64_C(0)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating | Returns true when the 128-bit unsigned integer formed from concatenating
@ -255,7 +246,8 @@ struct uint128
| point signaling NaN. | point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) #define softfloat_isSigNaNF128UI(uiA64, uiA0) \
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' | Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
@ -264,15 +256,13 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception | pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| is raised. | is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_f128UIToCommonNaN(uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
softfloat_f128UIToCommonNaN(
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN*);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting the unsigned integer formed from concatenating 'uiA64' and | Interpreting the unsigned integer formed from concatenating 'uiA64' and
@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid | If either original floating-point value is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
#else #else
@ -304,18 +288,14 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling | common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| NaN, the invalid exception is raised. | NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
softfloat_extF80MToCommonNaN(
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and stores this NaN at the location pointed to by | floating-point NaN, and stores this NaN at the location pointed to by
| 'zSPtr'. | 'zSPtr'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming at least one of the two 80-bit extended floating-point values | Assuming at least one of the two 80-bit extended floating-point values
@ -323,12 +303,7 @@ void
| at the location pointed to by 'zSPtr'. If either original floating-point | at the location pointed to by 'zSPtr'. If either original floating-point
| value is a signaling NaN, the invalid exception is raised. | value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
@ -336,7 +311,7 @@ void
#define defaultNaNF128UI96 0x7FFF8000 #define defaultNaNF128UI96 0x7FFF8000
#define defaultNaNF128UI64 0 #define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0 #define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0 #define defaultNaNF128UI0 0
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, | Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN,
@ -346,8 +321,7 @@ void
| four 32-bit elements that concatenate in the platform's normal endian order | four 32-bit elements that concatenate in the platform's normal endian order
| to form a 128-bit floating-point value. | to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
@ -355,8 +329,7 @@ void
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the | 'zWPtr' points to an array of four 32-bit elements that concatenate in the
| platform's normal endian order to form a 128-bit floating-point value. | platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming at least one of the two 128-bit floating-point values pointed to by | Assuming at least one of the two 128-bit floating-point values pointed to by
@ -366,11 +339,8 @@ void
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in | and 'zWPtr' points to an array of four 32-bit elements that concatenate in
| the platform's normal endian order to form a 128-bit floating-point value. | the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
#endif #endif
#endif #endif

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h #ifndef specialize_h
#define specialize_h 1 #define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h" #include "primitiveTypes.h"
#include "softfloat.h" #include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Default value for 'softfloat_detectTininess'. | Default value for 'softfloat_detectTininess'.
@ -53,21 +53,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui32_fromPosOverflow UINT32_C(0xFFFFFFFF) #define ui32_fromPosOverflow UINT32_C(0xFFFFFFFF)
#define ui32_fromNegOverflow UINT32_C(0x0) #define ui32_fromNegOverflow UINT32_C(0x0)
#define ui32_fromNaN UINT32_C(0xFFFFFFFF) #define ui32_fromNaN UINT32_C(0xFFFFFFFF)
#define i32_fromPosOverflow INT64_C(0x7FFFFFFF) #define i32_fromPosOverflow INT64_C(0x7FFFFFFF)
#define i32_fromNegOverflow (-INT64_C(0x7FFFFFFF)-1) #define i32_fromNegOverflow (-INT64_C(0x7FFFFFFF) - 1)
#define i32_fromNaN INT64_C(0x7FFFFFFF) #define i32_fromNaN INT64_C(0x7FFFFFFF)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an | The values to return on conversions to 64-bit integer formats that raise an
| invalid exception. | invalid exception.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) #define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow UINT64_C( 0x0 ) #define ui64_fromNegOverflow UINT64_C(0x0)
#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF) #define ui64_fromNaN UINT64_C(0xFFFFFFFFFFFFFFFF)
#define i64_fromPosOverflow INT64_C( 0x7FFFFFFFFFFFFFFF) #define i64_fromPosOverflow INT64_C(0x7FFFFFFFFFFFFFFF)
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF)-1) #define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN INT64_C( 0x7FFFFFFFFFFFFFFF) #define i64_fromNaN INT64_C(0x7FFFFFFFFFFFFFFF)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format | "Common NaN" structure, used to transfer NaN representations from one format
@ -92,7 +92,7 @@ struct commonNaN {
| 16-bit floating-point signaling NaN. | 16-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) #define softfloat_isSigNaNF16UI(uiA) ((((uiA)&0x7E00) == 0x7C00) && ((uiA)&0x01FF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts
@ -100,13 +100,13 @@ struct commonNaN {
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ); void softfloat_f16UIToCommonNaN(uint_fast16_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ); uint_fast16_t softfloat_commonNaNToF16UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating-
@ -114,8 +114,7 @@ uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast16_t uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 32-bit floating-point NaN. | The bit pattern for a default generated 32-bit floating-point NaN.
@ -127,7 +126,7 @@ uint_fast16_t
| 32-bit floating-point signaling NaN. | 32-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) #define softfloat_isSigNaNF32UI(uiA) ((((uiA)&0x7FC00000) == 0x7F800000) && ((uiA)&0x003FFFFF))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts
@ -135,13 +134,13 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ); void softfloat_f32UIToCommonNaN(uint_fast32_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ); uint_fast32_t softfloat_commonNaNToF32UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating-
@ -149,20 +148,20 @@ uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 64-bit floating-point NaN. | The bit pattern for a default generated 64-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 ) #define defaultNaNF64UI UINT64_C(0x7FF8000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a | Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a
| 64-bit floating-point signaling NaN. | 64-bit floating-point signaling NaN.
| Note: This macro evaluates its argument more than once. | Note: This macro evaluates its argument more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) #define softfloat_isSigNaNF64UI(uiA) \
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts | Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
@ -170,13 +169,13 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ); void softfloat_f64UIToCommonNaN(uint_fast64_t uiA, struct commonNaN* zPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ); uint_fast64_t softfloat_commonNaNToF64UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- | Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating-
@ -184,14 +183,13 @@ uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr );
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a | the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised. | signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast64_t uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN. | The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0xFFFF #define defaultNaNExtF80UI64 0xFFFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) #define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating | Returns true when the 80-bit unsigned integer formed from concatenating
@ -199,7 +197,8 @@ uint_fast64_t
| floating-point signaling NaN. | floating-point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) #define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
@ -215,16 +214,14 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid | location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_extF80UIToCommonNaN(uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
softfloat_extF80UIToCommonNaN(
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and returns the bit pattern of this value as an unsigned | floating-point NaN, and returns the bit pattern of this value as an unsigned
| integer. | integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting the unsigned integer formed from concatenating 'uiA64' and | Interpreting the unsigned integer formed from concatenating 'uiA64' and
@ -235,19 +232,13 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
| result. If either original floating-point value is a signaling NaN, the | result. If either original floating-point value is a signaling NaN, the
| invalid exception is raised. | invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0xFFFF800000000000 ) #define defaultNaNF128UI64 UINT64_C(0xFFFF800000000000)
#define defaultNaNF128UI0 UINT64_C( 0 ) #define defaultNaNF128UI0 UINT64_C(0)
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating | Returns true when the 128-bit unsigned integer formed from concatenating
@ -255,7 +246,8 @@ struct uint128
| point signaling NaN. | point signaling NaN.
| Note: This macro evaluates its arguments more than once. | Note: This macro evaluates its arguments more than once.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) #define softfloat_isSigNaNF128UI(uiA64, uiA0) \
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' | Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
@ -264,15 +256,13 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception | pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| is raised. | is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_f128UIToCommonNaN(uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
softfloat_f128UIToCommonNaN(
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer. | NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN*);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Interpreting the unsigned integer formed from concatenating 'uiA64' and | Interpreting the unsigned integer formed from concatenating 'uiA64' and
@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid | If either original floating-point value is a signaling NaN, the invalid
| exception is raised. | exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
#else #else
@ -304,18 +288,14 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling | common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| NaN, the invalid exception is raised. | NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
softfloat_extF80MToCommonNaN(
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended | Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
| floating-point NaN, and stores this NaN at the location pointed to by | floating-point NaN, and stores this NaN at the location pointed to by
| 'zSPtr'. | 'zSPtr'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming at least one of the two 80-bit extended floating-point values | Assuming at least one of the two 80-bit extended floating-point values
@ -323,12 +303,7 @@ void
| at the location pointed to by 'zSPtr'. If either original floating-point | at the location pointed to by 'zSPtr'. If either original floating-point
| value is a signaling NaN, the invalid exception is raised. | value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The bit pattern for a default generated 128-bit floating-point NaN. | The bit pattern for a default generated 128-bit floating-point NaN.
@ -336,7 +311,7 @@ void
#define defaultNaNF128UI96 0xFFFF8000 #define defaultNaNF128UI96 0xFFFF8000
#define defaultNaNF128UI64 0 #define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0 #define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0 #define defaultNaNF128UI0 0
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, | Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN,
@ -346,8 +321,7 @@ void
| four 32-bit elements that concatenate in the platform's normal endian order | four 32-bit elements that concatenate in the platform's normal endian order
| to form a 128-bit floating-point value. | to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point | Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
@ -355,8 +329,7 @@ void
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the | 'zWPtr' points to an array of four 32-bit elements that concatenate in the
| platform's normal endian order to form a 128-bit floating-point value. | platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Assuming at least one of the two 128-bit floating-point values pointed to by | Assuming at least one of the two 128-bit floating-point values pointed to by
@ -366,11 +339,8 @@ void
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in | and 'zWPtr' points to an array of four 32-bit elements that concatenate in
| the platform's normal endian order to form a 128-bit floating-point value. | the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
#endif #endif
#endif #endif

View File

@ -37,242 +37,205 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef internals_h #ifndef internals_h
#define internals_h 1 #define internals_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitives.h" #include "primitives.h"
#include "softfloat_types.h" #include "softfloat_types.h"
#include <stdbool.h>
#include <stdint.h>
union ui16_f16 { uint16_t ui; float16_t f; }; union ui16_f16 {
union ui32_f32 { uint32_t ui; float32_t f; }; uint16_t ui;
union ui64_f64 { uint64_t ui; float64_t f; }; float16_t f;
};
#ifdef SOFTFLOAT_FAST_INT64 union ui32_f32 {
union extF80M_extF80 { struct extFloat80M fM; extFloat80_t f; }; uint32_t ui;
union ui128_f128 { struct uint128 ui; float128_t f; }; float32_t f;
#endif };
union ui64_f64 {
enum { uint64_t ui;
softfloat_mulAdd_subC = 1, float64_t f;
softfloat_mulAdd_subProd = 2
}; };
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
uint_fast32_t softfloat_roundToUI32( bool, uint_fast64_t, uint_fast8_t, bool );
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
uint_fast64_t union extF80M_extF80 {
softfloat_roundToUI64( struct extFloat80M fM;
bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool ); extFloat80_t f;
#else };
uint_fast64_t softfloat_roundMToUI64( bool, uint32_t *, uint_fast8_t, bool ); union ui128_f128 {
struct uint128 ui;
float128_t f;
};
#endif #endif
int_fast32_t softfloat_roundToI32( bool, uint_fast64_t, uint_fast8_t, bool ); enum { softfloat_mulAdd_subC = 1, softfloat_mulAdd_subProd = 2 };
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
uint_fast32_t softfloat_roundToUI32(bool, uint_fast64_t, uint_fast8_t, bool);
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
int_fast64_t uint_fast64_t softfloat_roundToUI64(bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool);
softfloat_roundToI64(
bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool );
#else #else
int_fast64_t softfloat_roundMToI64( bool, uint32_t *, uint_fast8_t, bool ); uint_fast64_t softfloat_roundMToUI64(bool, uint32_t*, uint_fast8_t, bool);
#endif
int_fast32_t softfloat_roundToI32(bool, uint_fast64_t, uint_fast8_t, bool);
#ifdef SOFTFLOAT_FAST_INT64
int_fast64_t softfloat_roundToI64(bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool);
#else
int_fast64_t softfloat_roundMToI64(bool, uint32_t*, uint_fast8_t, bool);
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define signF16UI( a ) ((bool) ((uint16_t) (a)>>15)) #define signF16UI(a) ((bool)((uint16_t)(a) >> 15))
#define expF16UI( a ) ((int_fast8_t) ((a)>>10) & 0x1F) #define expF16UI(a) ((int_fast8_t)((a) >> 10) & 0x1F)
#define fracF16UI( a ) ((a) & 0x03FF) #define fracF16UI(a) ((a)&0x03FF)
#define packToF16UI( sign, exp, sig ) (((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<10) + (sig)) #define packToF16UI(sign, exp, sig) (((uint16_t)(sign) << 15) + ((uint16_t)(exp) << 10) + (sig))
#define isNaNF16UI( a ) (((~(a) & 0x7C00) == 0) && ((a) & 0x03FF)) #define isNaNF16UI(a) (((~(a)&0x7C00) == 0) && ((a)&0x03FF))
struct exp8_sig16 { int_fast8_t exp; uint_fast16_t sig; }; struct exp8_sig16 {
struct exp8_sig16 softfloat_normSubnormalF16Sig( uint_fast16_t ); int_fast8_t exp;
uint_fast16_t sig;
};
struct exp8_sig16 softfloat_normSubnormalF16Sig(uint_fast16_t);
float16_t softfloat_roundPackToF16( bool, int_fast16_t, uint_fast16_t ); float16_t softfloat_roundPackToF16(bool, int_fast16_t, uint_fast16_t);
float16_t softfloat_normRoundPackToF16( bool, int_fast16_t, uint_fast16_t ); float16_t softfloat_normRoundPackToF16(bool, int_fast16_t, uint_fast16_t);
float16_t softfloat_addMagsF16( uint_fast16_t, uint_fast16_t ); float16_t softfloat_addMagsF16(uint_fast16_t, uint_fast16_t);
float16_t softfloat_subMagsF16( uint_fast16_t, uint_fast16_t ); float16_t softfloat_subMagsF16(uint_fast16_t, uint_fast16_t);
float16_t float16_t softfloat_mulAddF16(uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t);
softfloat_mulAddF16(
uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define signF32UI( a ) ((bool) ((uint32_t) (a)>>31)) #define signF32UI(a) ((bool)((uint32_t)(a) >> 31))
#define expF32UI( a ) ((int_fast16_t) ((a)>>23) & 0xFF) #define expF32UI(a) ((int_fast16_t)((a) >> 23) & 0xFF)
#define fracF32UI( a ) ((a) & 0x007FFFFF) #define fracF32UI(a) ((a)&0x007FFFFF)
#define packToF32UI( sign, exp, sig ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig)) #define packToF32UI(sign, exp, sig) (((uint32_t)(sign) << 31) + ((uint32_t)(exp) << 23) + (sig))
#define isNaNF32UI( a ) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF)) #define isNaNF32UI(a) (((~(a)&0x7F800000) == 0) && ((a)&0x007FFFFF))
struct exp16_sig32 { int_fast16_t exp; uint_fast32_t sig; }; struct exp16_sig32 {
struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t ); int_fast16_t exp;
uint_fast32_t sig;
};
struct exp16_sig32 softfloat_normSubnormalF32Sig(uint_fast32_t);
float32_t softfloat_roundPackToF32( bool, int_fast16_t, uint_fast32_t ); float32_t softfloat_roundPackToF32(bool, int_fast16_t, uint_fast32_t);
float32_t softfloat_normRoundPackToF32( bool, int_fast16_t, uint_fast32_t ); float32_t softfloat_normRoundPackToF32(bool, int_fast16_t, uint_fast32_t);
float32_t softfloat_addMagsF32( uint_fast32_t, uint_fast32_t ); float32_t softfloat_addMagsF32(uint_fast32_t, uint_fast32_t);
float32_t softfloat_subMagsF32( uint_fast32_t, uint_fast32_t ); float32_t softfloat_subMagsF32(uint_fast32_t, uint_fast32_t);
float32_t float32_t softfloat_mulAddF32(uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t);
softfloat_mulAddF32(
uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define signF64UI( a ) ((bool) ((uint64_t) (a)>>63)) #define signF64UI(a) ((bool)((uint64_t)(a) >> 63))
#define expF64UI( a ) ((int_fast16_t) ((a)>>52) & 0x7FF) #define expF64UI(a) ((int_fast16_t)((a) >> 52) & 0x7FF)
#define fracF64UI( a ) ((a) & UINT64_C( 0x000FFFFFFFFFFFFF )) #define fracF64UI(a) ((a)&UINT64_C(0x000FFFFFFFFFFFFF))
#define packToF64UI( sign, exp, sig ) ((uint64_t) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<52) + (sig))) #define packToF64UI(sign, exp, sig) ((uint64_t)(((uint_fast64_t)(sign) << 63) + ((uint_fast64_t)(exp) << 52) + (sig)))
#define isNaNF64UI( a ) (((~(a) & UINT64_C( 0x7FF0000000000000 )) == 0) && ((a) & UINT64_C( 0x000FFFFFFFFFFFFF ))) #define isNaNF64UI(a) (((~(a)&UINT64_C(0x7FF0000000000000)) == 0) && ((a)&UINT64_C(0x000FFFFFFFFFFFFF)))
struct exp16_sig64 { int_fast16_t exp; uint_fast64_t sig; }; struct exp16_sig64 {
struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t ); int_fast16_t exp;
uint_fast64_t sig;
};
struct exp16_sig64 softfloat_normSubnormalF64Sig(uint_fast64_t);
float64_t softfloat_roundPackToF64( bool, int_fast16_t, uint_fast64_t ); float64_t softfloat_roundPackToF64(bool, int_fast16_t, uint_fast64_t);
float64_t softfloat_normRoundPackToF64( bool, int_fast16_t, uint_fast64_t ); float64_t softfloat_normRoundPackToF64(bool, int_fast16_t, uint_fast64_t);
float64_t softfloat_addMagsF64( uint_fast64_t, uint_fast64_t, bool ); float64_t softfloat_addMagsF64(uint_fast64_t, uint_fast64_t, bool);
float64_t softfloat_subMagsF64( uint_fast64_t, uint_fast64_t, bool ); float64_t softfloat_subMagsF64(uint_fast64_t, uint_fast64_t, bool);
float64_t float64_t softfloat_mulAddF64(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t);
softfloat_mulAddF64(
uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define signExtF80UI64( a64 ) ((bool) ((uint16_t) (a64)>>15)) #define signExtF80UI64(a64) ((bool)((uint16_t)(a64) >> 15))
#define expExtF80UI64( a64 ) ((a64) & 0x7FFF) #define expExtF80UI64(a64) ((a64)&0x7FFF)
#define packToExtF80UI64( sign, exp ) ((uint_fast16_t) (sign)<<15 | (exp)) #define packToExtF80UI64(sign, exp) ((uint_fast16_t)(sign) << 15 | (exp))
#define isNaNExtF80UI( a64, a0 ) ((((a64) & 0x7FFF) == 0x7FFF) && ((a0) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) #define isNaNExtF80UI(a64, a0) ((((a64)&0x7FFF) == 0x7FFF) && ((a0)&UINT64_C(0x7FFFFFFFFFFFFFFF)))
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct exp32_sig64 { int_fast32_t exp; uint64_t sig; }; struct exp32_sig64 {
struct exp32_sig64 softfloat_normSubnormalExtF80Sig( uint_fast64_t ); int_fast32_t exp;
uint64_t sig;
};
struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint_fast64_t);
extFloat80_t extFloat80_t softfloat_roundPackToExtF80(bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t);
softfloat_roundPackToExtF80( extFloat80_t softfloat_normRoundPackToExtF80(bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t);
bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );
extFloat80_t
softfloat_normRoundPackToExtF80(
bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );
extFloat80_t extFloat80_t softfloat_addMagsExtF80(uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool);
softfloat_addMagsExtF80( extFloat80_t softfloat_subMagsExtF80(uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool);
uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool );
extFloat80_t
softfloat_subMagsExtF80(
uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define signF128UI64( a64 ) ((bool) ((uint64_t) (a64)>>63)) #define signF128UI64(a64) ((bool)((uint64_t)(a64) >> 63))
#define expF128UI64( a64 ) ((int_fast32_t) ((a64)>>48) & 0x7FFF) #define expF128UI64(a64) ((int_fast32_t)((a64) >> 48) & 0x7FFF)
#define fracF128UI64( a64 ) ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )) #define fracF128UI64(a64) ((a64)&UINT64_C(0x0000FFFFFFFFFFFF))
#define packToF128UI64( sign, exp, sig64 ) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<48) + (sig64)) #define packToF128UI64(sign, exp, sig64) (((uint_fast64_t)(sign) << 63) + ((uint_fast64_t)(exp) << 48) + (sig64))
#define isNaNF128UI( a64, a0 ) (((~(a64) & UINT64_C( 0x7FFF000000000000 )) == 0) && (a0 || ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )))) #define isNaNF128UI(a64, a0) (((~(a64)&UINT64_C(0x7FFF000000000000)) == 0) && (a0 || ((a64)&UINT64_C(0x0000FFFFFFFFFFFF))))
struct exp32_sig128 { int_fast32_t exp; struct uint128 sig; }; struct exp32_sig128 {
struct exp32_sig128 int_fast32_t exp;
softfloat_normSubnormalF128Sig( uint_fast64_t, uint_fast64_t ); struct uint128 sig;
};
struct exp32_sig128 softfloat_normSubnormalF128Sig(uint_fast64_t, uint_fast64_t);
float128_t float128_t softfloat_roundPackToF128(bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast64_t);
softfloat_roundPackToF128( float128_t softfloat_normRoundPackToF128(bool, int_fast32_t, uint_fast64_t, uint_fast64_t);
bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast64_t );
float128_t
softfloat_normRoundPackToF128(
bool, int_fast32_t, uint_fast64_t, uint_fast64_t );
float128_t float128_t softfloat_addMagsF128(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool);
softfloat_addMagsF128( float128_t softfloat_subMagsF128(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool);
uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); float128_t softfloat_mulAddF128(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t);
float128_t
softfloat_subMagsF128(
uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool );
float128_t
softfloat_mulAddF128(
uint_fast64_t,
uint_fast64_t,
uint_fast64_t,
uint_fast64_t,
uint_fast64_t,
uint_fast64_t,
uint_fast8_t
);
#else #else
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
bool bool softfloat_tryPropagateNaNExtF80M(const struct extFloat80M*, const struct extFloat80M*, struct extFloat80M*);
softfloat_tryPropagateNaNExtF80M( void softfloat_invalidExtF80M(struct extFloat80M*);
const struct extFloat80M *,
const struct extFloat80M *,
struct extFloat80M *
);
void softfloat_invalidExtF80M( struct extFloat80M * );
int softfloat_normExtF80SigM( uint64_t * ); int softfloat_normExtF80SigM(uint64_t*);
void void softfloat_roundPackMToExtF80M(bool, int32_t, uint32_t*, uint_fast8_t, struct extFloat80M*);
softfloat_roundPackMToExtF80M( void softfloat_normRoundPackMToExtF80M(bool, int32_t, uint32_t*, uint_fast8_t, struct extFloat80M*);
bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * );
void
softfloat_normRoundPackMToExtF80M(
bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * );
void void softfloat_addExtF80M(const struct extFloat80M*, const struct extFloat80M*, struct extFloat80M*, bool);
softfloat_addExtF80M(
const struct extFloat80M *,
const struct extFloat80M *,
struct extFloat80M *,
bool
);
int int softfloat_compareNonnormExtF80M(const struct extFloat80M*, const struct extFloat80M*);
softfloat_compareNonnormExtF80M(
const struct extFloat80M *, const struct extFloat80M * );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define signF128UI96( a96 ) ((bool) ((uint32_t) (a96)>>31)) #define signF128UI96(a96) ((bool)((uint32_t)(a96) >> 31))
#define expF128UI96( a96 ) ((int32_t) ((a96)>>16) & 0x7FFF) #define expF128UI96(a96) ((int32_t)((a96) >> 16) & 0x7FFF)
#define fracF128UI96( a96 ) ((a96) & 0x0000FFFF) #define fracF128UI96(a96) ((a96)&0x0000FFFF)
#define packToF128UI96( sign, exp, sig96 ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<16) + (sig96)) #define packToF128UI96(sign, exp, sig96) (((uint32_t)(sign) << 31) + ((uint32_t)(exp) << 16) + (sig96))
bool softfloat_isNaNF128M( const uint32_t * ); bool softfloat_isNaNF128M(const uint32_t*);
bool bool softfloat_tryPropagateNaNF128M(const uint32_t*, const uint32_t*, uint32_t*);
softfloat_tryPropagateNaNF128M( void softfloat_invalidF128M(uint32_t*);
const uint32_t *, const uint32_t *, uint32_t * );
void softfloat_invalidF128M( uint32_t * );
int softfloat_shiftNormSigF128M( const uint32_t *, uint_fast8_t, uint32_t * ); int softfloat_shiftNormSigF128M(const uint32_t*, uint_fast8_t, uint32_t*);
void softfloat_roundPackMToF128M( bool, int32_t, uint32_t *, uint32_t * ); void softfloat_roundPackMToF128M(bool, int32_t, uint32_t*, uint32_t*);
void softfloat_normRoundPackMToF128M( bool, int32_t, uint32_t *, uint32_t * ); void softfloat_normRoundPackMToF128M(bool, int32_t, uint32_t*, uint32_t*);
void void softfloat_addF128M(const uint32_t*, const uint32_t*, uint32_t*, bool);
softfloat_addF128M( const uint32_t *, const uint32_t *, uint32_t *, bool ); void softfloat_mulAddF128M(const uint32_t*, const uint32_t*, const uint32_t*, uint32_t*, uint_fast8_t);
void
softfloat_mulAddF128M(
const uint32_t *,
const uint32_t *,
const uint32_t *,
uint32_t *,
uint_fast8_t
);
#endif #endif
#endif #endif

View File

@ -39,70 +39,70 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef INLINE #ifdef INLINE
#include <stdint.h>
#include "primitiveTypes.h" #include "primitiveTypes.h"
#include <stdint.h>
#ifdef SOFTFLOAT_BUILTIN_CLZ #ifdef SOFTFLOAT_BUILTIN_CLZ
INLINE uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ) INLINE uint_fast8_t softfloat_countLeadingZeros16(uint16_t a) { return a ? __builtin_clz(a) - 16 : 16; }
{ return a ? __builtin_clz( a ) - 16 : 16; }
#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16 #define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16
INLINE uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ) INLINE uint_fast8_t softfloat_countLeadingZeros32(uint32_t a) { return a ? __builtin_clz(a) : 32; }
{ return a ? __builtin_clz( a ) : 32; }
#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32 #define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32
INLINE uint_fast8_t softfloat_countLeadingZeros64( uint64_t a ) INLINE uint_fast8_t softfloat_countLeadingZeros64(uint64_t a) { return a ? __builtin_clzll(a) : 64; }
{ return a ? __builtin_clzll( a ) : 64; }
#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64 #define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64
#endif #endif
#ifdef SOFTFLOAT_INTRINSIC_INT128 #ifdef SOFTFLOAT_INTRINSIC_INT128
INLINE struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ) INLINE struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b) {
{ union {
union { unsigned __int128 ui; struct uint128 s; } uZ; unsigned __int128 ui;
uZ.ui = (unsigned __int128) a * ((uint_fast64_t) b<<32); struct uint128 s;
} uZ;
uZ.ui = (unsigned __int128)a * ((uint_fast64_t)b << 32);
return uZ.s; return uZ.s;
} }
#define softfloat_mul64ByShifted32To128 softfloat_mul64ByShifted32To128 #define softfloat_mul64ByShifted32To128 softfloat_mul64ByShifted32To128
INLINE struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ) INLINE struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b) {
{ union {
union { unsigned __int128 ui; struct uint128 s; } uZ; unsigned __int128 ui;
uZ.ui = (unsigned __int128) a * b; struct uint128 s;
} uZ;
uZ.ui = (unsigned __int128)a * b;
return uZ.s; return uZ.s;
} }
#define softfloat_mul64To128 softfloat_mul64To128 #define softfloat_mul64To128 softfloat_mul64To128
INLINE INLINE
struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ) struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b) {
{ union {
union { unsigned __int128 ui; struct uint128 s; } uZ; unsigned __int128 ui;
uZ.ui = ((unsigned __int128) a64<<64 | a0) * b; struct uint128 s;
} uZ;
uZ.ui = ((unsigned __int128)a64 << 64 | a0) * b;
return uZ.s; return uZ.s;
} }
#define softfloat_mul128By32 softfloat_mul128By32 #define softfloat_mul128By32 softfloat_mul128By32
INLINE INLINE
void void softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t* zPtr) {
softfloat_mul128To256M(
uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr )
{
unsigned __int128 z0, mid1, mid, z128; unsigned __int128 z0, mid1, mid, z128;
z0 = (unsigned __int128) a0 * b0; z0 = (unsigned __int128)a0 * b0;
mid1 = (unsigned __int128) a64 * b0; mid1 = (unsigned __int128)a64 * b0;
mid = mid1 + (unsigned __int128) a0 * b64; mid = mid1 + (unsigned __int128)a0 * b64;
z128 = (unsigned __int128) a64 * b64; z128 = (unsigned __int128)a64 * b64;
z128 += (unsigned __int128) (mid < mid1)<<64 | mid>>64; z128 += (unsigned __int128)(mid < mid1) << 64 | mid >> 64;
mid <<= 64; mid <<= 64;
z0 += mid; z0 += mid;
z128 += (z0 < mid); z128 += (z0 < mid);
zPtr[indexWord( 4, 0 )] = z0; zPtr[indexWord(4, 0)] = z0;
zPtr[indexWord( 4, 1 )] = z0>>64; zPtr[indexWord(4, 1)] = z0 >> 64;
zPtr[indexWord( 4, 2 )] = z128; zPtr[indexWord(4, 2)] = z128;
zPtr[indexWord( 4, 3 )] = z128>>64; zPtr[indexWord(4, 3)] = z128 >> 64;
} }
#define softfloat_mul128To256M softfloat_mul128To256M #define softfloat_mul128To256M softfloat_mul128To256M
@ -111,4 +111,3 @@ void
#endif #endif
#endif #endif

View File

@ -42,13 +42,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
#ifdef LITTLEENDIAN #ifdef LITTLEENDIAN
struct uint128 { uint64_t v0, v64; }; struct uint128 {
struct uint64_extra { uint64_t extra, v; }; uint64_t v0, v64;
struct uint128_extra { uint64_t extra; struct uint128 v; }; };
struct uint64_extra {
uint64_t extra, v;
};
struct uint128_extra {
uint64_t extra;
struct uint128 v;
};
#else #else
struct uint128 { uint64_t v64, v0; }; struct uint128 {
struct uint64_extra { uint64_t v, extra; }; uint64_t v64, v0;
struct uint128_extra { struct uint128 v; uint64_t extra; }; };
struct uint64_extra {
uint64_t v, extra;
};
struct uint128_extra {
struct uint128 v;
uint64_t extra;
};
#endif #endif
#endif #endif
@ -59,27 +73,28 @@ struct uint128_extra { struct uint128 v; uint64_t extra; };
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef LITTLEENDIAN #ifdef LITTLEENDIAN
#define wordIncr 1 #define wordIncr 1
#define indexWord( total, n ) (n) #define indexWord(total, n) (n)
#define indexWordHi( total ) ((total) - 1) #define indexWordHi(total) ((total)-1)
#define indexWordLo( total ) 0 #define indexWordLo(total) 0
#define indexMultiword( total, m, n ) (n) #define indexMultiword(total, m, n) (n)
#define indexMultiwordHi( total, n ) ((total) - (n)) #define indexMultiwordHi(total, n) ((total) - (n))
#define indexMultiwordLo( total, n ) 0 #define indexMultiwordLo(total, n) 0
#define indexMultiwordHiBut( total, n ) (n) #define indexMultiwordHiBut(total, n) (n)
#define indexMultiwordLoBut( total, n ) 0 #define indexMultiwordLoBut(total, n) 0
#define INIT_UINTM4( v3, v2, v1, v0 ) { v0, v1, v2, v3 } #define INIT_UINTM4(v3, v2, v1, v0) \
{ v0, v1, v2, v3 }
#else #else
#define wordIncr -1 #define wordIncr -1
#define indexWord( total, n ) ((total) - 1 - (n)) #define indexWord(total, n) ((total)-1 - (n))
#define indexWordHi( total ) 0 #define indexWordHi(total) 0
#define indexWordLo( total ) ((total) - 1) #define indexWordLo(total) ((total)-1)
#define indexMultiword( total, m, n ) ((total) - 1 - (m)) #define indexMultiword(total, m, n) ((total)-1 - (m))
#define indexMultiwordHi( total, n ) 0 #define indexMultiwordHi(total, n) 0
#define indexMultiwordLo( total, n ) ((total) - (n)) #define indexMultiwordLo(total, n) ((total) - (n))
#define indexMultiwordHiBut( total, n ) 0 #define indexMultiwordHiBut(total, n) 0
#define indexMultiwordLoBut( total, n ) (n) #define indexMultiwordLoBut(total, n) (n)
#define INIT_UINTM4( v3, v2, v1, v0 ) { v3, v2, v1, v0 } #define INIT_UINTM4(v3, v2, v1, v0) \
{ v3, v2, v1, v0 }
#endif #endif
#endif #endif

View File

@ -37,9 +37,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef primitives_h #ifndef primitives_h
#define primitives_h 1 #define primitives_h 1
#include "primitiveTypes.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "primitiveTypes.h"
#ifndef softfloat_shortShiftRightJam64 #ifndef softfloat_shortShiftRightJam64
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -50,10 +50,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE INLINE
uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist ) uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint_fast8_t dist) { return a >> dist | ((a & (((uint_fast64_t)1 << dist) - 1)) != 0); }
{ return a>>dist | ((a & (((uint_fast64_t) 1<<dist) - 1)) != 0); }
#else #else
uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist ); uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint_fast8_t dist);
#endif #endif
#endif #endif
@ -68,13 +67,11 @@ uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist );
| is zero or nonzero. | is zero or nonzero.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist ) INLINE uint32_t softfloat_shiftRightJam32(uint32_t a, uint_fast16_t dist) {
{ return (dist < 31) ? a >> dist | ((uint32_t)(a << (-dist & 31)) != 0) : (a != 0);
return
(dist < 31) ? a>>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0);
} }
#else #else
uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist ); uint32_t softfloat_shiftRightJam32(uint32_t a, uint_fast16_t dist);
#endif #endif
#endif #endif
@ -89,13 +86,11 @@ uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist );
| is zero or nonzero. | is zero or nonzero.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
INLINE uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist ) INLINE uint64_t softfloat_shiftRightJam64(uint64_t a, uint_fast32_t dist) {
{ return (dist < 63) ? a >> dist | ((uint64_t)(a << (-dist & 63)) != 0) : (a != 0);
return
(dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0);
} }
#else #else
uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist ); uint64_t softfloat_shiftRightJam64(uint64_t a, uint_fast32_t dist);
#endif #endif
#endif #endif
@ -112,10 +107,9 @@ extern const uint_least8_t softfloat_countLeadingZeros8[256];
| 'a'. If 'a' is zero, 16 is returned. | 'a'. If 'a' is zero, 16 is returned.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ) INLINE uint_fast8_t softfloat_countLeadingZeros16(uint16_t a) {
{
uint_fast8_t count = 8; uint_fast8_t count = 8;
if ( 0x100 <= a ) { if(0x100 <= a) {
count = 0; count = 0;
a >>= 8; a >>= 8;
} }
@ -123,7 +117,7 @@ INLINE uint_fast8_t softfloat_countLeadingZeros16( uint16_t a )
return count; return count;
} }
#else #else
uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ); uint_fast8_t softfloat_countLeadingZeros16(uint16_t a);
#endif #endif
#endif #endif
@ -133,22 +127,21 @@ uint_fast8_t softfloat_countLeadingZeros16( uint16_t a );
| 'a'. If 'a' is zero, 32 is returned. | 'a'. If 'a' is zero, 32 is returned.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
INLINE uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ) INLINE uint_fast8_t softfloat_countLeadingZeros32(uint32_t a) {
{
uint_fast8_t count = 0; uint_fast8_t count = 0;
if ( a < 0x10000 ) { if(a < 0x10000) {
count = 16; count = 16;
a <<= 16; a <<= 16;
} }
if ( a < 0x1000000 ) { if(a < 0x1000000) {
count += 8; count += 8;
a <<= 8; a <<= 8;
} }
count += softfloat_countLeadingZeros8[a>>24]; count += softfloat_countLeadingZeros8[a >> 24];
return count; return count;
} }
#else #else
uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ); uint_fast8_t softfloat_countLeadingZeros32(uint32_t a);
#endif #endif
#endif #endif
@ -157,7 +150,7 @@ uint_fast8_t softfloat_countLeadingZeros32( uint32_t a );
| Returns the number of leading 0 bits before the most-significant 1 bit of | Returns the number of leading 0 bits before the most-significant 1 bit of
| 'a'. If 'a' is zero, 64 is returned. | 'a'. If 'a' is zero, 64 is returned.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast8_t softfloat_countLeadingZeros64( uint64_t a ); uint_fast8_t softfloat_countLeadingZeros64(uint64_t a);
#endif #endif
extern const uint16_t softfloat_approxRecip_1k0s[16]; extern const uint16_t softfloat_approxRecip_1k0s[16];
@ -176,9 +169,9 @@ extern const uint16_t softfloat_approxRecip_1k1s[16];
| (units in the last place). | (units in the last place).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef SOFTFLOAT_FAST_DIV64TO32 #ifdef SOFTFLOAT_FAST_DIV64TO32
#define softfloat_approxRecip32_1( a ) ((uint32_t) (UINT64_C( 0x7FFFFFFFFFFFFFFF ) / (uint32_t) (a))) #define softfloat_approxRecip32_1(a) ((uint32_t)(UINT64_C(0x7FFFFFFFFFFFFFFF) / (uint32_t)(a)))
#else #else
uint32_t softfloat_approxRecip32_1( uint32_t a ); uint32_t softfloat_approxRecip32_1(uint32_t a);
#endif #endif
#endif #endif
@ -204,7 +197,7 @@ extern const uint16_t softfloat_approxRecipSqrt_1k1s[16];
| returned is also always within the range 0.5 to 1; thus, the most- | returned is also always within the range 0.5 to 1; thus, the most-
| significant bit of the result is always set. | significant bit of the result is always set.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a ); uint32_t softfloat_approxRecipSqrt32_1(unsigned int oddExpA, uint32_t a);
#endif #endif
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
@ -222,10 +215,9 @@ uint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a );
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (1 <= INLINE_LEVEL)
INLINE INLINE
bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) bool softfloat_eq128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) { return (a64 == b64) && (a0 == b0); }
{ return (a64 == b64) && (a0 == b0); }
#else #else
bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); bool softfloat_eq128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
#endif #endif
#endif #endif
@ -237,10 +229,9 @@ bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE INLINE
bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) { return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); }
{ return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); }
#else #else
bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
#endif #endif
#endif #endif
@ -252,10 +243,9 @@ bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE INLINE
bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) { return (a64 < b64) || ((a64 == b64) && (a0 < b0)); }
{ return (a64 < b64) || ((a64 == b64) && (a0 < b0)); }
#else #else
bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
#endif #endif
#endif #endif
@ -266,17 +256,14 @@ bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE INLINE
struct uint128 struct uint128 softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint_fast8_t dist) {
softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist )
{
struct uint128 z; struct uint128 z;
z.v64 = a64<<dist | a0>>(-dist & 63); z.v64 = a64 << dist | a0 >> (-dist & 63);
z.v0 = a0<<dist; z.v0 = a0 << dist;
return z; return z;
} }
#else #else
struct uint128 struct uint128 softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint_fast8_t dist);
softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist );
#endif #endif
#endif #endif
@ -287,17 +274,14 @@ struct uint128
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE INLINE
struct uint128 struct uint128 softfloat_shortShiftRight128(uint64_t a64, uint64_t a0, uint_fast8_t dist) {
softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist )
{
struct uint128 z; struct uint128 z;
z.v64 = a64>>dist; z.v64 = a64 >> dist;
z.v0 = a64<<(-dist & 63) | a0>>dist; z.v0 = a64 << (-dist & 63) | a0 >> dist;
return z; return z;
} }
#else #else
struct uint128 struct uint128 softfloat_shortShiftRight128(uint64_t a64, uint64_t a0, uint_fast8_t dist);
softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist );
#endif #endif
#endif #endif
@ -308,19 +292,14 @@ struct uint128
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE INLINE
struct uint64_extra struct uint64_extra softfloat_shortShiftRightJam64Extra(uint64_t a, uint64_t extra, uint_fast8_t dist) {
softfloat_shortShiftRightJam64Extra(
uint64_t a, uint64_t extra, uint_fast8_t dist )
{
struct uint64_extra z; struct uint64_extra z;
z.v = a>>dist; z.v = a >> dist;
z.extra = a<<(-dist & 63) | (extra != 0); z.extra = a << (-dist & 63) | (extra != 0);
return z; return z;
} }
#else #else
struct uint64_extra struct uint64_extra softfloat_shortShiftRightJam64Extra(uint64_t a, uint64_t extra, uint_fast8_t dist);
softfloat_shortShiftRightJam64Extra(
uint64_t a, uint64_t extra, uint_fast8_t dist );
#endif #endif
#endif #endif
@ -334,22 +313,15 @@ struct uint64_extra
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
INLINE INLINE
struct uint128 struct uint128 softfloat_shortShiftRightJam128(uint64_t a64, uint64_t a0, uint_fast8_t dist) {
softfloat_shortShiftRightJam128(
uint64_t a64, uint64_t a0, uint_fast8_t dist )
{
uint_fast8_t negDist = -dist; uint_fast8_t negDist = -dist;
struct uint128 z; struct uint128 z;
z.v64 = a64>>dist; z.v64 = a64 >> dist;
z.v0 = z.v0 = a64 << (negDist & 63) | a0 >> dist | ((uint64_t)(a0 << (negDist & 63)) != 0);
a64<<(negDist & 63) | a0>>dist
| ((uint64_t) (a0<<(negDist & 63)) != 0);
return z; return z;
} }
#else #else
struct uint128 struct uint128 softfloat_shortShiftRightJam128(uint64_t a64, uint64_t a0, uint_fast8_t dist);
softfloat_shortShiftRightJam128(
uint64_t a64, uint64_t a0, uint_fast8_t dist );
#endif #endif
#endif #endif
@ -360,21 +332,16 @@ struct uint128
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
INLINE INLINE
struct uint128_extra struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist) {
softfloat_shortShiftRightJam128Extra(
uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist )
{
uint_fast8_t negDist = -dist; uint_fast8_t negDist = -dist;
struct uint128_extra z; struct uint128_extra z;
z.v.v64 = a64>>dist; z.v.v64 = a64 >> dist;
z.v.v0 = a64<<(negDist & 63) | a0>>dist; z.v.v0 = a64 << (negDist & 63) | a0 >> dist;
z.extra = a0<<(negDist & 63) | (extra != 0); z.extra = a0 << (negDist & 63) | (extra != 0);
return z; return z;
} }
#else #else
struct uint128_extra struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist);
softfloat_shortShiftRightJam128Extra(
uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist );
#endif #endif
#endif #endif
@ -397,14 +364,11 @@ struct uint128_extra
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (4 <= INLINE_LEVEL)
INLINE INLINE
struct uint64_extra struct uint64_extra softfloat_shiftRightJam64Extra(uint64_t a, uint64_t extra, uint_fast32_t dist) {
softfloat_shiftRightJam64Extra(
uint64_t a, uint64_t extra, uint_fast32_t dist )
{
struct uint64_extra z; struct uint64_extra z;
if ( dist < 64 ) { if(dist < 64) {
z.v = a>>dist; z.v = a >> dist;
z.extra = a<<(-dist & 63); z.extra = a << (-dist & 63);
} else { } else {
z.v = 0; z.v = 0;
z.extra = (dist == 64) ? a : (a != 0); z.extra = (dist == 64) ? a : (a != 0);
@ -413,9 +377,7 @@ struct uint64_extra
return z; return z;
} }
#else #else
struct uint64_extra struct uint64_extra softfloat_shiftRightJam64Extra(uint64_t a, uint64_t extra, uint_fast32_t dist);
softfloat_shiftRightJam64Extra(
uint64_t a, uint64_t extra, uint_fast32_t dist );
#endif #endif
#endif #endif
@ -430,8 +392,7 @@ struct uint64_extra
| greater than 128, the result will be either 0 or 1, depending on whether the | greater than 128, the result will be either 0 or 1, depending on whether the
| original 128 bits are all zeros. | original 128 bits are all zeros.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 struct uint128 softfloat_shiftRightJam128(uint64_t a64, uint64_t a0, uint_fast32_t dist);
softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t dist );
#endif #endif
#ifndef softfloat_shiftRightJam128Extra #ifndef softfloat_shiftRightJam128Extra
@ -452,9 +413,7 @@ struct uint128
| is modified as described above and returned in the 'extra' field of the | is modified as described above and returned in the 'extra' field of the
| result.) | result.)
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128_extra struct uint128_extra softfloat_shiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist);
softfloat_shiftRightJam128Extra(
uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist );
#endif #endif
#ifndef softfloat_shiftRightJam256M #ifndef softfloat_shiftRightJam256M
@ -470,9 +429,7 @@ struct uint128_extra
| is greater than 256, the stored result will be either 0 or 1, depending on | is greater than 256, the stored result will be either 0 or 1, depending on
| whether the original 256 bits are all zeros. | whether the original 256 bits are all zeros.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_shiftRightJam256M(const uint64_t* aPtr, uint_fast32_t dist, uint64_t* zPtr);
softfloat_shiftRightJam256M(
const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr );
#endif #endif
#ifndef softfloat_add128 #ifndef softfloat_add128
@ -483,17 +440,14 @@ void
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE INLINE
struct uint128 struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) {
softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
{
struct uint128 z; struct uint128 z;
z.v0 = a0 + b0; z.v0 = a0 + b0;
z.v64 = a64 + b64 + (z.v0 < a0); z.v64 = a64 + b64 + (z.v0 < a0);
return z; return z;
} }
#else #else
struct uint128 struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
#endif #endif
#endif #endif
@ -505,9 +459,7 @@ struct uint128
| an array of four 64-bit elements that concatenate in the platform's normal | an array of four 64-bit elements that concatenate in the platform's normal
| endian order to form a 256-bit integer. | endian order to form a 256-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_add256M(const uint64_t* aPtr, const uint64_t* bPtr, uint64_t* zPtr);
softfloat_add256M(
const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr );
#endif #endif
#ifndef softfloat_sub128 #ifndef softfloat_sub128
@ -518,9 +470,7 @@ void
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE INLINE
struct uint128 struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) {
softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
{
struct uint128 z; struct uint128 z;
z.v0 = a0 - b0; z.v0 = a0 - b0;
z.v64 = a64 - b64; z.v64 = a64 - b64;
@ -528,8 +478,7 @@ struct uint128
return z; return z;
} }
#else #else
struct uint128 struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
#endif #endif
#endif #endif
@ -542,9 +491,7 @@ struct uint128
| 64-bit elements that concatenate in the platform's normal endian order to | 64-bit elements that concatenate in the platform's normal endian order to
| form a 256-bit integer. | form a 256-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_sub256M(const uint64_t* aPtr, const uint64_t* bPtr, uint64_t* zPtr);
softfloat_sub256M(
const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr );
#endif #endif
#ifndef softfloat_mul64ByShifted32To128 #ifndef softfloat_mul64ByShifted32To128
@ -552,17 +499,16 @@ void
| Returns the 128-bit product of 'a', 'b', and 2^32. | Returns the 128-bit product of 'a', 'b', and 2^32.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
INLINE struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ) INLINE struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b) {
{
uint_fast64_t mid; uint_fast64_t mid;
struct uint128 z; struct uint128 z;
mid = (uint_fast64_t) (uint32_t) a * b; mid = (uint_fast64_t)(uint32_t)a * b;
z.v0 = mid<<32; z.v0 = mid << 32;
z.v64 = (uint_fast64_t) (uint32_t) (a>>32) * b + (mid>>32); z.v64 = (uint_fast64_t)(uint32_t)(a >> 32) * b + (mid >> 32);
return z; return z;
} }
#else #else
struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ); struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b);
#endif #endif
#endif #endif
@ -570,7 +516,7 @@ struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Returns the 128-bit product of 'a' and 'b'. | Returns the 128-bit product of 'a' and 'b'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ); struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b);
#endif #endif
#ifndef softfloat_mul128By32 #ifndef softfloat_mul128By32
@ -581,19 +527,18 @@ struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b );
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (4 <= INLINE_LEVEL)
INLINE INLINE
struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ) struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b) {
{
struct uint128 z; struct uint128 z;
uint_fast64_t mid; uint_fast64_t mid;
uint_fast32_t carry; uint_fast32_t carry;
z.v0 = a0 * b; z.v0 = a0 * b;
mid = (uint_fast64_t) (uint32_t) (a0>>32) * b; mid = (uint_fast64_t)(uint32_t)(a0 >> 32) * b;
carry = (uint32_t) ((uint_fast32_t) (z.v0>>32) - (uint_fast32_t) mid); carry = (uint32_t)((uint_fast32_t)(z.v0 >> 32) - (uint_fast32_t)mid);
z.v64 = a64 * b + (uint_fast32_t) ((mid + carry)>>32); z.v64 = a64 * b + (uint_fast32_t)((mid + carry) >> 32);
return z; return z;
} }
#else #else
struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ); struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b);
#endif #endif
#endif #endif
@ -605,9 +550,7 @@ struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b );
| Argument 'zPtr' points to an array of four 64-bit elements that concatenate | Argument 'zPtr' points to an array of four 64-bit elements that concatenate
| in the platform's normal endian order to form a 256-bit integer. | in the platform's normal endian order to form a 256-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t* zPtr);
softfloat_mul128To256M(
uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr );
#endif #endif
#else #else
@ -626,7 +569,7 @@ void
| Each of 'aPtr' and 'bPtr' points to an array of three 32-bit elements that | Each of 'aPtr' and 'bPtr' points to an array of three 32-bit elements that
| concatenate in the platform's normal endian order to form a 96-bit integer. | concatenate in the platform's normal endian order to form a 96-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr ); int_fast8_t softfloat_compare96M(const uint32_t* aPtr, const uint32_t* bPtr);
#endif #endif
#ifndef softfloat_compare128M #ifndef softfloat_compare128M
@ -638,8 +581,7 @@ int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr );
| Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that | Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that
| concatenate in the platform's normal endian order to form a 128-bit integer. | concatenate in the platform's normal endian order to form a 128-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
int_fast8_t int_fast8_t softfloat_compare128M(const uint32_t* aPtr, const uint32_t* bPtr);
softfloat_compare128M( const uint32_t *aPtr, const uint32_t *bPtr );
#endif #endif
#ifndef softfloat_shortShiftLeft64To96M #ifndef softfloat_shortShiftLeft64To96M
@ -652,19 +594,14 @@ int_fast8_t
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
INLINE INLINE
void void softfloat_shortShiftLeft64To96M(uint64_t a, uint_fast8_t dist, uint32_t* zPtr) {
softfloat_shortShiftLeft64To96M( zPtr[indexWord(3, 0)] = (uint32_t)a << dist;
uint64_t a, uint_fast8_t dist, uint32_t *zPtr )
{
zPtr[indexWord( 3, 0 )] = (uint32_t) a<<dist;
a >>= 32 - dist; a >>= 32 - dist;
zPtr[indexWord( 3, 2 )] = a>>32; zPtr[indexWord(3, 2)] = a >> 32;
zPtr[indexWord( 3, 1 )] = a; zPtr[indexWord(3, 1)] = a;
} }
#else #else
void void softfloat_shortShiftLeft64To96M(uint64_t a, uint_fast8_t dist, uint32_t* zPtr);
softfloat_shortShiftLeft64To96M(
uint64_t a, uint_fast8_t dist, uint32_t *zPtr );
#endif #endif
#endif #endif
@ -678,13 +615,7 @@ void
| that concatenate in the platform's normal endian order to form an N-bit | that concatenate in the platform's normal endian order to form an N-bit
| integer. | integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_shortShiftLeftM(uint_fast8_t size_words, const uint32_t* aPtr, uint_fast8_t dist, uint32_t* zPtr);
softfloat_shortShiftLeftM(
uint_fast8_t size_words,
const uint32_t *aPtr,
uint_fast8_t dist,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_shortShiftLeft96M #ifndef softfloat_shortShiftLeft96M
@ -692,7 +623,7 @@ void
| This function or macro is the same as 'softfloat_shortShiftLeftM' with | This function or macro is the same as 'softfloat_shortShiftLeftM' with
| 'size_words' = 3 (N = 96). | 'size_words' = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shortShiftLeft96M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 3, aPtr, dist, zPtr ) #define softfloat_shortShiftLeft96M(aPtr, dist, zPtr) softfloat_shortShiftLeftM(3, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shortShiftLeft128M #ifndef softfloat_shortShiftLeft128M
@ -700,7 +631,7 @@ void
| This function or macro is the same as 'softfloat_shortShiftLeftM' with | This function or macro is the same as 'softfloat_shortShiftLeftM' with
| 'size_words' = 4 (N = 128). | 'size_words' = 4 (N = 128).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shortShiftLeft128M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 4, aPtr, dist, zPtr ) #define softfloat_shortShiftLeft128M(aPtr, dist, zPtr) softfloat_shortShiftLeftM(4, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shortShiftLeft160M #ifndef softfloat_shortShiftLeft160M
@ -708,7 +639,7 @@ void
| This function or macro is the same as 'softfloat_shortShiftLeftM' with | This function or macro is the same as 'softfloat_shortShiftLeftM' with
| 'size_words' = 5 (N = 160). | 'size_words' = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shortShiftLeft160M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 5, aPtr, dist, zPtr ) #define softfloat_shortShiftLeft160M(aPtr, dist, zPtr) softfloat_shortShiftLeftM(5, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shiftLeftM #ifndef softfloat_shiftLeftM
@ -722,13 +653,7 @@ void
| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is | The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
| greater than N, the stored result will be 0. | greater than N, the stored result will be 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_shiftLeftM(uint_fast8_t size_words, const uint32_t* aPtr, uint32_t dist, uint32_t* zPtr);
softfloat_shiftLeftM(
uint_fast8_t size_words,
const uint32_t *aPtr,
uint32_t dist,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_shiftLeft96M #ifndef softfloat_shiftLeft96M
@ -736,7 +661,7 @@ void
| This function or macro is the same as 'softfloat_shiftLeftM' with | This function or macro is the same as 'softfloat_shiftLeftM' with
| 'size_words' = 3 (N = 96). | 'size_words' = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shiftLeft96M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 3, aPtr, dist, zPtr ) #define softfloat_shiftLeft96M(aPtr, dist, zPtr) softfloat_shiftLeftM(3, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shiftLeft128M #ifndef softfloat_shiftLeft128M
@ -744,7 +669,7 @@ void
| This function or macro is the same as 'softfloat_shiftLeftM' with | This function or macro is the same as 'softfloat_shiftLeftM' with
| 'size_words' = 4 (N = 128). | 'size_words' = 4 (N = 128).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shiftLeft128M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 4, aPtr, dist, zPtr ) #define softfloat_shiftLeft128M(aPtr, dist, zPtr) softfloat_shiftLeftM(4, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shiftLeft160M #ifndef softfloat_shiftLeft160M
@ -752,7 +677,7 @@ void
| This function or macro is the same as 'softfloat_shiftLeftM' with | This function or macro is the same as 'softfloat_shiftLeftM' with
| 'size_words' = 5 (N = 160). | 'size_words' = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shiftLeft160M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 5, aPtr, dist, zPtr ) #define softfloat_shiftLeft160M(aPtr, dist, zPtr) softfloat_shiftLeftM(5, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shortShiftRightM #ifndef softfloat_shortShiftRightM
@ -765,13 +690,7 @@ void
| that concatenate in the platform's normal endian order to form an N-bit | that concatenate in the platform's normal endian order to form an N-bit
| integer. | integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_shortShiftRightM(uint_fast8_t size_words, const uint32_t* aPtr, uint_fast8_t dist, uint32_t* zPtr);
softfloat_shortShiftRightM(
uint_fast8_t size_words,
const uint32_t *aPtr,
uint_fast8_t dist,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_shortShiftRight128M #ifndef softfloat_shortShiftRight128M
@ -779,7 +698,7 @@ void
| This function or macro is the same as 'softfloat_shortShiftRightM' with | This function or macro is the same as 'softfloat_shortShiftRightM' with
| 'size_words' = 4 (N = 128). | 'size_words' = 4 (N = 128).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shortShiftRight128M( aPtr, dist, zPtr ) softfloat_shortShiftRightM( 4, aPtr, dist, zPtr ) #define softfloat_shortShiftRight128M(aPtr, dist, zPtr) softfloat_shortShiftRightM(4, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shortShiftRight160M #ifndef softfloat_shortShiftRight160M
@ -787,7 +706,7 @@ void
| This function or macro is the same as 'softfloat_shortShiftRightM' with | This function or macro is the same as 'softfloat_shortShiftRightM' with
| 'size_words' = 5 (N = 160). | 'size_words' = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shortShiftRight160M( aPtr, dist, zPtr ) softfloat_shortShiftRightM( 5, aPtr, dist, zPtr ) #define softfloat_shortShiftRight160M(aPtr, dist, zPtr) softfloat_shortShiftRightM(5, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shortShiftRightJamM #ifndef softfloat_shortShiftRightJamM
@ -801,9 +720,7 @@ void
| to a 'size_words'-long array of 32-bit elements that concatenate in the | to a 'size_words'-long array of 32-bit elements that concatenate in the
| platform's normal endian order to form an N-bit integer. | platform's normal endian order to form an N-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_shortShiftRightJamM(uint_fast8_t, const uint32_t*, uint_fast8_t, uint32_t*);
softfloat_shortShiftRightJamM(
uint_fast8_t, const uint32_t *, uint_fast8_t, uint32_t * );
#endif #endif
#ifndef softfloat_shortShiftRightJam160M #ifndef softfloat_shortShiftRightJam160M
@ -811,7 +728,7 @@ void
| This function or macro is the same as 'softfloat_shortShiftRightJamM' with | This function or macro is the same as 'softfloat_shortShiftRightJamM' with
| 'size_words' = 5 (N = 160). | 'size_words' = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shortShiftRightJam160M( aPtr, dist, zPtr ) softfloat_shortShiftRightJamM( 5, aPtr, dist, zPtr ) #define softfloat_shortShiftRightJam160M(aPtr, dist, zPtr) softfloat_shortShiftRightJamM(5, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shiftRightM #ifndef softfloat_shiftRightM
@ -825,13 +742,7 @@ void
| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is | The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
| greater than N, the stored result will be 0. | greater than N, the stored result will be 0.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_shiftRightM(uint_fast8_t size_words, const uint32_t* aPtr, uint32_t dist, uint32_t* zPtr);
softfloat_shiftRightM(
uint_fast8_t size_words,
const uint32_t *aPtr,
uint32_t dist,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_shiftRight96M #ifndef softfloat_shiftRight96M
@ -839,7 +750,7 @@ void
| This function or macro is the same as 'softfloat_shiftRightM' with | This function or macro is the same as 'softfloat_shiftRightM' with
| 'size_words' = 3 (N = 96). | 'size_words' = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shiftRight96M( aPtr, dist, zPtr ) softfloat_shiftRightM( 3, aPtr, dist, zPtr ) #define softfloat_shiftRight96M(aPtr, dist, zPtr) softfloat_shiftRightM(3, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shiftRightJamM #ifndef softfloat_shiftRightJamM
@ -856,13 +767,7 @@ void
| is greater than N, the stored result will be either 0 or 1, depending on | is greater than N, the stored result will be either 0 or 1, depending on
| whether the original N bits are all zeros. | whether the original N bits are all zeros.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_shiftRightJamM(uint_fast8_t size_words, const uint32_t* aPtr, uint32_t dist, uint32_t* zPtr);
softfloat_shiftRightJamM(
uint_fast8_t size_words,
const uint32_t *aPtr,
uint32_t dist,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_shiftRightJam96M #ifndef softfloat_shiftRightJam96M
@ -870,7 +775,7 @@ void
| This function or macro is the same as 'softfloat_shiftRightJamM' with | This function or macro is the same as 'softfloat_shiftRightJamM' with
| 'size_words' = 3 (N = 96). | 'size_words' = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shiftRightJam96M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 3, aPtr, dist, zPtr ) #define softfloat_shiftRightJam96M(aPtr, dist, zPtr) softfloat_shiftRightJamM(3, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shiftRightJam128M #ifndef softfloat_shiftRightJam128M
@ -878,7 +783,7 @@ void
| This function or macro is the same as 'softfloat_shiftRightJamM' with | This function or macro is the same as 'softfloat_shiftRightJamM' with
| 'size_words' = 4 (N = 128). | 'size_words' = 4 (N = 128).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shiftRightJam128M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 4, aPtr, dist, zPtr ) #define softfloat_shiftRightJam128M(aPtr, dist, zPtr) softfloat_shiftRightJamM(4, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_shiftRightJam160M #ifndef softfloat_shiftRightJam160M
@ -886,7 +791,7 @@ void
| This function or macro is the same as 'softfloat_shiftRightJamM' with | This function or macro is the same as 'softfloat_shiftRightJamM' with
| 'size_words' = 5 (N = 160). | 'size_words' = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_shiftRightJam160M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 5, aPtr, dist, zPtr ) #define softfloat_shiftRightJam160M(aPtr, dist, zPtr) softfloat_shiftRightJamM(5, aPtr, dist, zPtr)
#endif #endif
#ifndef softfloat_addM #ifndef softfloat_addM
@ -898,13 +803,7 @@ void
| elements that concatenate in the platform's normal endian order to form an | elements that concatenate in the platform's normal endian order to form an
| N-bit integer. | N-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_addM(uint_fast8_t size_words, const uint32_t* aPtr, const uint32_t* bPtr, uint32_t* zPtr);
softfloat_addM(
uint_fast8_t size_words,
const uint32_t *aPtr,
const uint32_t *bPtr,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_add96M #ifndef softfloat_add96M
@ -912,7 +811,7 @@ void
| This function or macro is the same as 'softfloat_addM' with 'size_words' | This function or macro is the same as 'softfloat_addM' with 'size_words'
| = 3 (N = 96). | = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_add96M( aPtr, bPtr, zPtr ) softfloat_addM( 3, aPtr, bPtr, zPtr ) #define softfloat_add96M(aPtr, bPtr, zPtr) softfloat_addM(3, aPtr, bPtr, zPtr)
#endif #endif
#ifndef softfloat_add128M #ifndef softfloat_add128M
@ -920,7 +819,7 @@ void
| This function or macro is the same as 'softfloat_addM' with 'size_words' | This function or macro is the same as 'softfloat_addM' with 'size_words'
| = 4 (N = 128). | = 4 (N = 128).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_add128M( aPtr, bPtr, zPtr ) softfloat_addM( 4, aPtr, bPtr, zPtr ) #define softfloat_add128M(aPtr, bPtr, zPtr) softfloat_addM(4, aPtr, bPtr, zPtr)
#endif #endif
#ifndef softfloat_add160M #ifndef softfloat_add160M
@ -928,7 +827,7 @@ void
| This function or macro is the same as 'softfloat_addM' with 'size_words' | This function or macro is the same as 'softfloat_addM' with 'size_words'
| = 5 (N = 160). | = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_add160M( aPtr, bPtr, zPtr ) softfloat_addM( 5, aPtr, bPtr, zPtr ) #define softfloat_add160M(aPtr, bPtr, zPtr) softfloat_addM(5, aPtr, bPtr, zPtr)
#endif #endif
#ifndef softfloat_addCarryM #ifndef softfloat_addCarryM
@ -940,14 +839,7 @@ void
| points to a 'size_words'-long array of 32-bit elements that concatenate in | points to a 'size_words'-long array of 32-bit elements that concatenate in
| the platform's normal endian order to form an N-bit integer. | the platform's normal endian order to form an N-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast8_t uint_fast8_t softfloat_addCarryM(uint_fast8_t size_words, const uint32_t* aPtr, const uint32_t* bPtr, uint_fast8_t carry, uint32_t* zPtr);
softfloat_addCarryM(
uint_fast8_t size_words,
const uint32_t *aPtr,
const uint32_t *bPtr,
uint_fast8_t carry,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_addComplCarryM #ifndef softfloat_addComplCarryM
@ -956,14 +848,8 @@ uint_fast8_t
| the value of the unsigned integer pointed to by 'bPtr' is bit-wise completed | the value of the unsigned integer pointed to by 'bPtr' is bit-wise completed
| before the addition. | before the addition.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast8_t uint_fast8_t softfloat_addComplCarryM(uint_fast8_t size_words, const uint32_t* aPtr, const uint32_t* bPtr, uint_fast8_t carry,
softfloat_addComplCarryM( uint32_t* zPtr);
uint_fast8_t size_words,
const uint32_t *aPtr,
const uint32_t *bPtr,
uint_fast8_t carry,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_addComplCarry96M #ifndef softfloat_addComplCarry96M
@ -971,7 +857,7 @@ uint_fast8_t
| This function or macro is the same as 'softfloat_addComplCarryM' with | This function or macro is the same as 'softfloat_addComplCarryM' with
| 'size_words' = 3 (N = 96). | 'size_words' = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_addComplCarry96M( aPtr, bPtr, carry, zPtr ) softfloat_addComplCarryM( 3, aPtr, bPtr, carry, zPtr ) #define softfloat_addComplCarry96M(aPtr, bPtr, carry, zPtr) softfloat_addComplCarryM(3, aPtr, bPtr, carry, zPtr)
#endif #endif
#ifndef softfloat_negXM #ifndef softfloat_negXM
@ -981,7 +867,7 @@ uint_fast8_t
| points to a 'size_words'-long array of 32-bit elements that concatenate in | points to a 'size_words'-long array of 32-bit elements that concatenate in
| the platform's normal endian order to form an N-bit integer. | the platform's normal endian order to form an N-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ); void softfloat_negXM(uint_fast8_t size_words, uint32_t* zPtr);
#endif #endif
#ifndef softfloat_negX96M #ifndef softfloat_negX96M
@ -989,7 +875,7 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr );
| This function or macro is the same as 'softfloat_negXM' with 'size_words' | This function or macro is the same as 'softfloat_negXM' with 'size_words'
| = 3 (N = 96). | = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_negX96M( zPtr ) softfloat_negXM( 3, zPtr ) #define softfloat_negX96M(zPtr) softfloat_negXM(3, zPtr)
#endif #endif
#ifndef softfloat_negX128M #ifndef softfloat_negX128M
@ -997,7 +883,7 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr );
| This function or macro is the same as 'softfloat_negXM' with 'size_words' | This function or macro is the same as 'softfloat_negXM' with 'size_words'
| = 4 (N = 128). | = 4 (N = 128).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_negX128M( zPtr ) softfloat_negXM( 4, zPtr ) #define softfloat_negX128M(zPtr) softfloat_negXM(4, zPtr)
#endif #endif
#ifndef softfloat_negX160M #ifndef softfloat_negX160M
@ -1005,7 +891,7 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr );
| This function or macro is the same as 'softfloat_negXM' with 'size_words' | This function or macro is the same as 'softfloat_negXM' with 'size_words'
| = 5 (N = 160). | = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_negX160M( zPtr ) softfloat_negXM( 5, zPtr ) #define softfloat_negX160M(zPtr) softfloat_negXM(5, zPtr)
#endif #endif
#ifndef softfloat_negX256M #ifndef softfloat_negX256M
@ -1013,7 +899,7 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr );
| This function or macro is the same as 'softfloat_negXM' with 'size_words' | This function or macro is the same as 'softfloat_negXM' with 'size_words'
| = 8 (N = 256). | = 8 (N = 256).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_negX256M( zPtr ) softfloat_negXM( 8, zPtr ) #define softfloat_negX256M(zPtr) softfloat_negXM(8, zPtr)
#endif #endif
#ifndef softfloat_sub1XM #ifndef softfloat_sub1XM
@ -1024,7 +910,7 @@ void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr );
| elements that concatenate in the platform's normal endian order to form an | elements that concatenate in the platform's normal endian order to form an
| N-bit integer. | N-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr ); void softfloat_sub1XM(uint_fast8_t size_words, uint32_t* zPtr);
#endif #endif
#ifndef softfloat_sub1X96M #ifndef softfloat_sub1X96M
@ -1032,7 +918,7 @@ void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr );
| This function or macro is the same as 'softfloat_sub1XM' with 'size_words' | This function or macro is the same as 'softfloat_sub1XM' with 'size_words'
| = 3 (N = 96). | = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_sub1X96M( zPtr ) softfloat_sub1XM( 3, zPtr ) #define softfloat_sub1X96M(zPtr) softfloat_sub1XM(3, zPtr)
#endif #endif
#ifndef softfloat_sub1X160M #ifndef softfloat_sub1X160M
@ -1040,7 +926,7 @@ void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr );
| This function or macro is the same as 'softfloat_sub1XM' with 'size_words' | This function or macro is the same as 'softfloat_sub1XM' with 'size_words'
| = 5 (N = 160). | = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_sub1X160M( zPtr ) softfloat_sub1XM( 5, zPtr ) #define softfloat_sub1X160M(zPtr) softfloat_sub1XM(5, zPtr)
#endif #endif
#ifndef softfloat_subM #ifndef softfloat_subM
@ -1052,13 +938,7 @@ void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr );
| array of 32-bit elements that concatenate in the platform's normal endian | array of 32-bit elements that concatenate in the platform's normal endian
| order to form an N-bit integer. | order to form an N-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_subM(uint_fast8_t size_words, const uint32_t* aPtr, const uint32_t* bPtr, uint32_t* zPtr);
softfloat_subM(
uint_fast8_t size_words,
const uint32_t *aPtr,
const uint32_t *bPtr,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_sub96M #ifndef softfloat_sub96M
@ -1066,7 +946,7 @@ void
| This function or macro is the same as 'softfloat_subM' with 'size_words' | This function or macro is the same as 'softfloat_subM' with 'size_words'
| = 3 (N = 96). | = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_sub96M( aPtr, bPtr, zPtr ) softfloat_subM( 3, aPtr, bPtr, zPtr ) #define softfloat_sub96M(aPtr, bPtr, zPtr) softfloat_subM(3, aPtr, bPtr, zPtr)
#endif #endif
#ifndef softfloat_sub128M #ifndef softfloat_sub128M
@ -1074,7 +954,7 @@ void
| This function or macro is the same as 'softfloat_subM' with 'size_words' | This function or macro is the same as 'softfloat_subM' with 'size_words'
| = 4 (N = 128). | = 4 (N = 128).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_sub128M( aPtr, bPtr, zPtr ) softfloat_subM( 4, aPtr, bPtr, zPtr ) #define softfloat_sub128M(aPtr, bPtr, zPtr) softfloat_subM(4, aPtr, bPtr, zPtr)
#endif #endif
#ifndef softfloat_sub160M #ifndef softfloat_sub160M
@ -1082,7 +962,7 @@ void
| This function or macro is the same as 'softfloat_subM' with 'size_words' | This function or macro is the same as 'softfloat_subM' with 'size_words'
| = 5 (N = 160). | = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_sub160M( aPtr, bPtr, zPtr ) softfloat_subM( 5, aPtr, bPtr, zPtr ) #define softfloat_sub160M(aPtr, bPtr, zPtr) softfloat_subM(5, aPtr, bPtr, zPtr)
#endif #endif
#ifndef softfloat_mul64To128M #ifndef softfloat_mul64To128M
@ -1092,7 +972,7 @@ void
| elements that concatenate in the platform's normal endian order to form a | elements that concatenate in the platform's normal endian order to form a
| 128-bit integer. | 128-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr ); void softfloat_mul64To128M(uint64_t a, uint64_t b, uint32_t* zPtr);
#endif #endif
#ifndef softfloat_mul128MTo256M #ifndef softfloat_mul128MTo256M
@ -1104,9 +984,7 @@ void softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr );
| Argument 'zPtr' points to an array of eight 32-bit elements that concatenate | Argument 'zPtr' points to an array of eight 32-bit elements that concatenate
| to form a 256-bit integer. | to form a 256-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_mul128MTo256M(const uint32_t* aPtr, const uint32_t* bPtr, uint32_t* zPtr);
softfloat_mul128MTo256M(
const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr );
#endif #endif
#ifndef softfloat_remStepMBy32 #ifndef softfloat_remStepMBy32
@ -1119,15 +997,8 @@ void
| to a 'size_words'-long array of 32-bit elements that concatenate in the | to a 'size_words'-long array of 32-bit elements that concatenate in the
| platform's normal endian order to form an N-bit integer. | platform's normal endian order to form an N-bit integer.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void softfloat_remStepMBy32(uint_fast8_t size_words, const uint32_t* remPtr, uint_fast8_t dist, const uint32_t* bPtr, uint32_t q,
softfloat_remStepMBy32( uint32_t* zPtr);
uint_fast8_t size_words,
const uint32_t *remPtr,
uint_fast8_t dist,
const uint32_t *bPtr,
uint32_t q,
uint32_t *zPtr
);
#endif #endif
#ifndef softfloat_remStep96MBy32 #ifndef softfloat_remStep96MBy32
@ -1135,7 +1006,7 @@ void
| This function or macro is the same as 'softfloat_remStepMBy32' with | This function or macro is the same as 'softfloat_remStepMBy32' with
| 'size_words' = 3 (N = 96). | 'size_words' = 3 (N = 96).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_remStep96MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 3, remPtr, dist, bPtr, q, zPtr ) #define softfloat_remStep96MBy32(remPtr, dist, bPtr, q, zPtr) softfloat_remStepMBy32(3, remPtr, dist, bPtr, q, zPtr)
#endif #endif
#ifndef softfloat_remStep128MBy32 #ifndef softfloat_remStep128MBy32
@ -1143,7 +1014,7 @@ void
| This function or macro is the same as 'softfloat_remStepMBy32' with | This function or macro is the same as 'softfloat_remStepMBy32' with
| 'size_words' = 4 (N = 128). | 'size_words' = 4 (N = 128).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_remStep128MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 4, remPtr, dist, bPtr, q, zPtr ) #define softfloat_remStep128MBy32(remPtr, dist, bPtr, q, zPtr) softfloat_remStepMBy32(4, remPtr, dist, bPtr, q, zPtr)
#endif #endif
#ifndef softfloat_remStep160MBy32 #ifndef softfloat_remStep160MBy32
@ -1151,10 +1022,9 @@ void
| This function or macro is the same as 'softfloat_remStepMBy32' with | This function or macro is the same as 'softfloat_remStepMBy32' with
| 'size_words' = 5 (N = 160). | 'size_words' = 5 (N = 160).
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define softfloat_remStep160MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 5, remPtr, dist, bPtr, q, zPtr ) #define softfloat_remStep160MBy32(remPtr, dist, bPtr, q, zPtr) softfloat_remStepMBy32(5, remPtr, dist, bPtr, q, zPtr)
#endif #endif
#endif #endif
#endif #endif

View File

@ -34,7 +34,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/ =============================================================================*/
/*============================================================================ /*============================================================================
| Note: If SoftFloat is made available as a general library for programs to | Note: If SoftFloat is made available as a general library for programs to
| use, it is strongly recommended that a platform-specific version of this | use, it is strongly recommended that a platform-specific version of this
@ -42,13 +41,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
| eliminates all dependencies on compile-time macros. | eliminates all dependencies on compile-time macros.
*============================================================================*/ *============================================================================*/
#ifndef softfloat_h #ifndef softfloat_h
#define softfloat_h 1 #define softfloat_h 1
#include "softfloat_types.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "softfloat_types.h"
#ifndef THREAD_LOCAL #ifndef THREAD_LOCAL
#define THREAD_LOCAL #define THREAD_LOCAL
@ -58,10 +56,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
| Software floating-point underflow tininess-detection mode. | Software floating-point underflow tininess-detection mode.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern THREAD_LOCAL uint_fast8_t softfloat_detectTininess; extern THREAD_LOCAL uint_fast8_t softfloat_detectTininess;
enum { enum { softfloat_tininess_beforeRounding = 0, softfloat_tininess_afterRounding = 1 };
softfloat_tininess_beforeRounding = 0,
softfloat_tininess_afterRounding = 1
};
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software floating-point rounding mode. (Mode "odd" is supported only if | Software floating-point rounding mode. (Mode "odd" is supported only if
@ -69,12 +64,12 @@ enum {
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern THREAD_LOCAL uint_fast8_t softfloat_roundingMode; extern THREAD_LOCAL uint_fast8_t softfloat_roundingMode;
enum { enum {
softfloat_round_near_even = 0, softfloat_round_near_even = 0,
softfloat_round_minMag = 1, softfloat_round_minMag = 1,
softfloat_round_min = 2, softfloat_round_min = 2,
softfloat_round_max = 3, softfloat_round_max = 3,
softfloat_round_near_maxMag = 4, softfloat_round_near_maxMag = 4,
softfloat_round_odd = 6 softfloat_round_odd = 6
}; };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -82,162 +77,162 @@ enum {
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
extern THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags; extern THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags;
enum { enum {
softfloat_flag_inexact = 1, softfloat_flag_inexact = 1,
softfloat_flag_underflow = 2, softfloat_flag_underflow = 2,
softfloat_flag_overflow = 4, softfloat_flag_overflow = 4,
softfloat_flag_infinite = 8, softfloat_flag_infinite = 8,
softfloat_flag_invalid = 16 softfloat_flag_invalid = 16
}; };
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Routine to raise any or all of the software floating-point exception flags. | Routine to raise any or all of the software floating-point exception flags.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void softfloat_raiseFlags( uint_fast8_t ); void softfloat_raiseFlags(uint_fast8_t);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Integer-to-floating-point conversion routines. | Integer-to-floating-point conversion routines.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
float16_t ui32_to_f16( uint32_t ); float16_t ui32_to_f16(uint32_t);
float32_t ui32_to_f32( uint32_t ); float32_t ui32_to_f32(uint32_t);
float64_t ui32_to_f64( uint32_t ); float64_t ui32_to_f64(uint32_t);
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
extFloat80_t ui32_to_extF80( uint32_t ); extFloat80_t ui32_to_extF80(uint32_t);
float128_t ui32_to_f128( uint32_t ); float128_t ui32_to_f128(uint32_t);
#endif #endif
void ui32_to_extF80M( uint32_t, extFloat80_t * ); void ui32_to_extF80M(uint32_t, extFloat80_t*);
void ui32_to_f128M( uint32_t, float128_t * ); void ui32_to_f128M(uint32_t, float128_t*);
float16_t ui64_to_f16( uint64_t ); float16_t ui64_to_f16(uint64_t);
float32_t ui64_to_f32( uint64_t ); float32_t ui64_to_f32(uint64_t);
float64_t ui64_to_f64( uint64_t ); float64_t ui64_to_f64(uint64_t);
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
extFloat80_t ui64_to_extF80( uint64_t ); extFloat80_t ui64_to_extF80(uint64_t);
float128_t ui64_to_f128( uint64_t ); float128_t ui64_to_f128(uint64_t);
#endif #endif
void ui64_to_extF80M( uint64_t, extFloat80_t * ); void ui64_to_extF80M(uint64_t, extFloat80_t*);
void ui64_to_f128M( uint64_t, float128_t * ); void ui64_to_f128M(uint64_t, float128_t*);
float16_t i32_to_f16( int32_t ); float16_t i32_to_f16(int32_t);
float32_t i32_to_f32( int32_t ); float32_t i32_to_f32(int32_t);
float64_t i32_to_f64( int32_t ); float64_t i32_to_f64(int32_t);
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
extFloat80_t i32_to_extF80( int32_t ); extFloat80_t i32_to_extF80(int32_t);
float128_t i32_to_f128( int32_t ); float128_t i32_to_f128(int32_t);
#endif #endif
void i32_to_extF80M( int32_t, extFloat80_t * ); void i32_to_extF80M(int32_t, extFloat80_t*);
void i32_to_f128M( int32_t, float128_t * ); void i32_to_f128M(int32_t, float128_t*);
float16_t i64_to_f16( int64_t ); float16_t i64_to_f16(int64_t);
float32_t i64_to_f32( int64_t ); float32_t i64_to_f32(int64_t);
float64_t i64_to_f64( int64_t ); float64_t i64_to_f64(int64_t);
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
extFloat80_t i64_to_extF80( int64_t ); extFloat80_t i64_to_extF80(int64_t);
float128_t i64_to_f128( int64_t ); float128_t i64_to_f128(int64_t);
#endif #endif
void i64_to_extF80M( int64_t, extFloat80_t * ); void i64_to_extF80M(int64_t, extFloat80_t*);
void i64_to_f128M( int64_t, float128_t * ); void i64_to_f128M(int64_t, float128_t*);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| 16-bit (half-precision) floating-point operations. | 16-bit (half-precision) floating-point operations.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t f16_to_ui32( float16_t, uint_fast8_t, bool ); uint_fast32_t f16_to_ui32(float16_t, uint_fast8_t, bool);
uint_fast64_t f16_to_ui64( float16_t, uint_fast8_t, bool ); uint_fast64_t f16_to_ui64(float16_t, uint_fast8_t, bool);
int_fast32_t f16_to_i32( float16_t, uint_fast8_t, bool ); int_fast32_t f16_to_i32(float16_t, uint_fast8_t, bool);
int_fast64_t f16_to_i64( float16_t, uint_fast8_t, bool ); int_fast64_t f16_to_i64(float16_t, uint_fast8_t, bool);
uint_fast32_t f16_to_ui32_r_minMag( float16_t, bool ); uint_fast32_t f16_to_ui32_r_minMag(float16_t, bool);
uint_fast64_t f16_to_ui64_r_minMag( float16_t, bool ); uint_fast64_t f16_to_ui64_r_minMag(float16_t, bool);
int_fast32_t f16_to_i32_r_minMag( float16_t, bool ); int_fast32_t f16_to_i32_r_minMag(float16_t, bool);
int_fast64_t f16_to_i64_r_minMag( float16_t, bool ); int_fast64_t f16_to_i64_r_minMag(float16_t, bool);
float32_t f16_to_f32( float16_t ); float32_t f16_to_f32(float16_t);
float64_t f16_to_f64( float16_t ); float64_t f16_to_f64(float16_t);
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
extFloat80_t f16_to_extF80( float16_t ); extFloat80_t f16_to_extF80(float16_t);
float128_t f16_to_f128( float16_t ); float128_t f16_to_f128(float16_t);
#endif #endif
void f16_to_extF80M( float16_t, extFloat80_t * ); void f16_to_extF80M(float16_t, extFloat80_t*);
void f16_to_f128M( float16_t, float128_t * ); void f16_to_f128M(float16_t, float128_t*);
float16_t f16_roundToInt( float16_t, uint_fast8_t, bool ); float16_t f16_roundToInt(float16_t, uint_fast8_t, bool);
float16_t f16_add( float16_t, float16_t ); float16_t f16_add(float16_t, float16_t);
float16_t f16_sub( float16_t, float16_t ); float16_t f16_sub(float16_t, float16_t);
float16_t f16_mul( float16_t, float16_t ); float16_t f16_mul(float16_t, float16_t);
float16_t f16_mulAdd( float16_t, float16_t, float16_t ); float16_t f16_mulAdd(float16_t, float16_t, float16_t);
float16_t f16_div( float16_t, float16_t ); float16_t f16_div(float16_t, float16_t);
float16_t f16_rem( float16_t, float16_t ); float16_t f16_rem(float16_t, float16_t);
float16_t f16_sqrt( float16_t ); float16_t f16_sqrt(float16_t);
bool f16_eq( float16_t, float16_t ); bool f16_eq(float16_t, float16_t);
bool f16_le( float16_t, float16_t ); bool f16_le(float16_t, float16_t);
bool f16_lt( float16_t, float16_t ); bool f16_lt(float16_t, float16_t);
bool f16_eq_signaling( float16_t, float16_t ); bool f16_eq_signaling(float16_t, float16_t);
bool f16_le_quiet( float16_t, float16_t ); bool f16_le_quiet(float16_t, float16_t);
bool f16_lt_quiet( float16_t, float16_t ); bool f16_lt_quiet(float16_t, float16_t);
bool f16_isSignalingNaN( float16_t ); bool f16_isSignalingNaN(float16_t);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| 32-bit (single-precision) floating-point operations. | 32-bit (single-precision) floating-point operations.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t f32_to_ui32( float32_t, uint_fast8_t, bool ); uint_fast32_t f32_to_ui32(float32_t, uint_fast8_t, bool);
uint_fast64_t f32_to_ui64( float32_t, uint_fast8_t, bool ); uint_fast64_t f32_to_ui64(float32_t, uint_fast8_t, bool);
int_fast32_t f32_to_i32( float32_t, uint_fast8_t, bool ); int_fast32_t f32_to_i32(float32_t, uint_fast8_t, bool);
int_fast64_t f32_to_i64( float32_t, uint_fast8_t, bool ); int_fast64_t f32_to_i64(float32_t, uint_fast8_t, bool);
uint_fast32_t f32_to_ui32_r_minMag( float32_t, bool ); uint_fast32_t f32_to_ui32_r_minMag(float32_t, bool);
uint_fast64_t f32_to_ui64_r_minMag( float32_t, bool ); uint_fast64_t f32_to_ui64_r_minMag(float32_t, bool);
int_fast32_t f32_to_i32_r_minMag( float32_t, bool ); int_fast32_t f32_to_i32_r_minMag(float32_t, bool);
int_fast64_t f32_to_i64_r_minMag( float32_t, bool ); int_fast64_t f32_to_i64_r_minMag(float32_t, bool);
float16_t f32_to_f16( float32_t ); float16_t f32_to_f16(float32_t);
float64_t f32_to_f64( float32_t ); float64_t f32_to_f64(float32_t);
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
extFloat80_t f32_to_extF80( float32_t ); extFloat80_t f32_to_extF80(float32_t);
float128_t f32_to_f128( float32_t ); float128_t f32_to_f128(float32_t);
#endif #endif
void f32_to_extF80M( float32_t, extFloat80_t * ); void f32_to_extF80M(float32_t, extFloat80_t*);
void f32_to_f128M( float32_t, float128_t * ); void f32_to_f128M(float32_t, float128_t*);
float32_t f32_roundToInt( float32_t, uint_fast8_t, bool ); float32_t f32_roundToInt(float32_t, uint_fast8_t, bool);
float32_t f32_add( float32_t, float32_t ); float32_t f32_add(float32_t, float32_t);
float32_t f32_sub( float32_t, float32_t ); float32_t f32_sub(float32_t, float32_t);
float32_t f32_mul( float32_t, float32_t ); float32_t f32_mul(float32_t, float32_t);
float32_t f32_mulAdd( float32_t, float32_t, float32_t ); float32_t f32_mulAdd(float32_t, float32_t, float32_t);
float32_t f32_div( float32_t, float32_t ); float32_t f32_div(float32_t, float32_t);
float32_t f32_rem( float32_t, float32_t ); float32_t f32_rem(float32_t, float32_t);
float32_t f32_sqrt( float32_t ); float32_t f32_sqrt(float32_t);
bool f32_eq( float32_t, float32_t ); bool f32_eq(float32_t, float32_t);
bool f32_le( float32_t, float32_t ); bool f32_le(float32_t, float32_t);
bool f32_lt( float32_t, float32_t ); bool f32_lt(float32_t, float32_t);
bool f32_eq_signaling( float32_t, float32_t ); bool f32_eq_signaling(float32_t, float32_t);
bool f32_le_quiet( float32_t, float32_t ); bool f32_le_quiet(float32_t, float32_t);
bool f32_lt_quiet( float32_t, float32_t ); bool f32_lt_quiet(float32_t, float32_t);
bool f32_isSignalingNaN( float32_t ); bool f32_isSignalingNaN(float32_t);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| 64-bit (double-precision) floating-point operations. | 64-bit (double-precision) floating-point operations.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
uint_fast32_t f64_to_ui32( float64_t, uint_fast8_t, bool ); uint_fast32_t f64_to_ui32(float64_t, uint_fast8_t, bool);
uint_fast64_t f64_to_ui64( float64_t, uint_fast8_t, bool ); uint_fast64_t f64_to_ui64(float64_t, uint_fast8_t, bool);
int_fast32_t f64_to_i32( float64_t, uint_fast8_t, bool ); int_fast32_t f64_to_i32(float64_t, uint_fast8_t, bool);
int_fast64_t f64_to_i64( float64_t, uint_fast8_t, bool ); int_fast64_t f64_to_i64(float64_t, uint_fast8_t, bool);
uint_fast32_t f64_to_ui32_r_minMag( float64_t, bool ); uint_fast32_t f64_to_ui32_r_minMag(float64_t, bool);
uint_fast64_t f64_to_ui64_r_minMag( float64_t, bool ); uint_fast64_t f64_to_ui64_r_minMag(float64_t, bool);
int_fast32_t f64_to_i32_r_minMag( float64_t, bool ); int_fast32_t f64_to_i32_r_minMag(float64_t, bool);
int_fast64_t f64_to_i64_r_minMag( float64_t, bool ); int_fast64_t f64_to_i64_r_minMag(float64_t, bool);
float16_t f64_to_f16( float64_t ); float16_t f64_to_f16(float64_t);
float32_t f64_to_f32( float64_t ); float32_t f64_to_f32(float64_t);
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
extFloat80_t f64_to_extF80( float64_t ); extFloat80_t f64_to_extF80(float64_t);
float128_t f64_to_f128( float64_t ); float128_t f64_to_f128(float64_t);
#endif #endif
void f64_to_extF80M( float64_t, extFloat80_t * ); void f64_to_extF80M(float64_t, extFloat80_t*);
void f64_to_f128M( float64_t, float128_t * ); void f64_to_f128M(float64_t, float128_t*);
float64_t f64_roundToInt( float64_t, uint_fast8_t, bool ); float64_t f64_roundToInt(float64_t, uint_fast8_t, bool);
float64_t f64_add( float64_t, float64_t ); float64_t f64_add(float64_t, float64_t);
float64_t f64_sub( float64_t, float64_t ); float64_t f64_sub(float64_t, float64_t);
float64_t f64_mul( float64_t, float64_t ); float64_t f64_mul(float64_t, float64_t);
float64_t f64_mulAdd( float64_t, float64_t, float64_t ); float64_t f64_mulAdd(float64_t, float64_t, float64_t);
float64_t f64_div( float64_t, float64_t ); float64_t f64_div(float64_t, float64_t);
float64_t f64_rem( float64_t, float64_t ); float64_t f64_rem(float64_t, float64_t);
float64_t f64_sqrt( float64_t ); float64_t f64_sqrt(float64_t);
bool f64_eq( float64_t, float64_t ); bool f64_eq(float64_t, float64_t);
bool f64_le( float64_t, float64_t ); bool f64_le(float64_t, float64_t);
bool f64_lt( float64_t, float64_t ); bool f64_lt(float64_t, float64_t);
bool f64_eq_signaling( float64_t, float64_t ); bool f64_eq_signaling(float64_t, float64_t);
bool f64_le_quiet( float64_t, float64_t ); bool f64_le_quiet(float64_t, float64_t);
bool f64_lt_quiet( float64_t, float64_t ); bool f64_lt_quiet(float64_t, float64_t);
bool f64_isSignalingNaN( float64_t ); bool f64_isSignalingNaN(float64_t);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Rounding precision for 80-bit extended double-precision floating-point. | Rounding precision for 80-bit extended double-precision floating-point.
@ -249,124 +244,118 @@ extern THREAD_LOCAL uint_fast8_t extF80_roundingPrecision;
| 80-bit extended double-precision floating-point operations. | 80-bit extended double-precision floating-point operations.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
uint_fast32_t extF80_to_ui32( extFloat80_t, uint_fast8_t, bool ); uint_fast32_t extF80_to_ui32(extFloat80_t, uint_fast8_t, bool);
uint_fast64_t extF80_to_ui64( extFloat80_t, uint_fast8_t, bool ); uint_fast64_t extF80_to_ui64(extFloat80_t, uint_fast8_t, bool);
int_fast32_t extF80_to_i32( extFloat80_t, uint_fast8_t, bool ); int_fast32_t extF80_to_i32(extFloat80_t, uint_fast8_t, bool);
int_fast64_t extF80_to_i64( extFloat80_t, uint_fast8_t, bool ); int_fast64_t extF80_to_i64(extFloat80_t, uint_fast8_t, bool);
uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t, bool ); uint_fast32_t extF80_to_ui32_r_minMag(extFloat80_t, bool);
uint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t, bool ); uint_fast64_t extF80_to_ui64_r_minMag(extFloat80_t, bool);
int_fast32_t extF80_to_i32_r_minMag( extFloat80_t, bool ); int_fast32_t extF80_to_i32_r_minMag(extFloat80_t, bool);
int_fast64_t extF80_to_i64_r_minMag( extFloat80_t, bool ); int_fast64_t extF80_to_i64_r_minMag(extFloat80_t, bool);
float16_t extF80_to_f16( extFloat80_t ); float16_t extF80_to_f16(extFloat80_t);
float32_t extF80_to_f32( extFloat80_t ); float32_t extF80_to_f32(extFloat80_t);
float64_t extF80_to_f64( extFloat80_t ); float64_t extF80_to_f64(extFloat80_t);
float128_t extF80_to_f128( extFloat80_t ); float128_t extF80_to_f128(extFloat80_t);
extFloat80_t extF80_roundToInt( extFloat80_t, uint_fast8_t, bool ); extFloat80_t extF80_roundToInt(extFloat80_t, uint_fast8_t, bool);
extFloat80_t extF80_add( extFloat80_t, extFloat80_t ); extFloat80_t extF80_add(extFloat80_t, extFloat80_t);
extFloat80_t extF80_sub( extFloat80_t, extFloat80_t ); extFloat80_t extF80_sub(extFloat80_t, extFloat80_t);
extFloat80_t extF80_mul( extFloat80_t, extFloat80_t ); extFloat80_t extF80_mul(extFloat80_t, extFloat80_t);
extFloat80_t extF80_div( extFloat80_t, extFloat80_t ); extFloat80_t extF80_div(extFloat80_t, extFloat80_t);
extFloat80_t extF80_rem( extFloat80_t, extFloat80_t ); extFloat80_t extF80_rem(extFloat80_t, extFloat80_t);
extFloat80_t extF80_sqrt( extFloat80_t ); extFloat80_t extF80_sqrt(extFloat80_t);
bool extF80_eq( extFloat80_t, extFloat80_t ); bool extF80_eq(extFloat80_t, extFloat80_t);
bool extF80_le( extFloat80_t, extFloat80_t ); bool extF80_le(extFloat80_t, extFloat80_t);
bool extF80_lt( extFloat80_t, extFloat80_t ); bool extF80_lt(extFloat80_t, extFloat80_t);
bool extF80_eq_signaling( extFloat80_t, extFloat80_t ); bool extF80_eq_signaling(extFloat80_t, extFloat80_t);
bool extF80_le_quiet( extFloat80_t, extFloat80_t ); bool extF80_le_quiet(extFloat80_t, extFloat80_t);
bool extF80_lt_quiet( extFloat80_t, extFloat80_t ); bool extF80_lt_quiet(extFloat80_t, extFloat80_t);
bool extF80_isSignalingNaN( extFloat80_t ); bool extF80_isSignalingNaN(extFloat80_t);
#endif #endif
uint_fast32_t extF80M_to_ui32( const extFloat80_t *, uint_fast8_t, bool ); uint_fast32_t extF80M_to_ui32(const extFloat80_t*, uint_fast8_t, bool);
uint_fast64_t extF80M_to_ui64( const extFloat80_t *, uint_fast8_t, bool ); uint_fast64_t extF80M_to_ui64(const extFloat80_t*, uint_fast8_t, bool);
int_fast32_t extF80M_to_i32( const extFloat80_t *, uint_fast8_t, bool ); int_fast32_t extF80M_to_i32(const extFloat80_t*, uint_fast8_t, bool);
int_fast64_t extF80M_to_i64( const extFloat80_t *, uint_fast8_t, bool ); int_fast64_t extF80M_to_i64(const extFloat80_t*, uint_fast8_t, bool);
uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *, bool ); uint_fast32_t extF80M_to_ui32_r_minMag(const extFloat80_t*, bool);
uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *, bool ); uint_fast64_t extF80M_to_ui64_r_minMag(const extFloat80_t*, bool);
int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *, bool ); int_fast32_t extF80M_to_i32_r_minMag(const extFloat80_t*, bool);
int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *, bool ); int_fast64_t extF80M_to_i64_r_minMag(const extFloat80_t*, bool);
float16_t extF80M_to_f16( const extFloat80_t * ); float16_t extF80M_to_f16(const extFloat80_t*);
float32_t extF80M_to_f32( const extFloat80_t * ); float32_t extF80M_to_f32(const extFloat80_t*);
float64_t extF80M_to_f64( const extFloat80_t * ); float64_t extF80M_to_f64(const extFloat80_t*);
void extF80M_to_f128M( const extFloat80_t *, float128_t * ); void extF80M_to_f128M(const extFloat80_t*, float128_t*);
void void extF80M_roundToInt(const extFloat80_t*, uint_fast8_t, bool, extFloat80_t*);
extF80M_roundToInt( void extF80M_add(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
const extFloat80_t *, uint_fast8_t, bool, extFloat80_t * ); void extF80M_sub(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
void extF80M_add( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); void extF80M_mul(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
void extF80M_sub( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); void extF80M_div(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
void extF80M_mul( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); void extF80M_rem(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
void extF80M_div( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); void extF80M_sqrt(const extFloat80_t*, extFloat80_t*);
void extF80M_rem( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); bool extF80M_eq(const extFloat80_t*, const extFloat80_t*);
void extF80M_sqrt( const extFloat80_t *, extFloat80_t * ); bool extF80M_le(const extFloat80_t*, const extFloat80_t*);
bool extF80M_eq( const extFloat80_t *, const extFloat80_t * ); bool extF80M_lt(const extFloat80_t*, const extFloat80_t*);
bool extF80M_le( const extFloat80_t *, const extFloat80_t * ); bool extF80M_eq_signaling(const extFloat80_t*, const extFloat80_t*);
bool extF80M_lt( const extFloat80_t *, const extFloat80_t * ); bool extF80M_le_quiet(const extFloat80_t*, const extFloat80_t*);
bool extF80M_eq_signaling( const extFloat80_t *, const extFloat80_t * ); bool extF80M_lt_quiet(const extFloat80_t*, const extFloat80_t*);
bool extF80M_le_quiet( const extFloat80_t *, const extFloat80_t * ); bool extF80M_isSignalingNaN(const extFloat80_t*);
bool extF80M_lt_quiet( const extFloat80_t *, const extFloat80_t * );
bool extF80M_isSignalingNaN( const extFloat80_t * );
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| 128-bit (quadruple-precision) floating-point operations. | 128-bit (quadruple-precision) floating-point operations.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef SOFTFLOAT_FAST_INT64 #ifdef SOFTFLOAT_FAST_INT64
uint_fast32_t f128_to_ui32( float128_t, uint_fast8_t, bool ); uint_fast32_t f128_to_ui32(float128_t, uint_fast8_t, bool);
uint_fast64_t f128_to_ui64( float128_t, uint_fast8_t, bool ); uint_fast64_t f128_to_ui64(float128_t, uint_fast8_t, bool);
int_fast32_t f128_to_i32( float128_t, uint_fast8_t, bool ); int_fast32_t f128_to_i32(float128_t, uint_fast8_t, bool);
int_fast64_t f128_to_i64( float128_t, uint_fast8_t, bool ); int_fast64_t f128_to_i64(float128_t, uint_fast8_t, bool);
uint_fast32_t f128_to_ui32_r_minMag( float128_t, bool ); uint_fast32_t f128_to_ui32_r_minMag(float128_t, bool);
uint_fast64_t f128_to_ui64_r_minMag( float128_t, bool ); uint_fast64_t f128_to_ui64_r_minMag(float128_t, bool);
int_fast32_t f128_to_i32_r_minMag( float128_t, bool ); int_fast32_t f128_to_i32_r_minMag(float128_t, bool);
int_fast64_t f128_to_i64_r_minMag( float128_t, bool ); int_fast64_t f128_to_i64_r_minMag(float128_t, bool);
float16_t f128_to_f16( float128_t ); float16_t f128_to_f16(float128_t);
float32_t f128_to_f32( float128_t ); float32_t f128_to_f32(float128_t);
float64_t f128_to_f64( float128_t ); float64_t f128_to_f64(float128_t);
extFloat80_t f128_to_extF80( float128_t ); extFloat80_t f128_to_extF80(float128_t);
float128_t f128_roundToInt( float128_t, uint_fast8_t, bool ); float128_t f128_roundToInt(float128_t, uint_fast8_t, bool);
float128_t f128_add( float128_t, float128_t ); float128_t f128_add(float128_t, float128_t);
float128_t f128_sub( float128_t, float128_t ); float128_t f128_sub(float128_t, float128_t);
float128_t f128_mul( float128_t, float128_t ); float128_t f128_mul(float128_t, float128_t);
float128_t f128_mulAdd( float128_t, float128_t, float128_t ); float128_t f128_mulAdd(float128_t, float128_t, float128_t);
float128_t f128_div( float128_t, float128_t ); float128_t f128_div(float128_t, float128_t);
float128_t f128_rem( float128_t, float128_t ); float128_t f128_rem(float128_t, float128_t);
float128_t f128_sqrt( float128_t ); float128_t f128_sqrt(float128_t);
bool f128_eq( float128_t, float128_t ); bool f128_eq(float128_t, float128_t);
bool f128_le( float128_t, float128_t ); bool f128_le(float128_t, float128_t);
bool f128_lt( float128_t, float128_t ); bool f128_lt(float128_t, float128_t);
bool f128_eq_signaling( float128_t, float128_t ); bool f128_eq_signaling(float128_t, float128_t);
bool f128_le_quiet( float128_t, float128_t ); bool f128_le_quiet(float128_t, float128_t);
bool f128_lt_quiet( float128_t, float128_t ); bool f128_lt_quiet(float128_t, float128_t);
bool f128_isSignalingNaN( float128_t ); bool f128_isSignalingNaN(float128_t);
#endif #endif
uint_fast32_t f128M_to_ui32( const float128_t *, uint_fast8_t, bool ); uint_fast32_t f128M_to_ui32(const float128_t*, uint_fast8_t, bool);
uint_fast64_t f128M_to_ui64( const float128_t *, uint_fast8_t, bool ); uint_fast64_t f128M_to_ui64(const float128_t*, uint_fast8_t, bool);
int_fast32_t f128M_to_i32( const float128_t *, uint_fast8_t, bool ); int_fast32_t f128M_to_i32(const float128_t*, uint_fast8_t, bool);
int_fast64_t f128M_to_i64( const float128_t *, uint_fast8_t, bool ); int_fast64_t f128M_to_i64(const float128_t*, uint_fast8_t, bool);
uint_fast32_t f128M_to_ui32_r_minMag( const float128_t *, bool ); uint_fast32_t f128M_to_ui32_r_minMag(const float128_t*, bool);
uint_fast64_t f128M_to_ui64_r_minMag( const float128_t *, bool ); uint_fast64_t f128M_to_ui64_r_minMag(const float128_t*, bool);
int_fast32_t f128M_to_i32_r_minMag( const float128_t *, bool ); int_fast32_t f128M_to_i32_r_minMag(const float128_t*, bool);
int_fast64_t f128M_to_i64_r_minMag( const float128_t *, bool ); int_fast64_t f128M_to_i64_r_minMag(const float128_t*, bool);
float16_t f128M_to_f16( const float128_t * ); float16_t f128M_to_f16(const float128_t*);
float32_t f128M_to_f32( const float128_t * ); float32_t f128M_to_f32(const float128_t*);
float64_t f128M_to_f64( const float128_t * ); float64_t f128M_to_f64(const float128_t*);
void f128M_to_extF80M( const float128_t *, extFloat80_t * ); void f128M_to_extF80M(const float128_t*, extFloat80_t*);
void f128M_roundToInt( const float128_t *, uint_fast8_t, bool, float128_t * ); void f128M_roundToInt(const float128_t*, uint_fast8_t, bool, float128_t*);
void f128M_add( const float128_t *, const float128_t *, float128_t * ); void f128M_add(const float128_t*, const float128_t*, float128_t*);
void f128M_sub( const float128_t *, const float128_t *, float128_t * ); void f128M_sub(const float128_t*, const float128_t*, float128_t*);
void f128M_mul( const float128_t *, const float128_t *, float128_t * ); void f128M_mul(const float128_t*, const float128_t*, float128_t*);
void void f128M_mulAdd(const float128_t*, const float128_t*, const float128_t*, float128_t*);
f128M_mulAdd( void f128M_div(const float128_t*, const float128_t*, float128_t*);
const float128_t *, const float128_t *, const float128_t *, float128_t * void f128M_rem(const float128_t*, const float128_t*, float128_t*);
); void f128M_sqrt(const float128_t*, float128_t*);
void f128M_div( const float128_t *, const float128_t *, float128_t * ); bool f128M_eq(const float128_t*, const float128_t*);
void f128M_rem( const float128_t *, const float128_t *, float128_t * ); bool f128M_le(const float128_t*, const float128_t*);
void f128M_sqrt( const float128_t *, float128_t * ); bool f128M_lt(const float128_t*, const float128_t*);
bool f128M_eq( const float128_t *, const float128_t * ); bool f128M_eq_signaling(const float128_t*, const float128_t*);
bool f128M_le( const float128_t *, const float128_t * ); bool f128M_le_quiet(const float128_t*, const float128_t*);
bool f128M_lt( const float128_t *, const float128_t * ); bool f128M_lt_quiet(const float128_t*, const float128_t*);
bool f128M_eq_signaling( const float128_t *, const float128_t * ); bool f128M_isSignalingNaN(const float128_t*);
bool f128M_le_quiet( const float128_t *, const float128_t * );
bool f128M_lt_quiet( const float128_t *, const float128_t * );
bool f128M_isSignalingNaN( const float128_t * );
#endif #endif

View File

@ -47,10 +47,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
| the types below may, if desired, be defined as aliases for the native types | the types below may, if desired, be defined as aliases for the native types
| (typically 'float' and 'double', and possibly 'long double'). | (typically 'float' and 'double', and possibly 'long double').
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
typedef struct { uint16_t v; } float16_t; typedef struct {
typedef struct { uint32_t v; } float32_t; uint16_t v;
typedef struct { uint64_t v; } float64_t; } float16_t;
typedef struct { uint64_t v[2]; } float128_t; typedef struct {
uint32_t v;
} float32_t;
typedef struct {
uint64_t v;
} float64_t;
typedef struct {
uint64_t v[2];
} float128_t;
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| The format of an 80-bit extended floating-point number in memory. This | The format of an 80-bit extended floating-point number in memory. This
@ -58,9 +66,15 @@ typedef struct { uint64_t v[2]; } float128_t;
| named 'signif'. | named 'signif'.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifdef LITTLEENDIAN #ifdef LITTLEENDIAN
struct extFloat80M { uint64_t signif; uint16_t signExp; }; struct extFloat80M {
uint64_t signif;
uint16_t signExp;
};
#else #else
struct extFloat80M { uint16_t signExp; uint64_t signif; }; struct extFloat80M {
uint16_t signExp;
uint64_t signif;
};
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -78,4 +92,3 @@ struct extFloat80M { uint16_t signExp; uint64_t signif; };
typedef struct extFloat80M extFloat80_t; typedef struct extFloat80M extFloat80_t;
#endif #endif

View File

@ -50,45 +50,67 @@ public:
virtual ~hwl() = default; virtual ~hwl() = default;
protected: protected:
iss::status read_custom_csr_reg(unsigned addr, reg_t &val) override; iss::status read_custom_csr_reg(unsigned addr, reg_t& val) override;
iss::status write_custom_csr_reg(unsigned addr, reg_t val) override; iss::status write_custom_csr_reg(unsigned addr, reg_t val) override;
}; };
template <typename BASE>
template<typename BASE> inline hwl<BASE>::hwl(feature_config cfg)
inline hwl<BASE>::hwl(feature_config cfg): BASE(cfg) { : BASE(cfg) {
for (unsigned addr = 0x800; addr < 0x803; ++addr){ for(unsigned addr = 0x800; addr < 0x803; ++addr) {
this->register_custom_csr_rd(addr); this->register_custom_csr_rd(addr);
this->register_custom_csr_wr(addr); this->register_custom_csr_wr(addr);
} }
for (unsigned addr = 0x804; addr < 0x807; ++addr){ for(unsigned addr = 0x804; addr < 0x807; ++addr) {
this->register_custom_csr_rd(addr); this->register_custom_csr_rd(addr);
this->register_custom_csr_wr(addr); this->register_custom_csr_wr(addr);
} }
} }
template<typename BASE> template <typename BASE> inline iss::status iss::arch::hwl<BASE>::read_custom_csr_reg(unsigned addr, reg_t& val) {
inline iss::status iss::arch::hwl<BASE>::read_custom_csr_reg(unsigned addr, reg_t &val) { switch(addr) {
switch(addr){ case 0x800:
case 0x800: val = this->reg.lpstart0; break; val = this->reg.lpstart0;
case 0x801: val = this->reg.lpend0; break; break;
case 0x802: val = this->reg.lpcount0; break; case 0x801:
case 0x804: val = this->reg.lpstart1; break; val = this->reg.lpend0;
case 0x805: val = this->reg.lpend1; break; break;
case 0x806: val = this->reg.lpcount1; break; case 0x802:
val = this->reg.lpcount0;
break;
case 0x804:
val = this->reg.lpstart1;
break;
case 0x805:
val = this->reg.lpend1;
break;
case 0x806:
val = this->reg.lpcount1;
break;
} }
return iss::Ok; return iss::Ok;
} }
template<typename BASE> template <typename BASE> inline iss::status iss::arch::hwl<BASE>::write_custom_csr_reg(unsigned addr, reg_t val) {
inline iss::status iss::arch::hwl<BASE>::write_custom_csr_reg(unsigned addr, reg_t val) { switch(addr) {
switch(addr){ case 0x800:
case 0x800: this->reg.lpstart0 = val; break; this->reg.lpstart0 = val;
case 0x801: this->reg.lpend0 = val; break; break;
case 0x802: this->reg.lpcount0 = val; break; case 0x801:
case 0x804: this->reg.lpstart1 = val; break; this->reg.lpend0 = val;
case 0x805: this->reg.lpend1 = val; break; break;
case 0x806: this->reg.lpcount1 = val; break; case 0x802:
this->reg.lpcount0 = val;
break;
case 0x804:
this->reg.lpstart1 = val;
break;
case 0x805:
this->reg.lpend1 = val;
break;
case 0x806:
this->reg.lpcount1 = val;
break;
} }
return iss::Ok; return iss::Ok;
} }
@ -96,5 +118,4 @@ inline iss::status iss::arch::hwl<BASE>::write_custom_csr_reg(unsigned addr, reg
} // namespace arch } // namespace arch
} // namespace iss } // namespace iss
#endif /* _RISCV_HART_M_P_H */ #endif /* _RISCV_HART_M_P_H */

View File

@ -43,7 +43,7 @@ namespace arch {
enum { tohost_dflt = 0xF0001000, fromhost_dflt = 0xF0001040 }; enum { tohost_dflt = 0xF0001000, fromhost_dflt = 0xF0001040 };
enum features_e{FEAT_NONE, FEAT_PMP=1, FEAT_EXT_N=2, FEAT_CLIC=4, FEAT_DEBUG=8, FEAT_TCM=16}; enum features_e { FEAT_NONE, FEAT_PMP = 1, FEAT_EXT_N = 2, FEAT_CLIC = 4, FEAT_DEBUG = 8, FEAT_TCM = 16 };
enum riscv_csr { enum riscv_csr {
/* user-level CSR */ /* user-level CSR */
@ -51,17 +51,17 @@ enum riscv_csr {
ustatus = 0x000, ustatus = 0x000,
uie = 0x004, uie = 0x004,
utvec = 0x005, utvec = 0x005,
utvt = 0x007, //CLIC utvt = 0x007, // CLIC
// User Trap Handling // User Trap Handling
uscratch = 0x040, uscratch = 0x040,
uepc = 0x041, uepc = 0x041,
ucause = 0x042, ucause = 0x042,
utval = 0x043, utval = 0x043,
uip = 0x044, uip = 0x044,
uxnti = 0x045, //CLIC uxnti = 0x045, // CLIC
uintstatus = 0xCB1, // MRW Current interrupt levels (CLIC) - addr subject to change uintstatus = 0xCB1, // MRW Current interrupt levels (CLIC) - addr subject to change
uintthresh = 0x047, // MRW Interrupt-level threshold (CLIC) - addr subject to change uintthresh = 0x047, // MRW Interrupt-level threshold (CLIC) - addr subject to change
uscratchcsw = 0x048, // MRW Conditional scratch swap on priv mode change (CLIC) uscratchcsw = 0x048, // MRW Conditional scratch swap on priv mode change (CLIC)
uscratchcswl = 0x049, // MRW Conditional scratch swap on level change (CLIC) uscratchcswl = 0x049, // MRW Conditional scratch swap on level change (CLIC)
// User Floating-Point CSRs // User Floating-Point CSRs
fflags = 0x001, fflags = 0x001,
@ -112,17 +112,17 @@ enum riscv_csr {
mie = 0x304, mie = 0x304,
mtvec = 0x305, mtvec = 0x305,
mcounteren = 0x306, mcounteren = 0x306,
mtvt = 0x307, //CLIC mtvt = 0x307, // CLIC
// Machine Trap Handling // Machine Trap Handling
mscratch = 0x340, mscratch = 0x340,
mepc = 0x341, mepc = 0x341,
mcause = 0x342, mcause = 0x342,
mtval = 0x343, mtval = 0x343,
mip = 0x344, mip = 0x344,
mxnti = 0x345, //CLIC mxnti = 0x345, // CLIC
mintstatus = 0xFB1, // MRW Current interrupt levels (CLIC) - addr subject to change mintstatus = 0xFB1, // MRW Current interrupt levels (CLIC) - addr subject to change
mintthresh = 0x347, // MRW Interrupt-level threshold (CLIC) - addr subject to change mintthresh = 0x347, // MRW Interrupt-level threshold (CLIC) - addr subject to change
mscratchcsw = 0x348, // MRW Conditional scratch swap on priv mode change (CLIC) mscratchcsw = 0x348, // MRW Conditional scratch swap on priv mode change (CLIC)
mscratchcswl = 0x349, // MRW Conditional scratch swap on level change (CLIC) mscratchcswl = 0x349, // MRW Conditional scratch swap on level change (CLIC)
// Physical Memory Protection // Physical Memory Protection
pmpcfg0 = 0x3A0, pmpcfg0 = 0x3A0,
@ -175,7 +175,6 @@ enum riscv_csr {
dscratch1 = 0x7B3 dscratch1 = 0x7B3
}; };
enum { enum {
PGSHIFT = 12, PGSHIFT = 12,
PTE_PPN_SHIFT = 10, PTE_PPN_SHIFT = 10,
@ -193,7 +192,7 @@ enum {
template <typename T> inline bool PTE_TABLE(T PTE) { return (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V); } template <typename T> inline bool PTE_TABLE(T PTE) { return (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V); }
enum { PRIV_U = 0, PRIV_S = 1, PRIV_M = 3, PRIV_D = 4}; enum { PRIV_U = 0, PRIV_S = 1, PRIV_M = 3, PRIV_D = 4 };
enum { enum {
ISA_A = 1, ISA_A = 1,
@ -256,49 +255,49 @@ public:
: trap_access(15 << 16, badaddr) {} : trap_access(15 << 16, badaddr) {}
}; };
inline void read_reg_uint32(uint64_t offs, uint32_t& reg, uint8_t *const data, unsigned length) { inline void read_reg_uint32(uint64_t offs, uint32_t& reg, uint8_t* const data, unsigned length) {
auto reg_ptr = reinterpret_cast<uint8_t*>(&reg); auto reg_ptr = reinterpret_cast<uint8_t*>(&reg);
switch (offs & 0x3) { switch(offs & 0x3) {
case 0: case 0:
for (auto i = 0U; i < length; ++i) for(auto i = 0U; i < length; ++i)
*(data + i) = *(reg_ptr + i); *(data + i) = *(reg_ptr + i);
break; break;
case 1: case 1:
for (auto i = 0U; i < length; ++i) for(auto i = 0U; i < length; ++i)
*(data + i) = *(reg_ptr + 1 + i); *(data + i) = *(reg_ptr + 1 + i);
break; break;
case 2: case 2:
for (auto i = 0U; i < length; ++i) for(auto i = 0U; i < length; ++i)
*(data + i) = *(reg_ptr + 2 + i); *(data + i) = *(reg_ptr + 2 + i);
break; break;
case 3: case 3:
*data = *(reg_ptr + 3); *data = *(reg_ptr + 3);
break; break;
} }
} }
inline void write_reg_uint32(uint64_t offs, uint32_t& reg, const uint8_t *const data, unsigned length) { inline void write_reg_uint32(uint64_t offs, uint32_t& reg, const uint8_t* const data, unsigned length) {
auto reg_ptr = reinterpret_cast<uint8_t*>(&reg); auto reg_ptr = reinterpret_cast<uint8_t*>(&reg);
switch (offs & 0x3) { switch(offs & 0x3) {
case 0: case 0:
for (auto i = 0U; i < length; ++i) for(auto i = 0U; i < length; ++i)
*(reg_ptr + i) = *(data + i); *(reg_ptr + i) = *(data + i);
break; break;
case 1: case 1:
for (auto i = 0U; i < length; ++i) for(auto i = 0U; i < length; ++i)
*(reg_ptr + 1 + i) = *(data + i); *(reg_ptr + 1 + i) = *(data + i);
break; break;
case 2: case 2:
for (auto i = 0U; i < length; ++i) for(auto i = 0U; i < length; ++i)
*(reg_ptr + 2 + i) = *(data + i); *(reg_ptr + 2 + i) = *(data + i);
break; break;
case 3: case 3:
*(reg_ptr + 3) = *data ; *(reg_ptr + 3) = *data;
break; break;
} }
} }
} } // namespace arch
} } // namespace iss
#endif #endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -32,38 +32,35 @@
#include "tgc5c.h" #include "tgc5c.h"
#include "util/ities.h" #include "util/ities.h"
#include <util/logging.h>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
#include <util/logging.h>
using namespace iss::arch; using namespace iss::arch;
constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc5c>::reg_names; constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc5c>::reg_names;
constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc5c>::reg_aliases; constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc5c>::reg_aliases;
constexpr std::array<const uint32_t, 43> iss::arch::traits<iss::arch::tgc5c>::reg_bit_widths; constexpr std::array<const uint32_t, 43> iss::arch::traits<iss::arch::tgc5c>::reg_bit_widths;
constexpr std::array<const uint32_t, 43> iss::arch::traits<iss::arch::tgc5c>::reg_byte_offsets; constexpr std::array<const uint32_t, 43> iss::arch::traits<iss::arch::tgc5c>::reg_byte_offsets;
tgc5c::tgc5c() = default; tgc5c::tgc5c() = default;
tgc5c::~tgc5c() = default; tgc5c::~tgc5c() = default;
void tgc5c::reset(uint64_t address) { void tgc5c::reset(uint64_t address) {
auto base_ptr = reinterpret_cast<traits<tgc5c>::reg_t*>(get_regs_base_ptr()); auto base_ptr = reinterpret_cast<traits<tgc5c>::reg_t*>(get_regs_base_ptr());
for(size_t i=0; i<traits<tgc5c>::NUM_REGS; ++i) for(size_t i = 0; i < traits<tgc5c>::NUM_REGS; ++i)
*(base_ptr+i)=0; *(base_ptr + i) = 0;
reg.PC=address; reg.PC = address;
reg.NEXT_PC=reg.PC; reg.NEXT_PC = reg.PC;
reg.PRIV=0x3; reg.PRIV = 0x3;
reg.trap_state=0; reg.trap_state = 0;
reg.icount=0; reg.icount = 0;
} }
uint8_t *tgc5c::get_regs_base_ptr() { uint8_t* tgc5c::get_regs_base_ptr() { return reinterpret_cast<uint8_t*>(&reg); }
return reinterpret_cast<uint8_t*>(&reg);
}
tgc5c::phys_addr_t tgc5c::virt2phys(const iss::addr_t &addr) { tgc5c::phys_addr_t tgc5c::virt2phys(const iss::addr_t& addr) {
return phys_addr_t(addr.access, addr.space, addr.val&traits<tgc5c>::addr_mask); return phys_addr_t(addr.access, addr.space, addr.val & traits<tgc5c>::addr_mask);
} }

View File

@ -47,35 +47,95 @@ template <> struct traits<tgc5c> {
constexpr static char const* const core_type = "TGC5C"; constexpr static char const* const core_type = "TGC5C";
static constexpr std::array<const char*, 36> reg_names{ static constexpr std::array<const char*, 36> reg_names{{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8",
{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc", "next_pc", "priv", "dpc"}}; "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17",
"x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26",
"x27", "x28", "x29", "x30", "x31", "pc", "next_pc", "priv", "dpc"}};
static constexpr std::array<const char*, 36> reg_aliases{ static constexpr std::array<const char*, 36> reg_aliases{
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc", "next_pc", "priv", "dpc"}}; {"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
"s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc", "next_pc", "priv", "dpc"}};
enum constants {MISA_VAL=1073746180ULL, MARCHID_VAL=2147483651ULL, XLEN=32ULL, INSTR_ALIGNMENT=2ULL, RFS=32ULL, fence=0ULL, fencei=1ULL, fencevmal=2ULL, fencevmau=3ULL, CSR_SIZE=4096ULL, MUL_LEN=64ULL}; enum constants {
MISA_VAL = 1073746180ULL,
MARCHID_VAL = 2147483651ULL,
XLEN = 32ULL,
INSTR_ALIGNMENT = 2ULL,
RFS = 32ULL,
fence = 0ULL,
fencei = 1ULL,
fencevmal = 2ULL,
fencevmau = 3ULL,
CSR_SIZE = 4096ULL,
MUL_LEN = 64ULL
};
constexpr static unsigned FP_REGS_SIZE = 0; constexpr static unsigned FP_REGS_SIZE = 0;
enum reg_e { enum reg_e {
X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, PC, NEXT_PC, PRIV, DPC, NUM_REGS, TRAP_STATE=NUM_REGS, PENDING_TRAP, ICOUNT, CYCLE, INSTRET, INSTRUCTION, LAST_BRANCH X0,
X1,
X2,
X3,
X4,
X5,
X6,
X7,
X8,
X9,
X10,
X11,
X12,
X13,
X14,
X15,
X16,
X17,
X18,
X19,
X20,
X21,
X22,
X23,
X24,
X25,
X26,
X27,
X28,
X29,
X30,
X31,
PC,
NEXT_PC,
PRIV,
DPC,
NUM_REGS,
TRAP_STATE = NUM_REGS,
PENDING_TRAP,
ICOUNT,
CYCLE,
INSTRET,
INSTRUCTION,
LAST_BRANCH
}; };
using reg_t = uint32_t; using reg_t = uint32_t;
using addr_t = uint32_t; using addr_t = uint32_t;
using code_word_t = uint32_t; //TODO: check removal using code_word_t = uint32_t; // TODO: check removal
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>; using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>; using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
static constexpr std::array<const uint32_t, 43> reg_bit_widths{ static constexpr std::array<const uint32_t, 43> reg_bit_widths{{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,8,32,32,32,64,64,64,32,32}}; 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 8, 32, 32, 32, 64, 64, 64, 32, 32}};
static constexpr std::array<const uint32_t, 43> reg_byte_offsets{ static constexpr std::array<const uint32_t, 43> reg_byte_offsets{
{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,137,141,145,149,157,165,173,177}}; {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84,
88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 137, 141, 145, 149, 157, 165, 173, 177}};
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
@ -175,17 +235,17 @@ template <> struct traits<tgc5c> {
}; };
}; };
struct tgc5c: public arch_if { struct tgc5c : public arch_if {
using virt_addr_t = typename traits<tgc5c>::virt_addr_t; using virt_addr_t = typename traits<tgc5c>::virt_addr_t;
using phys_addr_t = typename traits<tgc5c>::phys_addr_t; using phys_addr_t = typename traits<tgc5c>::phys_addr_t;
using reg_t = typename traits<tgc5c>::reg_t; using reg_t = typename traits<tgc5c>::reg_t;
using addr_t = typename traits<tgc5c>::addr_t; using addr_t = typename traits<tgc5c>::addr_t;
tgc5c(); tgc5c();
~tgc5c(); ~tgc5c();
void reset(uint64_t address=0) override; void reset(uint64_t address = 0) override;
uint8_t* get_regs_base_ptr() override; uint8_t* get_regs_base_ptr() override;
@ -201,7 +261,6 @@ struct tgc5c: public arch_if {
inline uint32_t get_last_branch() { return reg.last_branch; } inline uint32_t get_last_branch() { return reg.last_branch; }
#pragma pack(push, 1) #pragma pack(push, 1)
struct TGC5C_regs { struct TGC5C_regs {
uint32_t X0 = 0; uint32_t X0 = 0;
@ -250,13 +309,12 @@ struct tgc5c: public arch_if {
#pragma pack(pop) #pragma pack(pop)
std::array<address_type, 4> addr_mode; std::array<address_type, 4> addr_mode;
uint64_t interrupt_sim=0; uint64_t interrupt_sim = 0;
uint32_t get_fcsr(){return 0;}
void set_fcsr(uint32_t val){}
uint32_t get_fcsr() { return 0; }
void set_fcsr(uint32_t val) {}
}; };
} } // namespace arch
} } // namespace iss
#endif /* _TGC5C_H_ */ #endif /* _TGC5C_H_ */

View File

@ -15,36 +15,43 @@ using tgc5a_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc5a>;
using tgc5b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc5b>; using tgc5b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc5b>;
#endif #endif
#ifdef CORE_TGC5C_XRB_NN #ifdef CORE_TGC5C_XRB_NN
#include "riscv_hart_m_p.h"
#include "hwl.h" #include "hwl.h"
#include "riscv_hart_m_p.h"
#include <iss/arch/tgc5c_xrb_nn.h> #include <iss/arch/tgc5c_xrb_nn.h>
using tgc5c_xrb_nn_plat_type = iss::arch::hwl<iss::arch::riscv_hart_m_p<iss::arch::tgc5c_xrb_nn>>; using tgc5c_xrb_nn_plat_type = iss::arch::hwl<iss::arch::riscv_hart_m_p<iss::arch::tgc5c_xrb_nn>>;
#endif #endif
#ifdef CORE_TGC5D #ifdef CORE_TGC5D
#include "riscv_hart_mu_p.h" #include "riscv_hart_mu_p.h"
#include <iss/arch/tgc5d.h> #include <iss/arch/tgc5d.h>
using tgc5d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; using tgc5d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC |
iss::arch::FEAT_EXT_N)>;
#endif #endif
#ifdef CORE_TGC5D_XRB_MAC #ifdef CORE_TGC5D_XRB_MAC
#include "riscv_hart_mu_p.h" #include "riscv_hart_mu_p.h"
#include <iss/arch/tgc5d_xrb_mac.h> #include <iss/arch/tgc5d_xrb_mac.h>
using tgc5d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_mac, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; using tgc5d_xrb_mac_plat_type =
iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_mac,
(iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
#endif #endif
#ifdef CORE_TGC5D_XRB_NN #ifdef CORE_TGC5D_XRB_NN
#include "riscv_hart_mu_p.h"
#include "hwl.h" #include "hwl.h"
#include "riscv_hart_mu_p.h"
#include <iss/arch/tgc5d_xrb_nn.h> #include <iss/arch/tgc5d_xrb_nn.h>
using tgc5d_xrb_nn_plat_type = iss::arch::hwl<iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_nn, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>>; using tgc5d_xrb_nn_plat_type =
iss::arch::hwl<iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_nn,
(iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>>;
#endif #endif
#ifdef CORE_TGC5E #ifdef CORE_TGC5E
#include "riscv_hart_mu_p.h" #include "riscv_hart_mu_p.h"
#include <iss/arch/tgc5e.h> #include <iss/arch/tgc5e.h>
using tgc5e_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5e, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; using tgc5e_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5e, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC |
iss::arch::FEAT_EXT_N)>;
#endif #endif
#ifdef CORE_TGC5X #ifdef CORE_TGC5X
#include "riscv_hart_mu_p.h" #include "riscv_hart_mu_p.h"
#include <iss/arch/tgc5x.h> #include <iss/arch/tgc5x.h>
using tgc5x_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5x, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N | iss::arch::FEAT_TCM)>; using tgc5x_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5x, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC |
iss::arch::FEAT_EXT_N | iss::arch::FEAT_TCM)>;
#endif #endif
#endif #endif

View File

@ -36,25 +36,27 @@
#define _RISCV_HART_M_P_WT_CACHE_H #define _RISCV_HART_M_P_WT_CACHE_H
#include <iss/vm_types.h> #include <iss/vm_types.h>
#include <util/ities.h>
#include <vector>
#include <map> #include <map>
#include <memory> #include <memory>
#include <util/ities.h>
#include <vector>
namespace iss { namespace iss {
namespace arch { namespace arch {
namespace cache { namespace cache {
enum class state { INVALID, VALID}; enum class state { INVALID, VALID };
struct line { struct line {
uint64_t tag_addr{0}; uint64_t tag_addr{0};
state st{state::INVALID}; state st{state::INVALID};
std::vector<uint8_t> data; std::vector<uint8_t> data;
line(unsigned line_sz): data(line_sz) {} line(unsigned line_sz)
: data(line_sz) {}
}; };
struct set { struct set {
std::vector<line> ways; std::vector<line> ways;
set(unsigned ways_count, line const& l): ways(ways_count, l) {} set(unsigned ways_count, line const& l)
: ways(ways_count, l) {}
}; };
struct cache { struct cache {
std::vector<set> sets; std::vector<set> sets;
@ -62,14 +64,14 @@ struct cache {
cache(unsigned size, unsigned line_sz, unsigned ways) { cache(unsigned size, unsigned line_sz, unsigned ways) {
line const ref_line{line_sz}; line const ref_line{line_sz};
set const ref_set{ways, ref_line}; set const ref_set{ways, ref_line};
sets.resize(size/(ways*line_sz), ref_set); sets.resize(size / (ways * line_sz), ref_set);
} }
}; };
struct wt_policy { struct wt_policy {
bool is_cacheline_hit(cache& c ); bool is_cacheline_hit(cache& c);
}; };
} } // namespace cache
// write thru, allocate on read, direct mapped or set-associative with round-robin replacement policy // write thru, allocate on read, direct mapped or set-associative with round-robin replacement policy
template <typename BASE> class wt_cache : public BASE { template <typename BASE> class wt_cache : public BASE {
@ -89,78 +91,73 @@ public:
unsigned ways{1}; unsigned ways{1};
uint64_t io_address{0xf0000000}; uint64_t io_address{0xf0000000};
uint64_t io_addr_mask{0xf0000000}; uint64_t io_addr_mask{0xf0000000};
protected: protected:
iss::status read_cache(phys_addr_t addr, unsigned, uint8_t *const); iss::status read_cache(phys_addr_t addr, unsigned, uint8_t* const);
iss::status write_cache(phys_addr_t addr, unsigned, uint8_t const *const); iss::status write_cache(phys_addr_t addr, unsigned, uint8_t const* const);
std::function<mem_read_f> cache_mem_rd_delegate; std::function<mem_read_f> cache_mem_rd_delegate;
std::function<mem_write_f> cache_mem_wr_delegate; std::function<mem_write_f> cache_mem_wr_delegate;
std::unique_ptr<cache::cache> dcache_ptr; std::unique_ptr<cache::cache> dcache_ptr;
std::unique_ptr<cache::cache> icache_ptr; std::unique_ptr<cache::cache> icache_ptr;
size_t get_way_select() { size_t get_way_select() { return 0; }
return 0;
}
}; };
template <typename BASE>
template<typename BASE>
inline wt_cache<BASE>::wt_cache(feature_config cfg) inline wt_cache<BASE>::wt_cache(feature_config cfg)
:BASE(cfg) : BASE(cfg)
, io_address{cfg.io_address} , io_address{cfg.io_address}
, io_addr_mask{cfg.io_addr_mask} , io_addr_mask{cfg.io_addr_mask} {
{
auto cb = base_class::replace_mem_access( auto cb = base_class::replace_mem_access(
[this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status { return read_cache(a, l,d);}, [this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status { return read_cache(a, l, d); },
[this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return write_cache(a, l,d);}); [this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return write_cache(a, l, d); });
cache_mem_rd_delegate = cb.first; cache_mem_rd_delegate = cb.first;
cache_mem_wr_delegate = cb.second; cache_mem_wr_delegate = cb.second;
} }
template<typename BASE> template <typename BASE> iss::status iss::arch::wt_cache<BASE>::read_cache(phys_addr_t a, unsigned l, uint8_t* const d) {
iss::status iss::arch::wt_cache<BASE>::read_cache(phys_addr_t a, unsigned l, uint8_t* const d) {
if(!icache_ptr) { if(!icache_ptr) {
icache_ptr.reset(new cache::cache(size, line_sz, ways)); icache_ptr.reset(new cache::cache(size, line_sz, ways));
dcache_ptr.reset(new cache::cache(size, line_sz, ways)); dcache_ptr.reset(new cache::cache(size, line_sz, ways));
} }
if((a.val&io_addr_mask) != io_address) { if((a.val & io_addr_mask) != io_address) {
auto set_addr=(a.val&(size-1))>>util::ilog2(line_sz*ways); auto set_addr = (a.val & (size - 1)) >> util::ilog2(line_sz * ways);
auto tag_addr=a.val>>util::ilog2(line_sz); auto tag_addr = a.val >> util::ilog2(line_sz);
auto& set = (is_fetch(a.access)?icache_ptr:dcache_ptr)->sets[set_addr]; auto& set = (is_fetch(a.access) ? icache_ptr : dcache_ptr)->sets[set_addr];
for(auto& cl: set.ways) { for(auto& cl : set.ways) {
if(cl.st==cache::state::VALID && cl.tag_addr==tag_addr) { if(cl.st == cache::state::VALID && cl.tag_addr == tag_addr) {
auto start_addr = a.val&(line_sz-1); auto start_addr = a.val & (line_sz - 1);
for(auto i = 0U; i<l; ++i) for(auto i = 0U; i < l; ++i)
d[i] = cl.data[start_addr+i]; d[i] = cl.data[start_addr + i];
return iss::Ok; return iss::Ok;
} }
} }
auto& cl = set.ways[get_way_select()]; auto& cl = set.ways[get_way_select()];
phys_addr_t cl_addr{a}; phys_addr_t cl_addr{a};
cl_addr.val=tag_addr<<util::ilog2(line_sz); cl_addr.val = tag_addr << util::ilog2(line_sz);
cache_mem_rd_delegate(cl_addr, line_sz, cl.data.data()); cache_mem_rd_delegate(cl_addr, line_sz, cl.data.data());
cl.tag_addr=tag_addr; cl.tag_addr = tag_addr;
cl.st=cache::state::VALID; cl.st = cache::state::VALID;
auto start_addr = a.val&(line_sz-1); auto start_addr = a.val & (line_sz - 1);
for(auto i = 0U; i<l; ++i) for(auto i = 0U; i < l; ++i)
d[i] = cl.data[start_addr+i]; d[i] = cl.data[start_addr + i];
return iss::Ok; return iss::Ok;
} else } else
return cache_mem_rd_delegate(a, l, d); return cache_mem_rd_delegate(a, l, d);
} }
template<typename BASE> template <typename BASE> iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, const uint8_t* const d) {
iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, const uint8_t* const d) {
if(!dcache_ptr) if(!dcache_ptr)
dcache_ptr.reset(new cache::cache(size, line_sz, ways)); dcache_ptr.reset(new cache::cache(size, line_sz, ways));
auto res = cache_mem_wr_delegate(a, l, d); auto res = cache_mem_wr_delegate(a, l, d);
if(res == iss::Ok && ((a.val&io_addr_mask) != io_address)) { if(res == iss::Ok && ((a.val & io_addr_mask) != io_address)) {
auto set_addr=(a.val&(size-1))>>util::ilog2(line_sz*ways); auto set_addr = (a.val & (size - 1)) >> util::ilog2(line_sz * ways);
auto tag_addr=a.val>>util::ilog2(line_sz); auto tag_addr = a.val >> util::ilog2(line_sz);
auto& set = dcache_ptr->sets[set_addr]; auto& set = dcache_ptr->sets[set_addr];
for(auto& cl: set.ways) { for(auto& cl : set.ways) {
if(cl.st==cache::state::VALID && cl.tag_addr==tag_addr) { if(cl.st == cache::state::VALID && cl.tag_addr == tag_addr) {
auto start_addr = a.val&(line_sz-1); auto start_addr = a.val & (line_sz - 1);
for(auto i = 0U; i<l; ++i) for(auto i = 0U; i < l; ++i)
cl.data[start_addr+i] = d[i]; cl.data[start_addr + i] = d[i];
break; break;
} }
} }
@ -168,8 +165,6 @@ iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, co
return res; return res;
} }
} // namespace arch } // namespace arch
} // namespace iss } // namespace iss

View File

@ -53,20 +53,20 @@ using namespace iss::debugger;
template <typename ARCH> class riscv_target_adapter : public target_adapter_base { template <typename ARCH> class riscv_target_adapter : public target_adapter_base {
public: public:
riscv_target_adapter(server_if *srv, iss::arch_if *core) riscv_target_adapter(server_if* srv, iss::arch_if* core)
: target_adapter_base(srv) : target_adapter_base(srv)
, core(core) {} , core(core) {}
/*============== Thread Control ===============================*/ /*============== Thread Control ===============================*/
/* Set generic thread */ /* Set generic thread */
status set_gen_thread(rp_thread_ref &thread) override; status set_gen_thread(rp_thread_ref& thread) override;
/* Set control thread */ /* Set control thread */
status set_ctrl_thread(rp_thread_ref &thread) override; status set_ctrl_thread(rp_thread_ref& thread) override;
/* Get thread status */ /* Get thread status */
status is_thread_alive(rp_thread_ref &thread, bool &alive) override; status is_thread_alive(rp_thread_ref& thread, bool& alive) override;
/*============= Register Access ================================*/ /*============= Register Access ================================*/
@ -74,79 +74,77 @@ public:
target byte order. If register is not available target byte order. If register is not available
corresponding bytes in avail_buf are 0, otherwise corresponding bytes in avail_buf are 0, otherwise
avail buf is 1 */ avail buf is 1 */
status read_registers(std::vector<uint8_t> &data, std::vector<uint8_t> &avail) override; status read_registers(std::vector<uint8_t>& data, std::vector<uint8_t>& avail) override;
/* Write all registers. buf is 4-byte aligned and it is in target /* Write all registers. buf is 4-byte aligned and it is in target
byte order */ byte order */
status write_registers(const std::vector<uint8_t> &data) override; status write_registers(const std::vector<uint8_t>& data) override;
/* Read one register. buf is 4-byte aligned and it is in /* Read one register. buf is 4-byte aligned and it is in
target byte order. If register is not available target byte order. If register is not available
corresponding bytes in avail_buf are 0, otherwise corresponding bytes in avail_buf are 0, otherwise
avail buf is 1 */ avail buf is 1 */
status read_single_register(unsigned int reg_no, std::vector<uint8_t> &buf, status read_single_register(unsigned int reg_no, std::vector<uint8_t>& buf, std::vector<uint8_t>& avail_buf) override;
std::vector<uint8_t> &avail_buf) override;
/* Write one register. buf is 4-byte aligned and it is in target byte /* Write one register. buf is 4-byte aligned and it is in target byte
order */ order */
status write_single_register(unsigned int reg_no, const std::vector<uint8_t> &buf) override; status write_single_register(unsigned int reg_no, const std::vector<uint8_t>& buf) override;
/*=================== Memory Access =====================*/ /*=================== Memory Access =====================*/
/* Read memory, buf is 4-bytes aligned and it is in target /* Read memory, buf is 4-bytes aligned and it is in target
byte order */ byte order */
status read_mem(uint64_t addr, std::vector<uint8_t> &buf) override; status read_mem(uint64_t addr, std::vector<uint8_t>& buf) override;
/* Write memory, buf is 4-bytes aligned and it is in target /* Write memory, buf is 4-bytes aligned and it is in target
byte order */ byte order */
status write_mem(uint64_t addr, const std::vector<uint8_t> &buf) override; status write_mem(uint64_t addr, const std::vector<uint8_t>& buf) override;
status process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) override; status process_query(unsigned int& mask, const rp_thread_ref& arg, rp_thread_info& info) override;
status thread_list_query(int first, const rp_thread_ref &arg, std::vector<rp_thread_ref> &result, size_t max_num, status thread_list_query(int first, const rp_thread_ref& arg, std::vector<rp_thread_ref>& result, size_t max_num, size_t& num,
size_t &num, bool &done) override; bool& done) override;
status current_thread_query(rp_thread_ref &thread) override; status current_thread_query(rp_thread_ref& thread) override;
status offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) override; status offsets_query(uint64_t& text, uint64_t& data, uint64_t& bss) override;
status crc_query(uint64_t addr, size_t len, uint32_t &val) override; status crc_query(uint64_t addr, size_t len, uint32_t& val) override;
status raw_query(std::string in_buf, std::string &out_buf) override; status raw_query(std::string in_buf, std::string& out_buf) override;
status threadinfo_query(int first, std::string &out_buf) override; status threadinfo_query(int first, std::string& out_buf) override;
status threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) override; status threadextrainfo_query(const rp_thread_ref& thread, std::string& out_buf) override;
status packetsize_query(std::string &out_buf) override; status packetsize_query(std::string& out_buf) override;
status add_break(break_type type, uint64_t addr, unsigned int length) override; status add_break(break_type type, uint64_t addr, unsigned int length) override;
status remove_break(break_type type, uint64_t addr, unsigned int length) override; status remove_break(break_type type, uint64_t addr, unsigned int length) override;
status resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, status resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, std::function<void(unsigned)> stop_callback) override;
std::function<void(unsigned)> stop_callback) override;
status target_xml_query(std::string &out_buf) override; status target_xml_query(std::string& out_buf) override;
protected: protected:
static inline constexpr addr_t map_addr(const addr_t &i) { return i; } static inline constexpr addr_t map_addr(const addr_t& i) { return i; }
iss::arch_if *core; iss::arch_if* core;
rp_thread_ref thread_idx; rp_thread_ref thread_idx;
}; };
template <typename ARCH> status riscv_target_adapter<ARCH>::set_gen_thread(rp_thread_ref &thread) { template <typename ARCH> status riscv_target_adapter<ARCH>::set_gen_thread(rp_thread_ref& thread) {
thread_idx = thread; thread_idx = thread;
return Ok; return Ok;
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::set_ctrl_thread(rp_thread_ref &thread) { template <typename ARCH> status riscv_target_adapter<ARCH>::set_ctrl_thread(rp_thread_ref& thread) {
thread_idx = thread; thread_idx = thread;
return Ok; return Ok;
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::is_thread_alive(rp_thread_ref &thread, bool &alive) { template <typename ARCH> status riscv_target_adapter<ARCH>::is_thread_alive(rp_thread_ref& thread, bool& alive) {
alive = 1; alive = 1;
return Ok; return Ok;
} }
@ -158,10 +156,9 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::is_thread_alive(rp_t
* set if all threads are processed. * set if all threads are processed.
*/ */
template <typename ARCH> template <typename ARCH>
status riscv_target_adapter<ARCH>::thread_list_query(int first, const rp_thread_ref &arg, status riscv_target_adapter<ARCH>::thread_list_query(int first, const rp_thread_ref& arg, std::vector<rp_thread_ref>& result,
std::vector<rp_thread_ref> &result, size_t max_num, size_t &num, size_t max_num, size_t& num, bool& done) {
bool &done) { if(first == 0) {
if (first == 0) {
result.clear(); result.clear();
result.push_back(thread_idx); result.push_back(thread_idx);
num = 1; num = 1;
@ -171,23 +168,22 @@ status riscv_target_adapter<ARCH>::thread_list_query(int first, const rp_thread_
return NotSupported; return NotSupported;
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::current_thread_query(rp_thread_ref &thread) { template <typename ARCH> status riscv_target_adapter<ARCH>::current_thread_query(rp_thread_ref& thread) {
thread = thread_idx; thread = thread_idx;
return Ok; return Ok;
} }
template <typename ARCH> template <typename ARCH> status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, std::vector<uint8_t> &avail) {
LOG(TRACE) << "reading target registers"; LOG(TRACE) << "reading target registers";
// return idx<0?:; // return idx<0?:;
data.clear(); data.clear();
avail.clear(); avail.clear();
const uint8_t *reg_base = core->get_regs_base_ptr(); const uint8_t* reg_base = core->get_regs_base_ptr();
auto start_reg=arch::traits<ARCH>::X0; auto start_reg = arch::traits<ARCH>::X0;
for (size_t reg_no = start_reg; reg_no < start_reg+33/*arch::traits<ARCH>::NUM_REGS*/; ++reg_no) { for(size_t reg_no = start_reg; reg_no < start_reg + 33 /*arch::traits<ARCH>::NUM_REGS*/; ++reg_no) {
auto reg_width = arch::traits<ARCH>::reg_bit_widths[reg_no] / 8; auto reg_width = arch::traits<ARCH>::reg_bit_widths[reg_no] / 8;
unsigned offset = traits<ARCH>::reg_byte_offsets[reg_no]; unsigned offset = traits<ARCH>::reg_byte_offsets[reg_no];
for (size_t j = 0; j < reg_width; ++j) { for(size_t j = 0; j < reg_width; ++j) {
data.push_back(*(reg_base + offset + j)); data.push_back(*(reg_base + offset + j));
avail.push_back(0xff); avail.push_back(0xff);
} }
@ -210,19 +206,19 @@ status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, st
return Ok; return Ok;
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(const std::vector<uint8_t> &data) { template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(const std::vector<uint8_t>& data) {
auto start_reg=arch::traits<ARCH>::X0; auto start_reg = arch::traits<ARCH>::X0;
auto *reg_base = core->get_regs_base_ptr(); auto* reg_base = core->get_regs_base_ptr();
auto iter = data.data(); auto iter = data.data();
bool e_ext = arch::traits<ARCH>::PC<32; bool e_ext = arch::traits<ARCH>::PC < 32;
for (size_t reg_no = 0; reg_no < start_reg+33/*arch::traits<ARCH>::NUM_REGS*/; ++reg_no) { for(size_t reg_no = 0; reg_no < start_reg + 33 /*arch::traits<ARCH>::NUM_REGS*/; ++reg_no) {
if(e_ext && reg_no>15){ if(e_ext && reg_no > 15) {
if(reg_no==32){ if(reg_no == 32) {
auto reg_width = arch::traits<ARCH>::reg_bit_widths[arch::traits<ARCH>::PC] / 8; auto reg_width = arch::traits<ARCH>::reg_bit_widths[arch::traits<ARCH>::PC] / 8;
auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]; auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC];
std::copy(iter, iter + reg_width, reg_base); std::copy(iter, iter + reg_width, reg_base);
} else { } else {
const uint64_t zero_val=0; const uint64_t zero_val = 0;
auto reg_width = arch::traits<ARCH>::reg_bit_widths[15] / 8; auto reg_width = arch::traits<ARCH>::reg_bit_widths[15] / 8;
auto iter = (uint8_t*)&zero_val; auto iter = (uint8_t*)&zero_val;
std::copy(iter, iter + reg_width, reg_base); std::copy(iter, iter + reg_width, reg_base);
@ -239,12 +235,11 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(cons
} }
template <typename ARCH> template <typename ARCH>
status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vector<uint8_t> &data, status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
std::vector<uint8_t> &avail) { if(reg_no < 65) {
if (reg_no < 65) {
// auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename // auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename
// arch::traits<ARCH>::reg_e>(reg_no))/8; // arch::traits<ARCH>::reg_e>(reg_no))/8;
auto *reg_base = core->get_regs_base_ptr(); auto* reg_base = core->get_regs_base_ptr();
auto reg_width = arch::traits<ARCH>::reg_bit_widths[reg_no] / 8; auto reg_width = arch::traits<ARCH>::reg_bit_widths[reg_no] / 8;
data.resize(reg_width); data.resize(reg_width);
avail.resize(reg_width); avail.resize(reg_width);
@ -261,10 +256,9 @@ status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std
return data.size() > 0 ? Ok : Err; return data.size() > 0 ? Ok : Err;
} }
template <typename ARCH> template <typename ARCH> status riscv_target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t>& data) {
status riscv_target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t> &data) { if(reg_no < 65) {
if (reg_no < 65) { auto* reg_base = core->get_regs_base_ptr();
auto *reg_base = core->get_regs_base_ptr();
auto reg_width = arch::traits<ARCH>::reg_bit_widths[static_cast<typename arch::traits<ARCH>::reg_e>(reg_no)] / 8; auto reg_width = arch::traits<ARCH>::reg_bit_widths[static_cast<typename arch::traits<ARCH>::reg_e>(reg_no)] / 8;
auto offset = traits<ARCH>::reg_byte_offsets[reg_no]; auto offset = traits<ARCH>::reg_byte_offsets[reg_no];
std::copy(data.begin(), data.begin() + reg_width, reg_base + offset); std::copy(data.begin(), data.begin() + reg_width, reg_base + offset);
@ -275,41 +269,36 @@ status riscv_target_adapter<ARCH>::write_single_register(unsigned int reg_no, co
return Ok; return Ok;
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::read_mem(uint64_t addr, std::vector<uint8_t> &data) { template <typename ARCH> status riscv_target_adapter<ARCH>::read_mem(uint64_t addr, std::vector<uint8_t>& data) {
auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr}); auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr});
auto f = [&]() -> status { return core->read(a, data.size(), data.data()); }; auto f = [&]() -> status { return core->read(a, data.size(), data.data()); };
return srv->execute_syncronized(f); return srv->execute_syncronized(f);
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::write_mem(uint64_t addr, const std::vector<uint8_t> &data) { template <typename ARCH> status riscv_target_adapter<ARCH>::write_mem(uint64_t addr, const std::vector<uint8_t>& data) {
auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr}); auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr});
auto f = [&]() -> status { return core->write(a, data.size(), data.data()); }; auto f = [&]() -> status { return core->write(a, data.size(), data.data()); };
return srv->execute_syncronized(f); return srv->execute_syncronized(f);
} }
template <typename ARCH> template <typename ARCH>
status riscv_target_adapter<ARCH>::process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) { status riscv_target_adapter<ARCH>::process_query(unsigned int& mask, const rp_thread_ref& arg, rp_thread_info& info) {
return NotSupported; return NotSupported;
} }
template <typename ARCH> template <typename ARCH> status riscv_target_adapter<ARCH>::offsets_query(uint64_t& text, uint64_t& data, uint64_t& bss) {
status riscv_target_adapter<ARCH>::offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) {
text = 0; text = 0;
data = 0; data = 0;
bss = 0; bss = 0;
return Ok; return Ok;
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::crc_query(uint64_t addr, size_t len, uint32_t &val) { template <typename ARCH> status riscv_target_adapter<ARCH>::crc_query(uint64_t addr, size_t len, uint32_t& val) { return NotSupported; }
return NotSupported;
}
template <typename ARCH> status riscv_target_adapter<ARCH>::raw_query(std::string in_buf, std::string &out_buf) { template <typename ARCH> status riscv_target_adapter<ARCH>::raw_query(std::string in_buf, std::string& out_buf) { return NotSupported; }
return NotSupported;
}
template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int first, std::string &out_buf) { template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int first, std::string& out_buf) {
if (first) { if(first) {
out_buf = fmt::format("m{:x}", thread_idx.val); out_buf = fmt::format("m{:x}", thread_idx.val);
} else { } else {
out_buf = "l"; out_buf = "l";
@ -317,8 +306,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int
return Ok; return Ok;
} }
template <typename ARCH> template <typename ARCH> status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref& thread, std::string& out_buf) {
status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) {
std::array<char, 20> buf; std::array<char, 20> buf;
memset(buf.data(), 0, 20); memset(buf.data(), 0, 20);
sprintf(buf.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0); sprintf(buf.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0);
@ -326,7 +314,7 @@ status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref &th
return Ok; return Ok;
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::packetsize_query(std::string &out_buf) { template <typename ARCH> status riscv_target_adapter<ARCH>::packetsize_query(std::string& out_buf) {
out_buf = "PacketSize=1000"; out_buf = "PacketSize=1000";
return Ok; return Ok;
} }
@ -340,8 +328,8 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::add_break(break_type
auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr}); auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
auto eaddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr + length}); auto eaddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr + length});
target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val); target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val);
LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex << saddr.val
<< saddr.val << std::dec; << std::dec;
LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
return Ok; return Ok;
} }
@ -356,9 +344,8 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::remove_break(break_t
case HW_EXEC: { case HW_EXEC: {
auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr}); auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val); unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val);
if (handle) { if(handle) {
LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val << std::dec;
<< std::dec;
// TODO: check length of addr range // TODO: check length of addr range
target_adapter_base::bp_lut.removeEntry(handle); target_adapter_base::bp_lut.removeEntry(handle);
LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
@ -372,53 +359,53 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::remove_break(break_t
template <typename ARCH> template <typename ARCH>
status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread,
std::function<void(unsigned)> stop_callback) { std::function<void(unsigned)> stop_callback) {
auto *reg_base = core->get_regs_base_ptr(); auto* reg_base = core->get_regs_base_ptr();
auto reg_width = arch::traits<ARCH>::reg_bit_widths[arch::traits<ARCH>::PC] / 8; auto reg_width = arch::traits<ARCH>::reg_bit_widths[arch::traits<ARCH>::PC] / 8;
auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]; auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC];
const uint8_t *iter = reinterpret_cast<const uint8_t *>(&addr); const uint8_t* iter = reinterpret_cast<const uint8_t*>(&addr);
std::copy(iter, iter + reg_width, reg_base); std::copy(iter, iter + reg_width, reg_base);
return resume_from_current(step, sig, thread, stop_callback); return resume_from_current(step, sig, thread, stop_callback);
} }
template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std::string &out_buf) { template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std::string& out_buf) {
const std::string res{"<?xml version=\"1.0\"?><!DOCTYPE target SYSTEM \"gdb-target.dtd\">" const std::string res{"<?xml version=\"1.0\"?><!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target><architecture>riscv:rv32</architecture>" "<target><architecture>riscv:rv32</architecture>"
//" <feature name=\"org.gnu.gdb.riscv.rv32i\">\n" //" <feature name=\"org.gnu.gdb.riscv.rv32i\">\n"
//" <reg name=\"x0\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x0\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x1\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x1\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x2\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x2\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x3\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x3\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x4\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x4\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x5\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x5\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x6\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x6\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x7\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x7\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x8\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x8\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x9\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x9\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x10\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x10\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x11\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x11\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x12\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x12\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x13\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x13\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x14\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x14\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x15\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x15\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x16\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x16\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x17\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x17\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x18\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x18\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x19\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x19\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x20\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x20\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x21\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x21\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x22\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x22\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x23\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x23\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x24\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x24\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x25\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x25\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x26\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x26\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x27\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x27\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x28\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x28\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x29\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x29\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x30\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x30\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x31\" bitsize=\"32\" group=\"general\"/>\n" //" <reg name=\"x31\" bitsize=\"32\" group=\"general\"/>\n"
//" </feature>\n" //" </feature>\n"
"</target>"}; "</target>"};
out_buf = res; out_buf = res;
return Ok; return Ok;
} }
@ -468,7 +455,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std
</target> </target>
*/ */
} } // namespace debugger
} } // namespace iss
#endif /* _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_ */ #endif /* _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_ */

View File

@ -33,21 +33,20 @@
#ifndef _ISS_FACTORY_H_ #ifndef _ISS_FACTORY_H_
#define _ISS_FACTORY_H_ #define _ISS_FACTORY_H_
#include <algorithm>
#include <functional>
#include <iss/iss.h> #include <iss/iss.h>
#include <memory> #include <memory>
#include <unordered_map>
#include <functional>
#include <string> #include <string>
#include <algorithm> #include <unordered_map>
#include <vector> #include <vector>
namespace iss { namespace iss {
using cpu_ptr = std::unique_ptr<iss::arch_if>; using cpu_ptr = std::unique_ptr<iss::arch_if>;
using vm_ptr= std::unique_ptr<iss::vm_if>; using vm_ptr = std::unique_ptr<iss::vm_if>;
template<typename PLAT> template <typename PLAT> std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_port) {
std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_port){
using core_type = typename PLAT::core; using core_type = typename PLAT::core;
core_type* lcpu = new PLAT(); core_type* lcpu = new PLAT();
if(backend == "interp") if(backend == "interp")
@ -63,44 +62,45 @@ std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_
return {nullptr, nullptr}; return {nullptr, nullptr};
} }
class core_factory { class core_factory {
using cpu_ptr = std::unique_ptr<iss::arch_if>; using cpu_ptr = std::unique_ptr<iss::arch_if>;
using vm_ptr= std::unique_ptr<iss::vm_if>; using vm_ptr = std::unique_ptr<iss::vm_if>;
using base_t = std::tuple<cpu_ptr, vm_ptr>; using base_t = std::tuple<cpu_ptr, vm_ptr>;
using create_fn = std::function<base_t(unsigned, void*) >; using create_fn = std::function<base_t(unsigned, void*)>;
using registry_t = std::unordered_map<std::string, create_fn> ; using registry_t = std::unordered_map<std::string, create_fn>;
registry_t registry; registry_t registry;
core_factory() = default; core_factory() = default;
core_factory(const core_factory &) = delete; core_factory(const core_factory&) = delete;
core_factory & operator=(const core_factory &) = delete; core_factory& operator=(const core_factory&) = delete;
public: public:
static core_factory & instance() { static core_factory bf; return bf; } static core_factory& instance() {
static core_factory bf;
return bf;
}
bool register_creator(const std::string & className, create_fn const& fn) { bool register_creator(const std::string& className, create_fn const& fn) {
registry[className] = fn; registry[className] = fn;
return true; return true;
} }
base_t create(std::string const& className, unsigned gdb_port=0, void* init_data=nullptr) const { base_t create(std::string const& className, unsigned gdb_port = 0, void* init_data = nullptr) const {
registry_t::const_iterator regEntry = registry.find(className); registry_t::const_iterator regEntry = registry.find(className);
if (regEntry != registry.end()) if(regEntry != registry.end())
return regEntry->second(gdb_port, init_data); return regEntry->second(gdb_port, init_data);
return {nullptr, nullptr}; return {nullptr, nullptr};
} }
std::vector<std::string> get_names() { std::vector<std::string> get_names() {
std::vector<std::string> keys{registry.size()}; std::vector<std::string> keys{registry.size()};
std::transform(std::begin(registry), std::end(registry), std::begin(keys), [](std::pair<std::string, create_fn> const& p){ std::transform(std::begin(registry), std::end(registry), std::begin(keys),
return p.first; [](std::pair<std::string, create_fn> const& p) { return p.first; });
});
return keys; return keys;
} }
}; };
} } // namespace iss
#endif /* _ISS_FACTORY_H_ */ #endif /* _ISS_FACTORY_H_ */

View File

@ -36,17 +36,15 @@
#include <iss/plugin/calculator.h> #include <iss/plugin/calculator.h>
#include <yaml-cpp/yaml.h> #include <yaml-cpp/yaml.h>
#include <fstream>
#include <iss/arch_if.h> #include <iss/arch_if.h>
#include <util/logging.h> #include <util/logging.h>
#include <fstream>
using namespace std; using namespace std;
iss::plugin::cycle_estimate::cycle_estimate(string const& config_file_name) iss::plugin::cycle_estimate::cycle_estimate(string const& config_file_name)
: instr_if(nullptr) : instr_if(nullptr)
, config_file_name(config_file_name) , config_file_name(config_file_name) {}
{
}
iss::plugin::cycle_estimate::~cycle_estimate() = default; iss::plugin::cycle_estimate::~cycle_estimate() = default;
@ -54,23 +52,24 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
instr_if = vm.get_arch()->get_instrumentation_if(); instr_if = vm.get_arch()->get_instrumentation_if();
assert(instr_if && "No instrumentation interface available but callback executed"); assert(instr_if && "No instrumentation interface available but callback executed");
reg_base_ptr = reinterpret_cast<uint32_t*>(vm.get_arch()->get_regs_base_ptr()); reg_base_ptr = reinterpret_cast<uint32_t*>(vm.get_arch()->get_regs_base_ptr());
if(!instr_if) return false; if(!instr_if)
const string core_name = instr_if->core_type_name(); return false;
if (config_file_name.length() > 0) { const string core_name = instr_if->core_type_name();
if(config_file_name.length() > 0) {
std::ifstream is(config_file_name); std::ifstream is(config_file_name);
if (is.is_open()) { if(is.is_open()) {
try { try {
auto root = YAML::LoadAll(is); auto root = YAML::LoadAll(is);
if(root.size()!=1) { if(root.size() != 1) {
LOG(ERR) << "Too many root nodes in YAML file " << config_file_name; LOG(ERR) << "Too many root nodes in YAML file " << config_file_name;
} }
for (auto p : root[0]) { for(auto p : root[0]) {
auto isa_subset = p.first; auto isa_subset = p.first;
auto instructions = p.second; auto instructions = p.second;
for (auto const& instr : instructions) { for(auto const& instr : instructions) {
auto idx = instr.second["index"].as<unsigned>(); auto idx = instr.second["index"].as<unsigned>();
if(delays.size()<=idx) if(delays.size() <= idx)
delays.resize(idx+1); delays.resize(idx + 1);
auto& res = delays[idx]; auto& res = delays[idx];
res.is_branch = instr.second["branch"].as<bool>(); res.is_branch = instr.second["branch"].as<bool>();
auto delay = instr.second["delay"]; auto delay = instr.second["delay"];
@ -81,13 +80,13 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
try { try {
res.not_taken = delay.as<uint64_t>(); res.not_taken = delay.as<uint64_t>();
res.taken = res.not_taken; res.taken = res.not_taken;
} catch (const YAML::BadConversion& e) { } catch(const YAML::BadConversion& e) {
res.f = iss::plugin::calculator(reg_base_ptr, delay.as<std::string>()); res.f = iss::plugin::calculator(reg_base_ptr, delay.as<std::string>());
} }
} }
} }
} }
} catch (YAML::ParserException &e) { } catch(YAML::ParserException& e) {
LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what(); LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
return false; return false;
} }
@ -101,14 +100,14 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) { void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) {
size_t instr_id = instr_info.instr_id; size_t instr_id = instr_info.instr_id;
auto& entry = instr_id<delays.size()?delays[instr_id]:illegal_desc; auto& entry = instr_id < delays.size() ? delays[instr_id] : illegal_desc;
if(instr_info.phase_id==PRE_SYNC) { if(instr_info.phase_id == PRE_SYNC) {
if(entry.f) if(entry.f)
current_delay = entry.f(instr_if->get_instr_word()); current_delay = entry.f(instr_if->get_instr_word());
} else { } else {
if(!entry.f) if(!entry.f)
current_delay = instr_if->is_branch_taken()? entry.taken: entry.not_taken; current_delay = instr_if->is_branch_taken() ? entry.taken : entry.not_taken;
if(current_delay>1) if(current_delay > 1)
instr_if->update_last_instr_cycles(current_delay); instr_if->update_last_instr_cycles(current_delay);
current_delay = 1; current_delay = 1;
} }

View File

@ -37,16 +37,16 @@
#include "iss/instrumentation_if.h" #include "iss/instrumentation_if.h"
#include "iss/vm_plugin.h" #include "iss/vm_plugin.h"
#include <functional>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <functional>
namespace iss { namespace iss {
namespace plugin { namespace plugin {
class cycle_estimate: public vm_plugin { class cycle_estimate : public vm_plugin {
struct instr_desc { struct instr_desc {
size_t size{0}; size_t size{0};
bool is_branch{false}; bool is_branch{false};
@ -58,32 +58,32 @@ class cycle_estimate: public vm_plugin {
public: public:
cycle_estimate() = delete; cycle_estimate() = delete;
cycle_estimate(const cycle_estimate &) = delete; cycle_estimate(const cycle_estimate&) = delete;
cycle_estimate(const cycle_estimate &&) = delete; cycle_estimate(const cycle_estimate&&) = delete;
cycle_estimate(std::string const& config_file_name); cycle_estimate(std::string const& config_file_name);
virtual ~cycle_estimate(); virtual ~cycle_estimate();
cycle_estimate &operator=(const cycle_estimate &) = delete; cycle_estimate& operator=(const cycle_estimate&) = delete;
cycle_estimate &operator=(const cycle_estimate &&) = delete; cycle_estimate& operator=(const cycle_estimate&&) = delete;
bool registration(const char *const version, vm_if &arch) override; bool registration(const char* const version, vm_if& arch) override;
sync_type get_sync() override { return ALL_SYNC; }; sync_type get_sync() override { return ALL_SYNC; };
void callback(instr_info_t instr_info) override; void callback(instr_info_t instr_info) override;
private: private:
iss::instrumentation_if *instr_if{nullptr}; iss::instrumentation_if* instr_if{nullptr};
uint32_t* reg_base_ptr {nullptr}; uint32_t* reg_base_ptr{nullptr};
instr_desc illegal_desc{}; instr_desc illegal_desc{};
std::vector<instr_desc> delays; std::vector<instr_desc> delays;
unsigned current_delay{0}; unsigned current_delay{0};
struct pair_hash { struct pair_hash {
size_t operator()(const std::pair<uint64_t, uint64_t> &p) const { size_t operator()(const std::pair<uint64_t, uint64_t>& p) const {
std::hash<uint64_t> hash; std::hash<uint64_t> hash;
return hash(p.first) + hash(p.second); return hash(p.first) + hash(p.second);
} }
@ -91,7 +91,7 @@ private:
std::unordered_map<std::pair<uint64_t, uint64_t>, uint64_t, pair_hash> blocks; std::unordered_map<std::pair<uint64_t, uint64_t>, uint64_t, pair_hash> blocks;
std::string config_file_name; std::string config_file_name;
}; };
} } // namespace plugin
} } // namespace iss
#endif /* _ISS_PLUGIN_CYCLE_ESTIMATE_H_ */ #endif /* _ISS_PLUGIN_CYCLE_ESTIMATE_H_ */

View File

@ -36,26 +36,26 @@
#include <iss/instrumentation_if.h> #include <iss/instrumentation_if.h>
#include <yaml-cpp/yaml.h> #include <yaml-cpp/yaml.h>
#include <fstream>
#include <iss/arch_if.h> #include <iss/arch_if.h>
#include <util/logging.h> #include <util/logging.h>
#include <fstream>
iss::plugin::instruction_count::instruction_count(std::string config_file_name) { iss::plugin::instruction_count::instruction_count(std::string config_file_name) {
if (config_file_name.length() > 0) { if(config_file_name.length() > 0) {
std::ifstream is(config_file_name); std::ifstream is(config_file_name);
if (is.is_open()) { if(is.is_open()) {
try { try {
auto root = YAML::LoadAll(is); auto root = YAML::LoadAll(is);
if(root.size()!=1) { if(root.size() != 1) {
LOG(ERR) << "Too many rro nodes in YAML file " << config_file_name; LOG(ERR) << "Too many rro nodes in YAML file " << config_file_name;
} }
for (auto p : root[0]) { for(auto p : root[0]) {
auto isa_subset = p.first; auto isa_subset = p.first;
auto instructions = p.second; auto instructions = p.second;
for (auto const& instr : instructions) { for(auto const& instr : instructions) {
instr_delay res; instr_delay res;
res.instr_name = instr.first.as<std::string>(); res.instr_name = instr.first.as<std::string>();
res.size = instr.second["encoding"].as<std::string>().size()-2; // not counting 0b res.size = instr.second["encoding"].as<std::string>().size() - 2; // not counting 0b
auto delay = instr.second["delay"]; auto delay = instr.second["delay"];
if(delay.IsSequence()) { if(delay.IsSequence()) {
res.not_taken_delay = delay[0].as<uint64_t>(); res.not_taken_delay = delay[0].as<uint64_t>();
@ -68,7 +68,7 @@ iss::plugin::instruction_count::instruction_count(std::string config_file_name)
} }
} }
rep_counts.resize(delays.size()); rep_counts.resize(delays.size());
} catch (YAML::ParserException &e) { } catch(YAML::ParserException& e) {
LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what(); LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
} }
} else { } else {
@ -78,20 +78,19 @@ iss::plugin::instruction_count::instruction_count(std::string config_file_name)
} }
iss::plugin::instruction_count::~instruction_count() { iss::plugin::instruction_count::~instruction_count() {
size_t idx=0; size_t idx = 0;
for(auto it:delays){ for(auto it : delays) {
if(rep_counts[idx]>0 && it.instr_name.find("__"!=0)) if(rep_counts[idx] > 0 && it.instr_name.find("__" != 0))
LOG(INFO)<<it.instr_name<<";"<<rep_counts[idx]; LOG(INFO) << it.instr_name << ";" << rep_counts[idx];
idx++; idx++;
} }
} }
bool iss::plugin::instruction_count::registration(const char* const version, vm_if& vm) { bool iss::plugin::instruction_count::registration(const char* const version, vm_if& vm) {
auto instr_if = vm.get_arch()->get_instrumentation_if(); auto instr_if = vm.get_arch()->get_instrumentation_if();
if(!instr_if) return false; if(!instr_if)
return true; return false;
return true;
} }
void iss::plugin::instruction_count::callback(instr_info_t instr_info) { void iss::plugin::instruction_count::callback(instr_info_t instr_info) { rep_counts[instr_info.instr_id]++; }
rep_counts[instr_info.instr_id]++;
}

View File

@ -53,19 +53,19 @@ class instruction_count : public iss::vm_plugin {
public: public:
instruction_count() = delete; instruction_count() = delete;
instruction_count(const instruction_count &) = delete; instruction_count(const instruction_count&) = delete;
instruction_count(const instruction_count &&) = delete; instruction_count(const instruction_count&&) = delete;
instruction_count(std::string config_file_name); instruction_count(std::string config_file_name);
virtual ~instruction_count(); virtual ~instruction_count();
instruction_count &operator=(const instruction_count &) = delete; instruction_count& operator=(const instruction_count&) = delete;
instruction_count &operator=(const instruction_count &&) = delete; instruction_count& operator=(const instruction_count&&) = delete;
bool registration(const char *const version, vm_if &arch) override; bool registration(const char* const version, vm_if& arch) override;
sync_type get_sync() override { return POST_SYNC; }; sync_type get_sync() override { return POST_SYNC; };
@ -75,7 +75,7 @@ private:
std::vector<instr_delay> delays; std::vector<instr_delay> delays;
std::vector<uint64_t> rep_counts; std::vector<uint64_t> rep_counts;
}; };
} } // namespace plugin
} } // namespace iss
#endif /* _ISS_PLUGIN_INSTRUCTION_COUNTER_H_ */ #endif /* _ISS_PLUGIN_INSTRUCTION_COUNTER_H_ */

View File

@ -30,20 +30,20 @@
* *
*******************************************************************************/ *******************************************************************************/
#include <iostream>
#include <vector>
#include <array> #include <array>
#include <iostream>
#include <iss/factory.h> #include <iss/factory.h>
#include <vector>
#include "iss/arch/tgc_mapper.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include "iss/arch/tgc_mapper.h"
#ifdef WITH_LLVM #ifdef WITH_LLVM
#include <iss/llvm/jit_init.h> #include <iss/llvm/jit_init.h>
#endif #endif
#include <iss/log_categories.h>
#include "iss/plugin/cycle_estimate.h" #include "iss/plugin/cycle_estimate.h"
#include "iss/plugin/instruction_count.h" #include "iss/plugin/instruction_count.h"
#include <iss/log_categories.h>
#ifndef WIN32 #ifndef WIN32
#include <iss/plugin/loader.h> #include <iss/plugin/loader.h>
#endif #endif
@ -53,7 +53,7 @@
namespace po = boost::program_options; namespace po = boost::program_options;
int main(int argc, char *argv[]) { int main(int argc, char* argv[]) {
/* /*
* Define and parse the program options * Define and parse the program options
*/ */
@ -79,12 +79,12 @@ int main(int argc, char *argv[]) {
try { try {
po::store(parsed, clim); // can throw po::store(parsed, clim); // can throw
// --help option // --help option
if (clim.count("help")) { if(clim.count("help")) {
std::cout << "DBT-RISE-TGC simulator for TGC RISC-V cores" << std::endl << desc << std::endl; std::cout << "DBT-RISE-TGC simulator for TGC RISC-V cores" << std::endl << desc << std::endl;
return 0; return 0;
} }
po::notify(clim); // throws on error, so do after help in case po::notify(clim); // throws on error, so do after help in case
} catch (po::error &e) { } catch(po::error& e) {
// there are problems // there are problems
std::cerr << "ERROR: " << e.what() << std::endl << std::endl; std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
std::cerr << desc << std::endl; std::cerr << desc << std::endl;
@ -97,14 +97,14 @@ int main(int argc, char *argv[]) {
auto l = logging::as_log_level(clim["verbose"].as<int>()); auto l = logging::as_log_level(clim["verbose"].as<int>());
LOGGER(DEFAULT)::reporting_level() = l; LOGGER(DEFAULT)::reporting_level() = l;
LOGGER(connection)::reporting_level() = l; LOGGER(connection)::reporting_level() = l;
if (clim.count("logfile")) { if(clim.count("logfile")) {
// configure the connection logger // configure the connection logger
auto f = fopen(clim["logfile"].as<std::string>().c_str(), "w"); auto f = fopen(clim["logfile"].as<std::string>().c_str(), "w");
LOG_OUTPUT(DEFAULT)::stream() = f; LOG_OUTPUT(DEFAULT)::stream() = f;
LOG_OUTPUT(connection)::stream() = f; LOG_OUTPUT(connection)::stream() = f;
} }
std::vector<iss::vm_plugin *> plugin_list; std::vector<iss::vm_plugin*> plugin_list;
auto res = 0; auto res = 0;
try { try {
#ifdef WITH_LLVM #ifdef WITH_LLVM
@ -112,51 +112,51 @@ int main(int argc, char *argv[]) {
iss::init_jit_debug(argc, argv); iss::init_jit_debug(argc, argv);
#endif #endif
bool dump = clim.count("dump-ir"); bool dump = clim.count("dump-ir");
auto & f = iss::core_factory::instance(); auto& f = iss::core_factory::instance();
// instantiate the simulator // instantiate the simulator
iss::vm_ptr vm{nullptr}; iss::vm_ptr vm{nullptr};
iss::cpu_ptr cpu{nullptr}; iss::cpu_ptr cpu{nullptr};
std::string isa_opt(clim["isa"].as<std::string>()); std::string isa_opt(clim["isa"].as<std::string>());
if(isa_opt.size()==0 || isa_opt == "?") { if(isa_opt.size() == 0 || isa_opt == "?") {
auto list = f.get_names(); auto list = f.get_names();
std::sort(std::begin(list), std::end(list)); std::sort(std::begin(list), std::end(list));
std::cout<<"Available implementations (core|platform|backend):\n - "<<util::join(list, "\n - ")<<std::endl; std::cout << "Available implementations (core|platform|backend):\n - " << util::join(list, "\n - ") << std::endl;
return 0; return 0;
} else if (isa_opt.find('|') != std::string::npos) { } else if(isa_opt.find('|') != std::string::npos) {
std::tie(cpu, vm) = f.create(isa_opt+"|"+clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); std::tie(cpu, vm) = f.create(isa_opt + "|" + clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} else { } else {
auto base_isa = isa_opt.substr(0, 5); auto base_isa = isa_opt.substr(0, 5);
if(base_isa=="tgc5d" || base_isa=="tgc5e") { if(base_isa == "tgc5d" || base_isa == "tgc5e") {
isa_opt += "|mu_p_clic_pmp|"+clim["backend"].as<std::string>(); isa_opt += "|mu_p_clic_pmp|" + clim["backend"].as<std::string>();
} else { } else {
isa_opt += "|m_p|"+clim["backend"].as<std::string>(); isa_opt += "|m_p|" + clim["backend"].as<std::string>();
} }
std::tie(cpu, vm) = f.create(isa_opt, clim["gdb-port"].as<unsigned>()); std::tie(cpu, vm) = f.create(isa_opt, clim["gdb-port"].as<unsigned>());
} }
if(!cpu ){ if(!cpu) {
LOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " <<clim["backend"].as<std::string>()<< std::endl; LOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " << clim["backend"].as<std::string>() << std::endl;
return 127; return 127;
} }
if(!vm ){ if(!vm) {
LOG(ERR) << "Could not create vm for isa " << isa_opt << " and backend " <<clim["backend"].as<std::string>()<< std::endl; LOG(ERR) << "Could not create vm for isa " << isa_opt << " and backend " << clim["backend"].as<std::string>() << std::endl;
return 127; return 127;
} }
if (clim.count("plugin")) { if(clim.count("plugin")) {
for (std::string const& opt_val : clim["plugin"].as<std::vector<std::string>>()) { for(std::string const& opt_val : clim["plugin"].as<std::vector<std::string>>()) {
std::string plugin_name=opt_val; std::string plugin_name = opt_val;
std::string arg{""}; std::string arg{""};
std::size_t found = opt_val.find('='); std::size_t found = opt_val.find('=');
if (found != std::string::npos) { if(found != std::string::npos) {
plugin_name = opt_val.substr(0, found); plugin_name = opt_val.substr(0, found);
arg = opt_val.substr(found + 1, opt_val.size()); arg = opt_val.substr(found + 1, opt_val.size());
} }
#if defined(WITH_PLUGINS) #if defined(WITH_PLUGINS)
if (plugin_name == "ic") { if(plugin_name == "ic") {
auto *ic_plugin = new iss::plugin::instruction_count(arg); auto* ic_plugin = new iss::plugin::instruction_count(arg);
vm->register_plugin(*ic_plugin); vm->register_plugin(*ic_plugin);
plugin_list.push_back(ic_plugin); plugin_list.push_back(ic_plugin);
} else if (plugin_name == "ce") { } else if(plugin_name == "ce") {
auto *ce_plugin = new iss::plugin::cycle_estimate(arg); auto* ce_plugin = new iss::plugin::cycle_estimate(arg);
vm->register_plugin(*ce_plugin); vm->register_plugin(*ce_plugin);
plugin_list.push_back(ce_plugin); plugin_list.push_back(ce_plugin);
} else } else
@ -168,7 +168,7 @@ int main(int argc, char *argv[]) {
a.push_back({arg.c_str()}); a.push_back({arg.c_str()});
iss::plugin::loader l(plugin_name, {{"initPlugin"}}); iss::plugin::loader l(plugin_name, {{"initPlugin"}});
auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data()); auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data());
if(plugin){ if(plugin) {
vm->register_plugin(*plugin); vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else } else
@ -180,42 +180,43 @@ int main(int argc, char *argv[]) {
} }
} }
} }
if (clim.count("disass")) { if(clim.count("disass")) {
vm->setDisassEnabled(true); vm->setDisassEnabled(true);
LOGGER(disass)::reporting_level() = logging::INFO; LOGGER(disass)::reporting_level() = logging::INFO;
LOGGER(disass)::print_time() = false; LOGGER(disass)::print_time() = false;
auto file_name = clim["disass"].as<std::string>(); auto file_name = clim["disass"].as<std::string>();
if (file_name.length() > 0) { if(file_name.length() > 0) {
LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w"); LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w");
LOGGER(disass)::print_severity() = false; LOGGER(disass)::print_severity() = false;
} }
} }
uint64_t start_address = 0; uint64_t start_address = 0;
if (clim.count("mem")) if(clim.count("mem"))
vm->get_arch()->load_file(clim["mem"].as<std::string>()); vm->get_arch()->load_file(clim["mem"].as<std::string>());
if (clim.count("elf")) if(clim.count("elf"))
for (std::string input : clim["elf"].as<std::vector<std::string>>()) { for(std::string input : clim["elf"].as<std::vector<std::string>>()) {
auto start_addr = vm->get_arch()->load_file(input); auto start_addr = vm->get_arch()->load_file(input);
if (start_addr.second) start_address = start_addr.first; if(start_addr.second)
start_address = start_addr.first;
} }
for (std::string input : args) { for(std::string input : args) {
auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files
if (start_addr.second) start_address = start_addr.first; if(start_addr.second)
start_address = start_addr.first;
} }
if (clim.count("reset")) { if(clim.count("reset")) {
auto str = clim["reset"].as<std::string>(); auto str = clim["reset"].as<std::string>();
start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10); start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10);
} }
vm->reset(start_address); vm->reset(start_address);
auto cycles = clim["instructions"].as<uint64_t>(); auto cycles = clim["instructions"].as<uint64_t>();
res = vm->start(cycles, dump); res = vm->start(cycles, dump);
} catch (std::exception &e) { } catch(std::exception& e) {
LOG(ERR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" LOG(ERR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" << std::endl;
<< std::endl;
res = 2; res = 2;
} }
// cleanup to let plugins report of needed // cleanup to let plugins report of needed
for (auto *p : plugin_list) { for(auto* p : plugin_list) {
delete p; delete p;
} }
return res; return res;

View File

@ -55,8 +55,10 @@
// clang-format on // clang-format on
#define STR(X) #X #define STR(X) #X
#define CREATE_CORE(CN) \ #define CREATE_CORE(CN) \
if (type == STR(CN)) { std::tie(cpu, vm) = create_core<CN ## _plat_type>(backend, gdb_port, hart_id); } else if(type == STR(CN)) { \
std::tie(cpu, vm) = create_core<CN##_plat_type>(backend, gdb_port, hart_id); \
} else
#ifdef HAS_SCV #ifdef HAS_SCV
#include <scv.h> #include <scv.h>
@ -87,23 +89,22 @@ using namespace sc_core;
namespace { namespace {
iss::debugger::encoder_decoder encdec; iss::debugger::encoder_decoder encdec;
std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}}; std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
} } // namespace
int cmd_sysc(int argc, char *argv[], debugger::out_func of, debugger::data_func df, int cmd_sysc(int argc, char* argv[], debugger::out_func of, debugger::data_func df, debugger::target_adapter_if* tgt_adapter) {
debugger::target_adapter_if *tgt_adapter) { if(argc > 1) {
if (argc > 1) { if(strcasecmp(argv[1], "print_time") == 0) {
if (strcasecmp(argv[1], "print_time") == 0) {
std::string t = sc_time_stamp().to_string(); std::string t = sc_time_stamp().to_string();
of(t.c_str()); of(t.c_str());
std::array<char, 64> buf; std::array<char, 64> buf;
encdec.enc_string(t.c_str(), buf.data(), 63); encdec.enc_string(t.c_str(), buf.data(), 63);
df(buf.data()); df(buf.data());
return Ok; return Ok;
} else if (strcasecmp(argv[1], "break") == 0) { } else if(strcasecmp(argv[1], "break") == 0) {
sc_time t; sc_time t;
if (argc == 4) { if(argc == 4) {
t = scc::parse_from_string(argv[2], argv[3]); t = scc::parse_from_string(argv[2], argv[3]);
} else if (argc == 3) { } else if(argc == 3) {
t = scc::parse_from_string(argv[2]); t = scc::parse_from_string(argv[2]);
} else } else
return Err; return Err;
@ -120,17 +121,19 @@ int cmd_sysc(int argc, char *argv[], debugger::out_func of, debugger::data_func
} }
using cpu_ptr = std::unique_ptr<iss::arch_if>; using cpu_ptr = std::unique_ptr<iss::arch_if>;
using vm_ptr= std::unique_ptr<iss::vm_if>; using vm_ptr = std::unique_ptr<iss::vm_if>;
class core_wrapper { class core_wrapper {
public: public:
core_wrapper(core_complex *owner) : owner(owner) { } core_wrapper(core_complex* owner)
: owner(owner) {}
void reset(uint64_t addr){vm->reset(addr);} void reset(uint64_t addr) { vm->reset(addr); }
inline void start(bool dump = false){vm->start(std::numeric_limits<uint64_t>::max(), dump);} inline void start(bool dump = false) { vm->start(std::numeric_limits<uint64_t>::max(), dump); }
inline std::pair<uint64_t, bool> load_file(std::string const& name){ inline std::pair<uint64_t, bool> load_file(std::string const& name) {
iss::arch_if* cc = cpu->get_arch_if(); iss::arch_if* cc = cpu->get_arch_if();
return cc->load_file(name);}; return cc->load_file(name);
};
std::function<unsigned(void)> get_mode; std::function<unsigned(void)> get_mode;
std::function<uint64_t(void)> get_state; std::function<uint64_t(void)> get_state;
@ -138,26 +141,26 @@ public:
std::function<void(bool)> set_interrupt_execution; std::function<void(bool)> set_interrupt_execution;
std::function<void(short, bool)> local_irq; std::function<void(short, bool)> local_irq;
void create_cpu(std::string const& type, std::string const& backend, unsigned gdb_port, uint32_t hart_id){ void create_cpu(std::string const& type, std::string const& backend, unsigned gdb_port, uint32_t hart_id) {
auto & f = sysc::iss_factory::instance(); auto& f = sysc::iss_factory::instance();
if(type.size()==0 || type == "?") { if(type.size() == 0 || type == "?") {
std::cout<<"Available cores: "<<util::join(f.get_names(), ", ")<<std::endl; std::cout << "Available cores: " << util::join(f.get_names(), ", ") << std::endl;
sc_core::sc_stop(); sc_core::sc_stop();
} else if (type.find('|') != std::string::npos) { } else if(type.find('|') != std::string::npos) {
std::tie(cpu, vm) = f.create(type+"|"+backend); std::tie(cpu, vm) = f.create(type + "|" + backend);
} else { } else {
auto base_isa = type.substr(0, 5); auto base_isa = type.substr(0, 5);
if(base_isa=="tgc5d" || base_isa=="tgc5e") { if(base_isa == "tgc5d" || base_isa == "tgc5e") {
std::tie(cpu, vm) = f.create(type + "|mu_p_clic_pmp|" + backend, gdb_port, owner); std::tie(cpu, vm) = f.create(type + "|mu_p_clic_pmp|" + backend, gdb_port, owner);
} else { } else {
std::tie(cpu, vm) = f.create(type + "|m_p|" + backend, gdb_port, owner); std::tie(cpu, vm) = f.create(type + "|m_p|" + backend, gdb_port, owner);
} }
} }
if(!cpu ){ if(!cpu) {
SCCFATAL() << "Could not create cpu for isa " << type << " and backend " <<backend; SCCFATAL() << "Could not create cpu for isa " << type << " and backend " << backend;
} }
if(!vm ){ if(!vm) {
SCCFATAL() << "Could not create vm for isa " << type << " and backend " <<backend; SCCFATAL() << "Could not create vm for isa " << type << " and backend " << backend;
} }
auto* sc_cpu_if = reinterpret_cast<sc_core_adapter_if*>(cpu.get()); auto* sc_cpu_if = reinterpret_cast<sc_core_adapter_if*>(cpu.get());
sc_cpu_if->set_mhartid(hart_id); sc_cpu_if->set_mhartid(hart_id);
@ -167,59 +170,59 @@ public:
set_interrupt_execution = [sc_cpu_if](bool b) { return sc_cpu_if->set_interrupt_execution(b); }; set_interrupt_execution = [sc_cpu_if](bool b) { return sc_cpu_if->set_interrupt_execution(b); };
local_irq = [sc_cpu_if](short s, bool b) { return sc_cpu_if->local_irq(s, b); }; local_irq = [sc_cpu_if](short s, bool b) { return sc_cpu_if->local_irq(s, b); };
auto *srv = debugger::server<debugger::gdb_session>::get(); auto* srv = debugger::server<debugger::gdb_session>::get();
if (srv) tgt_adapter = srv->get_target(); if(srv)
if (tgt_adapter) tgt_adapter = srv->get_target();
tgt_adapter->add_custom_command( if(tgt_adapter)
{"sysc", [this](int argc, char *argv[], debugger::out_func of, tgt_adapter->add_custom_command({"sysc",
debugger::data_func df) -> int { return cmd_sysc(argc, argv, of, df, tgt_adapter); }, [this](int argc, char* argv[], debugger::out_func of, debugger::data_func df) -> int {
"SystemC sub-commands: break <time>, print_time"}); return cmd_sysc(argc, argv, of, df, tgt_adapter);
},
"SystemC sub-commands: break <time>, print_time"});
} }
core_complex * const owner; core_complex* const owner;
vm_ptr vm{nullptr}; vm_ptr vm{nullptr};
sc_cpu_ptr cpu{nullptr}; sc_cpu_ptr cpu{nullptr};
iss::debugger::target_adapter_if *tgt_adapter{nullptr}; iss::debugger::target_adapter_if* tgt_adapter{nullptr};
}; };
struct core_trace { struct core_trace {
//! transaction recording database //! transaction recording database
scv_tr_db *m_db{nullptr}; scv_tr_db* m_db{nullptr};
//! blocking transaction recording stream handle //! blocking transaction recording stream handle
scv_tr_stream *stream_handle{nullptr}; scv_tr_stream* stream_handle{nullptr};
//! transaction generator handle for blocking transactions //! transaction generator handle for blocking transactions
scv_tr_generator<_scv_tr_generator_default_data, _scv_tr_generator_default_data> *instr_tr_handle{nullptr}; scv_tr_generator<_scv_tr_generator_default_data, _scv_tr_generator_default_data>* instr_tr_handle{nullptr};
scv_tr_handle tr_handle; scv_tr_handle tr_handle;
}; };
SC_HAS_PROCESS(core_complex);// NOLINT SC_HAS_PROCESS(core_complex); // NOLINT
#ifndef CWR_SYSTEMC #ifndef CWR_SYSTEMC
core_complex::core_complex(sc_module_name const& name) core_complex::core_complex(sc_module_name const& name)
: sc_module(name) : sc_module(name)
, fetch_lut(tlm_dmi_ext()) , fetch_lut(tlm_dmi_ext())
, read_lut(tlm_dmi_ext()) , read_lut(tlm_dmi_ext())
, write_lut(tlm_dmi_ext()) , write_lut(tlm_dmi_ext()) {
{ init();
init();
} }
#endif #endif
void core_complex::init(){ void core_complex::init() {
trc=new core_trace(); trc = new core_trace();
ibus.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void { ibus.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void {
auto lut_entry = fetch_lut.getEntry(start); auto lut_entry = fetch_lut.getEntry(start);
if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) { if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) {
fetch_lut.removeEntry(lut_entry); fetch_lut.removeEntry(lut_entry);
} }
}); });
dbus.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void { dbus.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void {
auto lut_entry = read_lut.getEntry(start); auto lut_entry = read_lut.getEntry(start);
if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) { if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) {
read_lut.removeEntry(lut_entry); read_lut.removeEntry(lut_entry);
} }
lut_entry = write_lut.getEntry(start); lut_entry = write_lut.getEntry(start);
if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) { if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) {
write_lut.removeEntry(lut_entry); write_lut.removeEntry(lut_entry);
} }
}); });
@ -234,53 +237,53 @@ void core_complex::init(){
SC_METHOD(ext_irq_cb); SC_METHOD(ext_irq_cb);
sensitive << ext_irq_i; sensitive << ext_irq_i;
SC_METHOD(local_irq_cb); SC_METHOD(local_irq_cb);
for(auto pin:local_irq_i) for(auto pin : local_irq_i)
sensitive << pin; sensitive << pin;
trc->m_db=scv_tr_db::get_default_db(); trc->m_db = scv_tr_db::get_default_db();
SC_METHOD(forward); SC_METHOD(forward);
#ifndef CWR_SYSTEMC #ifndef CWR_SYSTEMC
sensitive<<clk_i; sensitive << clk_i;
#else #else
sensitive<<curr_clk; sensitive << curr_clk;
t2t.reset(new scc::tick2time{"t2t"}); t2t.reset(new scc::tick2time{"t2t"});
t2t->clk_i(clk_i); t2t->clk_i(clk_i);
t2t->clk_o(curr_clk); t2t->clk_o(curr_clk);
#endif #endif
} }
core_complex::~core_complex(){ core_complex::~core_complex() {
delete cpu; delete cpu;
delete trc; delete trc;
for (auto *p : plugin_list) for(auto* p : plugin_list)
delete p; delete p;
} }
void core_complex::trace(sc_trace_file *trf) const {} void core_complex::trace(sc_trace_file* trf) const {}
void core_complex::before_end_of_elaboration() { void core_complex::before_end_of_elaboration() {
SCCDEBUG(SCMOD)<<"instantiating iss::arch::tgf with "<<GET_PROP_VALUE(backend)<<" backend"; SCCDEBUG(SCMOD) << "instantiating iss::arch::tgf with " << GET_PROP_VALUE(backend) << " backend";
// cpu = scc::make_unique<core_wrapper>(this); // cpu = scc::make_unique<core_wrapper>(this);
cpu = new core_wrapper(this); cpu = new core_wrapper(this);
cpu->create_cpu(GET_PROP_VALUE(core_type), GET_PROP_VALUE(backend), GET_PROP_VALUE(gdb_server_port), GET_PROP_VALUE(mhartid)); cpu->create_cpu(GET_PROP_VALUE(core_type), GET_PROP_VALUE(backend), GET_PROP_VALUE(gdb_server_port), GET_PROP_VALUE(mhartid));
sc_assert(cpu->vm!=nullptr); sc_assert(cpu->vm != nullptr);
cpu->vm->setDisassEnabled(GET_PROP_VALUE(enable_disass) || trc->m_db != nullptr); cpu->vm->setDisassEnabled(GET_PROP_VALUE(enable_disass) || trc->m_db != nullptr);
if (GET_PROP_VALUE(plugins).length()) { if(GET_PROP_VALUE(plugins).length()) {
auto p = util::split(GET_PROP_VALUE(plugins), ';'); auto p = util::split(GET_PROP_VALUE(plugins), ';');
for (std::string const& opt_val : p) { for(std::string const& opt_val : p) {
std::string plugin_name=opt_val; std::string plugin_name = opt_val;
std::string filename{"cycles.txt"}; std::string filename{"cycles.txt"};
std::size_t found = opt_val.find('='); std::size_t found = opt_val.find('=');
if (found != std::string::npos) { if(found != std::string::npos) {
plugin_name = opt_val.substr(0, found); plugin_name = opt_val.substr(0, found);
filename = opt_val.substr(found + 1, opt_val.size()); filename = opt_val.substr(found + 1, opt_val.size());
} }
if (plugin_name == "ic") { if(plugin_name == "ic") {
auto *plugin = new iss::plugin::instruction_count(filename); auto* plugin = new iss::plugin::instruction_count(filename);
cpu->vm->register_plugin(*plugin); cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else if (plugin_name == "ce") { } else if(plugin_name == "ce") {
auto *plugin = new iss::plugin::cycle_estimate(filename); auto* plugin = new iss::plugin::cycle_estimate(filename);
cpu->vm->register_plugin(*plugin); cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else { } else {
@ -288,7 +291,7 @@ void core_complex::before_end_of_elaboration() {
std::array<char const*, 1> a{{filename.c_str()}}; std::array<char const*, 1> a{{filename.c_str()}};
iss::plugin::loader l(plugin_name, {{"initPlugin"}}); iss::plugin::loader l(plugin_name, {{"initPlugin"}});
auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data()); auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data());
if(plugin){ if(plugin) {
cpu->vm->register_plugin(*plugin); cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else } else
@ -297,26 +300,25 @@ void core_complex::before_end_of_elaboration() {
} }
} }
} }
} }
void core_complex::start_of_simulation() { void core_complex::start_of_simulation() {
// quantum_keeper.reset(); // quantum_keeper.reset();
if (GET_PROP_VALUE(elf_file).size() > 0) { if(GET_PROP_VALUE(elf_file).size() > 0) {
istringstream is(GET_PROP_VALUE(elf_file)); istringstream is(GET_PROP_VALUE(elf_file));
string s; string s;
while (getline(is, s, ',')) { while(getline(is, s, ',')) {
std::pair<uint64_t, bool> start_addr = cpu->load_file(s); std::pair<uint64_t, bool> start_addr = cpu->load_file(s);
#ifndef CWR_SYSTEMC #ifndef CWR_SYSTEMC
if (reset_address.is_default_value() && start_addr.second == true) if(reset_address.is_default_value() && start_addr.second == true)
reset_address.set_value(start_addr.first); reset_address.set_value(start_addr.first);
#else #else
if (start_addr.second == true) if(start_addr.second == true)
reset_address=start_addr.first; reset_address = start_addr.first;
#endif #endif
} }
} }
if (trc->m_db != nullptr && trc->stream_handle == nullptr) { if(trc->m_db != nullptr && trc->stream_handle == nullptr) {
string basename(this->name()); string basename(this->name());
trc->stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", trc->m_db); trc->stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", trc->m_db);
trc->instr_tr_handle = new scv_tr_generator<>("execute", *trc->stream_handle); trc->instr_tr_handle = new scv_tr_generator<>("execute", *trc->stream_handle);
@ -324,8 +326,10 @@ void core_complex::start_of_simulation() {
} }
bool core_complex::disass_output(uint64_t pc, const std::string instr_str) { bool core_complex::disass_output(uint64_t pc, const std::string instr_str) {
if (trc->m_db == nullptr) return false; if(trc->m_db == nullptr)
if (trc->tr_handle.is_active()) trc->tr_handle.end_transaction(); return false;
if(trc->tr_handle.is_active())
trc->tr_handle.end_transaction();
trc->tr_handle = trc->instr_tr_handle->begin_transaction(); trc->tr_handle = trc->instr_tr_handle->begin_transaction();
trc->tr_handle.record_attribute("PC", pc); trc->tr_handle.record_attribute("PC", pc);
trc->tr_handle.record_attribute("INSTR", instr_str); trc->tr_handle.record_attribute("INSTR", instr_str);
@ -337,20 +341,22 @@ bool core_complex::disass_output(uint64_t pc, const std::string instr_str) {
void core_complex::forward() { void core_complex::forward() {
#ifndef CWR_SYSTEMC #ifndef CWR_SYSTEMC
set_clock_period(clk_i.read()); set_clock_period(clk_i.read());
#else #else
set_clock_period(curr_clk.read()); set_clock_period(curr_clk.read());
#endif #endif
} }
void core_complex::set_clock_period(sc_core::sc_time period) { void core_complex::set_clock_period(sc_core::sc_time period) {
curr_clk = period; curr_clk = period;
if (period == SC_ZERO_TIME) cpu->set_interrupt_execution(true); if(period == SC_ZERO_TIME)
cpu->set_interrupt_execution(true);
} }
void core_complex::rst_cb() { void core_complex::rst_cb() {
if (rst_i.read()) cpu->set_interrupt_execution(true); if(rst_i.read())
cpu->set_interrupt_execution(true);
} }
void core_complex::sw_irq_cb() { cpu->local_irq(3, sw_irq_i.read()); } void core_complex::sw_irq_cb() { cpu->local_irq(3, sw_irq_i.read()); }
@ -360,9 +366,9 @@ void core_complex::timer_irq_cb() { cpu->local_irq(7, timer_irq_i.read()); }
void core_complex::ext_irq_cb() { cpu->local_irq(11, ext_irq_i.read()); } void core_complex::ext_irq_cb() { cpu->local_irq(11, ext_irq_i.read()); }
void core_complex::local_irq_cb() { void core_complex::local_irq_cb() {
for(auto i=0U; i<local_irq_i.size(); ++i) { for(auto i = 0U; i < local_irq_i.size(); ++i) {
if(local_irq_i[i].event()) { if(local_irq_i[i].event()) {
cpu->local_irq(16+i, local_irq_i[i].read()); cpu->local_irq(16 + i, local_irq_i[i].read());
} }
} }
} }
@ -371,42 +377,42 @@ void core_complex::run() {
wait(SC_ZERO_TIME); // separate from elaboration phase wait(SC_ZERO_TIME); // separate from elaboration phase
do { do {
wait(SC_ZERO_TIME); wait(SC_ZERO_TIME);
if (rst_i.read()) { if(rst_i.read()) {
cpu->reset(GET_PROP_VALUE(reset_address)); cpu->reset(GET_PROP_VALUE(reset_address));
wait(rst_i.negedge_event()); wait(rst_i.negedge_event());
} }
while (curr_clk.read() == SC_ZERO_TIME) { while(curr_clk.read() == SC_ZERO_TIME) {
wait(curr_clk.value_changed_event()); wait(curr_clk.value_changed_event());
} }
quantum_keeper.reset(); quantum_keeper.reset();
cpu->set_interrupt_execution(false); cpu->set_interrupt_execution(false);
cpu->start(dump_ir); cpu->start(dump_ir);
} while (cpu->get_interrupt_execution()); } while(cpu->get_interrupt_execution());
sc_stop(); sc_stop();
} }
bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data, bool is_fetch) { bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t* const data, bool is_fetch) {
auto& dmi_lut = is_fetch?fetch_lut:read_lut; auto& dmi_lut = is_fetch ? fetch_lut : read_lut;
auto lut_entry = dmi_lut.getEntry(addr); auto lut_entry = dmi_lut.getEntry(addr);
if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && addr + length <= lut_entry.get_end_address() + 1) { if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && addr + length <= lut_entry.get_end_address() + 1) {
auto offset = addr - lut_entry.get_start_address(); auto offset = addr - lut_entry.get_start_address();
std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data); std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data);
if(is_fetch) if(is_fetch)
ibus_inc+=lut_entry.get_read_latency()/curr_clk; ibus_inc += lut_entry.get_read_latency() / curr_clk;
else else
dbus_inc+=lut_entry.get_read_latency()/curr_clk; dbus_inc += lut_entry.get_read_latency() / curr_clk;
return true; return true;
} else { } else {
auto& sckt = is_fetch? ibus : dbus; auto& sckt = is_fetch ? ibus : dbus;
tlm::tlm_generic_payload gp; tlm::tlm_generic_payload gp;
gp.set_command(tlm::TLM_READ_COMMAND); gp.set_command(tlm::TLM_READ_COMMAND);
gp.set_address(addr); gp.set_address(addr);
gp.set_data_ptr(data); gp.set_data_ptr(data);
gp.set_data_length(length); gp.set_data_length(length);
gp.set_streaming_width(length); gp.set_streaming_width(length);
sc_time delay=quantum_keeper.get_local_time(); sc_time delay = quantum_keeper.get_local_time();
if (trc->m_db != nullptr && trc->tr_handle.is_valid()) { if(trc->m_db != nullptr && trc->tr_handle.is_valid()) {
if (is_fetch && trc->tr_handle.is_active()) { if(is_fetch && trc->tr_handle.is_active()) {
trc->tr_handle.end_transaction(); trc->tr_handle.end_transaction();
} }
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this); auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this);
@ -414,40 +420,39 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data,
} }
auto pre_delay = delay; auto pre_delay = delay;
dbus->b_transport(gp, delay); dbus->b_transport(gp, delay);
if(pre_delay>delay) { if(pre_delay > delay) {
quantum_keeper.reset(); quantum_keeper.reset();
} else { } else {
auto incr = (delay-quantum_keeper.get_local_time())/curr_clk; auto incr = (delay - quantum_keeper.get_local_time()) / curr_clk;
if(is_fetch) if(is_fetch)
ibus_inc+=incr; ibus_inc += incr;
else else
dbus_inc+=incr; dbus_inc += incr;
} }
SCCTRACE(this->name()) << "[local time: "<<delay<<"]: finish read_mem(0x" << std::hex << addr << ") : 0x" << (length==4?*(uint32_t*)data:length==2?*(uint16_t*)data:(unsigned)*data); SCCTRACE(this->name()) << "[local time: " << delay << "]: finish read_mem(0x" << std::hex << addr << ") : 0x"
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { << (length == 4 ? *(uint32_t*)data : length == 2 ? *(uint16_t*)data : (unsigned)*data);
if(gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
return false; return false;
} }
if (gp.is_dmi_allowed() && !GET_PROP_VALUE(disable_dmi)) { if(gp.is_dmi_allowed() && !GET_PROP_VALUE(disable_dmi)) {
gp.set_command(tlm::TLM_READ_COMMAND); gp.set_command(tlm::TLM_READ_COMMAND);
gp.set_address(addr); gp.set_address(addr);
tlm_dmi_ext dmi_data; tlm_dmi_ext dmi_data;
if (sckt->get_direct_mem_ptr(gp, dmi_data)) { if(sckt->get_direct_mem_ptr(gp, dmi_data)) {
if (dmi_data.is_read_allowed()) if(dmi_data.is_read_allowed())
dmi_lut.addEntry(dmi_data, dmi_data.get_start_address(), dmi_lut.addEntry(dmi_data, dmi_data.get_start_address(), dmi_data.get_end_address() - dmi_data.get_start_address() + 1);
dmi_data.get_end_address() - dmi_data.get_start_address() + 1);
} }
} }
return true; return true;
} }
} }
bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *const data) { bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t* const data) {
auto lut_entry = write_lut.getEntry(addr); auto lut_entry = write_lut.getEntry(addr);
if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && addr + length <= lut_entry.get_end_address() + 1) {
addr + length <= lut_entry.get_end_address() + 1) {
auto offset = addr - lut_entry.get_start_address(); auto offset = addr - lut_entry.get_start_address();
std::copy(data, data + length, lut_entry.get_dmi_ptr() + offset); std::copy(data, data + length, lut_entry.get_dmi_ptr() + offset);
dbus_inc+=lut_entry.get_write_latency()/curr_clk; dbus_inc += lut_entry.get_write_latency() / curr_clk;
return true; return true;
} else { } else {
write_buf.resize(length); write_buf.resize(length);
@ -458,27 +463,28 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons
gp.set_data_ptr(write_buf.data()); gp.set_data_ptr(write_buf.data());
gp.set_data_length(length); gp.set_data_length(length);
gp.set_streaming_width(length); gp.set_streaming_width(length);
sc_time delay=quantum_keeper.get_local_time(); sc_time delay = quantum_keeper.get_local_time();
if (trc->m_db != nullptr && trc->tr_handle.is_valid()) { if(trc->m_db != nullptr && trc->tr_handle.is_valid()) {
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this); auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this);
gp.set_extension(preExt); gp.set_extension(preExt);
} }
auto pre_delay = delay; auto pre_delay = delay;
dbus->b_transport(gp, delay); dbus->b_transport(gp, delay);
if(pre_delay>delay) if(pre_delay > delay)
quantum_keeper.reset(); quantum_keeper.reset();
else else
dbus_inc+=(delay-quantum_keeper.get_local_time())/curr_clk; dbus_inc += (delay - quantum_keeper.get_local_time()) / curr_clk;
SCCTRACE() << "[local time: "<<delay<<"]: finish write_mem(0x" << std::hex << addr << ") : 0x" << (length==4?*(uint32_t*)data:length==2?*(uint16_t*)data:(unsigned)*data); SCCTRACE() << "[local time: " << delay << "]: finish write_mem(0x" << std::hex << addr << ") : 0x"
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { << (length == 4 ? *(uint32_t*)data : length == 2 ? *(uint16_t*)data : (unsigned)*data);
if(gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
return false; return false;
} }
if (gp.is_dmi_allowed() && !GET_PROP_VALUE(disable_dmi)) { if(gp.is_dmi_allowed() && !GET_PROP_VALUE(disable_dmi)) {
gp.set_command(tlm::TLM_READ_COMMAND); gp.set_command(tlm::TLM_READ_COMMAND);
gp.set_address(addr); gp.set_address(addr);
tlm_dmi_ext dmi_data; tlm_dmi_ext dmi_data;
if (dbus->get_direct_mem_ptr(gp, dmi_data)) { if(dbus->get_direct_mem_ptr(gp, dmi_data)) {
if (dmi_data.is_write_allowed()) if(dmi_data.is_write_allowed())
write_lut.addEntry(dmi_data, dmi_data.get_start_address(), write_lut.addEntry(dmi_data, dmi_data.get_start_address(),
dmi_data.get_end_address() - dmi_data.get_start_address() + 1); dmi_data.get_end_address() - dmi_data.get_start_address() + 1);
} }
@ -487,7 +493,7 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons
} }
} }
bool core_complex::read_mem_dbg(uint64_t addr, unsigned length, uint8_t *const data) { bool core_complex::read_mem_dbg(uint64_t addr, unsigned length, uint8_t* const data) {
tlm::tlm_generic_payload gp; tlm::tlm_generic_payload gp;
gp.set_command(tlm::TLM_READ_COMMAND); gp.set_command(tlm::TLM_READ_COMMAND);
gp.set_address(addr); gp.set_address(addr);
@ -497,7 +503,7 @@ bool core_complex::read_mem_dbg(uint64_t addr, unsigned length, uint8_t *const d
return dbus->transport_dbg(gp) == length; return dbus->transport_dbg(gp) == length;
} }
bool core_complex::write_mem_dbg(uint64_t addr, unsigned length, const uint8_t *const data) { bool core_complex::write_mem_dbg(uint64_t addr, unsigned length, const uint8_t* const data) {
write_buf.resize(length); write_buf.resize(length);
std::copy(data, data + length, write_buf.begin()); // need to copy as TLM does not guarantee data integrity std::copy(data, data + length, write_buf.begin()); // need to copy as TLM does not guarantee data integrity
tlm::tlm_generic_payload gp; tlm::tlm_generic_payload gp;

View File

@ -33,10 +33,10 @@
#ifndef _SYSC_CORE_COMPLEX_H_ #ifndef _SYSC_CORE_COMPLEX_H_
#define _SYSC_CORE_COMPLEX_H_ #define _SYSC_CORE_COMPLEX_H_
#include <tlm/scc/initiator_mixin.h>
#include <scc/traceable.h>
#include <scc/tick2time.h> #include <scc/tick2time.h>
#include <scc/traceable.h>
#include <scc/utilities.h> #include <scc/utilities.h>
#include <tlm/scc/initiator_mixin.h>
#include <tlm/scc/scv/tlm_rec_initiator_socket.h> #include <tlm/scc/scv/tlm_rec_initiator_socket.h>
#ifdef CWR_SYSTEMC #ifdef CWR_SYSTEMC
#include <scmlinc/scml_property.h> #include <scmlinc/scml_property.h>
@ -45,24 +45,24 @@
#include <cci_configuration> #include <cci_configuration>
#define SOCKET_WIDTH scc::LT #define SOCKET_WIDTH scc::LT
#endif #endif
#include <memory>
#include <tlm> #include <tlm>
#include <tlm_utils/tlm_quantumkeeper.h> #include <tlm_utils/tlm_quantumkeeper.h>
#include <util/range_lut.h> #include <util/range_lut.h>
#include <memory>
namespace iss { namespace iss {
class vm_plugin; class vm_plugin;
} }
namespace sysc { namespace sysc {
class tlm_dmi_ext : public tlm::tlm_dmi { class tlm_dmi_ext : public tlm::tlm_dmi {
public: public:
bool operator==(const tlm_dmi_ext &o) const { bool operator==(const tlm_dmi_ext& o) const {
return this->get_granted_access() == o.get_granted_access() && return this->get_granted_access() == o.get_granted_access() && this->get_start_address() == o.get_start_address() &&
this->get_start_address() == o.get_start_address() && this->get_end_address() == o.get_end_address(); this->get_end_address() == o.get_end_address();
} }
bool operator!=(const tlm_dmi_ext &o) const { return !operator==(o); } bool operator!=(const tlm_dmi_ext& o) const { return !operator==(o); }
}; };
namespace tgfs { namespace tgfs {
@ -86,7 +86,7 @@ public:
sc_core::sc_vector<sc_core::sc_in<bool>> local_irq_i{"local_irq_i", 16}; sc_core::sc_vector<sc_core::sc_in<bool>> local_irq_i{"local_irq_i", 16};
#ifndef CWR_SYSTEMC #ifndef CWR_SYSTEMC
sc_core::sc_in<sc_core::sc_time> clk_i{"clk_i"}; sc_core::sc_in<sc_core::sc_time> clk_i{"clk_i"};
sc_core::sc_port<tlm::tlm_peek_if<uint64_t>, 1, sc_core::SC_ZERO_OR_MORE_BOUND> mtime_o{"mtime_o"}; sc_core::sc_port<tlm::tlm_peek_if<uint64_t>, 1, sc_core::SC_ZERO_OR_MORE_BOUND> mtime_o{"mtime_o"};
@ -113,11 +113,11 @@ public:
core_complex(sc_core::sc_module_name const& name); core_complex(sc_core::sc_module_name const& name);
#else #else
sc_core::sc_in<bool> clk_i{"clk_i"}; sc_core::sc_in<bool> clk_i{"clk_i"};
sc_core::sc_in<uint64_t> mtime_i{"mtime_i"}; sc_core::sc_in<uint64_t> mtime_i{"mtime_i"};
scml_property<std::string> elf_file{"elf_file", ""}; scml_property<std::string> elf_file{"elf_file", ""};
scml_property<bool> enable_disass{"enable_disass", false}; scml_property<bool> enable_disass{"enable_disass", false};
@ -151,49 +151,48 @@ public:
, plugins{"plugins", ""} , plugins{"plugins", ""}
, fetch_lut(tlm_dmi_ext()) , fetch_lut(tlm_dmi_ext())
, read_lut(tlm_dmi_ext()) , read_lut(tlm_dmi_ext())
, write_lut(tlm_dmi_ext()) , write_lut(tlm_dmi_ext()) {
{ init();
init();
} }
#endif #endif
~core_complex(); ~core_complex();
inline unsigned get_last_bus_cycles() { inline unsigned get_last_bus_cycles() {
auto mem_incr = std::max(ibus_inc, dbus_inc); auto mem_incr = std::max(ibus_inc, dbus_inc);
ibus_inc = dbus_inc = 0; ibus_inc = dbus_inc = 0;
return mem_incr>1?mem_incr:1; return mem_incr > 1 ? mem_incr : 1;
} }
inline void sync(uint64_t cycle) { inline void sync(uint64_t cycle) {
auto core_inc = curr_clk * (cycle - last_sync_cycle); auto core_inc = curr_clk * (cycle - last_sync_cycle);
quantum_keeper.inc(core_inc); quantum_keeper.inc(core_inc);
if (quantum_keeper.need_sync()) { if(quantum_keeper.need_sync()) {
wait(quantum_keeper.get_local_time()); wait(quantum_keeper.get_local_time());
quantum_keeper.reset(); quantum_keeper.reset();
} }
last_sync_cycle = cycle; last_sync_cycle = cycle;
} }
bool read_mem(uint64_t addr, unsigned length, uint8_t *const data, bool is_fetch); bool read_mem(uint64_t addr, unsigned length, uint8_t* const data, bool is_fetch);
bool write_mem(uint64_t addr, unsigned length, const uint8_t *const data); bool write_mem(uint64_t addr, unsigned length, const uint8_t* const data);
bool read_mem_dbg(uint64_t addr, unsigned length, uint8_t *const data); bool read_mem_dbg(uint64_t addr, unsigned length, uint8_t* const data);
bool write_mem_dbg(uint64_t addr, unsigned length, const uint8_t *const data); bool write_mem_dbg(uint64_t addr, unsigned length, const uint8_t* const data);
void trace(sc_core::sc_trace_file *trf) const override; void trace(sc_core::sc_trace_file* trf) const override;
bool disass_output(uint64_t pc, const std::string instr); bool disass_output(uint64_t pc, const std::string instr);
void set_clock_period(sc_core::sc_time period); void set_clock_period(sc_core::sc_time period);
protected: protected:
void before_end_of_elaboration() override; void before_end_of_elaboration() override;
void start_of_simulation() override; void start_of_simulation() override;
void forward(); void forward();
void run(); void run();
void rst_cb(); void rst_cb();
void sw_irq_cb(); void sw_irq_cb();
@ -209,10 +208,10 @@ protected:
uint64_t ibus_inc{0}, dbus_inc{0}; uint64_t ibus_inc{0}, dbus_inc{0};
core_trace* trc{nullptr}; core_trace* trc{nullptr};
std::unique_ptr<scc::tick2time> t2t; std::unique_ptr<scc::tick2time> t2t;
private: private:
void init(); void init();
std::vector<iss::vm_plugin *> plugin_list; std::vector<iss::vm_plugin*> plugin_list;
}; };
} /* namespace tgfs */ } /* namespace tgfs */
} /* namespace sysc */ } /* namespace sysc */

View File

@ -33,56 +33,58 @@
#ifndef _ISS_FACTORY_H_ #ifndef _ISS_FACTORY_H_
#define _ISS_FACTORY_H_ #define _ISS_FACTORY_H_
#include <iss/iss.h>
#include "sc_core_adapter_if.h" #include "sc_core_adapter_if.h"
#include <memory>
#include <unordered_map>
#include <functional>
#include <string>
#include <algorithm> #include <algorithm>
#include <functional>
#include <iss/iss.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector> #include <vector>
namespace sysc { namespace sysc {
using sc_cpu_ptr = std::unique_ptr<sc_core_adapter_if>; using sc_cpu_ptr = std::unique_ptr<sc_core_adapter_if>;
using vm_ptr= std::unique_ptr<iss::vm_if>; using vm_ptr = std::unique_ptr<iss::vm_if>;
class iss_factory { class iss_factory {
public: public:
using base_t = std::tuple<sc_cpu_ptr, vm_ptr>; using base_t = std::tuple<sc_cpu_ptr, vm_ptr>;
using create_fn = std::function<base_t(unsigned, void*) >; using create_fn = std::function<base_t(unsigned, void*)>;
using registry_t = std::unordered_map<std::string, create_fn> ; using registry_t = std::unordered_map<std::string, create_fn>;
iss_factory() = default; iss_factory() = default;
iss_factory(const iss_factory &) = delete; iss_factory(const iss_factory&) = delete;
iss_factory & operator=(const iss_factory &) = delete; iss_factory& operator=(const iss_factory&) = delete;
static iss_factory & instance() { static iss_factory bf; return bf; } static iss_factory& instance() {
static iss_factory bf;
return bf;
}
bool register_creator(const std::string & className, create_fn const& fn) { bool register_creator(const std::string& className, create_fn const& fn) {
registry[className] = fn; registry[className] = fn;
return true; return true;
} }
base_t create(std::string const& className, unsigned gdb_port=0, void* init_data=nullptr) const { base_t create(std::string const& className, unsigned gdb_port = 0, void* init_data = nullptr) const {
registry_t::const_iterator regEntry = registry.find(className); registry_t::const_iterator regEntry = registry.find(className);
if (regEntry != registry.end()) if(regEntry != registry.end())
return regEntry->second(gdb_port, init_data); return regEntry->second(gdb_port, init_data);
return {nullptr, nullptr}; return {nullptr, nullptr};
} }
std::vector<std::string> get_names() { std::vector<std::string> get_names() {
std::vector<std::string> keys{registry.size()}; std::vector<std::string> keys{registry.size()};
std::transform(std::begin(registry), std::end(registry), std::begin(keys), [](std::pair<std::string, create_fn> const& p){ std::transform(std::begin(registry), std::end(registry), std::begin(keys),
return p.first; [](std::pair<std::string, create_fn> const& p) { return p.first; });
});
return keys; return keys;
} }
private: private:
registry_t registry; registry_t registry;
}; };
} } // namespace sysc
#endif /* _ISS_FACTORY_H_ */ #endif /* _ISS_FACTORY_H_ */

View File

@ -30,79 +30,79 @@
* *
*******************************************************************************/ *******************************************************************************/
#include "core_complex.h"
#include "iss_factory.h" #include "iss_factory.h"
#include <iss/arch/tgc5c.h> #include "sc_core_adapter.h"
#include <array>
#include <iss/arch/riscv_hart_m_p.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/arch/riscv_hart_mu_p.h> #include <iss/arch/riscv_hart_mu_p.h>
#include "sc_core_adapter.h" #include <iss/arch/tgc5c.h>
#include "core_complex.h"
#include <array>
namespace iss { namespace iss {
namespace interp { namespace interp {
using namespace sysc; using namespace sysc;
volatile std::array<bool, 2> tgc_init = { volatile std::array<bool, 2> tgc_init = {
iss_factory::instance().register_creator("tgc5c|m_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { iss_factory::instance().register_creator("tgc5c|m_p|interp",
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); [](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc5c>>(cc); auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}}; auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc5c>>(cc);
}), return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}};
iss_factory::instance().register_creator("tgc5c|mu_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { }),
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); iss_factory::instance().register_creator("tgc5c|mu_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc5c>>(cc); auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}}; auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc5c>>(cc);
}) return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}};
}; })};
} } // namespace interp
#if defined(WITH_LLVM) #if defined(WITH_LLVM)
namespace llvm { namespace llvm {
using namespace sysc; using namespace sysc;
volatile std::array<bool, 2> tgc_init = { volatile std::array<bool, 2> tgc_init = {
iss_factory::instance().register_creator("tgc5c|m_p|llvm", [](unsigned gdb_port, void* data) -> iss_factory::base_t { iss_factory::instance().register_creator("tgc5c|m_p|llvm",
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); [](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc5c>>(cc); auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}}; auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc5c>>(cc);
}), return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}};
iss_factory::instance().register_creator("tgc5c|mu_p|llvm", [](unsigned gdb_port, void* data) -> iss_factory::base_t { }),
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); iss_factory::instance().register_creator("tgc5c|mu_p|llvm", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc5c>>(cc); auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}}; auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc5c>>(cc);
}) return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}};
}; })};
} } // namespace llvm
#endif #endif
#if defined(WITH_TCC) #if defined(WITH_TCC)
namespace tcc { namespace tcc {
using namespace sysc; using namespace sysc;
volatile std::array<bool, 2> tgc_init = { volatile std::array<bool, 2> tgc_init = {
iss_factory::instance().register_creator("tgc5c|m_p|tcc", [](unsigned gdb_port, void* data) -> iss_factory::base_t { iss_factory::instance().register_creator("tgc5c|m_p|tcc",
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); [](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc5c>>(cc); auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}}; auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc5c>>(cc);
}), return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}};
iss_factory::instance().register_creator("tgc5c|mu_p|tcc", [](unsigned gdb_port, void* data) -> iss_factory::base_t { }),
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); iss_factory::instance().register_creator("tgc5c|mu_p|tcc", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc5c>>(cc); auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}}; auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc5c>>(cc);
}) return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}};
}; })};
} } // namespace tcc
#endif #endif
#if defined(WITH_ASMJIT) #if defined(WITH_ASMJIT)
namespace asmjit { namespace asmjit {
using namespace sysc; using namespace sysc;
volatile std::array<bool, 2> tgc_init = { volatile std::array<bool, 2> tgc_init = {
iss_factory::instance().register_creator("tgc5c|m_p|asmjit", [](unsigned gdb_port, void* data) -> iss_factory::base_t { iss_factory::instance().register_creator("tgc5c|m_p|asmjit",
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); [](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc5c>>(cc); auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}}; auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc5c>>(cc);
}), return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}};
iss_factory::instance().register_creator("tgc5c|mu_p|asmjit", [](unsigned gdb_port, void* data) -> iss_factory::base_t { }),
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data); iss_factory::instance().register_creator("tgc5c|mu_p|asmjit", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc5c>>(cc); auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}}; auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc5c>>(cc);
}) return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::tgc5c*>(cpu), gdb_port)}};
}; })};
} } // namespace asmjit
#endif #endif
} } // namespace iss

View File

@ -8,90 +8,85 @@
#ifndef _SYSC_SC_CORE_ADAPTER_H_ #ifndef _SYSC_SC_CORE_ADAPTER_H_
#define _SYSC_SC_CORE_ADAPTER_H_ #define _SYSC_SC_CORE_ADAPTER_H_
#include <scc/report.h>
#include <util/ities.h>
#include "sc_core_adapter_if.h" #include "sc_core_adapter_if.h"
#include <iostream>
#include <iss/iss.h> #include <iss/iss.h>
#include <iss/vm_types.h> #include <iss/vm_types.h>
#include <iostream> #include <scc/report.h>
#include <util/ities.h>
namespace sysc { namespace sysc {
template<typename PLAT> template <typename PLAT> class sc_core_adapter : public PLAT, public sc_core_adapter_if {
class sc_core_adapter : public PLAT, public sc_core_adapter_if {
public: public:
using reg_t = typename iss::arch::traits<typename PLAT::core>::reg_t; using reg_t = typename iss::arch::traits<typename PLAT::core>::reg_t;
using phys_addr_t = typename iss::arch::traits<typename PLAT::core>::phys_addr_t; using phys_addr_t = typename iss::arch::traits<typename PLAT::core>::phys_addr_t;
using heart_state_t = typename PLAT::hart_state_type; using heart_state_t = typename PLAT::hart_state_type;
sc_core_adapter(sysc::tgfs::core_complex *owner) sc_core_adapter(sysc::tgfs::core_complex* owner)
: owner(owner) { } : owner(owner) {}
iss::arch_if* get_arch_if() override { return this;} iss::arch_if* get_arch_if() override { return this; }
void set_mhartid(unsigned id) override { PLAT::set_mhartid(id); } void set_mhartid(unsigned id) override { PLAT::set_mhartid(id); }
uint32_t get_mode() override { return this->reg.PRIV; } uint32_t get_mode() override { return this->reg.PRIV; }
void set_interrupt_execution(bool v) override { this->interrupt_sim = v?1:0; } void set_interrupt_execution(bool v) override { this->interrupt_sim = v ? 1 : 0; }
bool get_interrupt_execution() override { return this->interrupt_sim; } bool get_interrupt_execution() override { return this->interrupt_sim; }
uint64_t get_state() override { return this->state.mstatus.backing.val; } uint64_t get_state() override { return this->state.mstatus.backing.val; }
void notify_phase(iss::arch_if::exec_phase p) override { void notify_phase(iss::arch_if::exec_phase p) override {
if (p == iss::arch_if::ISTART && !first) { if(p == iss::arch_if::ISTART && !first) {
auto cycle_incr = owner->get_last_bus_cycles(); auto cycle_incr = owner->get_last_bus_cycles();
if(cycle_incr>1) if(cycle_incr > 1)
this->instr_if.update_last_instr_cycles(cycle_incr); this->instr_if.update_last_instr_cycles(cycle_incr);
owner->sync(this->instr_if.get_total_cycles()); owner->sync(this->instr_if.get_total_cycles());
} }
first=false; first = false;
} }
iss::sync_type needed_sync() const override { return iss::PRE_SYNC; } iss::sync_type needed_sync() const override { return iss::PRE_SYNC; }
void disass_output(uint64_t pc, const std::string instr) override { void disass_output(uint64_t pc, const std::string instr) override {
static constexpr std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}}; static constexpr std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
if (!owner->disass_output(pc, instr)) { if(!owner->disass_output(pc, instr)) {
std::stringstream s; std::stringstream s;
s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0') s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0') << std::setw(sizeof(reg_t) * 2)
<< std::setw(sizeof(reg_t) * 2) << (reg_t)this->state.mstatus << std::dec << ";c:" << (reg_t)this->state.mstatus << std::dec << ";c:" << this->reg.icount + this->cycle_offset << "]";
<< this->reg.icount + this->cycle_offset << "]"; SCCDEBUG(owner->name()) << "disass: "
SCCDEBUG(owner->name())<<"disass: " << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40)
<< "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40) << std::setfill(' ') << std::left << instr << s.str();
<< std::setfill(' ') << std::left << instr << s.str();
} }
}; };
iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) override { iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t* const data) override {
if (addr.access && iss::access_type::DEBUG) if(addr.access && iss::access_type::DEBUG)
return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
else { else {
return owner->read_mem(addr.val, length, data, is_fetch(addr.access)) ? iss::Ok : iss::Err; return owner->read_mem(addr.val, length, data, is_fetch(addr.access)) ? iss::Ok : iss::Err;
} }
} }
iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) override { iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t* const data) override {
if (addr.access && iss::access_type::DEBUG) if(addr.access && iss::access_type::DEBUG)
return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
else { else {
auto tohost_upper = (sizeof(reg_t) == 4 && addr.val == (this->tohost + 4)) || auto tohost_upper = (sizeof(reg_t) == 4 && addr.val == (this->tohost + 4)) || (sizeof(reg_t) == 8 && addr.val == this->tohost);
(sizeof(reg_t) == 8 && addr.val == this->tohost); auto tohost_lower = (sizeof(reg_t) == 4 && addr.val == this->tohost) || (sizeof(reg_t) == 64 && addr.val == this->tohost);
auto tohost_lower = (sizeof(reg_t) == 4 && addr.val == this->tohost) || if(tohost_lower || tohost_upper) {
(sizeof(reg_t)== 64 && addr.val == this->tohost); if(tohost_upper || (tohost_lower && to_host_wr_cnt > 0)) {
if (tohost_lower || tohost_upper) { switch(hostvar >> 48) {
if (tohost_upper || (tohost_lower && to_host_wr_cnt > 0)) {
switch (hostvar >> 48) {
case 0: case 0:
if (hostvar != 0x1) { if(hostvar != 0x1) {
SCCINFO(owner->name()) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar SCCINFO(owner->name())
<< "), stopping simulation"; << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar << "), stopping simulation";
} else { } else {
SCCINFO(owner->name()) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar SCCINFO(owner->name())
<< "), stopping simulation"; << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar << "), stopping simulation";
} }
this->reg.trap_state=std::numeric_limits<uint32_t>::max(); this->reg.trap_state = std::numeric_limits<uint32_t>::max();
this->interrupt_sim=hostvar; this->interrupt_sim = hostvar;
#ifndef WITH_TCC #ifndef WITH_TCC
throw(iss::simulation_stopped(hostvar)); throw(iss::simulation_stopped(hostvar));
#endif #endif
@ -99,41 +94,44 @@ public:
default: default:
break; break;
} }
} else if (tohost_lower) } else if(tohost_lower)
to_host_wr_cnt++; to_host_wr_cnt++;
return iss::Ok; return iss::Ok;
} else { } else {
auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err; auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err;
// clear MTIP on mtimecmp write // clear MTIP on mtimecmp write
if (addr.val == 0x2004000) { if(addr.val == 0x2004000) {
reg_t val; reg_t val;
this->read_csr(iss::arch::mip, val); this->read_csr(iss::arch::mip, val);
if (val & (1ULL << 7)) this->write_csr(iss::arch::mip, val & ~(1ULL << 7)); if(val & (1ULL << 7))
this->write_csr(iss::arch::mip, val & ~(1ULL << 7));
} }
return res; return res;
} }
} }
} }
iss::status read_csr(unsigned addr, reg_t &val) override { iss::status read_csr(unsigned addr, reg_t& val) override {
#ifndef CWR_SYSTEMC #ifndef CWR_SYSTEMC
if((addr==iss::arch::time || addr==iss::arch::timeh) && owner->mtime_o.get_interface(0)){ if((addr == iss::arch::time || addr == iss::arch::timeh) && owner->mtime_o.get_interface(0)) {
uint64_t time_val; uint64_t time_val;
bool ret = owner->mtime_o->nb_peek(time_val); bool ret = owner->mtime_o->nb_peek(time_val);
if (addr == iss::arch::time) { if(addr == iss::arch::time) {
val = static_cast<reg_t>(time_val); val = static_cast<reg_t>(time_val);
} else if (addr == iss::arch::timeh) { } else if(addr == iss::arch::timeh) {
if (sizeof(reg_t) != 4) return iss::Err; if(sizeof(reg_t) != 4)
return iss::Err;
val = static_cast<reg_t>(time_val >> 32); val = static_cast<reg_t>(time_val >> 32);
} }
return ret?iss::Ok:iss::Err; return ret ? iss::Ok : iss::Err;
#else #else
if((addr==iss::arch::time || addr==iss::arch::timeh)){ if((addr == iss::arch::time || addr == iss::arch::timeh)) {
uint64_t time_val = owner->mtime_i.read(); uint64_t time_val = owner->mtime_i.read();
if (addr == iss::arch::time) { if(addr == iss::arch::time) {
val = static_cast<reg_t>(time_val); val = static_cast<reg_t>(time_val);
} else if (addr == iss::arch::timeh) { } else if(addr == iss::arch::timeh) {
if (sizeof(reg_t) != 4) return iss::Err; if(sizeof(reg_t) != 4)
return iss::Err;
val = static_cast<reg_t>(time_val >> 32); val = static_cast<reg_t>(time_val >> 32);
} }
return iss::Ok; return iss::Ok;
@ -153,7 +151,7 @@ public:
void local_irq(short id, bool value) override { void local_irq(short id, bool value) override {
reg_t mask = 0; reg_t mask = 0;
switch (id) { switch(id) {
case 3: // SW case 3: // SW
mask = 1 << 3; mask = 1 << 3;
break; break;
@ -164,10 +162,11 @@ public:
mask = 1 << 11; mask = 1 << 11;
break; break;
default: default:
if(id>15) mask = 1 << id; if(id > 15)
mask = 1 << id;
break; break;
} }
if (value) { if(value) {
this->csr[iss::arch::mip] |= mask; this->csr[iss::arch::mip] |= mask;
wfi_evt.notify(); wfi_evt.notify();
} else } else
@ -178,11 +177,11 @@ public:
} }
private: private:
sysc::tgfs::core_complex *const owner; sysc::tgfs::core_complex* const owner;
sc_core::sc_event wfi_evt; sc_core::sc_event wfi_evt;
uint64_t hostvar{std::numeric_limits<uint64_t>::max()}; uint64_t hostvar{std::numeric_limits<uint64_t>::max()};
unsigned to_host_wr_cnt = 0; unsigned to_host_wr_cnt = 0;
bool first{true}; bool first{true};
}; };
} } // namespace sysc
#endif /* _SYSC_SC_CORE_ADAPTER_H_ */ #endif /* _SYSC_SC_CORE_ADAPTER_H_ */

View File

@ -8,13 +8,12 @@
#ifndef _SYSC_SC_CORE_ADAPTER_IF_H_ #ifndef _SYSC_SC_CORE_ADAPTER_IF_H_
#define _SYSC_SC_CORE_ADAPTER_IF_H_ #define _SYSC_SC_CORE_ADAPTER_IF_H_
#include <scc/report.h>
#include <util/ities.h>
#include "core_complex.h" #include "core_complex.h"
#include <iostream>
#include <iss/iss.h> #include <iss/iss.h>
#include <iss/vm_types.h> #include <iss/vm_types.h>
#include <iostream> #include <scc/report.h>
#include <util/ities.h>
namespace sysc { namespace sysc {
struct sc_core_adapter_if { struct sc_core_adapter_if {
@ -27,5 +26,5 @@ struct sc_core_adapter_if {
virtual void local_irq(short id, bool value) = 0; virtual void local_irq(short id, bool value) = 0;
virtual ~sc_core_adapter_if() = default; virtual ~sc_core_adapter_if() = default;
}; };
} } // namespace sysc
#endif /* _SYSC_SC_CORE_ADAPTER_IF_H_ */ #endif /* _SYSC_SC_CORE_ADAPTER_IF_H_ */

View File

@ -1,26 +1,41 @@
x86::Mem get_reg_ptr(jit_holder& jh, unsigned idx){ x86::Mem get_reg_ptr(jit_holder& jh, unsigned idx) {
x86::Gp tmp_ptr = jh.cc.newUIntPtr("tmp_ptr"); x86::Gp tmp_ptr = jh.cc.newUIntPtr("tmp_ptr");
jh.cc.mov(tmp_ptr, jh.regs_base_ptr); jh.cc.mov(tmp_ptr, jh.regs_base_ptr);
jh.cc.add(tmp_ptr, traits::reg_byte_offsets[idx]); jh.cc.add(tmp_ptr, traits::reg_byte_offsets[idx]);
switch(traits::reg_bit_widths[idx]){ switch(traits::reg_bit_widths[idx]) {
case 8: case 8:
return x86::ptr_8(tmp_ptr); return x86::ptr_8(tmp_ptr);
case 16: case 16:
return x86::ptr_16(tmp_ptr); return x86::ptr_16(tmp_ptr);
case 32: case 32:
return x86::ptr_32(tmp_ptr); return x86::ptr_32(tmp_ptr);
case 64: case 64:
return x86::ptr_64(tmp_ptr); return x86::ptr_64(tmp_ptr);
default: default:
throw std::runtime_error("Invalid reg size in get_reg_ptr"); throw std::runtime_error("Invalid reg size in get_reg_ptr");
} }
} }
x86::Gp get_reg_for(jit_holder& jh, unsigned idx){ x86::Gp get_reg_for(jit_holder& jh, unsigned idx) {
//can check for regs in jh and return them instead of creating new ones // can check for regs in jh and return them instead of creating new ones
switch(traits::reg_bit_widths[idx]){ switch(traits::reg_bit_widths[idx]) {
case 8:
return jh.cc.newInt8();
case 16:
return jh.cc.newInt16();
case 32:
return jh.cc.newInt32();
case 64:
return jh.cc.newInt64();
default:
throw std::runtime_error("Invalid reg size in get_reg_ptr");
}
}
x86::Gp get_reg_for(jit_holder& jh, unsigned size, bool is_signed) {
if(is_signed)
switch(size) {
case 8: case 8:
return jh.cc.newInt8(); return jh.cc.newInt8();
case 16: case 16:
@ -32,23 +47,8 @@ x86::Gp get_reg_for(jit_holder& jh, unsigned idx){
default: default:
throw std::runtime_error("Invalid reg size in get_reg_ptr"); throw std::runtime_error("Invalid reg size in get_reg_ptr");
} }
}
x86::Gp get_reg_for(jit_holder& jh, unsigned size, bool is_signed){
if(is_signed)
switch(size){
case 8:
return jh.cc.newInt8();
case 16:
return jh.cc.newInt16();
case 32:
return jh.cc.newInt32();
case 64:
return jh.cc.newInt64();
default:
throw std::runtime_error("Invalid reg size in get_reg_ptr");
}
else else
switch(size){ switch(size) {
case 8: case 8:
return jh.cc.newUInt8(); return jh.cc.newUInt8();
case 16: case 16:
@ -61,18 +61,18 @@ x86::Gp get_reg_for(jit_holder& jh, unsigned size, bool is_signed){
throw std::runtime_error("Invalid reg size in get_reg_ptr"); throw std::runtime_error("Invalid reg size in get_reg_ptr");
} }
} }
inline x86::Gp load_reg_from_mem(jit_holder& jh, unsigned idx){ inline x86::Gp load_reg_from_mem(jit_holder& jh, unsigned idx) {
auto ptr = get_reg_ptr(jh, idx); auto ptr = get_reg_ptr(jh, idx);
auto reg = get_reg_for(jh, idx); auto reg = get_reg_for(jh, idx);
jh.cc.mov(reg, ptr); jh.cc.mov(reg, ptr);
return reg; return reg;
} }
inline void write_reg_to_mem(jit_holder& jh, x86::Gp reg, unsigned idx){ inline void write_reg_to_mem(jit_holder& jh, x86::Gp reg, unsigned idx) {
auto ptr = get_reg_ptr(jh, idx); auto ptr = get_reg_ptr(jh, idx);
jh.cc.mov(ptr, reg); jh.cc.mov(ptr, reg);
} }
void gen_instr_prologue(jit_holder& jh, addr_t pc){ void gen_instr_prologue(jit_holder& jh, addr_t pc) {
auto& cc = jh.cc; auto& cc = jh.cc;
cc.comment("\n//(*icount)++;"); cc.comment("\n//(*icount)++;");
@ -86,30 +86,27 @@ void gen_instr_prologue(jit_holder& jh, addr_t pc){
cc.comment("\n//increment *next_pc"); cc.comment("\n//increment *next_pc");
cc.mov(jh.next_pc, pc); cc.mov(jh.next_pc, pc);
} }
void gen_instr_epilogue(jit_holder& jh){ void gen_instr_epilogue(jit_holder& jh) {
auto& cc = jh.cc; auto& cc = jh.cc;
cc.comment("\n//if(*trap_state!=0) goto trap_entry;"); cc.comment("\n//if(*trap_state!=0) goto trap_entry;");
cc.test(jh.trap_state, jh.trap_state); cc.test(jh.trap_state, jh.trap_state);
cc.jnz(jh.trap_entry); cc.jnz(jh.trap_entry);
//Does this need to be done after every single instruction? // Does this need to be done after every single instruction?
cc.comment("\n//write back regs to mem"); cc.comment("\n//write back regs to mem");
write_reg_to_mem(jh, jh.pc, traits::PC); write_reg_to_mem(jh, jh.pc, traits::PC);
write_reg_to_mem(jh, jh.next_pc, traits::NEXT_PC); write_reg_to_mem(jh, jh.next_pc, traits::NEXT_PC);
write_reg_to_mem(jh, jh.trap_state, traits::TRAP_STATE); write_reg_to_mem(jh, jh.trap_state, traits::TRAP_STATE);
} }
void gen_block_prologue(jit_holder& jh) override{ void gen_block_prologue(jit_holder& jh) override {
jh.pc = load_reg_from_mem(jh, traits::PC); jh.pc = load_reg_from_mem(jh, traits::PC);
jh.next_pc = load_reg_from_mem(jh, traits::NEXT_PC); jh.next_pc = load_reg_from_mem(jh, traits::NEXT_PC);
jh.trap_state = load_reg_from_mem(jh, traits::TRAP_STATE); jh.trap_state = load_reg_from_mem(jh, traits::TRAP_STATE);
} }
void gen_block_epilogue(jit_holder& jh) override{ void gen_block_epilogue(jit_holder& jh) override {
x86::Compiler& cc = jh.cc; x86::Compiler& cc = jh.cc;
cc.comment("\n//return *next_pc;"); cc.comment("\n//return *next_pc;");
cc.ret(jh.next_pc); cc.ret(jh.next_pc);
@ -117,11 +114,11 @@ void gen_block_epilogue(jit_holder& jh) override{
cc.bind(jh.trap_entry); cc.bind(jh.trap_entry);
cc.comment("\n//enter_trap(core_ptr, *trap_state, *pc, 0);"); cc.comment("\n//enter_trap(core_ptr, *trap_state, *pc, 0);");
x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE); x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE);
cc.mov(current_trap_state, get_reg_ptr(jh, traits::TRAP_STATE)); cc.mov(current_trap_state, get_reg_ptr(jh, traits::TRAP_STATE));
x86::Gp current_pc = get_reg_for(jh, traits::PC); x86::Gp current_pc = get_reg_for(jh, traits::PC);
cc.mov(current_pc, get_reg_ptr(jh, traits::PC)); cc.mov(current_pc, get_reg_ptr(jh, traits::PC));
x86::Gp instr = cc.newInt32("instr"); x86::Gp instr = cc.newInt32("instr");
cc.mov(instr, 0); cc.mov(instr, 0);
@ -132,123 +129,162 @@ void gen_block_epilogue(jit_holder& jh) override{
call_enter_trap->setArg(2, current_pc); call_enter_trap->setArg(2, current_pc);
call_enter_trap->setArg(3, instr); call_enter_trap->setArg(3, instr);
cc.comment("\n//*last_branch = std::numeric_limits<uint32_t>::max();"); cc.comment("\n//*last_branch = std::numeric_limits<uint32_t>::max();");
cc.mov(get_reg_ptr(jh,traits::LAST_BRANCH), std::numeric_limits<uint32_t>::max()); cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), std::numeric_limits<uint32_t>::max());
cc.comment("\n//return *next_pc;"); cc.comment("\n//return *next_pc;");
cc.ret(jh.next_pc); cc.ret(jh.next_pc);
}
// TODO implement
} void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) { jh.cc.comment("//gen_raise"); }
//TODO implement void gen_wait(jit_holder& jh, unsigned type) { jh.cc.comment("//gen_wait"); }
void gen_leave(jit_holder& jh, unsigned lvl) { jh.cc.comment("//gen_leave"); }
void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) { enum operation { add, sub, band, bor, bxor, shl, sar, shr };
jh.cc.comment("//gen_raise");
}
void gen_wait(jit_holder& jh, unsigned type) {
jh.cc.comment("//gen_wait");
}
void gen_leave(jit_holder& jh, unsigned lvl){
jh.cc.comment("//gen_leave");
}
enum operation {add, sub, band, bor, bxor, shl, sar , shr};
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value || std::is_same<T, x86::Gp>::value>> template <typename T, typename = std::enable_if_t<std::is_integral<T>::value || std::is_same<T, x86::Gp>::value>>
x86::Gp gen_operation(jit_holder& jh, operation op, x86::Gp a, T b){ x86::Gp gen_operation(jit_holder& jh, operation op, x86::Gp a, T b) {
x86::Compiler& cc = jh.cc; x86::Compiler& cc = jh.cc;
switch (op) { switch(op) {
case add: { cc.add(a, b); break; } case add: {
case sub: { cc.sub(a, b); break; } cc.add(a, b);
case band: { cc.and_(a, b); break; } break;
case bor: { cc.or_(a, b); break; } }
case bxor: { cc.xor_(a, b); break; } case sub: {
case shl: { cc.shl(a, b); break; } cc.sub(a, b);
case sar: { cc.sar(a, b); break; } break;
case shr: { cc.shr(a, b); break; } }
default: throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (operation)", op)); case band: {
cc.and_(a, b);
break;
}
case bor: {
cc.or_(a, b);
break;
}
case bxor: {
cc.xor_(a, b);
break;
}
case shl: {
cc.shl(a, b);
break;
}
case sar: {
cc.sar(a, b);
break;
}
case shr: {
cc.shr(a, b);
break;
}
default:
throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (operation)", op));
} }
return a; return a;
} }
enum three_operand_operation{imul, mul, idiv, div, srem, urem}; enum three_operand_operation { imul, mul, idiv, div, srem, urem };
x86::Gp gen_operation(jit_holder& jh, three_operand_operation op, x86::Gp a, x86::Gp b){ x86::Gp gen_operation(jit_holder& jh, three_operand_operation op, x86::Gp a, x86::Gp b) {
x86::Compiler& cc = jh.cc; x86::Compiler& cc = jh.cc;
switch (op) { switch(op) {
case imul: { case imul: {
x86::Gp dummy = cc.newInt64(); x86::Gp dummy = cc.newInt64();
cc.imul(dummy, a.r64(), b.r64()); cc.imul(dummy, a.r64(), b.r64());
return a; return a;
} }
case mul: { case mul: {
x86::Gp dummy = cc.newInt64(); x86::Gp dummy = cc.newInt64();
cc.mul(dummy, a.r64(), b.r64()); cc.mul(dummy, a.r64(), b.r64());
return a; return a;
} }
case idiv: { case idiv: {
x86::Gp dummy = cc.newInt64(); x86::Gp dummy = cc.newInt64();
cc.mov(dummy, 0); cc.mov(dummy, 0);
cc.idiv(dummy, a.r64(), b.r64()); cc.idiv(dummy, a.r64(), b.r64());
return a; return a;
} }
case div: { case div: {
x86::Gp dummy = cc.newInt64(); x86::Gp dummy = cc.newInt64();
cc.mov(dummy, 0); cc.mov(dummy, 0);
cc.div(dummy, a.r64(), b.r64()); cc.div(dummy, a.r64(), b.r64());
return a; return a;
} }
case srem:{ case srem: {
x86::Gp rem = cc.newInt32(); x86::Gp rem = cc.newInt32();
cc.mov(rem, 0); cc.mov(rem, 0);
auto a_reg = cc.newInt32(); auto a_reg = cc.newInt32();
cc.mov(a_reg, a.r32()); cc.mov(a_reg, a.r32());
cc.idiv(rem, a_reg, b.r32()); cc.idiv(rem, a_reg, b.r32());
return rem; return rem;
} }
case urem:{ case urem: {
x86::Gp rem = cc.newInt32(); x86::Gp rem = cc.newInt32();
cc.mov(rem, 0); cc.mov(rem, 0);
auto a_reg = cc.newInt32(); auto a_reg = cc.newInt32();
cc.mov(a_reg, a.r32()); cc.mov(a_reg, a.r32());
cc.div(rem, a_reg, b.r32()); cc.div(rem, a_reg, b.r32());
return rem; return rem;
} }
default: throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (three_operand)", op)); default:
throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (three_operand)", op));
} }
return a; return a;
} }
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>> template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
x86::Gp gen_operation(jit_holder& jh, three_operand_operation op, x86::Gp a, T b){ x86::Gp gen_operation(jit_holder& jh, three_operand_operation op, x86::Gp a, T b) {
x86::Gp b_reg = jh.cc.newInt32(); x86::Gp b_reg = jh.cc.newInt32();
/* switch(a.size()){ /* switch(a.size()){
case 1: b_reg = jh.cc.newInt8(); break; case 1: b_reg = jh.cc.newInt8(); break;
case 2: b_reg = jh.cc.newInt16(); break; case 2: b_reg = jh.cc.newInt16(); break;
case 4: b_reg = jh.cc.newInt32(); break; case 4: b_reg = jh.cc.newInt32(); break;
case 8: b_reg = jh.cc.newInt64(); break; case 8: b_reg = jh.cc.newInt64(); break;
default: throw std::runtime_error(fmt::format("Invalid size ({}) in gen operation", a.size())); default: throw std::runtime_error(fmt::format("Invalid size ({}) in gen operation", a.size()));
} */ } */
jh.cc.mov(b_reg, b); jh.cc.mov(b_reg, b);
return gen_operation(jh, op, a, b_reg); return gen_operation(jh, op, a, b_reg);
} }
enum comparison_operation{land, lor, eq, ne, lt, ltu, gt, gtu, lte, lteu, gte, gteu}; enum comparison_operation { land, lor, eq, ne, lt, ltu, gt, gtu, lte, lteu, gte, gteu };
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value || std::is_same<T, x86::Gp>::value>> template <typename T, typename = std::enable_if_t<std::is_integral<T>::value || std::is_same<T, x86::Gp>::value>>
x86::Gp gen_operation(jit_holder& jh, comparison_operation op, x86::Gp a, T b){ x86::Gp gen_operation(jit_holder& jh, comparison_operation op, x86::Gp a, T b) {
x86::Compiler& cc = jh.cc; x86::Compiler& cc = jh.cc;
x86::Gp tmp = cc.newInt8(); x86::Gp tmp = cc.newInt8();
cc.mov(tmp,1); cc.mov(tmp, 1);
Label label_then = cc.newLabel(); Label label_then = cc.newLabel();
cc.cmp(a,b); cc.cmp(a, b);
switch (op) { switch(op) {
case eq: cc.je(label_then); break; case eq:
case ne: cc.jne(label_then); break; cc.je(label_then);
case lt: cc.jl(label_then); break; break;
case ltu: cc.jb(label_then); break; case ne:
case gt: cc.jg(label_then); break; cc.jne(label_then);
case gtu: cc.ja(label_then); break; break;
case lte: cc.jle(label_then); break; case lt:
case lteu: cc.jbe(label_then); break; cc.jl(label_then);
case gte: cc.jge(label_then); break; break;
case gteu: cc.jae(label_then); break; case ltu:
cc.jb(label_then);
break;
case gt:
cc.jg(label_then);
break;
case gtu:
cc.ja(label_then);
break;
case lte:
cc.jle(label_then);
break;
case lteu:
cc.jbe(label_then);
break;
case gte:
cc.jge(label_then);
break;
case gteu:
cc.jae(label_then);
break;
case land: { case land: {
Label label_false = cc.newLabel(); Label label_false = cc.newLabel();
cc.cmp(a, 0); cc.cmp(a, 0);
@ -270,75 +306,100 @@ x86::Gp gen_operation(jit_holder& jh, comparison_operation op, x86::Gp a, T b){
cc.jne(label_then); cc.jne(label_then);
break; break;
} }
default: throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (comparison)", op)); default:
throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (comparison)", op));
} }
cc.mov(tmp,0); cc.mov(tmp, 0);
cc.bind(label_then); cc.bind(label_then);
return tmp; return tmp;
} }
enum binary_operation{lnot, inc, dec, bnot, neg}; enum binary_operation { lnot, inc, dec, bnot, neg };
x86::Gp gen_operation(jit_holder& jh, binary_operation op, x86::Gp a){ x86::Gp gen_operation(jit_holder& jh, binary_operation op, x86::Gp a) {
x86::Compiler& cc = jh.cc; x86::Compiler& cc = jh.cc;
switch (op) { switch(op) {
case lnot: throw std::runtime_error("Current operation not supported in gen_operation(lnot)"); case lnot:
case inc: { cc.inc(a); break; } throw std::runtime_error("Current operation not supported in gen_operation(lnot)");
case dec: { cc.dec(a); break; } case inc: {
case bnot: { cc.not_(a); break; } cc.inc(a);
case neg: { cc.neg(a); break; } break;
default: throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (unary)", op)); }
case dec: {
cc.dec(a);
break;
}
case bnot: {
cc.not_(a);
break;
}
case neg: {
cc.neg(a);
break;
}
default:
throw std::runtime_error(fmt::format("Current operation {} not supported in gen_operation (unary)", op));
} }
return a; return a;
} }
/* template <typename T> /* template <typename T>
inline typename std::enable_if_t<std::is_unsigned<T>::value, x86::Gp> gen_ext(jit_holder& jh, T val, unsigned size, bool is_signed) const { inline typename std::enable_if_t<std::is_unsigned<T>::value, x86::Gp> gen_ext(jit_holder& jh, T val, unsigned size, bool
auto val_reg = get_reg_for(jh, sizeof(val)*8); is_signed) const { auto val_reg = get_reg_for(jh, sizeof(val)*8); auto tmp = get_reg_for(jh, size); jh.cc.mov(val_reg,
auto tmp = get_reg_for(jh, size); val); if(is_signed) jh.cc.movsx(tmp, val_reg); else jh.cc.movzx(tmp,val_reg); return tmp;
jh.cc.mov(val_reg, val);
if(is_signed) jh.cc.movsx(tmp, val_reg);
else jh.cc.movzx(tmp,val_reg);
return tmp;
} }
template <typename T> template <typename T>
inline typename std::enable_if_t<std::is_signed<T>::value, x86::Gp> gen_ext(jit_holder& jh, T val, unsigned size, bool is_signed) const { inline typename std::enable_if_t<std::is_signed<T>::value, x86::Gp> gen_ext(jit_holder& jh, T val, unsigned size, bool
auto val_reg = get_reg_for(jh, sizeof(val)*8); is_signed) const { auto val_reg = get_reg_for(jh, sizeof(val)*8); auto tmp = get_reg_for(jh, size); jh.cc.mov(val_reg,
auto tmp = get_reg_for(jh, size); val); if(is_signed) jh.cc.movsx(tmp, val_reg); else jh.cc.movzx(tmp,val_reg); return tmp;
jh.cc.mov(val_reg, val);
if(is_signed) jh.cc.movsx(tmp, val_reg);
else jh.cc.movzx(tmp,val_reg);
return tmp;
} */ } */
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>> template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
inline x86::Gp gen_ext(jit_holder& jh, T val, unsigned size, bool is_signed) { inline x86::Gp gen_ext(jit_holder& jh, T val, unsigned size, bool is_signed) {
auto val_reg = get_reg_for(jh, sizeof(val)*8); auto val_reg = get_reg_for(jh, sizeof(val) * 8);
jh.cc.mov(val_reg, val); jh.cc.mov(val_reg, val);
return gen_ext(jh, val_reg, size, is_signed); return gen_ext(jh, val_reg, size, is_signed);
} }
//explicit Gp size cast // explicit Gp size cast
inline x86::Gp gen_ext(jit_holder& jh, x86::Gp val, unsigned size, bool is_signed) { inline x86::Gp gen_ext(jit_holder& jh, x86::Gp val, unsigned size, bool is_signed) {
auto& cc = jh.cc; auto& cc = jh.cc;
if(is_signed){ if(is_signed) {
switch(val.size()){ switch(val.size()) {
case 1: cc.cbw(val); break; case 1:
case 2: cc.cwde(val); break; cc.cbw(val);
case 4: cc.cdqe(val); break; break;
case 8: break; case 2:
default: throw std::runtime_error("Invalid register size in gen_ext"); cc.cwde(val);
break;
case 4:
cc.cdqe(val);
break;
case 8:
break;
default:
throw std::runtime_error("Invalid register size in gen_ext");
} }
} }
switch(size){ switch(size) {
case 8: cc.and_(val,std::numeric_limits<uint8_t>::max()); return val.r8(); case 8:
case 16: cc.and_(val,std::numeric_limits<uint16_t>::max()); return val.r16(); cc.and_(val, std::numeric_limits<uint8_t>::max());
case 32: cc.and_(val,std::numeric_limits<uint32_t>::max()); return val.r32(); return val.r8();
case 64: cc.and_(val,std::numeric_limits<uint64_t>::max()); return val.r64(); case 16:
case 128: return val.r64(); cc.and_(val, std::numeric_limits<uint16_t>::max());
default: throw std::runtime_error("Invalid size in gen_ext"); return val.r16();
case 32:
cc.and_(val, std::numeric_limits<uint32_t>::max());
return val.r32();
case 64:
cc.and_(val, std::numeric_limits<uint64_t>::max());
return val.r64();
case 128:
return val.r64();
default:
throw std::runtime_error("Invalid size in gen_ext");
} }
} }
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint32_t length){ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint32_t length) {
x86::Compiler& cc = jh.cc; x86::Compiler& cc = jh.cc;
auto ret_reg = cc.newInt32(); auto ret_reg = cc.newInt32();
@ -355,28 +416,29 @@ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint3
uint64_t mask = 0; uint64_t mask = 0;
x86::Gp val_reg = cc.newInt64(); x86::Gp val_reg = cc.newInt64();
switch(length){ switch(length) {
case 1:{ case 1: {
cc.invoke(&invokeNode, &read_mem1, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uintptr_t>()); cc.invoke(&invokeNode, &read_mem1, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uintptr_t>());
mask = std::numeric_limits<uint8_t>::max(); mask = std::numeric_limits<uint8_t>::max();
break; break;
} }
case 2:{ case 2: {
cc.invoke(&invokeNode, &read_mem2, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uintptr_t>()); cc.invoke(&invokeNode, &read_mem2, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uintptr_t>());
mask = std::numeric_limits<uint16_t>::max(); mask = std::numeric_limits<uint16_t>::max();
break; break;
} }
case 4:{ case 4: {
cc.invoke(&invokeNode, &read_mem4, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uintptr_t>()); cc.invoke(&invokeNode, &read_mem4, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uintptr_t>());
mask = std::numeric_limits<uint32_t>::max(); mask = std::numeric_limits<uint32_t>::max();
break; break;
} }
case 8:{ case 8: {
cc.invoke(&invokeNode, &read_mem8, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uintptr_t>()); cc.invoke(&invokeNode, &read_mem8, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uintptr_t>());
mask = std::numeric_limits<uint64_t>::max(); mask = std::numeric_limits<uint64_t>::max();
break; break;
} }
default: throw std::runtime_error(fmt::format("Invalid length ({}) in gen_read_mem",length)); default:
throw std::runtime_error(fmt::format("Invalid length ({}) in gen_read_mem", length));
} }
invokeNode->setRet(0, ret_reg); invokeNode->setRet(0, ret_reg);
@ -388,42 +450,41 @@ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint3
cc.mov(val_reg, x86::ptr_64(val_ptr)); cc.mov(val_reg, x86::ptr_64(val_ptr));
cc.and_(val_reg, mask); cc.and_(val_reg, mask);
cc.cmp(ret_reg,0); cc.cmp(ret_reg, 0);
cc.jne(jh.trap_entry); cc.jne(jh.trap_entry);
return val_reg; return val_reg;
} }
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp length){ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp length) {
uint32_t length_val = 0; uint32_t length_val = 0;
auto length_ptr = jh.cc.newIntPtr(); auto length_ptr = jh.cc.newIntPtr();
jh.cc.mov(length_ptr, &length_val); jh.cc.mov(length_ptr, &length_val);
jh.cc.mov(x86::ptr_32(length_ptr),length); jh.cc.mov(x86::ptr_32(length_ptr), length);
return gen_read_mem(jh, type, addr, length); return gen_read_mem(jh, type, addr, length);
} }
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp length){ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp length) {
auto addr_reg = jh.cc.newInt64(); auto addr_reg = jh.cc.newInt64();
jh.cc.mov(addr_reg, addr); jh.cc.mov(addr_reg, addr);
uint32_t length_val = 0; uint32_t length_val = 0;
auto length_ptr = jh.cc.newIntPtr(); auto length_ptr = jh.cc.newIntPtr();
jh.cc.mov(length_ptr, &length_val); jh.cc.mov(length_ptr, &length_val);
jh.cc.mov(x86::ptr_32(length_ptr),length); jh.cc.mov(x86::ptr_32(length_ptr), length);
return gen_read_mem(jh, type, addr_reg, length_val); return gen_read_mem(jh, type, addr_reg, length_val);
} }
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, uint32_t length){ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, uint32_t length) {
auto addr_reg = jh.cc.newInt64(); auto addr_reg = jh.cc.newInt64();
jh.cc.mov(addr_reg, addr); jh.cc.mov(addr_reg, addr);
return gen_read_mem(jh, type, addr_reg, length); return gen_read_mem(jh, type, addr_reg, length);
} }
inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, int64_t val){ inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, int64_t val) {
auto val_reg = jh.cc.newInt64(); auto val_reg = jh.cc.newInt64();
jh.cc.mov(val_reg, val); jh.cc.mov(val_reg, val);
gen_write_mem(jh, type, addr, val_reg); gen_write_mem(jh, type, addr, val_reg);
} }
inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp val){ inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp val) {
x86::Compiler& cc = jh.cc; x86::Compiler& cc = jh.cc;
auto mem_type_reg = cc.newInt32(); auto mem_type_reg = cc.newInt32();
@ -433,42 +494,37 @@ inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp
auto ret_reg = cc.newInt32(); auto ret_reg = cc.newInt32();
InvokeNode* invokeNode; InvokeNode* invokeNode;
if(val.isGpb()){ if(val.isGpb()) {
cc.invoke(&invokeNode, &write_mem1, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint8_t>()); cc.invoke(&invokeNode, &write_mem1, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint8_t>());
} } else if(val.isGpw()) {
else if(val.isGpw()){
cc.invoke(&invokeNode, &write_mem2, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint16_t>()); cc.invoke(&invokeNode, &write_mem2, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint16_t>());
} } else if(val.isGpd()) {
else if(val.isGpd()){
cc.invoke(&invokeNode, &write_mem4, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint32_t>()); cc.invoke(&invokeNode, &write_mem4, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint32_t>());
} } else if(val.isGpq()) {
else if(val.isGpq()){
cc.invoke(&invokeNode, &write_mem8, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint64_t>()); cc.invoke(&invokeNode, &write_mem8, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint64_t>());
} } else
else throw std::runtime_error("Invalid register size in gen_write_mem"); throw std::runtime_error("Invalid register size in gen_write_mem");
invokeNode->setRet(0,ret_reg); invokeNode->setRet(0, ret_reg);
invokeNode->setArg(0, jh.arch_if_ptr); invokeNode->setArg(0, jh.arch_if_ptr);
invokeNode->setArg(1, space_reg); invokeNode->setArg(1, space_reg);
invokeNode->setArg(2, mem_type_reg); invokeNode->setArg(2, mem_type_reg);
invokeNode->setArg(3, addr); invokeNode->setArg(3, addr);
invokeNode->setArg(4, val); invokeNode->setArg(4, val);
cc.cmp(ret_reg,0); cc.cmp(ret_reg, 0);
cc.jne(jh.trap_entry); cc.jne(jh.trap_entry);
} }
inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp val){ inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp val) {
auto addr_reg = jh.cc.newInt64(); auto addr_reg = jh.cc.newInt64();
jh.cc.mov(addr_reg, addr); jh.cc.mov(addr_reg, addr);
gen_write_mem(jh, type, addr_reg, val); gen_write_mem(jh, type, addr_reg, val);
} }
inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, int64_t val){ inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, int64_t val) {
auto val_reg = jh.cc.newInt64(); auto val_reg = jh.cc.newInt64();
jh.cc.mov(val_reg, val); jh.cc.mov(val_reg, val);
auto addr_reg = jh.cc.newInt64(); auto addr_reg = jh.cc.newInt64();
jh.cc.mov(addr_reg, addr); jh.cc.mov(addr_reg, addr);
gen_write_mem(jh, type, addr_reg, val_reg); gen_write_mem(jh, type, addr_reg, val_reg);
} }

File diff suppressed because it is too large Load Diff

View File

@ -35,97 +35,90 @@
#include "fp_functions.h" #include "fp_functions.h"
extern "C" { extern "C" {
#include <softfloat.h>
#include "internals.h" #include "internals.h"
#include "specialize.h" #include "specialize.h"
#include <softfloat.h>
} }
#include <limits> #include <limits>
using this_t = uint8_t *; using this_t = uint8_t*;
const uint8_t rmm_map[] = { const uint8_t rmm_map[] = {
softfloat_round_near_even /*RNE*/, softfloat_round_near_even /*RNE*/, softfloat_round_minMag /*RTZ*/, softfloat_round_min /*RDN*/, softfloat_round_max /*RUP?*/,
softfloat_round_minMag/*RTZ*/, softfloat_round_near_maxMag /*RMM*/, softfloat_round_max /*RTZ*/, softfloat_round_max /*RTZ*/, softfloat_round_max /*RTZ*/,
softfloat_round_min/*RDN*/,
softfloat_round_max/*RUP?*/,
softfloat_round_near_maxMag /*RMM*/,
softfloat_round_max/*RTZ*/,
softfloat_round_max/*RTZ*/,
softfloat_round_max/*RTZ*/,
}; };
const uint32_t quiet_nan32=0x7fC00000; const uint32_t quiet_nan32 = 0x7fC00000;
extern "C" { extern "C" {
uint32_t fget_flags(){ uint32_t fget_flags() { return softfloat_exceptionFlags & 0x1f; }
return softfloat_exceptionFlags&0x1f;
}
uint32_t fadd_s(uint32_t v1, uint32_t v2, uint8_t mode) { uint32_t fadd_s(uint32_t v1, uint32_t v2, uint8_t mode) {
float32_t v1f{v1},v2f{v2}; float32_t v1f{v1}, v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float32_t r =f32_add(v1f, v2f); float32_t r = f32_add(v1f, v2f);
return r.v; return r.v;
} }
uint32_t fsub_s(uint32_t v1, uint32_t v2, uint8_t mode) { uint32_t fsub_s(uint32_t v1, uint32_t v2, uint8_t mode) {
float32_t v1f{v1},v2f{v2}; float32_t v1f{v1}, v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float32_t r=f32_sub(v1f, v2f); float32_t r = f32_sub(v1f, v2f);
return r.v; return r.v;
} }
uint32_t fmul_s(uint32_t v1, uint32_t v2, uint8_t mode) { uint32_t fmul_s(uint32_t v1, uint32_t v2, uint8_t mode) {
float32_t v1f{v1},v2f{v2}; float32_t v1f{v1}, v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float32_t r=f32_mul(v1f, v2f); float32_t r = f32_mul(v1f, v2f);
return r.v; return r.v;
} }
uint32_t fdiv_s(uint32_t v1, uint32_t v2, uint8_t mode) { uint32_t fdiv_s(uint32_t v1, uint32_t v2, uint8_t mode) {
float32_t v1f{v1},v2f{v2}; float32_t v1f{v1}, v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float32_t r=f32_div(v1f, v2f); float32_t r = f32_div(v1f, v2f);
return r.v; return r.v;
} }
uint32_t fsqrt_s(uint32_t v1, uint8_t mode) { uint32_t fsqrt_s(uint32_t v1, uint8_t mode) {
float32_t v1f{v1}; float32_t v1f{v1};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float32_t r=f32_sqrt(v1f); float32_t r = f32_sqrt(v1f);
return r.v; return r.v;
} }
uint32_t fcmp_s(uint32_t v1, uint32_t v2, uint32_t op) { uint32_t fcmp_s(uint32_t v1, uint32_t v2, uint32_t op) {
float32_t v1f{v1},v2f{v2}; float32_t v1f{v1}, v2f{v2};
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
bool nan = (v1&defaultNaNF32UI)==quiet_nan32 || (v2&defaultNaNF32UI)==quiet_nan32; bool nan = (v1 & defaultNaNF32UI) == quiet_nan32 || (v2 & defaultNaNF32UI) == quiet_nan32;
bool snan = softfloat_isSigNaNF32UI(v1) || softfloat_isSigNaNF32UI(v2); bool snan = softfloat_isSigNaNF32UI(v1) || softfloat_isSigNaNF32UI(v2);
switch(op){ switch(op) {
case 0: case 0:
if(nan | snan){ if(nan | snan) {
if(snan) softfloat_raiseFlags(softfloat_flag_invalid); if(snan)
softfloat_raiseFlags(softfloat_flag_invalid);
return 0; return 0;
} else } else
return f32_eq(v1f,v2f )?1:0; return f32_eq(v1f, v2f) ? 1 : 0;
case 1: case 1:
if(nan | snan){ if(nan | snan) {
softfloat_raiseFlags(softfloat_flag_invalid); softfloat_raiseFlags(softfloat_flag_invalid);
return 0; return 0;
} else } else
return f32_le(v1f,v2f )?1:0; return f32_le(v1f, v2f) ? 1 : 0;
case 2: case 2:
if(nan | snan){ if(nan | snan) {
softfloat_raiseFlags(softfloat_flag_invalid); softfloat_raiseFlags(softfloat_flag_invalid);
return 0; return 0;
} else } else
return f32_lt(v1f,v2f )?1:0; return f32_lt(v1f, v2f) ? 1 : 0;
default: default:
break; break;
} }
@ -134,22 +127,22 @@ uint32_t fcmp_s(uint32_t v1, uint32_t v2, uint32_t op) {
uint32_t fcvt_s(uint32_t v1, uint32_t op, uint8_t mode) { uint32_t fcvt_s(uint32_t v1, uint32_t op, uint8_t mode) {
float32_t v1f{v1}; float32_t v1f{v1};
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float32_t r; float32_t r;
switch(op){ switch(op) {
case 0:{ //w->s, fp to int32 case 0: { // w->s, fp to int32
uint_fast32_t res = f32_to_i32(v1f,rmm_map[mode&0x7],true); uint_fast32_t res = f32_to_i32(v1f, rmm_map[mode & 0x7], true);
return (uint32_t)res; return (uint32_t)res;
} }
case 1:{ //wu->s case 1: { // wu->s
uint_fast32_t res = f32_to_ui32(v1f,rmm_map[mode&0x7],true); uint_fast32_t res = f32_to_ui32(v1f, rmm_map[mode & 0x7], true);
return (uint32_t)res; return (uint32_t)res;
} }
case 2: //s->w case 2: // s->w
r=i32_to_f32(v1); r = i32_to_f32(v1);
return r.v; return r.v;
case 3: //s->wu case 3: // s->wu
r=ui32_to_f32(v1); r = ui32_to_f32(v1);
return r.v; return r.v;
} }
return 0; return 0;
@ -157,10 +150,11 @@ uint32_t fcvt_s(uint32_t v1, uint32_t op, uint8_t mode) {
uint32_t fmadd_s(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mode) { uint32_t fmadd_s(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mode) {
// op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)} // op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)}
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float32_t res = softfloat_mulAddF32(v1, v2, v3, op&0x1); float32_t res = softfloat_mulAddF32(v1, v2, v3, op & 0x1);
if(op>1) res.v ^= 1ULL<<31; if(op > 1)
res.v ^= 1ULL << 31;
return res.v; return res.v;
} }
@ -170,23 +164,23 @@ uint32_t fsel_s(uint32_t v1, uint32_t v2, uint32_t op) {
bool v2_nan = (v2 & defaultNaNF32UI) == defaultNaNF32UI; bool v2_nan = (v2 & defaultNaNF32UI) == defaultNaNF32UI;
bool v1_snan = softfloat_isSigNaNF32UI(v1); bool v1_snan = softfloat_isSigNaNF32UI(v1);
bool v2_snan = softfloat_isSigNaNF32UI(v2); bool v2_snan = softfloat_isSigNaNF32UI(v2);
if (v1_snan || v2_snan) softfloat_raiseFlags(softfloat_flag_invalid); if(v1_snan || v2_snan)
if (v1_nan || v1_snan) softfloat_raiseFlags(softfloat_flag_invalid);
if(v1_nan || v1_snan)
return (v2_nan || v2_snan) ? defaultNaNF32UI : v2; return (v2_nan || v2_snan) ? defaultNaNF32UI : v2;
else else if(v2_nan || v2_snan)
if (v2_nan || v2_snan) return v1;
return v1; else {
else { if((v1 & 0x7fffffff) == 0 && (v2 & 0x7fffffff) == 0) {
if ((v1 & 0x7fffffff) == 0 && (v2 & 0x7fffffff) == 0) { return op == 0 ? ((v1 & 0x80000000) ? v1 : v2) : ((v1 & 0x80000000) ? v2 : v1);
return op == 0 ? ((v1 & 0x80000000) ? v1 : v2) : ((v1 & 0x80000000) ? v2 : v1); } else {
} else { float32_t v1f{v1}, v2f{v2};
float32_t v1f{ v1 }, v2f{ v2 }; return op == 0 ? (f32_lt(v1f, v2f) ? v1 : v2) : (f32_lt(v1f, v2f) ? v2 : v1);
return op == 0 ? (f32_lt(v1f, v2f) ? v1 : v2) : (f32_lt(v1f, v2f) ? v2 : v1);
}
} }
}
} }
uint32_t fclass_s( uint32_t v1 ){ uint32_t fclass_s(uint32_t v1) {
float32_t a{v1}; float32_t a{v1};
union ui32_f32 uA; union ui32_f32 uA;
@ -195,30 +189,23 @@ uint32_t fclass_s( uint32_t v1 ){
uA.f = a; uA.f = a;
uiA = uA.ui; uiA = uA.ui;
uint_fast16_t infOrNaN = expF32UI( uiA ) == 0xFF; uint_fast16_t infOrNaN = expF32UI(uiA) == 0xFF;
uint_fast16_t subnormalOrZero = expF32UI( uiA ) == 0; uint_fast16_t subnormalOrZero = expF32UI(uiA) == 0;
bool sign = signF32UI( uiA ); bool sign = signF32UI(uiA);
bool fracZero = fracF32UI( uiA ) == 0; bool fracZero = fracF32UI(uiA) == 0;
bool isNaN = isNaNF32UI( uiA ); bool isNaN = isNaNF32UI(uiA);
bool isSNaN = softfloat_isSigNaNF32UI( uiA ); bool isSNaN = softfloat_isSigNaNF32UI(uiA);
return return (sign && infOrNaN && fracZero) << 0 | (sign && !infOrNaN && !subnormalOrZero) << 1 |
( sign && infOrNaN && fracZero ) << 0 | (sign && subnormalOrZero && !fracZero) << 2 | (sign && subnormalOrZero && fracZero) << 3 | (!sign && infOrNaN && fracZero) << 7 |
( sign && !infOrNaN && !subnormalOrZero ) << 1 | (!sign && !infOrNaN && !subnormalOrZero) << 6 | (!sign && subnormalOrZero && !fracZero) << 5 |
( sign && subnormalOrZero && !fracZero ) << 2 | (!sign && subnormalOrZero && fracZero) << 4 | (isNaN && isSNaN) << 8 | (isNaN && !isSNaN) << 9;
( sign && subnormalOrZero && fracZero ) << 3 |
( !sign && infOrNaN && fracZero ) << 7 |
( !sign && !infOrNaN && !subnormalOrZero ) << 6 |
( !sign && subnormalOrZero && !fracZero ) << 5 |
( !sign && subnormalOrZero && fracZero ) << 4 |
( isNaN && isSNaN ) << 8 |
( isNaN && !isSNaN ) << 9;
} }
uint32_t fconv_d2f(uint64_t v1, uint8_t mode){ uint32_t fconv_d2f(uint64_t v1, uint8_t mode) {
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
bool nan = (v1 & defaultNaNF64UI)==defaultNaNF64UI; bool nan = (v1 & defaultNaNF64UI) == defaultNaNF64UI;
if(nan){ if(nan) {
return defaultNaNF32UI; return defaultNaNF32UI;
} else { } else {
float32_t res = f64_to_f32(float64_t{v1}); float32_t res = f64_to_f32(float64_t{v1});
@ -226,83 +213,84 @@ uint32_t fconv_d2f(uint64_t v1, uint8_t mode){
} }
} }
uint64_t fconv_f2d(uint32_t v1, uint8_t mode){ uint64_t fconv_f2d(uint32_t v1, uint8_t mode) {
bool nan = (v1 & defaultNaNF32UI)==defaultNaNF32UI; bool nan = (v1 & defaultNaNF32UI) == defaultNaNF32UI;
if(nan){ if(nan) {
return defaultNaNF64UI; return defaultNaNF64UI;
} else { } else {
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
float64_t res = f32_to_f64(float32_t{v1}); float64_t res = f32_to_f64(float32_t{v1});
return res.v; return res.v;
} }
} }
uint64_t fadd_d(uint64_t v1, uint64_t v2, uint8_t mode) { uint64_t fadd_d(uint64_t v1, uint64_t v2, uint8_t mode) {
bool nan = (v1&defaultNaNF32UI)==quiet_nan32; bool nan = (v1 & defaultNaNF32UI) == quiet_nan32;
bool snan = softfloat_isSigNaNF32UI(v1); bool snan = softfloat_isSigNaNF32UI(v1);
float64_t v1f{v1},v2f{v2}; float64_t v1f{v1}, v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float64_t r =f64_add(v1f, v2f); float64_t r = f64_add(v1f, v2f);
return r.v; return r.v;
} }
uint64_t fsub_d(uint64_t v1, uint64_t v2, uint8_t mode) { uint64_t fsub_d(uint64_t v1, uint64_t v2, uint8_t mode) {
float64_t v1f{v1},v2f{v2}; float64_t v1f{v1}, v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float64_t r=f64_sub(v1f, v2f); float64_t r = f64_sub(v1f, v2f);
return r.v; return r.v;
} }
uint64_t fmul_d(uint64_t v1, uint64_t v2, uint8_t mode) { uint64_t fmul_d(uint64_t v1, uint64_t v2, uint8_t mode) {
float64_t v1f{v1},v2f{v2}; float64_t v1f{v1}, v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float64_t r=f64_mul(v1f, v2f); float64_t r = f64_mul(v1f, v2f);
return r.v; return r.v;
} }
uint64_t fdiv_d(uint64_t v1, uint64_t v2, uint8_t mode) { uint64_t fdiv_d(uint64_t v1, uint64_t v2, uint8_t mode) {
float64_t v1f{v1},v2f{v2}; float64_t v1f{v1}, v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float64_t r=f64_div(v1f, v2f); float64_t r = f64_div(v1f, v2f);
return r.v; return r.v;
} }
uint64_t fsqrt_d(uint64_t v1, uint8_t mode) { uint64_t fsqrt_d(uint64_t v1, uint8_t mode) {
float64_t v1f{v1}; float64_t v1f{v1};
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float64_t r=f64_sqrt(v1f); float64_t r = f64_sqrt(v1f);
return r.v; return r.v;
} }
uint64_t fcmp_d(uint64_t v1, uint64_t v2, uint32_t op) { uint64_t fcmp_d(uint64_t v1, uint64_t v2, uint32_t op) {
float64_t v1f{v1},v2f{v2}; float64_t v1f{v1}, v2f{v2};
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
bool nan = (v1&defaultNaNF64UI)==quiet_nan32 || (v2&defaultNaNF64UI)==quiet_nan32; bool nan = (v1 & defaultNaNF64UI) == quiet_nan32 || (v2 & defaultNaNF64UI) == quiet_nan32;
bool snan = softfloat_isSigNaNF64UI(v1) || softfloat_isSigNaNF64UI(v2); bool snan = softfloat_isSigNaNF64UI(v1) || softfloat_isSigNaNF64UI(v2);
switch(op){ switch(op) {
case 0: case 0:
if(nan | snan){ if(nan | snan) {
if(snan) softfloat_raiseFlags(softfloat_flag_invalid); if(snan)
softfloat_raiseFlags(softfloat_flag_invalid);
return 0; return 0;
} else } else
return f64_eq(v1f,v2f )?1:0; return f64_eq(v1f, v2f) ? 1 : 0;
case 1: case 1:
if(nan | snan){ if(nan | snan) {
softfloat_raiseFlags(softfloat_flag_invalid); softfloat_raiseFlags(softfloat_flag_invalid);
return 0; return 0;
} else } else
return f64_le(v1f,v2f )?1:0; return f64_le(v1f, v2f) ? 1 : 0;
case 2: case 2:
if(nan | snan){ if(nan | snan) {
softfloat_raiseFlags(softfloat_flag_invalid); softfloat_raiseFlags(softfloat_flag_invalid);
return 0; return 0;
} else } else
return f64_lt(v1f,v2f )?1:0; return f64_lt(v1f, v2f) ? 1 : 0;
default: default:
break; break;
} }
@ -311,22 +299,22 @@ uint64_t fcmp_d(uint64_t v1, uint64_t v2, uint32_t op) {
uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode) { uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode) {
float64_t v1f{v1}; float64_t v1f{v1};
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float64_t r; float64_t r;
switch(op){ switch(op) {
case 0:{ //l->d, fp to int32 case 0: { // l->d, fp to int32
int64_t res = f64_to_i64(v1f,rmm_map[mode&0x7],true); int64_t res = f64_to_i64(v1f, rmm_map[mode & 0x7], true);
return (uint64_t)res; return (uint64_t)res;
} }
case 1:{ //lu->s case 1: { // lu->s
uint64_t res = f64_to_ui64(v1f,rmm_map[mode&0x7],true); uint64_t res = f64_to_ui64(v1f, rmm_map[mode & 0x7], true);
return res; return res;
} }
case 2: //s->l case 2: // s->l
r=i64_to_f64(v1); r = i64_to_f64(v1);
return r.v; return r.v;
case 3: //s->lu case 3: // s->lu
r=ui64_to_f64(v1); r = ui64_to_f64(v1);
return r.v; return r.v;
} }
return 0; return 0;
@ -334,10 +322,11 @@ uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode) {
uint64_t fmadd_d(uint64_t v1, uint64_t v2, uint64_t v3, uint32_t op, uint8_t mode) { uint64_t fmadd_d(uint64_t v1, uint64_t v2, uint64_t v3, uint32_t op, uint8_t mode) {
// op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)} // op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)}
softfloat_roundingMode=rmm_map[mode&0x7]; softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float64_t res = softfloat_mulAddF64(v1, v2, v3, op&0x1); float64_t res = softfloat_mulAddF64(v1, v2, v3, op & 0x1);
if(op>1) res.v ^= 1ULL<<63; if(op > 1)
res.v ^= 1ULL << 63;
return res.v; return res.v;
} }
@ -347,27 +336,24 @@ uint64_t fsel_d(uint64_t v1, uint64_t v2, uint32_t op) {
bool v2_nan = (v2 & defaultNaNF64UI) == defaultNaNF64UI; bool v2_nan = (v2 & defaultNaNF64UI) == defaultNaNF64UI;
bool v1_snan = softfloat_isSigNaNF64UI(v1); bool v1_snan = softfloat_isSigNaNF64UI(v1);
bool v2_snan = softfloat_isSigNaNF64UI(v2); bool v2_snan = softfloat_isSigNaNF64UI(v2);
if (v1_snan || v2_snan) softfloat_raiseFlags(softfloat_flag_invalid); if(v1_snan || v2_snan)
if (v1_nan || v1_snan) softfloat_raiseFlags(softfloat_flag_invalid);
if(v1_nan || v1_snan)
return (v2_nan || v2_snan) ? defaultNaNF64UI : v2; return (v2_nan || v2_snan) ? defaultNaNF64UI : v2;
else else if(v2_nan || v2_snan)
if (v2_nan || v2_snan) return v1;
return v1; else {
else { if((v1 & std::numeric_limits<int64_t>::max()) == 0 && (v2 & std::numeric_limits<int64_t>::max()) == 0) {
if ((v1 & std::numeric_limits<int64_t>::max()) == 0 && (v2 & std::numeric_limits<int64_t>::max()) == 0) { return op == 0 ? ((v1 & std::numeric_limits<int64_t>::min()) ? v1 : v2)
return op == 0 ? : ((v1 & std::numeric_limits<int64_t>::min()) ? v2 : v1);
((v1 & std::numeric_limits<int64_t>::min()) ? v1 : v2) : } else {
((v1 & std::numeric_limits<int64_t>::min()) ? v2 : v1); float64_t v1f{v1}, v2f{v2};
} else { return op == 0 ? (f64_lt(v1f, v2f) ? v1 : v2) : (f64_lt(v1f, v2f) ? v2 : v1);
float64_t v1f{ v1 }, v2f{ v2 };
return op == 0 ?
(f64_lt(v1f, v2f) ? v1 : v2) :
(f64_lt(v1f, v2f) ? v2 : v1);
}
} }
}
} }
uint64_t fclass_d(uint64_t v1 ){ uint64_t fclass_d(uint64_t v1) {
float64_t a{v1}; float64_t a{v1};
union ui64_f64 uA; union ui64_f64 uA;
@ -376,68 +362,61 @@ uint64_t fclass_d(uint64_t v1 ){
uA.f = a; uA.f = a;
uiA = uA.ui; uiA = uA.ui;
uint_fast16_t infOrNaN = expF64UI( uiA ) == 0x7FF; uint_fast16_t infOrNaN = expF64UI(uiA) == 0x7FF;
uint_fast16_t subnormalOrZero = expF64UI( uiA ) == 0; uint_fast16_t subnormalOrZero = expF64UI(uiA) == 0;
bool sign = signF64UI( uiA ); bool sign = signF64UI(uiA);
bool fracZero = fracF64UI( uiA ) == 0; bool fracZero = fracF64UI(uiA) == 0;
bool isNaN = isNaNF64UI( uiA ); bool isNaN = isNaNF64UI(uiA);
bool isSNaN = softfloat_isSigNaNF64UI( uiA ); bool isSNaN = softfloat_isSigNaNF64UI(uiA);
return return (sign && infOrNaN && fracZero) << 0 | (sign && !infOrNaN && !subnormalOrZero) << 1 |
( sign && infOrNaN && fracZero ) << 0 | (sign && subnormalOrZero && !fracZero) << 2 | (sign && subnormalOrZero && fracZero) << 3 | (!sign && infOrNaN && fracZero) << 7 |
( sign && !infOrNaN && !subnormalOrZero ) << 1 | (!sign && !infOrNaN && !subnormalOrZero) << 6 | (!sign && subnormalOrZero && !fracZero) << 5 |
( sign && subnormalOrZero && !fracZero ) << 2 | (!sign && subnormalOrZero && fracZero) << 4 | (isNaN && isSNaN) << 8 | (isNaN && !isSNaN) << 9;
( sign && subnormalOrZero && fracZero ) << 3 |
( !sign && infOrNaN && fracZero ) << 7 |
( !sign && !infOrNaN && !subnormalOrZero ) << 6 |
( !sign && subnormalOrZero && !fracZero ) << 5 |
( !sign && subnormalOrZero && fracZero ) << 4 |
( isNaN && isSNaN ) << 8 |
( isNaN && !isSNaN ) << 9;
} }
uint64_t fcvt_32_64(uint32_t v1, uint32_t op, uint8_t mode) { uint64_t fcvt_32_64(uint32_t v1, uint32_t op, uint8_t mode) {
float32_t v1f{v1}; float32_t v1f{v1};
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float64_t r; float64_t r;
switch(op){ switch(op) {
case 0: //l->s, fp to int32 case 0: // l->s, fp to int32
return f32_to_i64(v1f,rmm_map[mode&0x7],true); return f32_to_i64(v1f, rmm_map[mode & 0x7], true);
case 1: //wu->s case 1: // wu->s
return f32_to_ui64(v1f,rmm_map[mode&0x7],true); return f32_to_ui64(v1f, rmm_map[mode & 0x7], true);
case 2: //s->w case 2: // s->w
r=i32_to_f64(v1); r = i32_to_f64(v1);
return r.v; return r.v;
case 3: //s->wu case 3: // s->wu
r=ui32_to_f64(v1); r = ui32_to_f64(v1);
return r.v; return r.v;
} }
return 0; return 0;
} }
uint32_t fcvt_64_32(uint64_t v1, uint32_t op, uint8_t mode) { uint32_t fcvt_64_32(uint64_t v1, uint32_t op, uint8_t mode) {
softfloat_exceptionFlags=0; softfloat_exceptionFlags = 0;
float32_t r; float32_t r;
switch(op){ switch(op) {
case 0:{ //wu->s case 0: { // wu->s
int32_t r=f64_to_i32(float64_t{v1}, rmm_map[mode&0x7],true); int32_t r = f64_to_i32(float64_t{v1}, rmm_map[mode & 0x7], true);
return r; return r;
} }
case 1:{ //wu->s case 1: { // wu->s
uint32_t r=f64_to_ui32(float64_t{v1}, rmm_map[mode&0x7],true); uint32_t r = f64_to_ui32(float64_t{v1}, rmm_map[mode & 0x7], true);
return r; return r;
} }
case 2: //l->s, fp to int32 case 2: // l->s, fp to int32
r=i64_to_f32(v1); r = i64_to_f32(v1);
return r.v; return r.v;
case 3: //wu->s case 3: // wu->s
r=ui64_to_f32(v1); r = ui64_to_f32(v1);
return r.v; return r.v;
} }
return 0; return 0;
} }
uint32_t unbox_s(uint64_t v){ uint32_t unbox_s(uint64_t v) {
constexpr uint64_t mask = std::numeric_limits<uint64_t>::max() & ~((uint64_t)std::numeric_limits<uint32_t>::max()); constexpr uint64_t mask = std::numeric_limits<uint64_t>::max() & ~((uint64_t)std::numeric_limits<uint32_t>::max());
if((v & mask) != mask) if((v & mask) != mask)
return 0x7fc00000; return 0x7fc00000;
@ -445,4 +424,3 @@ uint32_t unbox_s(uint64_t v){
return v & std::numeric_limits<uint32_t>::max(); return v & std::numeric_limits<uint32_t>::max();
} }
} }

View File

@ -44,11 +44,11 @@ uint32_t fsub_s(uint32_t v1, uint32_t v2, uint8_t mode);
uint32_t fmul_s(uint32_t v1, uint32_t v2, uint8_t mode); uint32_t fmul_s(uint32_t v1, uint32_t v2, uint8_t mode);
uint32_t fdiv_s(uint32_t v1, uint32_t v2, uint8_t mode); uint32_t fdiv_s(uint32_t v1, uint32_t v2, uint8_t mode);
uint32_t fsqrt_s(uint32_t v1, uint8_t mode); uint32_t fsqrt_s(uint32_t v1, uint8_t mode);
uint32_t fcmp_s(uint32_t v1, uint32_t v2, uint32_t op) ; uint32_t fcmp_s(uint32_t v1, uint32_t v2, uint32_t op);
uint32_t fcvt_s(uint32_t v1, uint32_t op, uint8_t mode); uint32_t fcvt_s(uint32_t v1, uint32_t op, uint8_t mode);
uint32_t fmadd_s(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mode); uint32_t fmadd_s(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mode);
uint32_t fsel_s(uint32_t v1, uint32_t v2, uint32_t op); uint32_t fsel_s(uint32_t v1, uint32_t v2, uint32_t op);
uint32_t fclass_s( uint32_t v1 ); uint32_t fclass_s(uint32_t v1);
uint32_t fconv_d2f(uint64_t v1, uint8_t mode); uint32_t fconv_d2f(uint64_t v1, uint8_t mode);
uint64_t fconv_f2d(uint32_t v1, uint8_t mode); uint64_t fconv_f2d(uint32_t v1, uint8_t mode);
uint64_t fadd_d(uint64_t v1, uint64_t v2, uint8_t mode); uint64_t fadd_d(uint64_t v1, uint64_t v2, uint8_t mode);
@ -59,8 +59,8 @@ uint64_t fsqrt_d(uint64_t v1, uint8_t mode);
uint64_t fcmp_d(uint64_t v1, uint64_t v2, uint32_t op); uint64_t fcmp_d(uint64_t v1, uint64_t v2, uint32_t op);
uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode); uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode);
uint64_t fmadd_d(uint64_t v1, uint64_t v2, uint64_t v3, uint32_t op, uint8_t mode); uint64_t fmadd_d(uint64_t v1, uint64_t v2, uint64_t v3, uint32_t op, uint8_t mode);
uint64_t fsel_d(uint64_t v1, uint64_t v2, uint32_t op) ; uint64_t fsel_d(uint64_t v1, uint64_t v2, uint32_t op);
uint64_t fclass_d(uint64_t v1 ); uint64_t fclass_d(uint64_t v1);
uint64_t fcvt_32_64(uint32_t v1, uint32_t op, uint8_t mode); uint64_t fcvt_32_64(uint32_t v1, uint32_t op, uint8_t mode);
uint32_t fcvt_64_32(uint64_t v1, uint32_t op, uint8_t mode); uint32_t fcvt_64_32(uint64_t v1, uint32_t op, uint8_t mode);
uint32_t unbox_s(uint64_t v); uint32_t unbox_s(uint64_t v);

File diff suppressed because it is too large Load Diff

View File

@ -36,9 +36,9 @@
#include <iss/llvm/vm_base.h> #include <iss/llvm/vm_base.h>
extern "C" { extern "C" {
#include <softfloat.h>
#include "internals.h" #include "internals.h"
#include "specialize.h" #include "specialize.h"
#include <softfloat.h>
} }
#include <limits> #include <limits>
@ -50,60 +50,58 @@ namespace fp_impl {
using namespace std; using namespace std;
using namespace ::llvm; using namespace ::llvm;
#define INT_TYPE(L) Type::getIntNTy(mod->getContext(), L) #define INT_TYPE(L) Type::getIntNTy(mod->getContext(), L)
#define FLOAT_TYPE Type::getFloatTy(mod->getContext()) #define FLOAT_TYPE Type::getFloatTy(mod->getContext())
#define DOUBLE_TYPE Type::getDoubleTy(mod->getContext()) #define DOUBLE_TYPE Type::getDoubleTy(mod->getContext())
#define VOID_TYPE Type::getVoidTy(mod->getContext()) #define VOID_TYPE Type::getVoidTy(mod->getContext())
#define THIS_PTR_TYPE Type::getIntNPtrTy(mod->getContext(), 8) #define THIS_PTR_TYPE Type::getIntNPtrTy(mod->getContext(), 8)
#define FDECLL(NAME, RET, ...) \ #define FDECLL(NAME, RET, ...) \
Function *NAME##_func = CurrentModule->getFunction(#NAME); \ Function* NAME##_func = CurrentModule->getFunction(#NAME); \
if (!NAME##_func) { \ if(!NAME##_func) { \
std::vector<Type *> NAME##_args{__VA_ARGS__}; \ std::vector<Type*> NAME##_args{__VA_ARGS__}; \
FunctionType *NAME##_type = FunctionType::get(RET, NAME##_args, false); \ FunctionType* NAME##_type = FunctionType::get(RET, NAME##_args, false); \
NAME##_func = Function::Create(NAME##_type, GlobalValue::ExternalLinkage, #NAME, CurrentModule); \ NAME##_func = Function::Create(NAME##_type, GlobalValue::ExternalLinkage, #NAME, CurrentModule); \
NAME##_func->setCallingConv(CallingConv::C); \ NAME##_func->setCallingConv(CallingConv::C); \
} }
#define FDECL(NAME, RET, ...) \ #define FDECL(NAME, RET, ...) \
std::vector<Type *> NAME##_args{__VA_ARGS__}; \ std::vector<Type*> NAME##_args{__VA_ARGS__}; \
FunctionType *NAME##_type = FunctionType::get(RET, NAME##_args, false); \ FunctionType* NAME##_type = FunctionType::get(RET, NAME##_args, false); \
mod->getOrInsertFunction(#NAME, NAME##_type); mod->getOrInsertFunction(#NAME, NAME##_type);
void add_fp_functions_2_module(Module* mod, uint32_t flen, uint32_t xlen) {
void add_fp_functions_2_module(Module *mod, uint32_t flen, uint32_t xlen) { if(flen) {
if(flen){
FDECL(fget_flags, INT_TYPE(32)); FDECL(fget_flags, INT_TYPE(32));
FDECL(fadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); FDECL(fadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
FDECL(fsub_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); FDECL(fsub_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
FDECL(fmul_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); FDECL(fmul_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
FDECL(fdiv_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); FDECL(fdiv_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
FDECL(fsqrt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); FDECL(fsqrt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
FDECL(fcmp_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32)); FDECL(fcmp_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32));
FDECL(fcvt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); FDECL(fcvt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
FDECL(fmadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); FDECL(fmadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
FDECL(fsel_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32)); FDECL(fsel_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32));
FDECL(fclass_s, INT_TYPE(32), INT_TYPE(32)); FDECL(fclass_s, INT_TYPE(32), INT_TYPE(32));
FDECL(fcvt_32_64, INT_TYPE(64), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); FDECL(fcvt_32_64, INT_TYPE(64), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
FDECL(fcvt_64_32, INT_TYPE(32), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); FDECL(fcvt_64_32, INT_TYPE(32), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8));
if(flen>32){ if(flen > 32) {
FDECL(fconv_d2f, INT_TYPE(32), INT_TYPE(64), INT_TYPE(8)); FDECL(fconv_d2f, INT_TYPE(32), INT_TYPE(64), INT_TYPE(8));
FDECL(fconv_f2d, INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); FDECL(fconv_f2d, INT_TYPE(64), INT_TYPE(32), INT_TYPE(8));
FDECL(fadd_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); FDECL(fadd_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
FDECL(fsub_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); FDECL(fsub_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
FDECL(fmul_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); FDECL(fmul_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
FDECL(fdiv_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); FDECL(fdiv_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
FDECL(fsqrt_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(8)); FDECL(fsqrt_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(8));
FDECL(fcmp_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32)); FDECL(fcmp_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32));
FDECL(fcvt_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); FDECL(fcvt_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8));
FDECL(fmadd_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); FDECL(fmadd_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8));
FDECL(fsel_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32)); FDECL(fsel_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32));
FDECL(fclass_d, INT_TYPE(64), INT_TYPE(64)); FDECL(fclass_d, INT_TYPE(64), INT_TYPE(64));
FDECL(unbox_s, INT_TYPE(32), INT_TYPE(64)); FDECL(unbox_s, INT_TYPE(32), INT_TYPE(64));
} }
} }
} }
} } // namespace fp_impl
} } // namespace llvm
} } // namespace iss

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff